aboutsummaryrefslogtreecommitdiff
path: root/engines/prince
diff options
context:
space:
mode:
authorKamil Zbróg2013-12-03 14:46:24 +0000
committerKamil Zbróg2013-12-03 14:46:24 +0000
commit69a58457744c662930f5f19b90d95d7647d580b2 (patch)
treed0ea10c811d91a41346db12f469b50f44fb60838 /engines/prince
parentf19f61a56da04e0dbd6e46ff9a303fdfb68d8390 (diff)
downloadscummvm-rg350-69a58457744c662930f5f19b90d95d7647d580b2.tar.gz
scummvm-rg350-69a58457744c662930f5f19b90d95d7647d580b2.tar.bz2
scummvm-rg350-69a58457744c662930f5f19b90d95d7647d580b2.zip
PRINCE: loadSample with sample looping added, escaping from intro works
Diffstat (limited to 'engines/prince')
-rw-r--r--engines/prince/archive.cpp1
-rw-r--r--engines/prince/font.h8
-rw-r--r--engines/prince/hero.cpp34
-rw-r--r--engines/prince/hero.h88
-rw-r--r--engines/prince/module.mk1
-rw-r--r--engines/prince/prince.cpp68
-rw-r--r--engines/prince/prince.h13
-rw-r--r--engines/prince/script.cpp19
8 files changed, 205 insertions, 27 deletions
diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp
index 0b1367f966..d1b680c204 100644
--- a/engines/prince/archive.cpp
+++ b/engines/prince/archive.cpp
@@ -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);
}
diff --git a/engines/prince/font.h b/engines/prince/font.h
index c41b176c72..bf9c09d0e9 100644
--- a/engines/prince/font.h
+++ b/engines/prince/font.h
@@ -41,13 +41,13 @@ public:
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; }
diff --git a/engines/prince/hero.cpp b/engines/prince/hero.cpp
new file mode 100644
index 0000000000..277e521bee
--- /dev/null
+++ b/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: */
diff --git a/engines/prince/hero.h b/engines/prince/hero.h
new file mode 100644
index 0000000000..e11a0f7395
--- /dev/null
+++ b/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: */
diff --git a/engines/prince/module.mk b/engines/prince/module.mk
index 48edcec9dd..2e5f0592b1 100644
--- a/engines/prince/module.mk
+++ b/engines/prince/module.mk
@@ -15,6 +15,7 @@ MODULE_OBJS = \
prince.o \
archive.o \
decompress.o \
+ hero.o \
cursor.o
# This module can be built as a plugin
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 9f4ae19af3..f82f9e0e0c 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -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"
@@ -56,6 +57,7 @@
#include "prince/mhwanh.h"
#include "prince/cursor.h"
#include "prince/archive.h"
+#include "prince/hero.h"
namespace Prince {
@@ -74,7 +76,7 @@ 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");
@@ -82,6 +84,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc)
DebugMan.enableDebugChannel("script");
+ memset(_voiceStream, 0, sizeof(_voiceStream));
+
gDebugLevel = 10;
}
@@ -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();
@@ -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));
@@ -357,19 +370,42 @@ 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) {
@@ -377,26 +413,26 @@ bool PrinceEngine::loadVoice(uint32 slot, const Common::String &streamName) {
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;
@@ -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;
}
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index 374048f285..d2c75e76cb 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -59,6 +59,7 @@ class VariaTxt;
class Cursor;
class MhwanhDecoder;
class Font;
+class Hero;
struct Text {
const char *_str;
@@ -103,7 +104,8 @@ public:
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);
@@ -146,8 +148,11 @@ private:
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;
@@ -155,6 +160,8 @@ private:
uint16 _newCameraX;
uint16 _sceneWidth;
+ Hero* _mainHero;
+
bool _flicLooped;
void mainLoop();
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index 07821f27a8..9daf3048ab 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -41,6 +41,7 @@ static const uint16 NUM_OPCODES = 144;
Script::Script(PrinceEngine *vm) :
_code(NULL), _stacktop(0), _vm(vm), _opcodeNF(false),
_waitFlag(0), _result(true) {
+ memset(_flags, 0, sizeof(_flags));
}
Script::~Script() {
@@ -146,7 +147,7 @@ uint16 Script::readScript16bits() {
uint16 Script::readScriptValue() {
uint16 value = readScript16bits();
if (value & FLAG_MASK) {
- value = _flags[value - FLAG_MASK];
+ return getFlagValue((Flags::Id)value);
}
return value;
}
@@ -183,6 +184,7 @@ void Script::O_SETSAMPLE() {
int32 sampleNameOffset = readScript32bits();
const char * sampleName = (const char *)&_code[_currentInstruction + sampleNameOffset - 4];
debugScript("O_SETSAMPLE %d %s", sampleId, sampleName);
+ _vm->loadSample(sampleId, sampleName);
}
void Script::O_FREESAMPLE() {
@@ -355,6 +357,7 @@ void Script::O_BACKANIMUPDATEON() {
void Script::O_CHANGECURSOR() {
uint16 cursorId = readScriptValue();
debugScript("O_CHANGECURSOR %x", cursorId);
+ _vm->changeCursor(cursorId);
}
void Script::O_CHANGEANIMTYPE() {
@@ -765,7 +768,7 @@ void Script::O_GETANIMDATA() {
void Script::O_SETBGCODE() {
int32 offset = readScript32bits();
- _bgOpcodePC = _currentInstruction + offset;
+ _bgOpcodePC = _currentInstruction + offset - 4;
debugScript("O_SETBGCODE next %08x, offset %08x", _bgOpcodePC, offset);
}
@@ -926,11 +929,18 @@ void Script::O_STOPSAMPLE() {
void Script::O_BACKANIMRANGE() {
uint16 slotId = readScriptValue();
- uint16 animId = readScriptValue();
+ uint16 animId = readScript16bits();
uint16 low = readScriptValue();
uint16 high = readScriptValue();
+ if (animId != 0xFFFF) {
+ if (animId & FLAG_MASK) {
+ animId = getFlagValue((Flags::Id)animId);
+ }
+ }
+
debugScript("O_BACKANIMRANGE slotId %d, animId %d, low %d, high %d", slotId, animId, low, high);
+ _result = 1;
}
void Script::O_CLEARPATH() {
@@ -982,7 +992,7 @@ void Script::O_POPSTRING() {
void Script::O_SETFGCODE() {
int32 offset = readScript32bits();
- _fgOpcodePC = _currentInstruction + offset;
+ _fgOpcodePC = _currentInstruction + offset - 4;
debugScript("O_SETFGCODE next %08x, offset %08x", _fgOpcodePC, offset);
}
@@ -1125,6 +1135,7 @@ void Script::SetVoice(uint32 sampleSlot) {
uint16 slot = readScriptValue();
_vm->loadVoice(
slot,
+ sampleSlot,
Common::String::format(
"%03d-%02d.WAV",
_currentString,