Skip to content

Commit

Permalink
PRINCE: loadSample with sample looping added, escaping from intro works
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamil Zbróg committed Dec 3, 2013
1 parent f19f61a commit 69a5845
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 27 deletions.
1 change: 1 addition & 0 deletions engines/prince/archive.cpp
Expand Up @@ -86,6 +86,7 @@ void PtcArchive::close() {
}

bool PtcArchive::hasFile(const Common::String &name) const {
// TODO: check if path matching should be added
return _items.contains(name);
}

Expand Down
8 changes: 4 additions & 4 deletions engines/prince/font.h
Expand Up @@ -41,13 +41,13 @@ class Font : public Graphics::Font {

bool loadFromStream(Common::SeekableReadStream &stream);

virtual int getFontHeight() const override;
virtual int getFontHeight() const override;

virtual int getMaxCharWidth() const override;
virtual int getMaxCharWidth() const override;

virtual int getCharWidth(uint32 chr) const override;
virtual int getCharWidth(uint32 chr) const override;

virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;

virtual int getKerningOffset(uint32 left, uint32 right) const override { return -2; }

Expand Down
34 changes: 34 additions & 0 deletions engines/prince/hero.cpp
@@ -0,0 +1,34 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#include "prince/hero.h"

namespace Prince {

Hero::Hero() : _number(0), _visible(false), _state(STAY), _middleX(0), _middleY(0)
, _boreNum(0), _currHeight(0), _moveDelay(0), _shadMinus(1)
{
}

}

/* vim: set tabstop=4 noexpandtab: */
88 changes: 88 additions & 0 deletions engines/prince/hero.h
@@ -0,0 +1,88 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#ifndef PRINCE_HERO_H
#define PRINCE_HERO_H

#include "common/scummsys.h"

namespace Prince {

class Hero {
public:
enum State {
STAY = 0,
TURN = 1,
MOVE = 2,
BORE = 3,
SPEC = 4,
TALK = 5,
MVAN = 6,
TRAN = 7,
RUN = 8,
DMOVE = 9
};

Hero();

private:
uint16 _number;
uint16 _visible;
State _state;
uint16 _middleX;
uint16 _middleY;

// Coords array of coordinates
// DirTab array of directions
// CurrCoords current coordinations
// CurrDirTab current direction
// LastDir previous move direction
// DestDir
// LeftRight previous left/right direction
// UpDown previous up/down direction
// Phase animation phase
// Step x/y step size depends on direction
// MaxBoredom stand still timeout
// Boredom current boredom time in frames
uint16 _boreNum; // Bore anim frame
// TalkTime time of talk anim
// SpecAnim additional anim

uint16 _currHeight; // height of current anim phase

// Inventory array of items
// Inventory2 array of items
// Font subtitiles font
// Color subtitiles color
// AnimSet number of animation set
// MoveAnims MoveSet
// TurnAnim ??

uint32 _moveDelay;
uint32 _shadMinus; //??
};

}

#endif

/* vim: set tabstop=4 noexpandtab: */
1 change: 1 addition & 0 deletions engines/prince/module.mk
Expand Up @@ -15,6 +15,7 @@ MODULE_OBJS = \
prince.o \
archive.o \
decompress.o \
hero.o \
cursor.o

# This module can be built as a plugin
Expand Down
68 changes: 52 additions & 16 deletions engines/prince/prince.cpp
Expand Up @@ -31,6 +31,7 @@
#include "common/fs.h"
#include "common/keyboard.h"
#include "common/substream.h"
#include "common/str.h"

#include "graphics/cursorman.h"
#include "graphics/surface.h"
Expand All @@ -56,6 +57,7 @@
#include "prince/mhwanh.h"
#include "prince/cursor.h"
#include "prince/archive.h"
#include "prince/hero.h"

namespace Prince {

Expand All @@ -74,14 +76,16 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc)
Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL),
_locationNr(0), _debugger(NULL), _midiPlayer(NULL),
_cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL),
_walizkaBmp(NULL), _roomBmp(NULL), _voiceStream(NULL), _cursorNr(0) {
_walizkaBmp(NULL), _roomBmp(NULL), _cursorNr(0) {

// Debug/console setup
DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel");
DebugMan.addDebugChannel(DebugChannel::kEngine, "engine", "Prince Engine debug channel");

DebugMan.enableDebugChannel("script");

memset(_voiceStream, 0, sizeof(_voiceStream));

gDebugLevel = 10;
}

Expand Down Expand Up @@ -196,17 +200,19 @@ void PrinceEngine::init() {
if (!voices->open("data/voices/databank.ptc"))
error("Can't open data/voices/databank.ptc");

PtcArchive *sound = new PtcArchive();
if (!sound->open("sound/databank.ptc"))
error("Can't open sound/databank.ptc");

SearchMan.add("all", all);
SearchMan.add("data/voices", voices);
SearchMan.add("sound", sound);

_graph = new GraphicsMan(this);

_rnd = new Common::RandomSource("prince");
_debugger = new Debugger(this);

SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2);
SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices", 0, 2);

_midiPlayer = new MusicPlayer(this);

_font = new Font();
Expand Down Expand Up @@ -263,6 +269,13 @@ Common::Error PrinceEngine::run() {
}

bool PrinceEngine::loadLocation(uint16 locationNr) {
_flicPlayer.close();

memset(_textSlots, 0, sizeof(_textSlots));
for(uint32 sampleId = 0; sampleId < MAX_SAMPLES; ++sampleId) {
stopSample(sampleId);
}

debugEngine("PrinceEngine::loadLocation %d", locationNr);
const Common::FSNode gameDataDir(ConfMan.get("path"));
SearchMan.remove(Common::String::format("%02d", _locationNr));
Expand Down Expand Up @@ -357,46 +370,69 @@ bool PrinceEngine::playNextFrame() {
}

void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) {
if (_voiceStream) {
if (_voiceStream[sampleId]) {

Audio::RewindableAudioStream *audioStream = Audio::makeWAVStream(_voiceStream, DisposeAfterUse::YES);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream, sampleId);
if (_mixer->isSoundIDActive(sampleId)) {
return;
}

Audio::AudioStream *audioStream = Audio::makeWAVStream(_voiceStream[sampleId], DisposeAfterUse::YES);
if (loopType) {
audioStream = new Audio::LoopingAudioStream((Audio::RewindableAudioStream*)audioStream, 0, DisposeAfterUse::NO);
}
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], audioStream, sampleId);
}
}

void PrinceEngine::stopSample(uint16 sampleId) {
_mixer->stopID(sampleId);
_voiceStream = NULL;
_voiceStream[sampleId] = NULL;
}

bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) {
// FIXME: This is just a workaround streamName is a path
// SOUND\\SCIERKA1.WAV for now only last path component is used
Common::String normalizedPath = lastPathComponent(streamName, '\\');

debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str());

_mixer->stopID(sampleSlot);
_voiceStream[sampleSlot] = NULL;
_voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath);
if (_voiceStream[sampleSlot] == NULL) {
error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot);
}
return _voiceStream[sampleSlot] == NULL;
}

bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) {
bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
debugEngine("Loading wav %s slot %d", streamName.c_str(), slot);

if (slot > MAXTEXTS) {
error("Text slot bigger than MAXTEXTS %d", MAXTEXTS);
return false;
}

_voiceStream = SearchMan.createReadStreamForMember(streamName);
if (!_voiceStream) {
_voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(streamName);
if (!_voiceStream[sampleSlot]) {
error("Can't open %s", streamName.c_str());
return false;
}

uint32 id = _voiceStream->readUint32LE();
uint32 id = _voiceStream[sampleSlot]->readUint32LE();
if (id != 0x46464952) {
error("It's not RIFF file %s", streamName.c_str());
return false;
}

_voiceStream->skip(0x20);
id = _voiceStream->readUint32LE();
_voiceStream[sampleSlot]->skip(0x20);
id = _voiceStream[sampleSlot]->readUint32LE();
if (id != 0x61746164) {
error("No data section in %s id %04x", streamName.c_str(), id);
return false;
}

id = _voiceStream->readUint32LE();
id = _voiceStream[sampleSlot]->readUint32LE();
debugEngine("SetVoice slot %d time %04x", slot, id);
id <<= 3;
id /= 22050;
Expand All @@ -405,7 +441,7 @@ bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) {
_textSlots[slot]._time = id;

debugEngine("SetVoice slot %d time %04x", slot, id);
_voiceStream->seek(0);
_voiceStream[sampleSlot]->seek(0);

return true;
}
Expand Down
13 changes: 10 additions & 3 deletions engines/prince/prince.h
Expand Up @@ -59,6 +59,7 @@ class VariaTxt;
class Cursor;
class MhwanhDecoder;
class Font;
class Hero;

struct Text {
const char *_str;
Expand Down Expand Up @@ -103,7 +104,8 @@ class PrinceEngine : public Engine {

bool loadLocation(uint16 locationNr);
bool loadAnim(uint16 animNr, bool loop);
bool loadVoice(uint32 slot, const Common::String &name);
bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name);
bool loadSample(uint32 sampleSlot, const Common::String &name);

void playSample(uint16 sampleId, uint16 loopType);
void stopSample(uint16 sampleId);
Expand Down Expand Up @@ -146,15 +148,20 @@ class PrinceEngine : public Engine {
Font *_font;
MusicPlayer *_midiPlayer;

Audio::SoundHandle _soundHandle;
Common::SeekableReadStream *_voiceStream;

static const uint32 MAX_SAMPLES = 60;
Common::SeekableReadStream *_voiceStream[MAX_SAMPLES];
Audio::SoundHandle _soundHandle[MAX_SAMPLES];

Common::Array<Mob> _mobList;
Common::Array<Object *> _objList;

uint16 _cameraX;
uint16 _newCameraX;
uint16 _sceneWidth;

Hero* _mainHero;

bool _flicLooped;

void mainLoop();
Expand Down

0 comments on commit 69a5845

Please sign in to comment.