aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/agi/detection.cpp4
-rw-r--r--engines/agi/preagi_mickey.cpp4
-rw-r--r--engines/agi/preagi_winnie.cpp4
-rw-r--r--engines/agi/saveload.cpp2
-rw-r--r--engines/agos/animation.cpp2
-rw-r--r--engines/cine/saveload.h4
-rw-r--r--engines/engines.mk5
-rw-r--r--engines/gob/save/savefile.h14
-rw-r--r--engines/groovie/cursor.cpp2
-rw-r--r--engines/groovie/music.cpp4
-rw-r--r--engines/kyra/kyra_hof.cpp81
-rw-r--r--engines/kyra/kyra_hof.h6
-rw-r--r--engines/kyra/kyra_mr.cpp2
-rw-r--r--engines/kyra/kyra_mr.h2
-rw-r--r--engines/kyra/kyra_v2.cpp5
-rw-r--r--engines/kyra/kyra_v2.h3
-rw-r--r--engines/kyra/lol.cpp4
-rw-r--r--engines/kyra/resource.h2
-rw-r--r--engines/kyra/resource_intern.cpp2
-rw-r--r--engines/kyra/saveload.cpp14
-rw-r--r--engines/kyra/scene_v2.cpp11
-rw-r--r--engines/kyra/script.cpp6
-rw-r--r--engines/kyra/script.h4
-rw-r--r--engines/kyra/script_tim.cpp4
-rw-r--r--engines/kyra/vqa.cpp42
-rw-r--r--engines/m4/assets.h16
-rw-r--r--engines/m4/converse.cpp48
-rw-r--r--engines/m4/font.cpp8
-rw-r--r--engines/made/database.cpp6
-rw-r--r--engines/made/pmvplayer.cpp6
-rw-r--r--engines/made/resource.cpp12
-rw-r--r--engines/made/resource.h20
-rw-r--r--engines/mohawk/console.cpp4
-rw-r--r--engines/mohawk/cursors.cpp4
-rw-r--r--engines/mohawk/detection.cpp1
-rw-r--r--engines/mohawk/detection_tables.h149
-rw-r--r--engines/mohawk/livingbooks.cpp176
-rw-r--r--engines/mohawk/livingbooks.h67
-rw-r--r--engines/mohawk/livingbooks_code.cpp238
-rw-r--r--engines/mohawk/livingbooks_code.h22
-rw-r--r--engines/mohawk/resource.h148
-rw-r--r--engines/mohawk/sound.cpp2
-rw-r--r--engines/parallaction/disk_ns.cpp4
-rw-r--r--engines/queen/display.cpp6
-rw-r--r--engines/queen/queen.cpp2
-rw-r--r--engines/queen/resource.cpp4
-rw-r--r--engines/saga/detection.cpp2
-rw-r--r--engines/saga/resource_hrs.cpp2
-rw-r--r--engines/saga/resource_rsc.cpp2
-rw-r--r--engines/saga/saveload.cpp6
-rw-r--r--engines/saga/script.cpp4
-rw-r--r--engines/sci/graphics/palette.cpp2
-rw-r--r--engines/sci/graphics/screen.cpp1
-rw-r--r--engines/sci/resource.cpp42
-rw-r--r--engines/sci/resource_audio.cpp8
-rw-r--r--engines/sci/sound/audio.cpp12
-rw-r--r--engines/sci/sound/drivers/midi.cpp2
-rw-r--r--engines/scumm/actor.cpp22
-rw-r--r--engines/scumm/akos.cpp32
-rw-r--r--engines/scumm/cursor.cpp4
-rw-r--r--engines/scumm/gfx.cpp38
-rw-r--r--engines/scumm/he/animation_he.cpp2
-rw-r--r--engines/scumm/he/cup_player_he.cpp40
-rw-r--r--engines/scumm/he/floodfill_he.cpp4
-rw-r--r--engines/scumm/he/palette_he.cpp6
-rw-r--r--engines/scumm/he/resource_he.cpp6
-rw-r--r--engines/scumm/he/script_v100he.cpp2
-rw-r--r--engines/scumm/he/script_v71he.cpp8
-rw-r--r--engines/scumm/he/script_v72he.cpp2
-rw-r--r--engines/scumm/he/sound_he.cpp38
-rw-r--r--engines/scumm/he/wiz_he.cpp74
-rw-r--r--engines/scumm/imuse/imuse.cpp32
-rw-r--r--engines/scumm/imuse_digi/dimuse.cpp1
-rw-r--r--engines/scumm/imuse_digi/dimuse_bndmgr.cpp7
-rw-r--r--engines/scumm/imuse_digi/dimuse_bndmgr.h8
-rw-r--r--engines/scumm/imuse_digi/dimuse_codecs.cpp311
-rw-r--r--engines/scumm/imuse_digi/dimuse_codecs.h44
-rw-r--r--engines/scumm/imuse_digi/dimuse_sndmgr.cpp42
-rw-r--r--engines/scumm/insane/insane.cpp2
-rw-r--r--engines/scumm/nut_renderer.cpp8
-rw-r--r--engines/scumm/object.cpp88
-rw-r--r--engines/scumm/palette.cpp6
-rw-r--r--engines/scumm/player_towns.cpp8
-rw-r--r--engines/scumm/resource.cpp104
-rw-r--r--engines/scumm/room.cpp46
-rw-r--r--engines/scumm/saveload.cpp8
-rw-r--r--engines/scumm/script.cpp4
-rw-r--r--engines/scumm/script_v6.cpp4
-rw-r--r--engines/scumm/scumm.cpp2
-rw-r--r--engines/scumm/smush/imuse_channel.cpp37
-rw-r--r--engines/scumm/smush/saud_channel.cpp10
-rw-r--r--engines/scumm/smush/smush_player.cpp32
-rw-r--r--engines/scumm/sound.cpp78
-rw-r--r--engines/scumm/verbs.cpp2
-rw-r--r--engines/sword1/control.h2
-rw-r--r--engines/sword1/screen.cpp2
-rw-r--r--engines/tinsel/adpcm.cpp168
-rw-r--r--engines/tinsel/adpcm.h105
-rw-r--r--engines/tinsel/background.cpp8
-rw-r--r--engines/tinsel/background.h2
-rw-r--r--engines/tinsel/bmv.cpp18
-rw-r--r--engines/tinsel/bmv.h1
-rw-r--r--engines/tinsel/drives.cpp3
-rw-r--r--engines/tinsel/dw.h2
-rw-r--r--engines/tinsel/handle.cpp8
-rw-r--r--engines/tinsel/module.mk1
-rw-r--r--engines/tinsel/music.cpp29
-rw-r--r--engines/tinsel/music.h2
-rw-r--r--engines/tinsel/saveload.cpp63
-rw-r--r--engines/tinsel/scene.cpp18
-rw-r--r--engines/tinsel/sound.cpp9
-rw-r--r--engines/tinsel/tinsel.cpp3
-rw-r--r--engines/toon/audio.cpp26
-rw-r--r--engines/toon/hotspot.cpp2
-rw-r--r--engines/toon/script.cpp6
-rw-r--r--engines/toon/script.h4
-rw-r--r--engines/toon/tools.cpp17
-rw-r--r--engines/toon/tools.h2
-rw-r--r--engines/tsage/converse.cpp948
-rw-r--r--engines/tsage/converse.h229
-rw-r--r--engines/tsage/core.cpp3735
-rw-r--r--engines/tsage/core.h956
-rw-r--r--engines/tsage/debugger.cpp172
-rw-r--r--engines/tsage/debugger.h48
-rw-r--r--engines/tsage/detection.cpp186
-rw-r--r--engines/tsage/detection_tables.h91
-rw-r--r--engines/tsage/dialogs.cpp598
-rw-r--r--engines/tsage/dialogs.h136
-rw-r--r--engines/tsage/events.cpp247
-rw-r--r--engines/tsage/events.h109
-rw-r--r--engines/tsage/globals.cpp103
-rw-r--r--engines/tsage/globals.h100
-rw-r--r--engines/tsage/graphics.cpp1430
-rw-r--r--engines/tsage/graphics.h349
-rw-r--r--engines/tsage/module.mk35
-rw-r--r--engines/tsage/resources.cpp410
-rw-r--r--engines/tsage/resources.h176
-rw-r--r--engines/tsage/ringworld_logic.cpp1162
-rw-r--r--engines/tsage/ringworld_logic.h402
-rw-r--r--engines/tsage/ringworld_scenes1.cpp3263
-rw-r--r--engines/tsage/ringworld_scenes1.h557
-rw-r--r--engines/tsage/ringworld_scenes10.cpp2064
-rw-r--r--engines/tsage/ringworld_scenes10.h544
-rw-r--r--engines/tsage/ringworld_scenes2.cpp929
-rw-r--r--engines/tsage/ringworld_scenes2.h152
-rw-r--r--engines/tsage/ringworld_scenes3.cpp6098
-rw-r--r--engines/tsage/ringworld_scenes3.h905
-rw-r--r--engines/tsage/ringworld_scenes4.cpp253
-rw-r--r--engines/tsage/ringworld_scenes4.h95
-rw-r--r--engines/tsage/ringworld_scenes5.cpp4356
-rw-r--r--engines/tsage/ringworld_scenes5.h695
-rw-r--r--engines/tsage/ringworld_scenes6.cpp2173
-rw-r--r--engines/tsage/ringworld_scenes6.h333
-rw-r--r--engines/tsage/ringworld_scenes8.cpp2508
-rw-r--r--engines/tsage/ringworld_scenes8.h495
-rw-r--r--engines/tsage/saveload.cpp387
-rw-r--r--engines/tsage/saveload.h215
-rw-r--r--engines/tsage/scenes.cpp471
-rw-r--r--engines/tsage/scenes.h115
-rw-r--r--engines/tsage/sound.cpp62
-rw-r--r--engines/tsage/sound.h49
-rw-r--r--engines/tsage/staticres.cpp117
-rw-r--r--engines/tsage/staticres.h84
-rw-r--r--engines/tsage/tsage.cpp136
-rw-r--r--engines/tsage/tsage.h104
165 files changed, 40598 insertions, 1106 deletions
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 6e9a996756..0a53f0c4f4 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -218,7 +218,7 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
}
SaveStateList AgiMetaEngine::listSaves(const char *target) const {
- const uint32 AGIflag = MKID_BE('AGI:');
+ const uint32 AGIflag = MKTAG('A','G','I',':');
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::StringArray filenames;
char saveDesc[31];
@@ -257,7 +257,7 @@ void AgiMetaEngine::removeSaveState(const char *target, int slot) const {
}
SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- const uint32 AGIflag = MKID_BE('AGI:');
+ const uint32 AGIflag = MKTAG('A','G','I',':');
char fileName[MAXPATHLEN];
sprintf(fileName, "%s.%03d", target, slot);
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index ea041a93c7..10ca797587 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -1003,7 +1003,7 @@ bool Mickey::loadGame() {
if (_vm->getSelection(kSelAnyKey) == 0)
return false;
} else {
- if (infile->readUint32BE() != MKID_BE('MICK')) {
+ if (infile->readUint32BE() != MKTAG('M','I','C','K')) {
warning("Mickey::loadGame wrong save game format");
return false;
}
@@ -1120,7 +1120,7 @@ void Mickey::saveGame() {
if (_vm->getSelection(kSelAnyKey) == 0)
return;
} else {
- outfile->writeUint32BE(MKID_BE('MICK')); // header
+ outfile->writeUint32BE(MKTAG('M','I','C','K')); // header
outfile->writeByte(MSA_SAVEGAME_VERSION);
outfile->writeByte(_game.iRoom);
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 643cbd86a9..e97c144872 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -1159,7 +1159,7 @@ void Winnie::saveGame() {
if (!(outfile = _vm->getSaveFileMan()->openForSaving(szFile)))
return;
- outfile->writeUint32BE(MKID_BE('WINN')); // header
+ outfile->writeUint32BE(MKTAG('W','I','N','N')); // header
outfile->writeByte(WTP_SAVEGAME_VERSION);
outfile->writeByte(_game.fSound);
@@ -1195,7 +1195,7 @@ void Winnie::loadGame() {
if (!(infile = _vm->getSaveFileMan()->openForLoading(szFile)))
return;
- if (infile->readUint32BE() == MKID_BE('WINN')) {
+ if (infile->readUint32BE() == MKTAG('W','I','N','N')) {
saveVersion = infile->readByte();
if (saveVersion != WTP_SAVEGAME_VERSION)
warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, WTP_SAVEGAME_VERSION);
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 94df063609..9194cc642c 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -53,7 +53,7 @@
namespace Agi {
-static const uint32 AGIflag = MKID_BE('AGI:');
+static const uint32 AGIflag = MKTAG('A','G','I',':');
int AgiEngine::saveGame(const char *fileName, const char *description) {
char gameIDstring[8] = "gameIDX";
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 10d3d7f1ff..acdc0084c4 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -301,7 +301,7 @@ void MoviePlayerDXA::stopVideo() {
void MoviePlayerDXA::startSound() {
uint32 offset, size;
- if (getSoundTag() == MKID_BE('WAVE')) {
+ if (getSoundTag() == MKTAG('W','A','V','E')) {
size = _fileStream->readUint32BE();
if (_sequenceNum) {
diff --git a/engines/cine/saveload.h b/engines/cine/saveload.h
index a6e0e3f1ab..f88338ed82 100644
--- a/engines/cine/saveload.h
+++ b/engines/cine/saveload.h
@@ -71,14 +71,14 @@ enum CineSaveGameFormat {
};
/** Identifier for the temporary Operation Stealth savegame format. */
-static const uint32 TEMP_OS_FORMAT_ID = MKID_BE('TEMP');
+static const uint32 TEMP_OS_FORMAT_ID = MKTAG('T','E','M','P');
/** The current version number of Operation Stealth's savegame format. */
static const uint32 CURRENT_OS_SAVE_VER = 1;
/** Chunk header used by the temporary Operation Stealth savegame format. */
struct ChunkHeader {
- uint32 id; ///< Identifier (e.g. MKID_BE('TEMP'))
+ uint32 id; ///< Identifier (e.g. MKTAG('T','E','M','P'))
uint32 version; ///< Version number
uint32 size; ///< Size of the chunk after this header in bytes
};
diff --git a/engines/engines.mk b/engines/engines.mk
index 414edcfc70..f8ff823c13 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -188,6 +188,11 @@ DEFINES += -DENABLE_TOUCHE=$(ENABLE_TOUCHE)
MODULES += engines/touche
endif
+ifdef ENABLE_TSAGE
+DEFINES += -DENABLE_TSAGE=$(ENABLE_TSAGE)
+MODULES += engines/tsage
+endif
+
ifdef ENABLE_TUCKER
DEFINES += -DENABLE_TUCKER=$(ENABLE_TUCKER)
MODULES += engines/tucker
diff --git a/engines/gob/save/savefile.h b/engines/gob/save/savefile.h
index eeee03847a..22eb79f4bf 100644
--- a/engines/gob/save/savefile.h
+++ b/engines/gob/save/savefile.h
@@ -48,8 +48,8 @@ class SaveHeader {
public:
/** The size of the header. */
static const int kSize = 20;
- static const uint32 kID1 = MKID_BE('\0SCV');
- static const uint32 kID2 = MKID_BE('MGOB');
+ static const uint32 kID1 = MKTAG(0,'S','C','V');
+ static const uint32 kID2 = MKTAG('M','G','O','B');
SaveHeader(uint32 type = 0, uint32 version = 0, uint32 size = 0);
@@ -106,7 +106,7 @@ protected:
class SavePartMem : public SavePart {
public:
static const uint32 kVersion = 1;
- static const uint32 kID = MKID_BE('PMEM');
+ static const uint32 kID = MKTAG('P','M','E','M');
SavePartMem(uint32 size);
~SavePartMem();
@@ -128,7 +128,7 @@ private:
class SavePartVars : public SavePart {
public:
static const uint32 kVersion = 1;
- static const uint32 kID = MKID_BE('VARS');
+ static const uint32 kID = MKTAG('V','A','R','S');
SavePartVars(GobEngine *vm, uint32 size);
~SavePartVars();
@@ -155,7 +155,7 @@ private:
class SavePartSprite : public SavePart {
public:
static const uint32 kVersion = 2;
- static const uint32 kID = MKID_BE('SPRT');
+ static const uint32 kID = MKTAG('S','P','R','T');
SavePartSprite(uint32 width, uint32 height, bool trueColor = false);
~SavePartSprite();
@@ -193,7 +193,7 @@ private:
class SavePartInfo : public SavePart {
public:
static const uint32 kVersion = 1;
- static const uint32 kID = MKID_BE('INFO');
+ static const uint32 kID = MKTAG('I','N','F','O');
/**
* The constructor.
@@ -235,7 +235,7 @@ private:
class SaveContainer {
public:
static const uint32 kVersion = 1;
- static const uint32 kID = MKID_BE('CONT');
+ static const uint32 kID = MKTAG('C','O','N','T');
/**
* The constructor.
diff --git a/engines/groovie/cursor.cpp b/engines/groovie/cursor.cpp
index 6a87af8daf..db4134ccb0 100644
--- a/engines/groovie/cursor.cpp
+++ b/engines/groovie/cursor.cpp
@@ -404,7 +404,7 @@ GrvCursorMan_v2::GrvCursorMan_v2(OSystem *system) :
// Verify the signature
uint32 tmp32 = iconsFile.readUint32BE();
uint16 tmp16 = iconsFile.readUint16LE();
- if (tmp32 != MKID_BE('icon') || tmp16 != 1)
+ if (tmp32 != MKTAG('i','c','o','n') || tmp16 != 1)
error("Groovie::Cursor: icons.ph signature failed: %s %d", tag2str(tmp32), tmp16);
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 7195198a6c..24306c8bfd 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -706,7 +706,7 @@ bool MusicPlayerMac::load(uint32 fileref, bool loop) {
debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Starting the playback of song: %04X", fileref);
// First try for compressed MIDI
- Common::SeekableReadStream *file = _vm->_macResFork->getResource(MKID_BE('cmid'), fileref & 0x3FF);
+ Common::SeekableReadStream *file = _vm->_macResFork->getResource(MKTAG('c','m','i','d'), fileref & 0x3FF);
if (file) {
// Found the resource, decompress it
@@ -715,7 +715,7 @@ bool MusicPlayerMac::load(uint32 fileref, bool loop) {
file = tmp;
} else {
// Otherwise, it's uncompressed
- file = _vm->_macResFork->getResource(MKID_BE('Midi'), fileref & 0x3FF);
+ file = _vm->_macResFork->getResource(MKTAG('M','i','d','i'), fileref & 0x3FF);
if (!file)
error("Groovie::Music: Couldn't find resource 0x%04X", fileref);
}
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 990e55bcf2..c73792ef8e 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -87,7 +87,9 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn
_pathfinderFlag = 0;
_mouseX = _mouseY = 0;
+ _nextIdleAnim = 0;
_lastIdleScript = -1;
+ _useSceneIdleAnim = false;
_currentTalkSections.STATim = 0;
_currentTalkSections.TLKTim = 0;
@@ -145,6 +147,11 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn
_menu = 0;
_chatIsNote = false;
memset(&_npcScriptData, 0, sizeof(_npcScriptData));
+
+ _setCharPalFinal = false;
+ _useCharPal = false;
+
+ memset(_characterFacingCountTable, 0, sizeof(_characterFacingCountTable));
}
KyraEngine_HoF::~KyraEngine_HoF() {
@@ -1135,8 +1142,6 @@ void KyraEngine_HoF::restorePage0() {
}
void KyraEngine_HoF::updateCharPal(int unk1) {
- static bool unkVar1 = false;
-
if (!_useCharPal)
return;
@@ -1152,12 +1157,12 @@ void KyraEngine_HoF::updateCharPal(int unk1) {
++src;
}
_screen->setScreenPalette(_screen->getPalette(0));
- unkVar1 = true;
+ _setCharPalFinal = true;
_charPalEntry = palEntry;
- } else if (unkVar1 || !unk1) {
+ } else if (_setCharPalFinal || !unk1) {
_screen->getPalette(0).copy(_scenePal, palEntry << 4, 16, 112);
_screen->setScreenPalette(_screen->getPalette(0));
- unkVar1 = false;
+ _setCharPalFinal = false;
}
}
@@ -1274,15 +1279,14 @@ int KyraEngine_HoF::getCharacterWalkspeed() const {
return _timer->getDelay(0);
}
-void KyraEngine_HoF::updateCharAnimFrame(int charId, int *table) {
- static int unkTable1[] = { 0, 0 };
- static const int unkTable2[] = { 17, 0 };
- static const int unkTable3[] = { 10, 0 };
- static const int unkTable4[] = { 24, 0 };
- static const int unkTable5[] = { 19, 0 };
- static const int unkTable6[] = { 21, 0 };
- static const int unkTable7[] = { 31, 0 };
- static const int unkTable8[] = { 26, 0 };
+void KyraEngine_HoF::updateCharAnimFrame(int *table) {
+ static const int unkFrame1 = 17;
+ static const int unkFrame2 = 10;
+ static const int unkFrame3 = 24;
+ static const int unkFrame4 = 19;
+ static const int unkFrame5 = 21;
+ static const int unkFrame6 = 31;
+ static const int unkFrame7 = 26;
Character *character = &_mainCharacter;
++character->animFrame;
@@ -1297,46 +1301,46 @@ void KyraEngine_HoF::updateCharAnimFrame(int charId, int *table) {
}
if (!facing) {
- ++unkTable1[charId];
+ ++_characterFacingCountTable[0];
} else if (facing == 4) {
- ++unkTable1[charId+1];
+ ++_characterFacingCountTable[1];
} else if (facing == 7 || facing == 1 || facing == 5 || facing == 3) {
if (facing == 7 || facing == 1) {
- if (unkTable1[charId] > 2)
+ if (_characterFacingCountTable[0] > 2)
facing = 0;
} else {
- if (unkTable1[charId+1] > 2)
+ if (_characterFacingCountTable[1] > 2)
facing = 4;
}
- unkTable1[charId] = 0;
- unkTable1[charId+1] = 0;
+ _characterFacingCountTable[0] = 0;
+ _characterFacingCountTable[1] = 0;
}
if (facing == 0) {
- if (character->animFrame < unkTable8[charId])
- character->animFrame = unkTable8[charId];
+ if (character->animFrame < unkFrame7)
+ character->animFrame = unkFrame7;
- if (character->animFrame > unkTable7[charId])
- character->animFrame = unkTable8[charId];
+ if (character->animFrame > unkFrame6)
+ character->animFrame = unkFrame7;
} else if (facing == 4) {
- if (character->animFrame < unkTable5[charId])
- character->animFrame = unkTable5[charId];
+ if (character->animFrame < unkFrame4)
+ character->animFrame = unkFrame4;
- if (character->animFrame > unkTable4[charId])
- character->animFrame = unkTable5[charId];
+ if (character->animFrame > unkFrame3)
+ character->animFrame = unkFrame4;
} else {
- if (character->animFrame > unkTable5[charId])
- character->animFrame = unkTable6[charId];
+ if (character->animFrame > unkFrame4)
+ character->animFrame = unkFrame5;
- if (character->animFrame == unkTable2[charId])
- character->animFrame = unkTable3[charId];
+ if (character->animFrame == unkFrame1)
+ character->animFrame = unkFrame2;
- if (character->animFrame > unkTable2[charId])
- character->animFrame = unkTable3[charId] + 2;
+ if (character->animFrame > unkFrame1)
+ character->animFrame = unkFrame2 + 2;
}
- updateCharacterAnim(charId);
+ updateCharacterAnim(0);
}
bool KyraEngine_HoF::checkCharCollision(int x, int y) {
@@ -1393,12 +1397,11 @@ void KyraEngine_HoF::showIdleAnim() {
if (queryGameFlag(0x159) && _flags.isTalkie)
return;
- static bool scriptAnimation = false;
- if (!scriptAnimation && _flags.isTalkie) {
- scriptAnimation = true;
+ if (!_useSceneIdleAnim && _flags.isTalkie) {
+ _useSceneIdleAnim = true;
randomSceneChat();
} else {
- scriptAnimation = false;
+ _useSceneIdleAnim = false;
if (_characterShapeFile > 8)
return;
diff --git a/engines/kyra/kyra_hof.h b/engines/kyra/kyra_hof.h
index b862a89dd0..308698484d 100644
--- a/engines/kyra/kyra_hof.h
+++ b/engines/kyra/kyra_hof.h
@@ -574,13 +574,16 @@ protected:
// character
bool _useCharPal;
+ bool _setCharPalFinal;
int _charPalEntry;
uint8 _charPalTable[16];
void updateCharPal(int unk1);
void setCharPalEntry(int entry, int value);
+ int _characterFacingCountTable[2];
+
int getCharacterWalkspeed() const;
- void updateCharAnimFrame(int num, int *table);
+ void updateCharAnimFrame(int *table);
bool checkCharCollision(int x, int y);
@@ -681,6 +684,7 @@ protected:
uint32 _nextIdleAnim;
int _lastIdleScript;
+ bool _useSceneIdleAnim;
void setNextIdleAnimTimer();
void showIdleAnim();
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index fee7835881..65e78448a5 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -788,7 +788,7 @@ int KyraEngine_MR::getCharacterWalkspeed() const {
return _mainCharacter.walkspeed;
}
-void KyraEngine_MR::updateCharAnimFrame(int character, int *table) {
+void KyraEngine_MR::updateCharAnimFrame(int *table) {
++_mainCharacter.animFrame;
int facing = _mainCharacter.facing;
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index f5ff3772ba..912c615757 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -386,7 +386,7 @@ private:
// character
int getCharacterWalkspeed() const;
- void updateCharAnimFrame(int character, int *table);
+ void updateCharAnimFrame(int *table);
int8 _characterAnimTable[2];
static const uint8 _characterFrameTable[];
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 53c57c21cd..804097c81d 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -74,6 +74,9 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const Engi
_pauseStart = 0;
+ _pathfinderFlag = 0;
+ _smoothingPath = false;
+
_lang = 0;
Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
if (lang == _flags.fanLang && _flags.replacedLang != Common::UNK_LANG)
@@ -236,7 +239,7 @@ int KyraEngine_v2::updateCharPos(int *table, int force) {
return 0;
_mainCharacter.x1 += _charAddXPosTable[_mainCharacter.facing];
_mainCharacter.y1 += _charAddYPosTable[_mainCharacter.facing];
- updateCharAnimFrame(0, table);
+ updateCharAnimFrame(table);
_updateCharPosNextUpdate = _system->getMillis() + getCharacterWalkspeed() * _tickLength;
return 1;
}
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 084b159ee2..9f0aecd78c 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -269,6 +269,7 @@ protected:
// pathfinder
int _movFacingTable[600];
int _pathfinderFlag;
+ bool _smoothingPath;
int findWay(int curX, int curY, int dstX, int dstY, int *moveTable, int moveTableSize);
@@ -340,7 +341,7 @@ protected:
uint32 _updateCharPosNextUpdate;
virtual int getCharacterWalkspeed() const = 0;
- virtual void updateCharAnimFrame(int num, int *table) = 0;
+ virtual void updateCharAnimFrame(int *table) = 0;
// chat
int _vocHigh;
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 7003d8c38f..5928c40f92 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -898,7 +898,9 @@ void LoLEngine::startupNew() {
memset(_globalScriptVars2, 0x100, 8);
- static int selectIds[] = { -9, -1, -8, -5 };
+ static const int selectIds[] = { -9, -1, -8, -5 };
+ assert(_charSelection >= 0);
+ assert(_charSelection < ARRAYSIZE(selectIds));
addCharacter(selectIds[_charSelection]);
gui_enableDefaultPlayfieldButtons();
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 8372bf9ad1..9948c52001 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -102,7 +102,7 @@ protected:
enum KyraResources {
kLoadAll = -1,
- // This list has to match orderwise (and thus value wise) the static data list of "tools/create_kyradat/create_kyradat.h"!
+ // This list has to match orderwise (and thus value wise) the static data list of "devtools/create_kyradat/create_kyradat.h"!
k1ForestSeq = 1,
k1KallakWritingSeq,
k1KyrandiaLogoSeq,
diff --git a/engines/kyra/resource_intern.cpp b/engines/kyra/resource_intern.cpp
index f26cb8fb26..1dc084f14d 100644
--- a/engines/kyra/resource_intern.cpp
+++ b/engines/kyra/resource_intern.cpp
@@ -356,7 +356,7 @@ Common::Archive *ResLoaderPak::load(Common::ArchiveMemberPtr memberFile, Common:
const uint32 magic = stream.readUint32BE();
- if (magic != MKID_BE('SCVM'))
+ if (magic != MKTAG('S','C','V','M'))
error("LINKLIST file does not contain 'SCVM' header");
const uint32 links = stream.readUint32BE();
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index cd5ef52b92..44579c3377 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -47,13 +47,13 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
header.flags = 0;
header.thumbnail = 0;
- if (type == MKID_BE('KYRA') || type == MKID_BE('ARYK')) { // old Kyra1 header ID
+ if (type == MKTAG('K','Y','R','A') || type == MKTAG('A','R','Y','K')) { // old Kyra1 header ID
header.gameID = GI_KYRA1;
header.oldHeader = true;
- } else if (type == MKID_BE('HOFS')) { // old Kyra2 header ID
+ } else if (type == MKTAG('H','O','F','S')) { // old Kyra2 header ID
header.gameID = GI_KYRA2;
header.oldHeader = true;
- } else if (type == MKID_BE('WWSV')) {
+ } else if (type == MKTAG('W','W','S','V')) {
header.gameID = in->readByte();
} else {
// try checking for original save header
@@ -71,12 +71,12 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
type = in->readUint32BE();
header.version = in->readUint16LE();
- if (type == MKID_BE('MBL3') && header.version == 100) {
+ if (type == MKTAG('M','B','L','3') && header.version == 100) {
saveOk = true;
header.description = descriptionBuffer;
header.gameID = GI_KYRA2;
break;
- } else if (type == MKID_BE('MBL4') && header.version == 102) {
+ } else if (type == MKTAG('M','B','L','4') && header.version == 102) {
saveOk = true;
header.description = descriptionBuffer;
header.gameID = GI_KYRA3;
@@ -94,7 +94,7 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
}
header.version = in->readUint32BE();
- if (header.version > CURRENT_SAVE_VERSION || (header.oldHeader && header.version > 8) || (type == MKID_BE('ARYK') && header.version > 3))
+ if (header.version > CURRENT_SAVE_VERSION || (header.oldHeader && header.version > 8) || (type == MKTAG('A','R','Y','K') && header.version > 3))
return kRSHEInvalidVersion;
// Versions prior to 9 are using a fixed length description field
@@ -190,7 +190,7 @@ Common::WriteStream *KyraEngine_v1::openSaveForWriting(const char *filename, con
}
// Savegame version
- out->writeUint32BE(MKID_BE('WWSV'));
+ out->writeUint32BE(MKTAG('W','W','S','V'));
out->writeByte(_flags.gameID);
out->writeUint32BE(CURRENT_SAVE_VERSION);
out->write(saveName, strlen(saveName)+1);
diff --git a/engines/kyra/scene_v2.cpp b/engines/kyra/scene_v2.cpp
index f0c26acd54..fdfbceb521 100644
--- a/engines/kyra/scene_v2.cpp
+++ b/engines/kyra/scene_v2.cpp
@@ -86,15 +86,16 @@ int KyraEngine_v2::findWay(int x, int y, int toX, int toY, int *moveTable, int m
x &= ~3; toX &= ~3;
y &= ~1; toY &= ~1;
int size = KyraEngine_v1::findWay(x, y, toX, toY, moveTable, moveTableSize);
- static bool usePostProcess = false;
- if (size && !usePostProcess) {
- usePostProcess = true;
+
+ if (size && !_smoothingPath) {
+ _smoothingPath = true;
int temp = pathfinderInitPositionTable(moveTable);
temp = pathfinderInitPositionIndexTable(temp, x, y);
pathfinderFinializePath(moveTable, temp, x, y, moveTableSize);
- usePostProcess = false;
+ _smoothingPath = false;
}
- return usePostProcess ? size : getMoveTableSize(moveTable);
+
+ return _smoothingPath ? size : getMoveTableSize(moveTable);
}
bool KyraEngine_v2::directLinePassable(int x, int y, int toX, int toY) {
diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp
index 0343cbfeae..956bf39b5a 100644
--- a/engines/kyra/script.cpp
+++ b/engines/kyra/script.cpp
@@ -68,14 +68,14 @@ EMCInterpreter::EMCInterpreter(KyraEngine_v1 *vm) : _vm(vm), _scriptData(0), _fi
bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
switch (chunk._type) {
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
_scriptData->text = new byte[chunk._size];
assert(_scriptData->text);
if (chunk._stream->read(_scriptData->text, chunk._size) != chunk._size)
error("Couldn't read TEXT chunk from file '%s'", _filename);
break;
- case MKID_BE('ORDR'):
+ case MKTAG('O','R','D','R'):
_scriptData->ordr = new uint16[chunk._size >> 1];
assert(_scriptData->ordr);
if (chunk._stream->read(_scriptData->ordr, chunk._size) != chunk._size)
@@ -85,7 +85,7 @@ bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
_scriptData->ordr[i] = READ_BE_UINT16(&_scriptData->ordr[i]);
break;
- case MKID_BE('DATA'):
+ case MKTAG('D','A','T','A'):
_scriptData->data = new uint16[chunk._size >> 1];
assert(_scriptData->data);
if (chunk._stream->read(_scriptData->data, chunk._size) != chunk._size)
diff --git a/engines/kyra/script.h b/engines/kyra/script.h
index 68620829bb..faa80a3f21 100644
--- a/engines/kyra/script.h
+++ b/engines/kyra/script.h
@@ -84,9 +84,9 @@ public:
// Both lead to some problems in our IFF parser, either reading after the end
// of file or producing a "Chunk overread" error message. To work around this
// we need to adjust the size field properly.
- if (_formType == MKID_BE('EMC2'))
+ if (_formType == MKTAG('E','M','C','2'))
_formChunk.size -= 8;
- else if (_formType == MKID_BE('AVFS'))
+ else if (_formType == MKTAG('A','V','F','S'))
_formChunk.size += 4;
}
};
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 28f18a1f79..1e978caf15 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -115,14 +115,14 @@ TIMInterpreter::~TIMInterpreter() {
bool TIMInterpreter::callback(Common::IFFChunk &chunk) {
switch (chunk._type) {
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
_tim->text = new byte[chunk._size];
assert(_tim->text);
if (chunk._stream->read(_tim->text, chunk._size) != chunk._size)
error("Couldn't read TEXT chunk from file '%s'", _filename);
break;
- case MKID_BE('AVTL'):
+ case MKTAG('A','V','T','L'):
_avtlChunkSize = chunk._size >> 1;
_tim->avtl = new uint16[_avtlChunkSize];
assert(_tim->avtl);
diff --git a/engines/kyra/vqa.cpp b/engines/kyra/vqa.cpp
index 382ec2429d..b3371793de 100644
--- a/engines/kyra/vqa.cpp
+++ b/engines/kyra/vqa.cpp
@@ -204,7 +204,7 @@ bool VQAMovie::open(const char *filename) {
if (!_file)
return false;
- if (_file->readUint32BE() != MKID_BE('FORM')) {
+ if (_file->readUint32BE() != MKTAG('F','O','R','M')) {
warning("VQAMovie::open: Cannot find `FORM' tag");
return false;
}
@@ -212,7 +212,7 @@ bool VQAMovie::open(const char *filename) {
// For now, we ignore the size of the FORM chunk.
_file->readUint32BE();
- if (_file->readUint32BE() != MKID_BE('WVQA')) {
+ if (_file->readUint32BE() != MKTAG('W','V','Q','A')) {
warning("WQAMovie::open: Cannot find `WVQA' tag");
return false;
}
@@ -228,7 +228,7 @@ bool VQAMovie::open(const char *filename) {
uint32 size = _file->readUint32BE();
switch (tag) {
- case MKID_BE('VQHD'): // VQA header
+ case MKTAG('V','Q','H','D'): // VQA header
_header.version = _file->readUint16LE();
_header.flags = _file->readUint16LE();
_header.numFrames = _file->readUint16LE();
@@ -304,7 +304,7 @@ bool VQAMovie::open(const char *filename) {
foundHeader = true;
break;
- case MKID_BE('FINF'): // Frame info
+ case MKTAG('F','I','N','F'): // Frame info
if (!foundHeader) {
warning("VQAMovie::open: Found `FINF' before `VQHD'");
return false;
@@ -343,7 +343,7 @@ bool VQAMovie::open(const char *filename) {
if (_file->eos())
break;
- if (scanTag == MKID_BE('VQFR')) {
+ if (scanTag == MKTAG('V','Q','F','R')) {
_frameInfo[0] = (_file->pos() - 8) | 0x80000000;
break;
}
@@ -421,7 +421,7 @@ void VQAMovie::displayFrame(uint frameNum) {
int32 end;
switch (tag) {
- case MKID_BE('SND0'): // Uncompressed sound
+ case MKTAG('S','N','D','0'): // Uncompressed sound
foundSound = true;
inbuf = (byte *)malloc(size);
_file->read(inbuf, size);
@@ -429,7 +429,7 @@ void VQAMovie::displayFrame(uint frameNum) {
_stream->queueBuffer(inbuf, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
break;
- case MKID_BE('SND1'): // Compressed sound, almost like AUD
+ case MKTAG('S','N','D','1'): // Compressed sound, almost like AUD
foundSound = true;
outsize = _file->readUint16LE();
insize = _file->readUint16LE();
@@ -449,13 +449,13 @@ void VQAMovie::displayFrame(uint frameNum) {
}
break;
- case MKID_BE('SND2'): // Compressed sound
+ case MKTAG('S','N','D','2'): // Compressed sound
foundSound = true;
warning("VQAMovie::displayFrame: `SND2' is not implemented");
_file->seek(size, SEEK_CUR);
break;
- case MKID_BE('VQFR'):
+ case MKTAG('V','Q','F','R'):
foundFrame = true;
end = _file->pos() + size - 8;
@@ -464,49 +464,49 @@ void VQAMovie::displayFrame(uint frameNum) {
size = _file->readUint32BE();
switch (tag) {
- case MKID_BE('CBF0'): // Full codebook
+ case MKTAG('C','B','F','0'): // Full codebook
_file->read(_codeBook, size);
break;
- case MKID_BE('CBFZ'): // Full codebook
+ case MKTAG('C','B','F','Z'): // Full codebook
inbuf = (byte *)allocBuffer(0, size);
_file->read(inbuf, size);
Screen::decodeFrame4(inbuf, _codeBook, _codeBookSize);
break;
- case MKID_BE('CBP0'): // Partial codebook
+ case MKTAG('C','B','P','0'): // Partial codebook
_compressedCodeBook = false;
_file->read(_partialCodeBook + _partialCodeBookSize, size);
_partialCodeBookSize += size;
_numPartialCodeBooks++;
break;
- case MKID_BE('CBPZ'): // Partial codebook
+ case MKTAG('C','B','P','Z'): // Partial codebook
_compressedCodeBook = true;
_file->read(_partialCodeBook + _partialCodeBookSize, size);
_partialCodeBookSize += size;
_numPartialCodeBooks++;
break;
- case MKID_BE('CPL0'): // Palette
+ case MKTAG('C','P','L','0'): // Palette
assert(size <= 3 * 256);
_file->read(_screen->getPalette(0).getData(), size);
break;
- case MKID_BE('CPLZ'): // Palette
+ case MKTAG('C','P','L','Z'): // Palette
inbuf = (byte *)allocBuffer(0, size);
_file->read(inbuf, size);
Screen::decodeFrame4(inbuf, _screen->getPalette(0).getData(), 768);
break;
- case MKID_BE('VPT0'): // Frame data
+ case MKTAG('V','P','T','0'): // Frame data
assert(size / 2 <= _numVectorPointers);
for (i = 0; i < size / 2; i++)
_vectorPointers[i] = _file->readUint16LE();
break;
- case MKID_BE('VPTZ'): // Frame data
+ case MKTAG('V','P','T','Z'): // Frame data
inbuf = (byte *)allocBuffer(0, size);
outbuf = (byte *)allocBuffer(1, 2 * _numVectorPointers);
@@ -613,13 +613,13 @@ void VQAMovie::play() {
}
switch (tag) {
- case MKID_BE('SND0'): // Uncompressed sound
+ case MKTAG('S','N','D','0'): // Uncompressed sound
inbuf = (byte *)malloc(size);
_file->read(inbuf, size);
_stream->queueBuffer(inbuf, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
break;
- case MKID_BE('SND1'): // Compressed sound
+ case MKTAG('S','N','D','1'): // Compressed sound
outsize = _file->readUint16LE();
insize = _file->readUint16LE();
@@ -636,12 +636,12 @@ void VQAMovie::play() {
}
break;
- case MKID_BE('SND2'): // Compressed sound
+ case MKTAG('S','N','D','2'): // Compressed sound
warning("VQAMovie::play: `SND2' is not implemented");
_file->seek(size, SEEK_CUR);
break;
- case MKID_BE('CMDS'): // Unused tag, always empty in kyra3
+ case MKTAG('C','M','D','S'): // Unused tag, always empty in kyra3
_file->seek(size, SEEK_CUR);
break;
diff --git a/engines/m4/assets.h b/engines/m4/assets.h
index 3ae7fb2e22..940646b5f2 100644
--- a/engines/m4/assets.h
+++ b/engines/m4/assets.h
@@ -33,16 +33,16 @@
namespace M4 {
// Sequence chunks
-#define CHUNK_SCEN MKID_BE('SCEN')
-#define CHUNK_MACH MKID_BE('MACH')
-#define CHUNK_SEQU MKID_BE('SEQU')
-#define CHUNK_DATA MKID_BE('DATA')
-#define CHUNK_CELS MKID_BE('CELS')
+#define CHUNK_SCEN MKTAG('S','C','E','N')
+#define CHUNK_MACH MKTAG('M','A','C','H')
+#define CHUNK_SEQU MKTAG('S','E','Q','U')
+#define CHUNK_DATA MKTAG('D','A','T','A')
+#define CHUNK_CELS MKTAG('C','E','L','S')
// Sprite chunks
-#define HEAD_M4SS MKID_BE('M4SS') //'M4SS'
-#define CELS__PAL MKID_BE(' PAL') //' PAL'
-#define CELS___SS MKID_BE(' SS') //' SS'
+#define HEAD_M4SS MKTAG('M','4','S','S') //'M4SS'
+#define CELS__PAL MKTAG(' ','P','A','L') //' PAL'
+#define CELS___SS MKTAG(' ',' ','S','S') //' SS'
#define SPRITE_SET_CHAR_INFO 4
diff --git a/engines/m4/converse.cpp b/engines/m4/converse.cpp
index 70c30d28f2..2d1b8e7e4f 100644
--- a/engines/m4/converse.cpp
+++ b/engines/m4/converse.cpp
@@ -45,35 +45,35 @@ namespace M4 {
// Conversation chunks
// Header
-#define HEAD_CONV MKID_BE('CONV') // conversation
-#define CHUNK_DECL MKID_BE('DECL') // declaration
-#define CHUNK_NODE MKID_BE('NODE') // node
-#define CHUNK_LNOD MKID_BE('LNOD') // linear node
-#define CHUNK_ETRY MKID_BE('ETRY') // entry
-#define CHUNK_TEXT MKID_BE('TEXT') // text
-#define CHUNK_MESG MKID_BE('MESG') // message
+#define HEAD_CONV MKTAG('C','O','N','V') // conversation
+#define CHUNK_DECL MKTAG('D','E','C','L') // declaration
+#define CHUNK_NODE MKTAG('N','O','D','E') // node
+#define CHUNK_LNOD MKTAG('L','N','O','D') // linear node
+#define CHUNK_ETRY MKTAG('E','T','R','Y') // entry
+#define CHUNK_TEXT MKTAG('T','E','X','T') // text
+#define CHUNK_MESG MKTAG('M','E','S','G') // message
// Conversation chunks - entry related (unconditional)
-#define CHUNK_RPLY MKID_BE('RPLY') // reply
-#define CHUNK_HIDE MKID_BE('HIDE') // hide entry
-#define CHUNK_UHID MKID_BE('UHID') // unhide entry
-#define CHUNK_DSTR MKID_BE('DSTR') // destroy entry
+#define CHUNK_RPLY MKTAG('R','P','L','Y') // reply
+#define CHUNK_HIDE MKTAG('H','I','D','E') // hide entry
+#define CHUNK_UHID MKTAG('U','H','I','D') // unhide entry
+#define CHUNK_DSTR MKTAG('D','S','T','R') // destroy entry
// Conversation chunks - entry related (conditional)
-#define CHUNK_CRPL MKID_BE('CRPL') // reply
-#define CHUNK_CHDE MKID_BE('CHDE') // hide entry
-#define CHUNK_CUHD MKID_BE('CUHD') // unhide entry
-#define CHUNK_CDST MKID_BE('DDTS') // destroy entry
+#define CHUNK_CRPL MKTAG('C','R','P','L') // reply
+#define CHUNK_CHDE MKTAG('C','H','D','E') // hide entry
+#define CHUNK_CUHD MKTAG('C','U','H','D') // unhide entry
+#define CHUNK_CDST MKTAG('D','D','T','S') // destroy entry
// Conversation chunks - branching and logic (unconditional)
-#define CHUNK_ASGN MKID_BE('ASGN') // assign
-#define CHUNK_GOTO MKID_BE('GOTO') // goto chunk
-#define CHUNK_EXIT MKID_BE('EXIT') // exit/return from goto
+#define CHUNK_ASGN MKTAG('A','S','G','N') // assign
+#define CHUNK_GOTO MKTAG('G','O','T','O') // goto chunk
+#define CHUNK_EXIT MKTAG('E','X','I','T') // exit/return from goto
// Conversation chunks - branching and logic (conditional)
-#define CHUNK_CASN MKID_BE('CASN') // assign
-#define CHUNK_CCGO MKID_BE('CCGO') // goto chunk
-#define CHUNK_CEGO MKID_BE('CEGO') // exit/return from goto
+#define CHUNK_CASN MKTAG('C','A','S','N') // assign
+#define CHUNK_CCGO MKTAG('C','C','G','O') // goto chunk
+#define CHUNK_CEGO MKTAG('C','E','G','O') // exit/return from goto
// Others
-#define CHUNK_FALL MKID_BE('FALL') // fallthrough
-#define CHUNK_WRPL MKID_BE('WRPL') // weighted reply chunk
-#define CHUNK_WPRL MKID_BE('WPRL') // weighted preply chunk
+#define CHUNK_FALL MKTAG('F','A','L','L') // fallthrough
+#define CHUNK_WRPL MKTAG('W','R','P','L') // weighted reply chunk
+#define CHUNK_WPRL MKTAG('W','P','R','L') // weighted preply chunk
ConversationView::ConversationView(MadsM4Engine *vm): View(vm, Common::Rect(0,
diff --git a/engines/m4/font.cpp b/engines/m4/font.cpp
index cba32c2225..3ed419675d 100644
--- a/engines/m4/font.cpp
+++ b/engines/m4/font.cpp
@@ -81,7 +81,7 @@ Font::Font(MadsM4Engine *vm, const char *filename) : _vm(vm) {
void Font::setFontM4(const char *filename) {
Common::SeekableReadStream *fontFile = _vm->res()->openFile(filename);
- if (fontFile->readUint32LE() != MKID_BE('FONT')) {
+ if (fontFile->readUint32LE() != MKTAG('F','O','N','T')) {
debugCN(kDebugGraphics, "Font::Font: FONT tag expected\n");
return;
}
@@ -92,7 +92,7 @@ void Font::setFontM4(const char *filename) {
//debugCN(kDebugGraphics, "Font::Font: _maxWidth = %d, _maxHeight = %d, fontSize = %d\n", _maxWidth, _maxHeight, fontSize);
- if (fontFile->readUint32LE() != MKID_BE('WIDT')) {
+ if (fontFile->readUint32LE() != MKTAG('W','I','D','T')) {
debugCN(kDebugGraphics, "Font::Font: WIDT tag expected\n");
return;
}
@@ -100,7 +100,7 @@ void Font::setFontM4(const char *filename) {
_charWidths = new uint8[256];
fontFile->read(_charWidths, 256);
- if (fontFile->readUint32LE() != MKID_BE('OFFS')) {
+ if (fontFile->readUint32LE() != MKTAG('O','F','F','S')) {
debugCN(kDebugGraphics, "Font::Font: OFFS tag expected\n");
return;
}
@@ -110,7 +110,7 @@ void Font::setFontM4(const char *filename) {
for (int i = 0; i < 256; i++)
_charOffs[i] = fontFile->readUint16LE();
- if (fontFile->readUint32LE() != MKID_BE('PIXS')) {
+ if (fontFile->readUint32LE() != MKTAG('P','I','X','S')) {
debugCN(kDebugGraphics, "Font::Font: PIXS tag expected\n");
return;
}
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 2aa378edf5..8d06aa0085 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -659,7 +659,7 @@ bool GameDatabaseV3::getSavegameDescription(const char *filename, Common::String
}
uint32 header = in->readUint32BE();
- if (header != MKID_BE('SGAM')) {
+ if (header != MKTAG('S','G','A','M')) {
warning("Save game header missing");
delete in;
return false;
@@ -696,7 +696,7 @@ int16 GameDatabaseV3::savegame(const char *filename, const char *description, in
return 6;
}
strncpy(desc, description, 64);
- out->writeUint32BE(MKID_BE('SGAM'));
+ out->writeUint32BE(MKTAG('S','G','A','M'));
out->writeUint32LE(size);
out->writeUint16LE(version);
out->write(desc, 64);
@@ -715,7 +715,7 @@ int16 GameDatabaseV3::loadgame(const char *filename, int16 version) {
}
uint32 header = in->readUint32BE();
- if (header != MKID_BE('SGAM')) {
+ if (header != MKTAG('S','G','A','M')) {
warning("Save game header missing");
delete in;
return 1;
diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp
index 87640f2b67..e37bd87a7e 100644
--- a/engines/made/pmvplayer.cpp
+++ b/engines/made/pmvplayer.cpp
@@ -50,14 +50,14 @@ bool PmvPlayer::play(const char *filename) {
uint32 chunkType, chunkSize, prevChunkSize = 0;
readChunk(chunkType, chunkSize); // "MOVE"
- if (chunkType != MKID_BE('MOVE')) {
+ if (chunkType != MKTAG('M','O','V','E')) {
warning("Unexpected PMV video header, expected 'MOVE'");
delete _fd;
return false;
}
readChunk(chunkType, chunkSize); // "MHED"
- if (chunkType != MKID_BE('MHED')) {
+ if (chunkType != MKTAG('M','H','E','D')) {
warning("Unexpected PMV video header, expected 'MHED'");
delete _fd;
return false;
@@ -111,7 +111,7 @@ bool PmvPlayer::play(const char *filename) {
int32 frameTime = _vm->_system->getMillis();
readChunk(chunkType, chunkSize);
- if (chunkType != MKID_BE('MFRM')) {
+ if (chunkType != MKTAG('M','F','R','M')) {
warning("Unknown chunk type");
}
diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp
index f8582aec40..e556e4ab38 100644
--- a/engines/made/resource.cpp
+++ b/engines/made/resource.cpp
@@ -57,7 +57,7 @@ PictureResource::~PictureResource() {
}
void PictureResource::load(byte *source, int size) {
- if (READ_BE_UINT32(source) == MKID_BE('Flex')) {
+ if (READ_BE_UINT32(source) == MKTAG('F','l','e','x')) {
loadChunked(source, size);
} else {
loadRaw(source, size);
@@ -126,13 +126,13 @@ void PictureResource::loadChunked(byte *source, int size) {
debug(0, "chunkType = %08X; chunkSize = %d", chunkType, chunkSize);
- if (chunkType == MKID_BE('Rect')) {
+ if (chunkType == MKTAG('R','e','c','t')) {
debug(0, "Rect");
sourceS->skip(4);
height = sourceS->readUint16BE();
width = sourceS->readUint16BE();
debug(0, "width = %d; height = %d", width, height);
- } else if (chunkType == MKID_BE('fMap')) {
+ } else if (chunkType == MKTAG('f','M','a','p')) {
debug(0, "fMap");
lineSize = sourceS->readUint16BE();
sourceS->skip(11);
@@ -140,21 +140,21 @@ void PictureResource::loadChunked(byte *source, int size) {
cmdOffs = sourceS->pos();
sourceS->skip(chunkSize - 14);
debug(0, "lineSize = %d; cmdFlags = %d; cmdOffs = %04X", lineSize, cmdFlags, cmdOffs);
- } else if (chunkType == MKID_BE('fLCo')) {
+ } else if (chunkType == MKTAG('f','L','C','o')) {
debug(0, "fLCo");
sourceS->skip(9);
pixelFlags = sourceS->readByte();
pixelOffs = sourceS->pos();
sourceS->skip(chunkSize - 10);
debug(0, "pixelFlags = %d; pixelOffs = %04X", pixelFlags, pixelOffs);
- } else if (chunkType == MKID_BE('fPix')) {
+ } else if (chunkType == MKTAG('f','P','i','x')) {
debug(0, "fPix");
sourceS->skip(9);
maskFlags = sourceS->readByte();
maskOffs = sourceS->pos();
sourceS->skip(chunkSize - 10);
debug(0, "maskFlags = %d; maskOffs = %04X", maskFlags, maskOffs);
- } else if (chunkType == MKID_BE('fGCo')) {
+ } else if (chunkType == MKTAG('f','G','C','o')) {
debug(0, "fGCo");
_hasPalette = true;
_paletteColorCount = chunkSize / 3;
diff --git a/engines/made/resource.h b/engines/made/resource.h
index 5d5664b4c7..ade6a23029 100644
--- a/engines/made/resource.h
+++ b/engines/made/resource.h
@@ -49,16 +49,16 @@ const int kMaxResourceCacheSize = 400 * 1024;
enum ResourceType {
- kResARCH = MKID_BE('ARCH'),
- kResFREE = MKID_BE('FREE'),
- kResOMNI = MKID_BE('OMNI'),
- kResFLEX = MKID_BE('FLEX'),
- kResSNDS = MKID_BE('SNDS'),
- kResANIM = MKID_BE('ANIM'),
- kResMENU = MKID_BE('MENU'),
- kResFONT = MKID_BE('FONT'),
- kResXMID = MKID_BE('XMID'),
- kResMIDI = MKID_BE('MIDI')
+ kResARCH = MKTAG('A','R','C','H'),
+ kResFREE = MKTAG('F','R','E','E'),
+ kResOMNI = MKTAG('O','M','N','I'),
+ kResFLEX = MKTAG('F','L','E','X'),
+ kResSNDS = MKTAG('S','N','D','S'),
+ kResANIM = MKTAG('A','N','I','M'),
+ kResMENU = MKTAG('M','E','N','U'),
+ kResFONT = MKTAG('F','O','N','T'),
+ kResXMID = MKTAG('X','M','I','D'),
+ kResMIDI = MKTAG('M','I','D','I')
};
struct ResourceSlot;
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 6dce147513..ee67c9f23c 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -563,7 +563,7 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
// deriven.
debugN("\n\nDumping scripts for %s\'s card %d!\n", argv[1], (uint16)atoi(argv[3]));
debugN("==================================\n\n");
- Common::SeekableReadStream *cardStream = _vm->getResource(MKID_BE('CARD'), (uint16)atoi(argv[3]));
+ Common::SeekableReadStream *cardStream = _vm->getResource(MKTAG('C','A','R','D'), (uint16)atoi(argv[3]));
cardStream->seek(4);
RivenScriptList scriptList = _vm->_scriptMan->readScripts(cardStream, false);
for (uint32 i = 0; i < scriptList.size(); i++) {
@@ -576,7 +576,7 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
debugN("\n\nDumping scripts for %s\'s card %d hotspots!\n", argv[1], (uint16)atoi(argv[3]));
debugN("===========================================\n\n");
- Common::SeekableReadStream *hsptStream = _vm->getResource(MKID_BE('HSPT'), (uint16)atoi(argv[3]));
+ Common::SeekableReadStream *hsptStream = _vm->getResource(MKTAG('H','S','P','T'), (uint16)atoi(argv[3]));
uint16 hotspotCount = hsptStream->readUint16BE();
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index 9233a8497c..b4969f990a 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -221,7 +221,7 @@ void MacCursorManager::setCursor(uint16 id) {
}
// Try a color cursor first
- Common::SeekableReadStream *stream = _resFork->getResource(MKID_BE('crsr'), id);
+ Common::SeekableReadStream *stream = _resFork->getResource(MKTAG('c','r','s','r'), id);
if (stream) {
byte *cursor, *palette;
@@ -239,7 +239,7 @@ void MacCursorManager::setCursor(uint16 id) {
}
// Fall back to b&w cursors
- stream = _resFork->getResource(MKID_BE('CURS'), id);
+ stream = _resFork->getResource(MKTAG('C','U','R','S'), id);
if (stream) {
setMacXorCursor(stream);
diff --git a/engines/mohawk/detection.cpp b/engines/mohawk/detection.cpp
index c31df3010d..cad24b55f1 100644
--- a/engines/mohawk/detection.cpp
+++ b/engines/mohawk/detection.cpp
@@ -121,6 +121,7 @@ static const PlainGameDescriptor mohawkGames[] = {
{"csworld", "Where in the World is Carmen Sandiego?"},
{"csamtrak", "Where in America is Carmen Sandiego? (The Great Amtrak Train Adventure)"},
{"carmentq", "Carmen Sandiego's ThinkQuick Challenge"},
+ {"carmentqc", "Carmen Sandiego's ThinkQuick Challenge Custom Question Creator"},
{"maggiesfa", "Maggie's Farmyard Adventure"},
{"jamesmath", "James Discovers/Explores Math"},
{"treehouse", "The Treehouse"},
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 27ee3401f5..a8f9ee557b 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -610,6 +610,21 @@ static const MohawkGameDescription gameDescriptions[] = {
{
{
+ "carmentqc",
+ "",
+ AD_ENTRY1("Outline.txt", "6a281eefe72987afb0f8fb6cf84553f5"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV5,
+ 0,
+ 0
+ },
+
+ {
+ {
"maggiesfa",
"",
AD_ENTRY1("Outline", "b7dc6e65fa9e80784a5bb8b557aa37c4"),
@@ -869,6 +884,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"TORTOISE.EXE"
},
+ // From Scarlatti in bug #3275626
+ {
+ {
+ "tortoise",
+ "Demo v1.1",
+ AD_ENTRY1("TORTOISE.512", "14400a3358a3f1148e4d4b47bc3523c9"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "TORTOISE.EXE"
+ },
+
{
{
"tortoise",
@@ -929,6 +960,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"ARTHUR.EXE"
},
+ // From Scarlatti in bug #3275626
+ {
+ {
+ "arthur",
+ "Demo v1.1",
+ AD_ENTRY1("ARTHUR.512", "dabdd466dea26ab5ecb9415cf73f8601"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "ARTHUR.EXE"
+ },
+
{
{
"arthur",
@@ -1006,6 +1053,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"GRANDMA.EXE"
},
+ // From Scarlatti in bug #3275626
+ {
+ {
+ "grandma",
+ "Demo v1.1",
+ AD_ENTRY1("GRANDMA.512", "4f616647245bb4e37e6dab7557dad304"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "GRANDMA.EXE"
+ },
+
{
{
"grandma",
@@ -1036,6 +1099,23 @@ static const MohawkGameDescription gameDescriptions[] = {
"Living Books Player"
},
+ // Ruff's Bone 1.0
+ // From pacifist
+ {
+ {
+ "ruff",
+ "",
+ AD_ENTRY1("RUFF.512", "3dbda0de6f47a64d1714d89f5a5f60d1"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "RUFF.EXE"
+ },
+
{
{
"ruff",
@@ -1051,36 +1131,35 @@ static const MohawkGameDescription gameDescriptions[] = {
"RUFF.EXE"
},
+ // From Scarlatti in bug #3275626
{
{
"ruff",
"Demo",
- AD_ENTRY1("Ruff's Bone Demo", "22553ac2ceb2a166bdf1def6ad348532"),
+ AD_ENTRY1("RUFF.512", "07b9d013e2400d61ca268892a76de4d2"),
Common::EN_ANY,
- Common::kPlatformMacintosh,
+ Common::kPlatformWindows,
ADGF_DEMO,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV1,
GF_DEMO,
- "Living Books Player"
+ "RUFF.EXE"
},
- // Ruff's Bone 1.0
- // From pacifist
{
{
"ruff",
- "",
- AD_ENTRY1("RUFF.512", "3dbda0de6f47a64d1714d89f5a5f60d1"),
+ "Demo",
+ AD_ENTRY1("Ruff's Bone Demo", "22553ac2ceb2a166bdf1def6ad348532"),
Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ Common::kPlatformMacintosh,
+ ADGF_DEMO,
Common::GUIO_NONE
},
GType_LIVINGBOOKSV1,
- 0,
- "RUFF.EXE"
+ GF_DEMO,
+ "Living Books Player"
},
{
@@ -1113,6 +1192,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"NEWKID.EXE"
},
+ // From Scarlatti in bug #3275626
+ {
+ {
+ "newkid",
+ "Demo v1.1",
+ AD_ENTRY1("NEWKID.512", "de576f3481f62e84eda03b4d2307492b"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "NEWKID.EXE"
+ },
+
{
{
"newkid",
@@ -1174,6 +1269,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"BIRTHDAY.EXE"
},
+ // From Scarlatti in bug #3275626
+ {
+ {
+ "arthurbday",
+ "Demo",
+ AD_ENTRY1("BIRTHDAY.512", "2946b1e06f59ea607b8b29dfc6ba8976"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "BIRTHDAY.EXE"
+ },
+
{
{
"arthurbday",
@@ -1219,6 +1330,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"Little Monster at School"
},
+ // From Scarlatti in bug #3275626
+ {
+ {
+ "lilmonster",
+ "Demo",
+ AD_ENTRY1("MONSTER.512", "029e57f1fc8dd1f93f6623a1841f0df2"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_DEMO,
+ "MONSTER.EXE"
+ },
+
{
{
"catinthehat",
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp
index 542cc9645d..7f6c3cc43a 100644
--- a/engines/mohawk/livingbooks.cpp
+++ b/engines/mohawk/livingbooks.cpp
@@ -72,6 +72,48 @@ Common::Rect MohawkEngine_LivingBooks::readRect(Common::SeekableSubReadStreamEnd
return rect;
}
+LBPage::LBPage(MohawkEngine_LivingBooks *vm) : _vm(vm) {
+ _code = NULL;
+ _mhk = NULL;
+
+ _baseId = 0;
+ _cascade = false;
+}
+
+void LBPage::open(MohawkArchive *mhk, uint16 baseId) {
+ _mhk = mhk;
+ _baseId = baseId;
+
+ _vm->addArchive(_mhk);
+ if (_vm->hasResource(ID_BCOD, baseId))
+ _code = new LBCode(_vm, baseId);
+
+ loadBITL(baseId);
+ for (uint i = 0; i < _items.size(); i++)
+ _vm->addItem(_items[i]);
+
+ for (uint32 i = 0; i < _items.size(); i++)
+ _items[i]->init();
+}
+
+void LBPage::itemDestroyed(LBItem *item) {
+ for (uint i = 0; i < _items.size(); i++)
+ if (item == _items[i]) {
+ _items.remove_at(i);
+ return;
+ }
+ error("itemDestroyed didn't find item");
+}
+
+LBPage::~LBPage() {
+ delete _code;
+ _vm->removeItems(_items);
+ for (uint i = 0; i < _items.size(); i++)
+ delete _items[i];
+ _vm->removeArchive(_mhk);
+ delete _mhk;
+}
+
MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGameDescription *gamedesc) : MohawkEngine(syst, gamedesc) {
_needsUpdate = false;
_needsRedraw = false;
@@ -82,11 +124,11 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa
_alreadyShowedIntro = false;
- _code = NULL;
-
_rnd = new Common::RandomSource();
g_eventRec.registerRandomSource(*_rnd, "livingbooks");
+ _page = NULL;
+
const Common::FSNode gameDataDir(ConfMan.get("path"));
// Rugrats
SearchMan.addSubDirectoryMatching(gameDataDir, "program");
@@ -281,16 +323,9 @@ void MohawkEngine_LivingBooks::destroyPage() {
_eventQueue.clear();
- delete _code;
- _code = NULL;
-
- for (uint32 i = 0; i < _items.size(); i++)
- delete _items[i];
- _items.clear();
-
- for (uint32 i = 0; i < _mhk.size(); i++)
- delete _mhk[i];
- _mhk.clear();
+ delete _page;
+ assert(_items.empty());
+ _page = NULL;
_notifyEvents.clear();
@@ -342,7 +377,8 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
MohawkArchive *pageArchive = createMohawkArchive();
if (!filename.empty() && pageArchive->open(filename)) {
- _mhk.push_back(pageArchive);
+ _page = new LBPage(this);
+ _page->open(pageArchive, 1000);
} else {
delete pageArchive;
debug(2, "Could not find page %d.%d for '%s'", page, subpage, name.c_str());
@@ -360,7 +396,7 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
}
}
- debug(1, "Stack Version: %d", getResourceVersion());
+ debug(1, "Page Version: %d", _page->getResourceVersion());
_curMode = mode;
_curPage = page;
@@ -370,13 +406,6 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) {
_gfx->setPalette(1000);
- if (hasResource(ID_BCOD, 1000))
- _code = new LBCode(this);
-
- loadBITL(1000);
- for (uint32 i = 0; i < _items.size(); i++)
- _items[i]->init();
-
_phase = 0;
_introDone = false;
@@ -523,6 +552,7 @@ void MohawkEngine_LivingBooks::updatePage() {
_items.remove_at(i);
i--;
delete delayedEvent.item;
+ _page->itemDestroyed(delayedEvent.item);
if (_focus == delayedEvent.item)
_focus = NULL;
break;
@@ -550,6 +580,39 @@ void MohawkEngine_LivingBooks::updatePage() {
}
}
+void MohawkEngine_LivingBooks::addArchive(MohawkArchive *archive) {
+ _mhk.push_back(archive);
+}
+
+void MohawkEngine_LivingBooks::removeArchive(MohawkArchive *archive) {
+ for (uint i = 0; i < _mhk.size(); i++) {
+ if (archive != _mhk[i])
+ continue;
+ _mhk.remove_at(i);
+ return;
+ }
+
+ error("removeArchive didn't find archive");
+}
+
+void MohawkEngine_LivingBooks::addItem(LBItem *item) {
+ _items.push_back(item);
+}
+
+void MohawkEngine_LivingBooks::removeItems(const Common::Array<LBItem *> &items) {
+ for (uint i = 0; i < items.size(); i++) {
+ bool found = false;
+ for (uint16 j = 0; j < _items.size(); j++) {
+ if (items[i] != _items[j])
+ continue;
+ found = true;
+ _items.remove_at(j);
+ break;
+ }
+ assert(found);
+ }
+}
+
LBItem *MohawkEngine_LivingBooks::getItemById(uint16 id) {
for (uint16 i = 0; i < _items.size(); i++)
if (_items[i]->getId() == id)
@@ -558,6 +621,14 @@ LBItem *MohawkEngine_LivingBooks::getItemById(uint16 id) {
return NULL;
}
+LBItem *MohawkEngine_LivingBooks::getItemByName(Common::String name) {
+ for (uint16 i = 0; i < _items.size(); i++)
+ if (_items[i]->getName() == name)
+ return _items[i];
+
+ return NULL;
+}
+
void MohawkEngine_LivingBooks::setFocus(LBItem *focus) {
_focus = focus;
}
@@ -624,9 +695,9 @@ void MohawkEngine_LivingBooks::lockSound(LBItem *owner, bool lock) {
}
}
-// Only 1 VSRN resource per stack, Id 1000
-uint16 MohawkEngine_LivingBooks::getResourceVersion() {
- Common::SeekableReadStream *versionStream = getResource(ID_VRSN, 1000);
+// Only 1 VSRN resource per page
+uint16 LBPage::getResourceVersion() {
+ Common::SeekableReadStream *versionStream = _vm->getResource(ID_VRSN, _baseId);
// FIXME: some V2 games have very strange version entries
if (versionStream->size() != 2)
@@ -638,43 +709,43 @@ uint16 MohawkEngine_LivingBooks::getResourceVersion() {
return version;
}
-void MohawkEngine_LivingBooks::loadBITL(uint16 resourceId) {
- Common::SeekableSubReadStreamEndian *bitlStream = wrapStreamEndian(ID_BITL, resourceId);
+void LBPage::loadBITL(uint16 resourceId) {
+ Common::SeekableSubReadStreamEndian *bitlStream = _vm->wrapStreamEndian(ID_BITL, resourceId);
while (true) {
- Common::Rect rect = readRect(bitlStream);
+ Common::Rect rect = _vm->readRect(bitlStream);
uint16 type = bitlStream->readUint16();
LBItem *res;
switch (type) {
case kLBPictureItem:
- res = new LBPictureItem(this, rect);
+ res = new LBPictureItem(_vm, this, rect);
break;
case kLBAnimationItem:
- res = new LBAnimationItem(this, rect);
+ res = new LBAnimationItem(_vm, this, rect);
break;
case kLBPaletteItem:
- res = new LBPaletteItem(this, rect);
+ res = new LBPaletteItem(_vm, this, rect);
break;
case kLBGroupItem:
- res = new LBGroupItem(this, rect);
+ res = new LBGroupItem(_vm, this, rect);
break;
case kLBSoundItem:
- res = new LBSoundItem(this, rect);
+ res = new LBSoundItem(_vm, this, rect);
break;
case kLBLiveTextItem:
- res = new LBLiveTextItem(this, rect);
+ res = new LBLiveTextItem(_vm, this, rect);
break;
case kLBMovieItem:
- res = new LBMovieItem(this, rect);
+ res = new LBMovieItem(_vm, this, rect);
break;
case kLBMiniGameItem:
- res = new LBMiniGameItem(this, rect);
+ res = new LBMiniGameItem(_vm, this, rect);
break;
default:
warning("Unknown item type %04x", type);
case 3: // often used for buttons
- res = new LBItem(this, rect);
+ res = new LBItem(_vm, this, rect);
break;
}
@@ -1802,7 +1873,7 @@ LBScriptEntry::~LBScriptEntry() {
delete subentries[i];
}
-LBItem::LBItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : _vm(vm), _rect(rect) {
+LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : _vm(vm), _page(page), _rect(rect) {
_phase = 0;
_loopMode = 0;
@@ -1926,13 +1997,14 @@ LBScriptEntry *LBItem::parseScriptEntry(uint16 type, uint16 &size, Common::Seeka
debug(4, "%d targets with targeting type %04x", count, targetingType);
// FIXME: targeting by name
+ uint oldAlign = size % 2;
for (uint i = 0; i < count; i++) {
Common::String target = _vm->readString(stream);
warning("ignoring target '%s' in script entry", target.c_str());
size -= target.size() + 1;
}
- if (size % 2 == 1) {
+ if (size % 2 != oldAlign) {
stream->skip(1);
size--;
}
@@ -2190,9 +2262,9 @@ void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEnd
{
assert(size == 4);
uint offset = stream->readUint32();
- if (!_vm->_code)
+ if (!_page->_code)
error("no BCOD?");
- _vm->_code->runCode(this, offset);
+ _page->_code->runCode(this, offset);
}
break;
@@ -2659,9 +2731,9 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
break;
case kLBOpSendExpression:
- if (!_vm->_code)
+ if (!_page->_code)
error("no BCOD?");
- _vm->_code->runCode(this, entry->offset);
+ _page->_code->runCode(this, entry->offset);
break;
case kLBOpRunSubentries:
@@ -2694,10 +2766,10 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
case kLBOpJumpUnlessExpression:
case kLBOpBreakExpression:
case kLBOpJumpToExpression:
- if (!_vm->_code)
+ if (!_page->_code)
error("no BCOD?");
{
- LBValue r = _vm->_code->runCode(this, entry->offset);
+ LBValue r = _page->_code->runCode(this, entry->offset);
// FIXME
return r.integer;
}
@@ -2973,7 +3045,7 @@ bool LBItem::checkCondition(const Common::String &condition) {
return false; // unreachable
}
-LBSoundItem::LBSoundItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBSoundItem::LBSoundItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBSoundItem");
_running = false;
}
@@ -3019,7 +3091,7 @@ void LBSoundItem::stop() {
LBItem::stop();
}
-LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBGroupItem");
_starting = false;
}
@@ -3134,7 +3206,7 @@ void LBGroupItem::stop() {
}
}
-LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBPaletteItem");
_fadeInStart = 0;
@@ -3219,7 +3291,7 @@ void LBPaletteItem::update() {
LBItem::update();
}
-LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
_currentPhrase = 0xFFFF;
_currentWord = 0xFFFF;
debug(3, "new LBLiveTextItem");
@@ -3466,7 +3538,7 @@ void LBLiveTextItem::notify(uint16 data, uint16 from) {
LBItem::notify(data, from);
}
-LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBPictureItem");
}
@@ -3509,7 +3581,7 @@ void LBPictureItem::draw() {
_vm->_gfx->copyAnimImageToScreen(_resourceId, _rect.left, _rect.top);
}
-LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
_anim = NULL;
_running = false;
debug(3, "new LBAnimationItem");
@@ -3608,7 +3680,7 @@ void LBAnimationItem::draw() {
_anim->draw();
}
-LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBMovieItem");
}
@@ -3637,7 +3709,7 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) {
return LBItem::togglePlaying(playing, restart);
}
-LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) {
+LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
debug(3, "new LBMiniGameItem");
}
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h
index 3eff039385..cd3b206d57 100644
--- a/engines/mohawk/livingbooks.h
+++ b/engines/mohawk/livingbooks.h
@@ -237,6 +237,7 @@ enum {
};
class MohawkEngine_LivingBooks;
+class LBPage;
class LBGraphics;
class LBAnimation;
@@ -357,7 +358,7 @@ class LBItem {
friend class LBCode;
public:
- LBItem(MohawkEngine_LivingBooks *vm, Common::Rect rect);
+ LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect);
virtual ~LBItem();
void readFrom(Common::SeekableSubReadStreamEndian *stream);
@@ -385,11 +386,14 @@ public:
virtual void notify(uint16 data, uint16 from); // 0x1A
uint16 getId() { return _itemId; }
+ const Common::String &getName() { return _desc; }
+ const Common::Rect &getRect() { return _rect; }
uint16 getSoundPriority() { return _soundMode; }
bool isAmbient() { return _isAmbient; }
protected:
MohawkEngine_LivingBooks *_vm;
+ LBPage *_page;
void setNextTime(uint16 min, uint16 max);
void setNextTime(uint16 min, uint16 max, uint32 start);
@@ -425,7 +429,7 @@ protected:
class LBSoundItem : public LBItem {
public:
- LBSoundItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBSoundItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBSoundItem();
void update();
@@ -443,7 +447,7 @@ struct GroupEntry {
class LBGroupItem : public LBItem {
public:
- LBGroupItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBGroupItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
@@ -467,7 +471,7 @@ protected:
class LBPaletteItem : public LBItem {
public:
- LBPaletteItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBPaletteItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBPaletteItem();
void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
@@ -494,7 +498,7 @@ struct LiveTextPhrase {
class LBLiveTextItem : public LBItem {
public:
- LBLiveTextItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBLiveTextItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
@@ -523,7 +527,7 @@ protected:
class LBPictureItem : public LBItem {
public:
- LBPictureItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBPictureItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream);
@@ -534,7 +538,7 @@ public:
class LBAnimationItem : public LBItem {
public:
- LBAnimationItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBAnimationItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBAnimationItem();
void setEnabled(bool enabled);
@@ -555,7 +559,7 @@ protected:
class LBMovieItem : public LBItem {
public:
- LBMovieItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBMovieItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBMovieItem();
void update();
@@ -564,14 +568,14 @@ public:
class LBMiniGameItem : public LBItem {
public:
- LBMiniGameItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect);
+ LBMiniGameItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect);
~LBMiniGameItem();
bool togglePlaying(bool playing, bool restart);
};
struct NotifyEvent {
- NotifyEvent(uint t, uint p) : type(t), param(p) { }
+ NotifyEvent(uint t, uint p) : type(t), param(p), newUnknown(0), newMode(0), newPage(0), newSubpage(0) { }
uint type;
uint param;
@@ -594,6 +598,30 @@ struct DelayedEvent {
DelayedEventType type;
};
+class LBPage {
+public:
+ LBPage(MohawkEngine_LivingBooks *vm);
+ ~LBPage();
+
+ void open(MohawkArchive *mhk, uint16 baseId);
+ uint16 getResourceVersion();
+
+ void itemDestroyed(LBItem *item);
+
+ LBCode *_code;
+
+protected:
+ MohawkEngine_LivingBooks *_vm;
+
+ MohawkArchive *_mhk;
+ Common::Array<LBItem *> _items;
+
+ uint16 _baseId;
+ bool _cascade;
+
+ void loadBITL(uint16 resourceId);
+};
+
class MohawkEngine_LivingBooks : public MohawkEngine {
protected:
Common::Error run();
@@ -614,7 +642,13 @@ public:
Common::Rect readRect(Common::SeekableSubReadStreamEndian *stream);
GUI::Debugger *getDebugger() { return _console; }
+ void addArchive(MohawkArchive *archive);
+ void removeArchive(MohawkArchive *Archive);
+ void addItem(LBItem *item);
+ void removeItems(const Common::Array<LBItem *> &items);
+
LBItem *getItemById(uint16 id);
+ LBItem *getItemByName(Common::String name);
void setFocus(LBItem *focus);
void setEnableForAll(bool enable, LBItem *except = 0);
@@ -633,11 +667,13 @@ public:
void prevPage();
void nextPage();
- LBCode *_code;
-
// TODO: make private
Common::HashMap<Common::String, LBValue> _variables;
+ // helper functions, also used by LBProxyItem
+ Common::String getFileNameFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
+ MohawkArchive *createMohawkArchive() const;
+
private:
LivingBooksConsole *_console;
Common::ConfigFile _bookInfoFile;
@@ -651,6 +687,7 @@ private:
LBMode _curMode;
uint16 _curPage, _curSubPage;
uint16 _phase;
+ LBPage *_page;
Common::Array<LBItem *> _items;
Common::Queue<DelayedEvent> _eventQueue;
LBItem *_focus;
@@ -663,8 +700,6 @@ private:
uint16 _soundLockOwner;
uint16 _maxSoundPriority;
- uint16 getResourceVersion();
- void loadBITL(uint16 resourceId);
void loadSHP(uint16 resourceId);
bool tryDefaultPage();
@@ -698,10 +733,6 @@ private:
Common::String getStringFromConfig(const Common::String &section, const Common::String &key);
Common::String getStringFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
int getIntFromConfig(const Common::String &section, const Common::String &key);
- Common::String getFileNameFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
-
- // Platform/Version functions
- MohawkArchive *createMohawkArchive() const;
};
} // End of namespace Mohawk
diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp
index c0718d941a..84f69af2ac 100644
--- a/engines/mohawk/livingbooks_code.cpp
+++ b/engines/mohawk/livingbooks_code.cpp
@@ -71,6 +71,19 @@ bool LBValue::isZero() const {
return toInt() == 0; // FIXME
}
+Common::String LBValue::toString() const {
+ switch (type) {
+ case kLBValueString:
+ return string;
+ case kLBValueInteger:
+ return Common::String::format("%d", integer);
+ case kLBValueReal:
+ return Common::String::format("%f", real);
+ default:
+ return string; // FIXME
+ }
+}
+
int LBValue::toInt() const {
return integer; // FIXME
}
@@ -79,8 +92,38 @@ double LBValue::toDouble() const {
return real; // FIXME
}
-LBCode::LBCode(MohawkEngine_LivingBooks *vm) : _vm(vm) {
- Common::SeekableSubReadStreamEndian *bcodStream = _vm->wrapStreamEndian(ID_BCOD, 1000);
+Common::Point LBValue::toPoint() const {
+ switch (type) {
+ case kLBValueString:
+ // FIXME
+ return Common::Point();
+ case kLBValueInteger:
+ return Common::Point(integer, integer);
+ case kLBValuePoint:
+ return point;
+ default:
+ error("failed to convert to point");
+ }
+}
+
+Common::Rect LBValue::toRect() const {
+ switch (type) {
+ case kLBValueString:
+ // FIXME
+ return Common::Rect();
+ case kLBValueInteger:
+ return Common::Rect(integer, integer, integer, integer);
+ case kLBValueRect:
+ return rect;
+ case kLBValueItemPtr:
+ return item->getRect();
+ default:
+ error("failed to convert to rect");
+ }
+}
+
+LBCode::LBCode(MohawkEngine_LivingBooks *vm, uint16 baseId) : _vm(vm) {
+ Common::SeekableSubReadStreamEndian *bcodStream = _vm->wrapStreamEndian(ID_BCOD, baseId);
uint32 totalSize = bcodStream->readUint32();
if (totalSize != (uint32)bcodStream->size())
@@ -206,7 +249,7 @@ LBValue LBCode::runCode(byte terminator) {
if (_currToken == terminator || _currToken == kTokenEndOfFile)
break;
if (_currToken != kTokenEndOfStatement && _currToken != kTokenEndOfFile)
- error("missing EOS");
+ error("missing EOS (got %02x)", _currToken);
debugN("\n");
}
@@ -214,8 +257,29 @@ LBValue LBCode::runCode(byte terminator) {
}
void LBCode::parseStatement() {
- // FIXME: logical operators
parseComparisons();
+
+ if (_currToken != kTokenAnd && _currToken != kTokenOr)
+ return;
+ byte op = _currToken;
+ if (op == kTokenAnd)
+ debugN(" && ");
+ else
+ debugN(" || ");
+
+ nextToken();
+ parseComparisons();
+
+ LBValue val2 = _stack.pop();
+ LBValue val1 = _stack.pop();
+ bool result;
+ if (op == kTokenAnd)
+ result = !val1.isZero() && !val2.isZero();
+ else
+ result = !val1.isZero() || !val2.isZero();
+
+ debugN(" [--> %s]", result ? "true" : "false");
+ _stack.push(result);
}
void LBCode::parseComparisons() {
@@ -253,7 +317,7 @@ void LBCode::parseComparisons() {
error("comparison didn't get enough values");
LBValue val2 = _stack.pop();
LBValue val1 = _stack.pop();
- bool result;
+ bool result = false;
// FIXME: should work for non-integers!!
switch (comparison) {
case kTokenEquals:
@@ -277,17 +341,50 @@ void LBCode::parseComparisons() {
}
debugN(" [--> %s]", result ? "true" : "false");
- _stack.push(result ? 1 : 0);
+ _stack.push(result);
}
void LBCode::parseConcat() {
parseArithmetic1();
- // FIXME: string concat
+
+ if (_currToken != kTokenConcat)
+ return;
+
+ debugN(" & ");
+ nextToken();
+ parseArithmetic1();
+
+ LBValue val2 = _stack.pop();
+ LBValue val1 = _stack.pop();
+ Common::String result = val1.toString() + val2.toString();
+ debugN(" [--> \"%s\"]", result.c_str());
+ _stack.push(result);
}
void LBCode::parseArithmetic1() {
parseArithmetic2();
- // FIXME: -/+ math operators
+
+ if (_currToken != kTokenMinus && _currToken != kTokenPlus)
+ return;
+
+ byte op = _currToken;
+ if (op == kTokenMinus)
+ debugN(" - ");
+ else if (op == kTokenPlus)
+ debugN(" + ");
+
+ nextToken();
+ parseArithmetic2();
+
+ LBValue val2 = _stack.pop();
+ LBValue val1 = _stack.pop();
+ LBValue result;
+ // TODO: cope with non-integers
+ if (op == kTokenMinus)
+ result = val1.toInt() - val2.toInt();
+ else
+ result = val1.toInt() + val2.toInt();
+ _stack.push(result);
}
void LBCode::parseArithmetic2() {
@@ -310,10 +407,11 @@ void LBCode::parseMain() {
Common::String varname = _currValue.string;
debugN("%s", varname.c_str());
nextToken();
- if (varname == "self") {
+ if (varname.equalsIgnoreCase("self")) {
_stack.push(LBValue(_currSource));
if (_currToken == kTokenAssign)
error("attempted assignment to self");
+ break;
} else if (_currToken == kTokenAssign) {
debugN(" = ");
nextToken();
@@ -326,7 +424,16 @@ void LBCode::parseMain() {
} else {
_stack.push(_vm->_variables[varname]);
}
- // FIXME: pre/postincrement
+ // FIXME: pre/postincrement for non-integers
+ if (_currToken == kTokenPlusPlus) {
+ debugN("++");
+ _vm->_variables[varname].integer++;
+ nextToken();
+ } else if (_currToken == kTokenMinusMinus) {
+ debugN("--");
+ _vm->_variables[varname].integer--;
+ nextToken();
+ }
}
break;
@@ -348,6 +455,17 @@ void LBCode::parseMain() {
nextToken();
break;
+ case kTokenTrue:
+ debugN("TRUE");
+ _stack.push(true);
+ nextToken();
+ break;
+ case kTokenFalse:
+ debugN("FALSE");
+ _stack.push(false);
+ nextToken();
+ break;
+
case kTokenOpenBracket:
debugN("(");
nextToken();
@@ -442,6 +560,21 @@ Common::Array<LBValue> LBCode::readParams() {
return params;
}
+Common::Rect LBCode::getRectFromParams(const Common::Array<LBValue> &params) {
+ if (params.size() == 0) {
+ assert(_currSource);
+ return _currSource->getRect();
+ } else if (params.size() == 1) {
+ const LBValue &val = params[0];
+ LBItem *item = _vm->getItemByName(val.toString());
+ if (item)
+ return item->getRect();
+ else
+ return val.toRect();
+ } else
+ error("getRectFromParams got called with weird state");
+}
+
struct CodeCommandInfo {
const char *name;
typedef void (LBCode::*CommandFunc)(const Common::Array<LBValue> &params);
@@ -457,16 +590,16 @@ CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
{ "max", 0 },
{ "min", 0 },
{ "abs", 0 },
- { "getRect", 0 }, // also "makeRect"
+ { "getRect", &LBCode::cmdGetRect }, // also "makeRect"
{ "makePt", 0 }, // also "makePair"
- { "topleft", 0 },
- { "bottomright", 0 },
+ { "topLeft", &LBCode::cmdTopLeft },
+ { "bottomRight", &LBCode::cmdBottomRight },
{ "mousePos", 0 },
- { "top", 0 },
- { "left", 0 },
- { "bottom", 0 },
+ { "top", &LBCode::cmdTop },
+ { "left", &LBCode::cmdLeft },
+ { "bottom", &LBCode::cmdBottom },
// 0x10
- { "right", 0 },
+ { "right", &LBCode::cmdRight },
{ "xpos", 0 },
{ "ypos", 0 },
{ "playFrom", 0 },
@@ -607,6 +740,67 @@ void LBCode::cmdUnimplemented(const Common::Array<LBValue> &params) {
warning("unimplemented command called");
}
+void LBCode::cmdGetRect(const Common::Array<LBValue> &params) {
+ if (params.size() < 2) {
+ _stack.push(getRectFromParams(params));
+ } else if (params.size() == 2) {
+ Common::Point p1 = params[0].toPoint();
+ Common::Point p2 = params[1].toPoint();
+ _stack.push(Common::Rect(p1.x, p1.y, p2.x, p2.y));
+ } else if (params.size() == 4) {
+ _stack.push(Common::Rect(params[0].toInt(), params[1].toInt(), params[2].toInt(), params[3].toInt()));
+ } else
+ error("incorrect number of parameters (%d) to getRect", params.size());
+}
+
+void LBCode::cmdTopLeft(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to topLeft", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(Common::Point(rect.top, rect.left));
+}
+
+void LBCode::cmdBottomRight(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to bottomRight", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(Common::Point(rect.bottom, rect.right));
+}
+
+void LBCode::cmdTop(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to top", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(rect.top);
+}
+
+void LBCode::cmdLeft(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to left", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(rect.left);
+}
+
+void LBCode::cmdBottom(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to bottom", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(rect.bottom);
+}
+
+void LBCode::cmdRight(const Common::Array<LBValue> &params) {
+ if (params.size() > 1)
+ error("too many parameters (%d) to right", params.size());
+
+ Common::Rect rect = getRectFromParams(params);
+ _stack.push(rect.right);
+}
+
void LBCode::cmdSetPlayParams(const Common::Array<LBValue> &params) {
if (params.size() > 8)
error("too many parameters (%d) to setPlayParams", params.size());
@@ -785,6 +979,16 @@ void LBCode::runNotifyCommand() {
}
break;
+ case kLBNotifyQuit:
+ {
+ debugN("quit");
+ Common::Array<LBValue> params = readParams();
+ if (params.size() != 0)
+ error("incorrect number of parameters (%d) to quit", params.size());
+ _vm->addNotifyEvent(NotifyEvent(kLBNotifyQuit, 0));
+ }
+ break;
+
default:
error("unknown notify command %02x in code", commandType);
}
diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h
index 71174cc09e..cd9ac1004a 100644
--- a/engines/mohawk/livingbooks_code.h
+++ b/engines/mohawk/livingbooks_code.h
@@ -57,6 +57,14 @@ struct LBValue {
type = kLBValueString;
string = str;
}
+ LBValue(const Common::Point &p) {
+ type = kLBValuePoint;
+ point = p;
+ }
+ LBValue(const Common::Rect &r) {
+ type = kLBValueRect;
+ rect = r;
+ }
LBValue(LBItem *itm) {
type = kLBValueItemPtr;
item = itm;
@@ -99,8 +107,11 @@ struct LBValue {
bool isNumeric() const;
bool isZero() const;
+ Common::String toString() const;
int toInt() const;
double toDouble() const;
+ Common::Point toPoint() const;
+ Common::Rect toRect() const;
};
enum {
@@ -169,7 +180,7 @@ enum {
class LBCode {
public:
- LBCode(MohawkEngine_LivingBooks *vm);
+ LBCode(MohawkEngine_LivingBooks *vm, uint16 baseId);
~LBCode();
LBValue runCode(LBItem *src, uint32 offset);
@@ -199,12 +210,21 @@ protected:
void parseMain();
Common::Array<LBValue> readParams();
+ Common::Rect getRectFromParams(const Common::Array<LBValue> &params);
+
void runGeneralCommand();
void runItemCommand();
void runNotifyCommand();
public:
void cmdUnimplemented(const Common::Array<LBValue> &params);
+ void cmdGetRect(const Common::Array<LBValue> &params);
+ void cmdTopLeft(const Common::Array<LBValue> &params);
+ void cmdBottomRight(const Common::Array<LBValue> &params);
+ void cmdTop(const Common::Array<LBValue> &params);
+ void cmdLeft(const Common::Array<LBValue> &params);
+ void cmdBottom(const Common::Array<LBValue> &params);
+ void cmdRight(const Common::Array<LBValue> &params);
void cmdSetPlayParams(const Common::Array<LBValue> &params);
void cmdSetKeyEvent(const Common::Array<LBValue> &params);
void cmdSetHitTest(const Common::Array<LBValue> &params);
diff --git a/engines/mohawk/resource.h b/engines/mohawk/resource.h
index 18e8f80fb2..07c727951c 100644
--- a/engines/mohawk/resource.h
+++ b/engines/mohawk/resource.h
@@ -34,102 +34,102 @@
namespace Mohawk {
// Main FourCC's
-#define ID_MHWK MKID_BE('MHWK') // Main FourCC
-#define ID_RSRC MKID_BE('RSRC') // Resource Directory Tag
+#define ID_MHWK MKTAG('M','H','W','K') // Main FourCC
+#define ID_RSRC MKTAG('R','S','R','C') // Resource Directory Tag
// Myst Resource FourCC's
-#define ID_CLRC MKID_BE('CLRC') // Cursor Hotspots
-#define ID_EXIT MKID_BE('EXIT') // Card Exit Scripts
-#define ID_HINT MKID_BE('HINT') // Cursor Hints
-#define ID_INIT MKID_BE('INIT') // Card Entrance Scripts
-#define ID_MSND MKID_BE('MSND') // Standard Mohawk Sound
-#define ID_RLST MKID_BE('RLST') // Resource List, Specifies HotSpots
-#define ID_RSFL MKID_BE('RSFL') // ??? (system.dat only)
-#define ID_VIEW MKID_BE('VIEW') // Card Details
-#define ID_WDIB MKID_BE('WDIB') // LZ-Compressed Windows Bitmap
+#define ID_CLRC MKTAG('C','L','R','C') // Cursor Hotspots
+#define ID_EXIT MKTAG('E','X','I','T') // Card Exit Scripts
+#define ID_HINT MKTAG('H','I','N','T') // Cursor Hints
+#define ID_INIT MKTAG('I','N','I','T') // Card Entrance Scripts
+#define ID_MSND MKTAG('M','S','N','D') // Standard Mohawk Sound
+#define ID_RLST MKTAG('R','L','S','T') // Resource List, Specifies HotSpots
+#define ID_RSFL MKTAG('R','S','F','L') // ??? (system.dat only)
+#define ID_VIEW MKTAG('V','I','E','W') // Card Details
+#define ID_WDIB MKTAG('W','D','I','B') // LZ-Compressed Windows Bitmap
// Myst Masterpiece Edition Resource FourCC's (In addition to Myst FourCC's)
-#define ID_HELP MKID_BE('HELP') // Help Chunk
-#define ID_MJMP MKID_BE('MJMP') // MSND Jumps (To reduce MSND duplication)
-#define ID_PICT MKID_BE('PICT') // JPEG/PICT/WDIB Image
+#define ID_HELP MKTAG('H','E','L','P') // Help Chunk
+#define ID_MJMP MKTAG('M','J','M','P') // MSND Jumps (To reduce MSND duplication)
+#define ID_PICT MKTAG('P','I','C','T') // JPEG/PICT/WDIB Image
// Riven Resource FourCC's
-#define ID_BLST MKID_BE('BLST') // Card Hotspot Enabling Lists
-#define ID_CARD MKID_BE('CARD') // Card Scripts
-#define ID_FLST MKID_BE('FLST') // Card SFXE Lists
-#define ID_HSPT MKID_BE('HSPT') // Card Hotspots
-#define ID_MLST MKID_BE('MLST') // Card Movie Lists
-#define ID_NAME MKID_BE('NAME') // Object Names
-#define ID_PLST MKID_BE('PLST') // Card Picture Lists
-#define ID_RMAP MKID_BE('RMAP') // Card Codes
-#define ID_SFXE MKID_BE('SFXE') // Water Effect Animations
-#define ID_SLST MKID_BE('SLST') // Card Ambient Sound Lists
-#define ID_TMOV MKID_BE('tMOV') // QuickTime Movie
+#define ID_BLST MKTAG('B','L','S','T') // Card Hotspot Enabling Lists
+#define ID_CARD MKTAG('C','A','R','D') // Card Scripts
+#define ID_FLST MKTAG('F','L','S','T') // Card SFXE Lists
+#define ID_HSPT MKTAG('H','S','P','T') // Card Hotspots
+#define ID_MLST MKTAG('M','L','S','T') // Card Movie Lists
+#define ID_NAME MKTAG('N','A','M','E') // Object Names
+#define ID_PLST MKTAG('P','L','S','T') // Card Picture Lists
+#define ID_RMAP MKTAG('R','M','A','P') // Card Codes
+#define ID_SFXE MKTAG('S','F','X','E') // Water Effect Animations
+#define ID_SLST MKTAG('S','L','S','T') // Card Ambient Sound Lists
+#define ID_TMOV MKTAG('t','M','O','V') // QuickTime Movie
// Riven Saved Game FourCC's
-#define ID_VARS MKID_BE('VARS') // Variable Values
-#define ID_VERS MKID_BE('VERS') // Version Info
-#define ID_ZIPS MKID_BE('ZIPS') // Zip Mode Status
+#define ID_VARS MKTAG('V','A','R','S') // Variable Values
+#define ID_VERS MKTAG('V','E','R','S') // Version Info
+#define ID_ZIPS MKTAG('Z','I','P','S') // Zip Mode Status
// Zoombini Resource FourCC's
-#define ID_SND MKID_BE('\0SND') // Standard Mohawk Sound
-#define ID_CURS MKID_BE('CURS') // Cursor
-#define ID_SCRB MKID_BE('SCRB') // Feature Script
-#define ID_SCRS MKID_BE('SCRS') // Snoid Script
-#define ID_NODE MKID_BE('NODE') // Walk Node
-#define ID_PATH MKID_BE('PATH') // Walk Path
-#define ID_SHPL MKID_BE('SHPL') // Shape List
+#define ID_SND MKTAG( 0 ,'S','N','D') // Standard Mohawk Sound
+#define ID_CURS MKTAG('C','U','R','S') // Cursor
+#define ID_SCRB MKTAG('S','C','R','B') // Feature Script
+#define ID_SCRS MKTAG('S','C','R','S') // Snoid Script
+#define ID_NODE MKTAG('N','O','D','E') // Walk Node
+#define ID_PATH MKTAG('P','A','T','H') // Walk Path
+#define ID_SHPL MKTAG('S','H','P','L') // Shape List
// Living Books Resource FourCC's
-#define ID_TCUR MKID_BE('tCUR') // Cursor
-#define ID_BITL MKID_BE('BITL') // Book Item List
-#define ID_CTBL MKID_BE('CTBL') // Color Table
-#define ID_SCRP MKID_BE('SCRP') // Script
-#define ID_SPR MKID_BE('SPR#') // Sprite?
-#define ID_VRSN MKID_BE('VRSN') // Version
-#define ID_ANI MKID_BE('ANI ') // Animation
-#define ID_SHP MKID_BE('SHP#') // Shape
-#define ID_WAV MKID_BE('WAV ') // Old Sound Resource
-#define ID_BMAP MKID_BE('BMAP') // Old Mohawk Bitmap
-#define ID_BCOD MKID_BE('BCOD') // Book Code
+#define ID_TCUR MKTAG('t','C','U','R') // Cursor
+#define ID_BITL MKTAG('B','I','T','L') // Book Item List
+#define ID_CTBL MKTAG('C','T','B','L') // Color Table
+#define ID_SCRP MKTAG('S','C','R','P') // Script
+#define ID_SPR MKTAG('S','P','R','#') // Sprite?
+#define ID_VRSN MKTAG('V','R','S','N') // Version
+#define ID_ANI MKTAG('A','N','I',' ') // Animation
+#define ID_SHP MKTAG('S','H','P','#') // Shape
+#define ID_WAV MKTAG('W','A','V',' ') // Old Sound Resource
+#define ID_BMAP MKTAG('B','M','A','P') // Old Mohawk Bitmap
+#define ID_BCOD MKTAG('B','C','O','D') // Book Code
// JamesMath Resource FourCC's
-#define ID_TANM MKID_BE('tANM') // Animation?
-#define ID_TMFO MKID_BE('tMFO') // ???
+#define ID_TANM MKTAG('t','A','N','M') // Animation?
+#define ID_TMFO MKTAG('t','M','F','O') // ???
// CSTime Resource FourCC's
-#define ID_CINF MKID_BE('CINF') // Case Info
-#define ID_CONV MKID_BE('CONV') // Conversation
-#define ID_HOTS MKID_BE('HOTS') // Hotspot
-#define ID_INVO MKID_BE('INVO') // Inventory Object
-#define ID_QARS MKID_BE('QARS') // Question and Responses
-#define ID_SCEN MKID_BE('SCEN') // Scene
-#define ID_STRI MKID_BE('STRI') // String Entry?
+#define ID_CINF MKTAG('C','I','N','F') // Case Info
+#define ID_CONV MKTAG('C','O','N','V') // Conversation
+#define ID_HOTS MKTAG('H','O','T','S') // Hotspot
+#define ID_INVO MKTAG('I','N','V','O') // Inventory Object
+#define ID_QARS MKTAG('Q','A','R','S') // Question and Responses
+#define ID_SCEN MKTAG('S','C','E','N') // Scene
+#define ID_STRI MKTAG('S','T','R','I') // String Entry?
// Mohawk Wave Tags
-#define ID_WAVE MKID_BE('WAVE') // Game Sound (Third Tag)
-#define ID_ADPC MKID_BE('ADPC') // Game Sound Chunk
-#define ID_DATA MKID_BE('Data') // Game Sound Chunk
-#define ID_CUE MKID_BE('Cue#') // Game Sound Chunk
+#define ID_WAVE MKTAG('W','A','V','E') // Game Sound (Third Tag)
+#define ID_ADPC MKTAG('A','D','P','C') // Game Sound Chunk
+#define ID_DATA MKTAG('D','a','t','a') // Game Sound Chunk
+#define ID_CUE MKTAG('C','u','e','#') // Game Sound Chunk
// Mohawk MIDI Tags
-#define ID_MIDI MKID_BE('MIDI') // Game Sound (Third Tag), instead of WAVE
-#define ID_PRG MKID_BE('Prg#') // MIDI Patch
+#define ID_MIDI MKTAG('M','I','D','I') // Game Sound (Third Tag), instead of WAVE
+#define ID_PRG MKTAG('P','r','g','#') // MIDI Patch
// Common Resource FourCC's
-#define ID_TBMP MKID_BE('tBMP') // Standard Mohawk Bitmap
-#define ID_TWAV MKID_BE('tWAV') // Standard Mohawk Sound
-#define ID_TPAL MKID_BE('tPAL') // Standard Mohawk Palette
-#define ID_TCNT MKID_BE('tCNT') // Shape Count (CSWorld, CSAmtrak, JamesMath)
-#define ID_TSCR MKID_BE('tSCR') // Script (CSWorld, CSAmtrak, Treehouse)
-#define ID_STRL MKID_BE('STRL') // String List (Zoombini, CSWorld, CSAmtrak)
-#define ID_TBMH MKID_BE('tBMH') // Standard Mohawk Bitmap
-#define ID_TMID MKID_BE('tMID') // Standard Mohawk MIDI
-#define ID_REGS MKID_BE('REGS') // Registration Data - Shape Offsets (Zoombini, Treehouse)
-#define ID_BYTS MKID_BE('BYTS') // Byte Array? (Used as Database Entry in CSWorld, CSAmtrak)
-#define ID_INTS MKID_BE('INTS') // uint16 Array? (CSWorld, CSAmtrak)
-#define ID_BBOX MKID_BE('BBOX') // Boxes? (CSWorld, CSAmtrak)
-#define ID_SYSX MKID_BE('SYSX') // MIDI Sysex
+#define ID_TBMP MKTAG('t','B','M','P') // Standard Mohawk Bitmap
+#define ID_TWAV MKTAG('t','W','A','V') // Standard Mohawk Sound
+#define ID_TPAL MKTAG('t','P','A','L') // Standard Mohawk Palette
+#define ID_TCNT MKTAG('t','C','N','T') // Shape Count (CSWorld, CSAmtrak, JamesMath)
+#define ID_TSCR MKTAG('t','S','C','R') // Script (CSWorld, CSAmtrak, Treehouse)
+#define ID_STRL MKTAG('S','T','R','L') // String List (Zoombini, CSWorld, CSAmtrak)
+#define ID_TBMH MKTAG('t','B','M','H') // Standard Mohawk Bitmap
+#define ID_TMID MKTAG('t','M','I','D') // Standard Mohawk MIDI
+#define ID_REGS MKTAG('R','E','G','S') // Registration Data - Shape Offsets (Zoombini, Treehouse)
+#define ID_BYTS MKTAG('B','Y','T','S') // Byte Array? (Used as Database Entry in CSWorld, CSAmtrak)
+#define ID_INTS MKTAG('I','N','T','S') // uint16 Array? (CSWorld, CSAmtrak)
+#define ID_BBOX MKTAG('B','B','O','X') // Boxes? (CSWorld, CSAmtrak)
+#define ID_SYSX MKTAG('S','Y','S','X') // MIDI Sysex
struct FileTable {
uint32 offset;
diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp
index b4ae50b74a..9759f14699 100644
--- a/engines/mohawk/sound.cpp
+++ b/engines/mohawk/sound.cpp
@@ -479,7 +479,7 @@ Audio::AudioStream *Sound::makeMohawkWaveStream(Common::SeekableReadStream *stre
return Audio::makeRawStream(dataChunk.audioData, dataChunk.sampleRate, flags);
} else if (dataChunk.encoding == kCodecADPCM) {
uint32 blockAlign = dataChunk.channels * dataChunk.bitsPerSample / 8;
- return Audio::makeADPCMStream(dataChunk.audioData, DisposeAfterUse::YES, dataSize, Audio::kADPCMIma, dataChunk.sampleRate, dataChunk.channels, blockAlign);
+ return Audio::makeADPCMStream(dataChunk.audioData, DisposeAfterUse::YES, dataSize, Audio::kADPCMDVI, dataChunk.sampleRate, dataChunk.channels, blockAlign);
} else if (dataChunk.encoding == kCodecMPEG2) {
#ifdef USE_MAD
return Audio::makeMP3Stream(dataChunk.audioData, DisposeAfterUse::YES);
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 98770b9a6d..133b7bef6c 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -91,7 +91,7 @@ NSArchive::NSArchive(Common::SeekableReadStream *stream, Common::Platform platfo
if (features & GF_DEMO) {
isSmallArchive = stream->size() == SIZEOF_SMALL_ARCHIVE;
} else if (features & GF_LANG_MULT) {
- isSmallArchive = (stream->readUint32BE() != MKID_BE('NDOS'));
+ isSmallArchive = (stream->readUint32BE() != MKTAG('N','D','O','S'));
}
}
@@ -801,7 +801,7 @@ void AmigaDisk_ns::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 b
uint16 planeSize = bytesPerPlane * height;
for (uint32 i = 0; i < numFrames; i++) {
- if (READ_BE_UINT32(src) == MKID_BE('DLTA')) {
+ if (READ_BE_UINT32(src) == MKTAG('D','L','T','A')) {
uint size = READ_BE_UINT32(src + 4);
diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
index 7b16df52bf..b130b27a89 100644
--- a/engines/queen/display.cpp
+++ b/engines/queen/display.cpp
@@ -843,19 +843,19 @@ void Display::decodeLBM(const uint8 *src, uint32 srcSize, uint8 *dst, uint16 dst
uint32 size = READ_BE_UINT32(src + 4);
src += 8;
switch (type) {
- case MKID_BE('BMHD'): {
+ case MKTAG('B','M','H','D'): {
*w = READ_BE_UINT16(src + 0);
*h = READ_BE_UINT16(src + 2);
planeCount = src[8];
planePitch = ((*w + 15) >> 4) * 2;
}
break;
- case MKID_BE('CMAP'): {
+ case MKTAG('C','M','A','P'): {
assert(palStart <= palEnd && palEnd <= size / 3);
memcpy(pal, src + palStart * 3, (palEnd - palStart) * 3);
}
break;
- case MKID_BE('BODY'): {
+ case MKTAG('B','O','D','Y'): {
uint32 planarSize = (*h) * planeCount * planePitch;
uint8 *planarBuf = new uint8[planarSize];
uint8 *dstPlanar = planarBuf;
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index 692e38179a..519f028cda 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -403,7 +403,7 @@ Common::InSaveFile *QueenEngine::readGameStateHeader(int slot, GameStateHeader *
char name[20];
makeGameStateName(slot, name);
Common::InSaveFile *file = _saveFileMan->openForLoading(name);
- if (file && file->readUint32BE() == MKID_BE('SCVM')) {
+ if (file && file->readUint32BE() == MKTAG('S','C','V','M')) {
gsh->version = file->readUint32BE();
gsh->flags = file->readUint32BE();
gsh->dataSize = file->readUint32BE();
diff --git a/engines/queen/resource.cpp b/engines/queen/resource.cpp
index a70d1f1613..e8519ee68b 100644
--- a/engines/queen/resource.cpp
+++ b/engines/queen/resource.cpp
@@ -132,7 +132,7 @@ void Resource::loadTextFile(const char *filename, Common::StringArray &stringLis
bool Resource::detectVersion(DetectedGameVersion *ver, Common::File *f) {
memset(ver, 0, sizeof(DetectedGameVersion));
- if (f->readUint32BE() == MKID_BE('QTBL')) {
+ if (f->readUint32BE() == MKTAG('Q','T','B','L')) {
f->read(ver->str, 6);
f->skip(2);
ver->compression = f->readByte();
@@ -269,7 +269,7 @@ void Resource::seekResourceFile(int num, uint32 offset) {
void Resource::readTableFile(uint8 version, uint32 offset) {
Common::File tableFile;
tableFile.open(_tableFilename);
- if (tableFile.isOpen() && tableFile.readUint32BE() == MKID_BE('QTBL')) {
+ if (tableFile.isOpen() && tableFile.readUint32BE() == MKTAG('Q','T','B','L')) {
uint32 tableVersion = tableFile.readUint32BE();
if (version > tableVersion) {
error("The game you are trying to play requires version %d of queen.tbl, "
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index f8c06bff8c..b1bcc99295 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -264,7 +264,7 @@ SaveStateDescriptor SagaMetaEngine::querySaveMetaInfos(const char *target, int s
if (version < 4)
warning("This savegame is not endian-safe. There may be problems");
- if (type != MKID_BE('SAGA')) {
+ if (type != MKTAG('S','A','G','A')) {
error("SagaEngine::load wrong save game format");
}
diff --git a/engines/saga/resource_hrs.cpp b/engines/saga/resource_hrs.cpp
index 2ec2099c8d..21cf0ef4c1 100644
--- a/engines/saga/resource_hrs.cpp
+++ b/engines/saga/resource_hrs.cpp
@@ -62,7 +62,7 @@ bool ResourceContext_HRS::loadResV2(uint32 contextSize) {
readElement(_file, origin);
// Check if the file is valid
- if (origin.id != MKID_BE('HRES')) { // header
+ if (origin.id != MKTAG('H','R','E','S')) { // header
return false;
}
diff --git a/engines/saga/resource_rsc.cpp b/engines/saga/resource_rsc.cpp
index 42c4dc05e8..089757ca27 100644
--- a/engines/saga/resource_rsc.cpp
+++ b/engines/saga/resource_rsc.cpp
@@ -30,7 +30,7 @@
namespace Saga {
-#define ID_MIDI MKID_BE('Midi')
+#define ID_MIDI MKTAG('M','i','d','i')
bool ResourceContext_RSC::loadMacMIDI() {
// Sanity check
diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp
index c5388d6878..9edb79fa7c 100644
--- a/engines/saga/saveload.cpp
+++ b/engines/saga/saveload.cpp
@@ -151,7 +151,7 @@ void SagaEngine::fillSaveList() {
_saveHeader.version = in->readUint32LE();
in->read(_saveHeader.name, sizeof(_saveHeader.name));
- if (_saveHeader.type != MKID_BE('SAGA')) {
+ if (_saveHeader.type != MKTAG('S','A','G','A')) {
warning("SagaEngine::load wrong save %s format", name);
i++;
continue;
@@ -175,7 +175,7 @@ void SagaEngine::save(const char *fileName, const char *saveName) {
return;
}
- _saveHeader.type = MKID_BE('SAGA');
+ _saveHeader.type = MKTAG('S','A','G','A');
_saveHeader.size = 0;
_saveHeader.version = CURRENT_SAGA_VER;
// Note that IHNM has a smaller save title size than ITE
@@ -287,7 +287,7 @@ void SagaEngine::load(const char *fileName) {
if (_saveHeader.version < 4)
warning("This savegame is not endian-safe. There may be problems");
- if (_saveHeader.type != MKID_BE('SAGA')) {
+ if (_saveHeader.type != MKTAG('S','A','G','A')) {
error("SagaEngine::load wrong save game format");
}
diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp
index 3ae2f19e1b..bd1d6e5d84 100644
--- a/engines/saga/script.cpp
+++ b/engines/saga/script.cpp
@@ -160,7 +160,7 @@ SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) {
}
// Script export segment (lookup table)
- uint32 saga2ExportSegId = MKID_BE('_EXP');
+ uint32 saga2ExportSegId = MKTAG('_','E','X','P');
int32 entryNum = _scriptContext->getEntryNum(saga2ExportSegId);
if (entryNum < 0)
error("Unable to locate the script's export segment");
@@ -176,7 +176,7 @@ SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) {
// Script data segment
/*
- uint32 saga2DataSegId = MKID_BE('__DA');
+ uint32 saga2DataSegId = MKTAG('_','_','D','A');
entryNum = _scriptContext->getEntryNum(saga2DataSegId);
if (entryNum < 0)
error("Unable to locate the script's data segment");
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 5a6b1859cd..0433479a09 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -903,7 +903,7 @@ void GfxPalette::loadMacIconBarPalette() {
if (!g_sci->hasMacIconBar())
return;
- Common::SeekableReadStream *clutStream = g_sci->getMacExecutable()->getResource(MKID_BE('clut'), 150);
+ Common::SeekableReadStream *clutStream = g_sci->getMacExecutable()->getResource(MKTAG('c','l','u','t'), 150);
if (!clutStream)
error("Could not find clut 150 for the Mac icon bar");
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 32f54c7e23..f619780c7c 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -360,7 +360,6 @@ byte GfxScreen::isFillMatch(int16 x, int16 y, byte screenMask, byte t_color, byt
int offset = y * _width + x;
byte match = 0;
- // FIXME:
if (screenMask & GFX_SCREEN_MASK_VISUAL) {
if (!isEGA) {
if (*(_visualScreen + offset) == t_color)
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 61df02acf9..4caa77b0ae 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -1488,7 +1488,7 @@ void ResourceManager::readResourcePatchesBase36() {
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(name);
uint32 tag = stream->readUint32BE();
- if (tag == MKID_BE('RIFF') || tag == MKID_BE('FORM')) {
+ if (tag == MKTAG('R','I','F','F') || tag == MKTAG('F','O','R','M')) {
delete stream;
processWavePatch(resource36, name);
continue;
@@ -1497,7 +1497,7 @@ void ResourceManager::readResourcePatchesBase36() {
// Check for SOL as well
tag = (tag << 16) | stream->readUint16BE();
- if (tag != MKID_BE('SOL\0')) {
+ if (tag != MKTAG('S','O','L',0)) {
delete stream;
continue;
}
@@ -1746,25 +1746,25 @@ struct MacResTag {
};
static const MacResTag macResTagMap[] = {
- { MKID_BE('V56 '), kResourceTypeView },
- { MKID_BE('P56 '), kResourceTypePic },
- { MKID_BE('SCR '), kResourceTypeScript },
- { MKID_BE('TEX '), kResourceTypeText },
- { MKID_BE('SND '), kResourceTypeSound },
- { MKID_BE('VOC '), kResourceTypeVocab },
- { MKID_BE('FON '), kResourceTypeFont },
- { MKID_BE('CURS'), kResourceTypeCursor },
- { MKID_BE('crsr'), kResourceTypeCursor },
- { MKID_BE('Pat '), kResourceTypePatch },
- { MKID_BE('PAL '), kResourceTypePalette },
- { MKID_BE('snd '), kResourceTypeAudio },
- { MKID_BE('MSG '), kResourceTypeMessage },
- { MKID_BE('HEP '), kResourceTypeHeap },
- { MKID_BE('IBIN'), kResourceTypeMacIconBarPictN },
- { MKID_BE('IBIS'), kResourceTypeMacIconBarPictS },
- { MKID_BE('PICT'), kResourceTypeMacPict },
- { MKID_BE('SYN '), kResourceTypeSync },
- { MKID_BE('SYNC'), kResourceTypeSync }
+ { MKTAG('V','5','6',' '), kResourceTypeView },
+ { MKTAG('P','5','6',' '), kResourceTypePic },
+ { MKTAG('S','C','R',' '), kResourceTypeScript },
+ { MKTAG('T','E','X',' '), kResourceTypeText },
+ { MKTAG('S','N','D',' '), kResourceTypeSound },
+ { MKTAG('V','O','C',' '), kResourceTypeVocab },
+ { MKTAG('F','O','N',' '), kResourceTypeFont },
+ { MKTAG('C','U','R','S'), kResourceTypeCursor },
+ { MKTAG('c','r','s','r'), kResourceTypeCursor },
+ { MKTAG('P','a','t',' '), kResourceTypePatch },
+ { MKTAG('P','A','L',' '), kResourceTypePalette },
+ { MKTAG('s','n','d',' '), kResourceTypeAudio },
+ { MKTAG('M','S','G',' '), kResourceTypeMessage },
+ { MKTAG('H','E','P',' '), kResourceTypeHeap },
+ { MKTAG('I','B','I','N'), kResourceTypeMacIconBarPictN },
+ { MKTAG('I','B','I','S'), kResourceTypeMacIconBarPictS },
+ { MKTAG('P','I','C','T'), kResourceTypeMacPict },
+ { MKTAG('S','Y','N',' '), kResourceTypeSync },
+ { MKTAG('S','Y','N','C'), kResourceTypeSync }
};
static Common::Array<uint32> resTypeToMacTags(ResourceType type) {
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 386bfb37f5..6e74553f56 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -53,9 +53,9 @@ AudioVolumeResourceSource::AudioVolumeResourceSource(ResourceManager *resMan, co
fileStream->seek(0, SEEK_SET);
uint32 compressionType = fileStream->readUint32BE();
switch (compressionType) {
- case MKID_BE('MP3 '):
- case MKID_BE('OGG '):
- case MKID_BE('FLAC'):
+ case MKTAG('M','P','3',' '):
+ case MKTAG('O','G','G',' '):
+ case MKTAG('F','L','A','C'):
// Detected a compressed audio volume
_audioCompressionType = compressionType;
// Now read the whole offset mapping table for later usage
@@ -91,7 +91,7 @@ bool Resource::loadFromWaveFile(Common::SeekableReadStream *file) {
bool Resource::loadFromAudioVolumeSCI11(Common::SeekableReadStream *file) {
// Check for WAVE files here
uint32 riffTag = file->readUint32BE();
- if (riffTag == MKID_BE('RIFF')) {
+ if (riffTag == MKTAG('R','I','F','F')) {
_headerSize = 0;
size = file->readUint32LE() + 8;
file->seek(-8, SEEK_CUR);
diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp
index 73f471b247..53311b4252 100644
--- a/engines/sci/sound/audio.cpp
+++ b/engines/sci/sound/audio.cpp
@@ -195,7 +195,7 @@ static bool readSOLHeader(Common::SeekableReadStream *audioStream, int headerSiz
uint32 tag = audioStream->readUint32BE();
- if (tag != MKID_BE('SOL\0')) {
+ if (tag != MKTAG('S','O','L',0)) {
warning("No 'SOL' FourCC found");
return false;
}
@@ -290,17 +290,17 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
Common::SeekableReadStream *compressedStream = new Common::MemoryReadStream(compressedData, audioRes->size, DisposeAfterUse::YES);
switch (audioCompressionType) {
- case MKID_BE('MP3 '):
+ case MKTAG('M','P','3',' '):
#ifdef USE_MAD
audioSeekStream = Audio::makeMP3Stream(compressedStream, DisposeAfterUse::YES);
#endif
break;
- case MKID_BE('OGG '):
+ case MKTAG('O','G','G',' '):
#ifdef USE_VORBIS
audioSeekStream = Audio::makeVorbisStream(compressedStream, DisposeAfterUse::YES);
#endif
break;
- case MKID_BE('FLAC'):
+ case MKTAG('F','L','A','C'):
#ifdef USE_FLAC
audioSeekStream = Audio::makeFLACStream(compressedStream, DisposeAfterUse::YES);
#endif
@@ -319,7 +319,7 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
Common::MemoryReadStream dataStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
data = readSOLAudio(&dataStream, size, audioFlags, flags);
}
- } else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKID_BE('RIFF')) {
+ } else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKTAG('R','I','F','F')) {
// WAVE detected
Common::SeekableReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
@@ -331,7 +331,7 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32
waveStream->seek(0, SEEK_SET);
audioStream = Audio::makeWAVStream(waveStream, DisposeAfterUse::YES);
- } else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKID_BE('FORM')) {
+ } else if (audioRes->size > 4 && READ_BE_UINT32(audioRes->data) == MKTAG('F','O','R','M')) {
// AIFF detected
Common::SeekableReadStream *waveStream = new Common::MemoryReadStream(audioRes->data, audioRes->size, DisposeAfterUse::NO);
diff --git a/engines/sci/sound/drivers/midi.cpp b/engines/sci/sound/drivers/midi.cpp
index f674a502d6..9eef867aeb 100644
--- a/engines/sci/sound/drivers/midi.cpp
+++ b/engines/sci/sound/drivers/midi.cpp
@@ -611,7 +611,7 @@ void MidiPlayer_Midi::readMt32DrvData() {
int size = f.size();
// Skip before-SysEx text
- if (size == 1773 || size == 1759) // XMAS88 / KQ4 early
+ if (size == 1773 || size == 1759 || size == 1747) // XMAS88 / KQ4 early (0.000.253 / 0.000.274)
f.seek(0x59);
else if (size == 2771) // LSL2 early
f.seek(0x29);
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 39db47b102..13581c4b45 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1853,8 +1853,8 @@ void Actor::animateLimb(int limb, int f) {
byte *akos = _vm->getResourceAddress(rtCostume, _costume);
assert(akos);
- aksq = _vm->findResourceData(MKID_BE('AKSQ'), akos);
- akfo = _vm->findResourceData(MKID_BE('AKFO'), akos);
+ aksq = _vm->findResourceData(MKTAG('A','K','S','Q'), akos);
+ akfo = _vm->findResourceData(MKTAG('A','K','F','O'), akos);
size = _vm->getResourceDataSize(akfo) / 2;
@@ -2374,7 +2374,7 @@ void Actor::remapActorPaletteColor(int color, int new_color) {
return;
}
- akpl = _vm->findResourceData(MKID_BE('AKPL'), akos);
+ akpl = _vm->findResourceData(MKTAG('A','K','P','L'), akos);
if (!akpl) {
debugC(DEBUG_ACTORS, "Actor::remapActorPaletteColor: Can't remap actor %d, costume %d doesn't contain an AKPL block", _number, _costume);
return;
@@ -2409,7 +2409,7 @@ void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold)
return;
}
- akpl = _vm->findResourceData(MKID_BE('AKPL'), akos);
+ akpl = _vm->findResourceData(MKTAG('A','K','P','L'), akos);
if (!akpl) {
debugC(DEBUG_ACTORS, "Actor::remapActorPalette: Can't remap actor %d, costume %d doesn't contain an AKPL block", _number, _costume);
return;
@@ -2418,7 +2418,7 @@ void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold)
// Get the number palette entries
akpl_size = _vm->getResourceDataSize(akpl);
- rgbs = _vm->findResourceData(MKID_BE('RGBS'), akos);
+ rgbs = _vm->findResourceData(MKTAG('R','G','B','S'), akos);
if (!rgbs) {
debugC(DEBUG_ACTORS, "Actor::remapActorPalette: Can't remap actor %d costume %d doesn't contain an RGB block", _number, _costume);
@@ -2535,19 +2535,19 @@ void ScummEngine_v71he::postProcessAuxQueue() {
if (_game.heversion >= 72)
dy -= a->getElevation();
- const uint8 *akax = findResource(MKID_BE('AKAX'), cost);
+ const uint8 *akax = findResource(MKTAG('A','K','A','X'), cost);
assert(akax);
const uint8 *auxd = findPalInPals(akax, ae->subIndex) - _resourceHeaderSize;
assert(auxd);
- const uint8 *frel = findResourceData(MKID_BE('FREL'), auxd);
+ const uint8 *frel = findResourceData(MKTAG('F','R','E','L'), auxd);
if (frel) {
error("unhandled FREL block");
}
- const uint8 *disp = findResourceData(MKID_BE('DISP'), auxd);
+ const uint8 *disp = findResourceData(MKTAG('D','I','S','P'), auxd);
if (disp) {
error("unhandled DISP block");
}
- const uint8 *axfd = findResourceData(MKID_BE('AXFD'), auxd);
+ const uint8 *axfd = findResourceData(MKTAG('A','X','F','D'), auxd);
assert(axfd);
uint16 comp = READ_LE_UINT16(axfd);
@@ -2567,7 +2567,7 @@ void ScummEngine_v71he::postProcessAuxQueue() {
error("unimplemented compression type %d", comp);
}
}
- const uint8 *axur = findResourceData(MKID_BE('AXUR'), auxd);
+ const uint8 *axur = findResourceData(MKTAG('A','X','U','R'), auxd);
if (axur) {
uint16 n = READ_LE_UINT16(axur); axur += 2;
while (n--) {
@@ -2579,7 +2579,7 @@ void ScummEngine_v71he::postProcessAuxQueue() {
axur += 8;
}
}
- const uint8 *axer = findResourceData(MKID_BE('AXER'), auxd);
+ const uint8 *axer = findResourceData(MKTAG('A','X','E','R'), auxd);
if (axer) {
a->_auxBlock.visible = true;
a->_auxBlock.r.left = (int16)READ_LE_UINT16(axer + 0) + dx;
diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp
index 354a1d4491..8acbb8058e 100644
--- a/engines/scumm/akos.cpp
+++ b/engines/scumm/akos.cpp
@@ -146,7 +146,7 @@ void AkosCostumeLoader::loadCostume(int id) {
bool AkosCostumeLoader::hasManyDirections() {
const AkosHeader *akhd;
- akhd = (const AkosHeader *)_vm->findResourceData(MKID_BE('AKHD'), _akos);
+ akhd = (const AkosHeader *)_vm->findResourceData(MKTAG('A','K','H','D'), _akos);
return (akhd->flags & 2) != 0;
}
@@ -170,12 +170,12 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
else
anim = newDirToOldDir(a->getFacing()) + frame * 4;
- akhd = (const AkosHeader *)_vm->findResourceData(MKID_BE('AKHD'), _akos);
+ akhd = (const AkosHeader *)_vm->findResourceData(MKTAG('A','K','H','D'), _akos);
if (anim >= READ_LE_UINT16(&akhd->num_anims))
return;
- r = _vm->findResourceData(MKID_BE('AKCH'), _akos);
+ r = _vm->findResourceData(MKTAG('A','K','C','H'), _akos);
assert(r);
offs = READ_LE_UINT16(r + anim * sizeof(uint16));
@@ -183,8 +183,8 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
return;
r += offs;
- const uint8 *akstPtr = _vm->findResourceData(MKID_BE('AKST'), _akos);
- const uint8 *aksfPtr = _vm->findResourceData(MKID_BE('AKSF'), _akos);
+ const uint8 *akstPtr = _vm->findResourceData(MKTAG('A','K','S','T'), _akos);
+ const uint8 *aksfPtr = _vm->findResourceData(MKTAG('A','K','S','F'), _akos);
i = 0;
mask = READ_LE_UINT16(r); r += 2;
@@ -341,21 +341,21 @@ void AkosRenderer::setCostume(int costume, int shadow) {
const byte *akos = _vm->getResourceAddress(rtCostume, costume);
assert(akos);
- akhd = (const AkosHeader *) _vm->findResourceData(MKID_BE('AKHD'), akos);
- akof = (const AkosOffset *) _vm->findResourceData(MKID_BE('AKOF'), akos);
- akci = _vm->findResourceData(MKID_BE('AKCI'), akos);
- aksq = _vm->findResourceData(MKID_BE('AKSQ'), akos);
- akcd = _vm->findResourceData(MKID_BE('AKCD'), akos);
- akpl = _vm->findResourceData(MKID_BE('AKPL'), akos);
+ akhd = (const AkosHeader *) _vm->findResourceData(MKTAG('A','K','H','D'), akos);
+ akof = (const AkosOffset *) _vm->findResourceData(MKTAG('A','K','O','F'), akos);
+ akci = _vm->findResourceData(MKTAG('A','K','C','I'), akos);
+ aksq = _vm->findResourceData(MKTAG('A','K','S','Q'), akos);
+ akcd = _vm->findResourceData(MKTAG('A','K','C','D'), akos);
+ akpl = _vm->findResourceData(MKTAG('A','K','P','L'), akos);
_codec = READ_LE_UINT16(&akhd->codec);
- akct = _vm->findResourceData(MKID_BE('AKCT'), akos);
- rgbs = _vm->findResourceData(MKID_BE('RGBS'), akos);
+ akct = _vm->findResourceData(MKTAG('A','K','C','T'), akos);
+ rgbs = _vm->findResourceData(MKTAG('R','G','B','S'), akos);
xmap = 0;
if (shadow) {
const uint8 *xmapPtr = _vm->getResourceAddress(rtImage, shadow);
assert(xmapPtr);
- xmap = _vm->findResourceData(MKID_BE('XMAP'), xmapPtr);
+ xmap = _vm->findResourceData(MKTAG('X','M','A','P'), xmapPtr);
assert(xmap);
}
}
@@ -1384,8 +1384,8 @@ bool ScummEngine_v6::akos_increaseAnims(const byte *akos, Actor *a) {
uint size;
bool result;
- aksq = findResourceData(MKID_BE('AKSQ'), akos);
- akfo = findResourceData(MKID_BE('AKFO'), akos);
+ aksq = findResourceData(MKTAG('A','K','S','Q'), akos);
+ akfo = findResourceData(MKTAG('A','K','F','O'), akos);
size = getResourceDataSize(akfo) / 2;
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index f49635d10f..bb3c4bcc02 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -240,7 +240,7 @@ void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) {
room = getObjectRoom(img);
findObjectInRoom(&foir, foCodeHeader | foImageHeader | foCheckAlreadyLoaded, img, room);
- imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), foir.obim);
+ imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), foir.obim);
if (_game.version == 8) {
setCursorHotspot(READ_LE_UINT32(&imhd->v8.hotspot[0].x),
@@ -270,7 +270,7 @@ void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) {
if (size > sizeof(_grabbedCursor))
error("setCursorFromImg: Cursor image too large");
- bomp = findResource(MKID_BE('BOMP'), dataptr);
+ bomp = findResource(MKTAG('B','O','M','P'), dataptr);
}
if (bomp != NULL)
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 0db77a1b7d..a6a97ec426 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -283,7 +283,7 @@ void Gdi::loadTiles(byte *roomptr) {
#ifdef USE_RGB_COLOR
void GdiPCEngine::loadTiles(byte *roomptr) {
- decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), roomptr));
+ decodePCEngineTileData(_vm->findResourceData(MKTAG('T','I','L','E'), roomptr));
}
#endif
@@ -858,7 +858,7 @@ void ScummEngine::initBGBuffers(int height) {
_gdi->_numZBuffer = 2;
} else if (_game.features & GF_SMALL_HEADER) {
int off;
- ptr = findResourceData(MKID_BE('SMAP'), room);
+ ptr = findResourceData(MKTAG('S','M','A','P'), room);
_gdi->_numZBuffer = 0;
if (_game.features & GF_16COLOR)
@@ -873,13 +873,13 @@ void ScummEngine::initBGBuffers(int height) {
}
} else if (_game.version == 8) {
// in V8 there is no RMIH and num z buffers is in RMHD
- ptr = findResource(MKID_BE('RMHD'), room);
+ ptr = findResource(MKTAG('R','M','H','D'), room);
_gdi->_numZBuffer = READ_LE_UINT32(ptr + 24) + 1;
} else if (_game.heversion >= 70) {
- ptr = findResource(MKID_BE('RMIH'), room);
+ ptr = findResource(MKTAG('R','M','I','H'), room);
_gdi->_numZBuffer = READ_LE_UINT16(ptr + 8) + 1;
} else {
- ptr = findResource(MKID_BE('RMIH'), findResource(MKID_BE('RMIM'), room));
+ ptr = findResource(MKTAG('R','M','I','H'), findResource(MKTAG('R','M','I','M'), room));
_gdi->_numZBuffer = READ_LE_UINT16(ptr + 8) + 1;
}
assert(_gdi->_numZBuffer >= 1 && _gdi->_numZBuffer <= 8);
@@ -1647,9 +1647,9 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage)
if ((_vm->_game.features & GF_SMALL_HEADER) || _vm->_game.version == 8)
zplane_list[0] = ptr;
else if (bmapImage)
- zplane_list[0] = _vm->findResource(MKID_BE('BMAP'), ptr);
+ zplane_list[0] = _vm->findResource(MKTAG('B','M','A','P'), ptr);
else
- zplane_list[0] = _vm->findResource(MKID_BE('SMAP'), ptr);
+ zplane_list[0] = _vm->findResource(MKTAG('S','M','A','P'), ptr);
if (_zbufferDisabled)
numzbuf = 0;
@@ -1692,11 +1692,11 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage)
}
} else {
const uint32 zplane_tags[] = {
- MKID_BE('ZP00'),
- MKID_BE('ZP01'),
- MKID_BE('ZP02'),
- MKID_BE('ZP03'),
- MKID_BE('ZP04')
+ MKTAG('Z','P','0','0'),
+ MKTAG('Z','P','0','1'),
+ MKTAG('Z','P','0','2'),
+ MKTAG('Z','P','0','3'),
+ MKTAG('Z','P','0','4')
};
for (i = 1; i < numzbuf; i++) {
@@ -1733,7 +1733,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
// Skip to the BSTR->WRAP->OFFS chunk
smap_ptr = ptr + 24;
} else {
- smap_ptr = _vm->findResource(MKID_BE('SMAP'), ptr);
+ smap_ptr = _vm->findResource(MKTAG('S','M','A','P'), ptr);
assert(smap_ptr);
}
@@ -1741,7 +1741,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
const byte *tmsk_ptr = NULL;
if (_vm->_game.heversion >= 72) {
- tmsk_ptr = _vm->findResource(MKID_BE('TMSK'), ptr);
+ tmsk_ptr = _vm->findResource(MKTAG('T','M','S','K'), ptr);
}
if (y + height > vs->h) {
@@ -2011,7 +2011,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) {
byte *mask_ptr;
const byte *zplane_list[9];
- const byte *bmap_ptr = _vm->findResourceData(MKID_BE('BMAP'), ptr);
+ const byte *bmap_ptr = _vm->findResourceData(MKTAG('B','M','A','P'), ptr);
assert(bmap_ptr);
byte code = *bmap_ptr++;
@@ -2091,7 +2091,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) {
}
void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h) {
- const byte *bmap_ptr = _vm->findResourceData(MKID_BE('BMAP'), ptr);
+ const byte *bmap_ptr = _vm->findResourceData(MKTAG('B','M','A','P'), ptr);
assert(bmap_ptr);
byte code = *bmap_ptr++;
@@ -2828,10 +2828,10 @@ void GdiPCEngine::decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint
void GdiPCEngine::decodePCEngineGfx(const byte *room) {
uint16* stripOffsets;
- decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), room));
- decodePCEngineMaskData(_vm->findResourceData(MKID_BE('ZP00'), room));
+ decodePCEngineTileData(_vm->findResourceData(MKTAG('T','I','L','E'), room));
+ decodePCEngineMaskData(_vm->findResourceData(MKTAG('Z','P','0','0'), room));
- const byte* smap_ptr = _vm->findResourceData(MKID_BE('IM00'), room);
+ const byte* smap_ptr = _vm->findResourceData(MKTAG('I','M','0','0'), room);
smap_ptr++; // roomID
int numStrips = *smap_ptr++;
int numRows = *smap_ptr++;
diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp
index 7840b9df20..e3e25c161c 100644
--- a/engines/scumm/he/animation_he.cpp
+++ b/engines/scumm/he/animation_he.cpp
@@ -112,7 +112,7 @@ void MoviePlayer::handleNextFrame() {
if (_flags & 2) {
uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum);
assert(dstPtr);
- uint8 *dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
+ uint8 *dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0);
assert(dst);
copyFrameToBuffer(dst, kDstResource, 0, 0, _vm->_screenWidth * _vm->_bytesPerPixel);
} else if (_flags & 1) {
diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp
index 79bb47aafc..a16af73135 100644
--- a/engines/scumm/he/cup_player_he.cpp
+++ b/engines/scumm/he/cup_player_he.cpp
@@ -47,7 +47,7 @@ bool CUP_Player::open(const char *filename) {
if (_fileStream.open(filename)) {
uint32 tag = _fileStream.readUint32BE();
_fileStream.readUint32BE();
- if (tag == MKID_BE('BEAN')) {
+ if (tag == MKTAG('B','E','A','N')) {
_playbackRate = kDefaultPlaybackRate;
_width = kDefaultVideoWidth;
_height = kDefaultVideoHeight;
@@ -168,7 +168,7 @@ void CUP_Player::updateSfx() {
assert(sfxIndex >= 0 && sfxIndex < _sfxCount);
uint32 offset = READ_LE_UINT32(_sfxBuffer + sfxIndex * 4) - 8;
uint8 *soundData = _sfxBuffer + offset;
- if (READ_BE_UINT32(soundData) == MKID_BE('DATA')) {
+ if (READ_BE_UINT32(soundData) == MKTAG('D','A','T','A')) {
uint32 soundSize = READ_BE_UINT32(soundData + 4);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &sfxChannel->handle,
Audio::makeLoopingAudioStream(
@@ -208,19 +208,19 @@ bool CUP_Player::parseNextHeaderTag(Common::SeekableReadStream &dataStream) {
uint32 next = dataStream.pos() + size;
debug(1, "New header tag %s %d dataSize %d", tag2str(tag), size, _dataSize);
switch (tag) {
- case MKID_BE('HEAD'):
+ case MKTAG('H','E','A','D'):
handleHEAD(dataStream, size);
break;
- case MKID_BE('SFXB'):
+ case MKTAG('S','F','X','B'):
handleSFXB(dataStream, size);
break;
- case MKID_BE('RGBS'):
+ case MKTAG('R','G','B','S'):
handleRGBS(dataStream, size);
break;
- case MKID_BE('DATA'):
+ case MKTAG('D','A','T','A'):
_dataSize = size;
return false;
- case MKID_BE('GFXB'):
+ case MKTAG('G','F','X','B'):
// this is never triggered
default:
warning("Unhandled tag %s", tag2str(tag));
@@ -236,34 +236,34 @@ bool CUP_Player::parseNextBlockTag(Common::SeekableReadStream &dataStream) {
uint32 next = dataStream.pos() + size;
debug(1, "New block tag %s %d dataSize %d", tag2str(tag), size, _dataSize);
switch (tag) {
- case MKID_BE('FRAM'):
+ case MKTAG('F','R','A','M'):
handleFRAM(dataStream, size);
break;
- case MKID_BE('LZSS'):
+ case MKTAG('L','Z','S','S'):
if (handleLZSS(dataStream, size) && _outLzssBufSize != 0) {
Common::MemoryReadStream memoryStream(_outLzssBufData, _outLzssBufSize);
parseNextBlockTag(memoryStream);
}
break;
- case MKID_BE('RATE'):
+ case MKTAG('R','A','T','E'):
handleRATE(dataStream, size);
break;
- case MKID_BE('RGBS'):
+ case MKTAG('R','G','B','S'):
handleRGBS(dataStream, size);
break;
- case MKID_BE('SNDE'):
+ case MKTAG('S','N','D','E'):
handleSNDE(dataStream, size);
break;
- case MKID_BE('TOIL'):
+ case MKTAG('T','O','I','L'):
handleTOIL(dataStream, size);
break;
- case MKID_BE('SRLE'):
+ case MKTAG('S','R','L','E'):
handleSRLE(dataStream, size);
break;
- case MKID_BE('BLOK'):
+ case MKTAG('B','L','O','K'):
_dataSize -= size + 8;
return false;
- case MKID_BE('WRLE'):
+ case MKTAG('W','R','L','E'):
// this is never triggered
default:
warning("Unhandled tag %s", tag2str(tag));
@@ -283,10 +283,10 @@ void CUP_Player::handleSFXB(Common::SeekableReadStream &dataStream, uint32 dataS
if (dataSize > 16) { // WRAP and OFFS chunks
uint32 tag = dataStream.readUint32BE();
uint32 size = dataStream.readUint32BE();
- if (tag == MKID_BE('WRAP')) {
+ if (tag == MKTAG('W','R','A','P')) {
tag = dataStream.readUint32BE();
size = dataStream.readUint32BE();
- if (tag == MKID_BE('OFFS')) {
+ if (tag == MKTAG('O','F','F','S')) {
_sfxCount = (size - 8) / 4;
_sfxBuffer = (uint8 *)malloc(dataSize - 16);
if (_sfxBuffer) {
@@ -439,12 +439,12 @@ static void decodeLZSS(uint8 *dst, const uint8 *src1, const uint8 *src2, const u
bool CUP_Player::handleLZSS(Common::SeekableReadStream &dataStream, uint32 dataSize) {
uint32 tag = dataStream.readUint32BE();
uint32 size = dataStream.readUint32BE();
- if (tag == MKID_BE('LZHD')) {
+ if (tag == MKTAG('L','Z','H','D')) {
uint32 compressionType = dataStream.readUint32LE();
uint32 compressionSize = dataStream.readUint32LE();
tag = dataStream.readUint32BE();
size = dataStream.readUint32BE();
- if (tag == MKID_BE('DATA') && compressionType == 0x2000) {
+ if (tag == MKTAG('D','A','T','A') && compressionType == 0x2000) {
if (_inLzssBufSize < size - 16) {
free(_inLzssBufData);
_inLzssBufSize = size - 16;
diff --git a/engines/scumm/he/floodfill_he.cpp b/engines/scumm/he/floodfill_he.cpp
index 491b91c17e..026a848828 100644
--- a/engines/scumm/he/floodfill_he.cpp
+++ b/engines/scumm/he/floodfill_he.cpp
@@ -240,7 +240,7 @@ void Wiz::fillWizFlood(const WizParameters *params) {
if (params->processFlags & kWPFNewState) {
state = params->img.state;
}
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
int w = READ_LE_UINT32(wizh + 0x4);
@@ -258,7 +258,7 @@ void Wiz::fillWizFlood(const WizParameters *params) {
color = params->fillColor;
}
if (imageRect.contains(px, py)) {
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(wizd);
FloodFillState *ffs = new FloodFillState;
diff --git a/engines/scumm/he/palette_he.cpp b/engines/scumm/he/palette_he.cpp
index b42d6e97e2..7f517c56ed 100644
--- a/engines/scumm/he/palette_he.cpp
+++ b/engines/scumm/he/palette_he.cpp
@@ -192,7 +192,7 @@ void ScummEngine_v90he::setHEPaletteFromCostume(int palSlot, int resId) {
assertRange(1, palSlot, _numPalettes, "palette");
const uint8 *data = getResourceAddress(rtCostume, resId);
assert(data);
- const uint8 *rgbs = findResourceData(MKID_BE('RGBS'), data);
+ const uint8 *rgbs = findResourceData(MKTAG('R','G','B','S'), data);
assert(rgbs);
setHEPaletteFromPtr(palSlot, rgbs);
}
@@ -202,7 +202,7 @@ void ScummEngine_v90he::setHEPaletteFromImage(int palSlot, int resId, int state)
assertRange(1, palSlot, _numPalettes, "palette");
uint8 *data = getResourceAddress(rtImage, resId);
assert(data);
- const uint8 *rgbs = findWrappedBlock(MKID_BE('RGBS'), data, state, 0);
+ const uint8 *rgbs = findWrappedBlock(MKTAG('R','G','B','S'), data, state, 0);
if (rgbs)
setHEPaletteFromPtr(palSlot, rgbs);
}
@@ -212,7 +212,7 @@ void ScummEngine_v90he::setHEPaletteFromRoom(int palSlot, int resId, int state)
assertRange(1, palSlot, _numPalettes, "palette");
const uint8 *data = getResourceAddress(rtRoom, resId);
assert(data);
- const uint8 *pals = findResourceData(MKID_BE('PALS'), data);
+ const uint8 *pals = findResourceData(MKTAG('P','A','L','S'), data);
assert(pals);
const uint8 *rgbs = findPalInPals(pals, state);
assert(rgbs);
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp
index 9349e70eb9..ecb094f29b 100644
--- a/engines/scumm/he/resource_he.cpp
+++ b/engines/scumm/he/resource_he.cpp
@@ -332,7 +332,7 @@ int ScummEngine_v72he::getSoundResourceSize(int id) {
if (!ptr)
return 0;
- if (READ_BE_UINT32(ptr) == MKID_BE('RIFF')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('R','I','F','F')) {
byte flags;
int rate;
@@ -344,11 +344,11 @@ int ScummEngine_v72he::getSoundResourceSize(int id) {
}
} else {
ptr += 8 + READ_BE_UINT32(ptr + 12);
- if (READ_BE_UINT32(ptr) == MKID_BE('SBNG')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('S','B','N','G')) {
ptr += READ_BE_UINT32(ptr + 4);
}
- assert(READ_BE_UINT32(ptr) == MKID_BE('SDAT'));
+ assert(READ_BE_UINT32(ptr) == MKTAG('S','D','A','T'));
size = READ_BE_UINT32(ptr + 4) - 8;
}
}
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index ca4a65ac74..69063a1837 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2999,7 +2999,7 @@ void ScummEngine_v100he::decodeParseString(int m, int n) {
case 78:
{
byte *dataPtr = getResourceAddress(rtTalkie, pop());
- byte *text = findWrappedBlock(MKID_BE('TEXT'), dataPtr, 0, 0);
+ byte *text = findWrappedBlock(MKTAG('T','E','X','T'), dataPtr, 0, 0);
size = getResourceDataSize(text);
memcpy(name, text, size);
printString(m, name);
diff --git a/engines/scumm/he/script_v71he.cpp b/engines/scumm/he/script_v71he.cpp
index 46a8868949..a800a7d85c 100644
--- a/engines/scumm/he/script_v71he.cpp
+++ b/engines/scumm/he/script_v71he.cpp
@@ -88,15 +88,15 @@ byte *ScummEngine_v71he::heFindResource(uint32 tag, byte *searchin) {
}
byte *ScummEngine_v71he::findWrappedBlock(uint32 tag, byte *ptr, int state, bool errorFlag) {
- if (READ_BE_UINT32(ptr) == MKID_BE('MULT')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('M','U','L','T')) {
byte *offs, *wrap;
uint32 size;
- wrap = heFindResource(MKID_BE('WRAP'), ptr);
+ wrap = heFindResource(MKTAG('W','R','A','P'), ptr);
if (wrap == NULL)
return NULL;
- offs = heFindResourceData(MKID_BE('OFFS'), wrap);
+ offs = heFindResourceData(MKTAG('O','F','F','S'), wrap);
if (offs == NULL)
return NULL;
@@ -109,7 +109,7 @@ byte *ScummEngine_v71he::findWrappedBlock(uint32 tag, byte *ptr, int state, bool
if (offs)
return offs;
- offs = heFindResourceData(MKID_BE('DEFA'), ptr);
+ offs = heFindResourceData(MKTAG('D','E','F','A'), ptr);
if (offs == NULL)
return NULL;
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 8aaf16e81b..17bd29d826 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -2039,7 +2039,7 @@ void ScummEngine_v72he::decodeParseString(int m, int n) {
case 0xE1:
{
byte *dataPtr = getResourceAddress(rtTalkie, pop());
- byte *text = findWrappedBlock(MKID_BE('TEXT'), dataPtr, 0, 0);
+ byte *text = findWrappedBlock(MKTAG('T','E','X','T'), dataPtr, 0, 0);
size = getResourceDataSize(text);
memcpy(name, text, size);
printString(m, name);
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 4770f28cbc..4fd7caebf5 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -499,11 +499,11 @@ byte *findSoundTag(uint32 tag, byte *ptr) {
byte *endPtr;
uint32 offset, size;
- if (READ_BE_UINT32(ptr) == MKID_BE('WSOU')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('W','S','O','U')) {
ptr += 8;
}
- if (READ_BE_UINT32(ptr) != MKID_BE('RIFF'))
+ if (READ_BE_UINT32(ptr) != MKTAG('R','I','F','F'))
return NULL;
endPtr = (ptr + 12);
@@ -591,14 +591,14 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
}
// Support for sound in later HE games
- if (READ_BE_UINT32(ptr) == MKID_BE('RIFF') || READ_BE_UINT32(ptr) == MKID_BE('WSOU')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('R','I','F','F') || READ_BE_UINT32(ptr) == MKTAG('W','S','O','U')) {
uint16 compType;
int blockAlign;
int codeOffs = -1;
priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18);
- byte *sbngPtr = findSoundTag(MKID_BE('SBNG'), ptr);
+ byte *sbngPtr = findSoundTag(MKTAG('S','B','N','G'), ptr);
if (sbngPtr != NULL) {
codeOffs = sbngPtr - ptr + 8;
}
@@ -611,7 +611,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
return;
}
- if (READ_BE_UINT32(ptr) == MKID_BE('WSOU'))
+ if (READ_BE_UINT32(ptr) == MKTAG('W','S','O','U'))
ptr += 8;
size = READ_LE_UINT32(ptr + 4);
@@ -675,7 +675,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
Audio::makeLoopingAudioStream(stream, (heFlags & 1) ? 0 : 1), soundID);
}
// Support for sound in Humongous Entertainment games
- else if (READ_BE_UINT32(ptr) == MKID_BE('DIGI') || READ_BE_UINT32(ptr) == MKID_BE('TALK')) {
+ else if (READ_BE_UINT32(ptr) == MKTAG('D','I','G','I') || READ_BE_UINT32(ptr) == MKTAG('T','A','L','K')) {
byte *sndPtr = ptr;
int codeOffs = -1;
@@ -693,12 +693,12 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
return;
}
- if (READ_BE_UINT32(ptr) == MKID_BE('SBNG')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('S','B','N','G')) {
codeOffs = ptr - sndPtr + 8;
ptr += READ_BE_UINT32(ptr + 4);
}
- assert(READ_BE_UINT32(ptr) == MKID_BE('SDAT'));
+ assert(READ_BE_UINT32(ptr) == MKTAG('S','D','A','T'));
size = READ_BE_UINT32(ptr + 4) - 8;
if (heOffset < 0 || heOffset > size) {
// Occurs when making fireworks in puttmoon
@@ -734,14 +734,14 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
Audio::makeLoopingAudioStream(stream, (heFlags & 1) ? 0 : 1), soundID);
}
// Support for PCM music in 3DO versions of Humongous Entertainment games
- else if (READ_BE_UINT32(ptr) == MKID_BE('MRAW')) {
+ else if (READ_BE_UINT32(ptr) == MKTAG('M','R','A','W')) {
priority = *(ptr + 18);
rate = READ_LE_UINT16(ptr + 22);
// Skip DIGI (8) and HSHD (24) blocks
ptr += 32;
- assert(READ_BE_UINT32(ptr) == MKID_BE('SDAT'));
+ assert(READ_BE_UINT32(ptr) == MKTAG('S','D','A','T'));
size = READ_BE_UINT32(ptr + 4) - 8;
byte *sound = (byte *)malloc(size);
@@ -753,7 +753,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags)
stream = Audio::makeRawStream(sound, size, rate, 0);
_mixer->playStream(Audio::Mixer::kMusicSoundType, NULL, stream, soundID);
}
- else if (READ_BE_UINT32(ptr) == MKID_BE('MIDI')) {
+ else if (READ_BE_UINT32(ptr) == MKTAG('M','I','D','I')) {
if (_vm->_imuse) {
// This is used in the DOS version of Fatty Bear's
// Birthday Surprise to change the note on the piano
@@ -833,9 +833,9 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) {
chan = i;
}
- if (!findSoundTag(MKID_BE('data'), snd1Ptr)) {
- sbng1Ptr = heFindResource(MKID_BE('SBNG'), snd1Ptr);
- sbng2Ptr = heFindResource(MKID_BE('SBNG'), snd2Ptr);
+ if (!findSoundTag(MKTAG('d','a','t','a'), snd1Ptr)) {
+ sbng1Ptr = heFindResource(MKTAG('S','B','N','G'), snd1Ptr);
+ sbng2Ptr = heFindResource(MKTAG('S','B','N','G'), snd2Ptr);
}
if (sbng1Ptr != NULL && sbng2Ptr != NULL) {
@@ -879,10 +879,10 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) {
}
}
- if (findSoundTag(MKID_BE('data'), snd1Ptr)) {
- sdat1Ptr = findSoundTag(MKID_BE('data'), snd1Ptr);
+ if (findSoundTag(MKTAG('d','a','t','a'), snd1Ptr)) {
+ sdat1Ptr = findSoundTag(MKTAG('d','a','t','a'), snd1Ptr);
assert(sdat1Ptr);
- sdat2Ptr = findSoundTag(MKID_BE('data'), snd2Ptr);
+ sdat2Ptr = findSoundTag(MKTAG('d','a','t','a'), snd2Ptr);
assert(sdat2Ptr);
if (!_sndDataSize)
@@ -890,9 +890,9 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) {
sdat2size = READ_LE_UINT32(sdat2Ptr + 4) - 8;
} else {
- sdat1Ptr = heFindResource(MKID_BE('SDAT'), snd1Ptr);
+ sdat1Ptr = heFindResource(MKTAG('S','D','A','T'), snd1Ptr);
assert(sdat1Ptr);
- sdat2Ptr = heFindResource(MKID_BE('SDAT'), snd2Ptr);
+ sdat2Ptr = heFindResource(MKTAG('S','D','A','T'), snd2Ptr);
assert(sdat2Ptr);
_sndDataSize = READ_BE_UINT32(sdat1Ptr + 4) - 8;
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index 3d1aa5b048..16cbadd65b 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -1445,21 +1445,21 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
if (shadow) {
dataPtr = _vm->getResourceAddress(rtImage, shadow);
assert(dataPtr);
- xmapPtr = _vm->findResourceData(MKID_BE('XMAP'), dataPtr);
+ xmapPtr = _vm->findResourceData(MKTAG('X','M','A','P'), dataPtr);
assert(xmapPtr);
}
dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
uint32 comp = READ_LE_UINT32(wizh + 0x0);
uint32 width = READ_LE_UINT32(wizh + 0x4);
uint32 height = READ_LE_UINT32(wizh + 0x8);
debug(3, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height);
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(wizd);
uint8 *mask = NULL;
@@ -1467,28 +1467,28 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
uint8 *maskPtr = _vm->getResourceAddress(rtImage, maskNum);
assert(maskPtr);
- wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), maskPtr, maskState, 0);
+ wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), maskPtr, maskState, 0);
assert(wizh);
assert(comp == 2 && READ_LE_UINT32(wizh + 0x0) == 1);
width = READ_LE_UINT32(wizh + 0x4);
height = READ_LE_UINT32(wizh + 0x8);
- mask = _vm->findWrappedBlock(MKID_BE('WIZD'), maskPtr, maskState, 0);
+ mask = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), maskPtr, maskState, 0);
assert(mask);
}
if (flags & kWIFHasPalette) {
- uint8 *pal = _vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0);
+ uint8 *pal = _vm->findWrappedBlock(MKTAG('R','G','B','S'), dataPtr, state, 0);
assert(pal);
_vm->setPaletteFromPtr(pal, 256);
}
uint8 *rmap = NULL;
if (flags & kWIFRemapPalette) {
- rmap = _vm->findWrappedBlock(MKID_BE('RMAP'), dataPtr, state, 0);
+ rmap = _vm->findWrappedBlock(MKTAG('R','M','A','P'), dataPtr, state, 0);
assert(rmap);
if (_vm->_game.heversion <= 80 || READ_BE_UINT32(rmap) != 0x01234567) {
- uint8 *rgbs = _vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0);
+ uint8 *rgbs = _vm->findWrappedBlock(MKTAG('R','G','B','S'), dataPtr, state, 0);
assert(rgbs);
_vm->remapHEPalette(rgbs, rmap + 4);
}
@@ -1526,7 +1526,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
if (dstResNum) {
uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum);
assert(dstPtr);
- dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
+ dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0);
assert(dst);
getWizImageDim(dstResNum, 0, cw, ch);
dstPitch = cw * _vm->_bytesPerPixel;
@@ -1567,7 +1567,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int
int transColor = -1;
if (_vm->VAR_WIZ_TCOLOR != 0xFF) {
- uint8 *trns = _vm->findWrappedBlock(MKID_BE('TRNS'), dataPtr, state, 0);
+ uint8 *trns = _vm->findWrappedBlock(MKTAG('T','R','N','S'), dataPtr, state, 0);
transColor = (trns == NULL) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : -1;
}
@@ -1817,7 +1817,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
assert(_vm->_bytesPerPixel == 1);
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
- srcWizBuf = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ srcWizBuf = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(srcWizBuf);
freeBuffer = false;
}
@@ -1827,7 +1827,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
} else {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
- srcWizBuf = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ srcWizBuf = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(srcWizBuf);
freeBuffer = false;
}
@@ -1842,7 +1842,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int
if (dstResNum) {
uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum);
assert(dstPtr);
- dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
+ dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0);
assert(dst);
getWizImageDim(dstResNum, 0, dstw, dsth);
dstpitch = dstw * _vm->_bytesPerPixel;
@@ -2185,7 +2185,7 @@ void Wiz::fillWizRect(const WizParameters *params) {
}
uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum);
if (dataPtr) {
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
int w = READ_LE_UINT32(wizh + 0x4);
@@ -2210,7 +2210,7 @@ void Wiz::fillWizRect(const WizParameters *params) {
}
if (areaRect.intersects(imageRect)) {
areaRect.clip(imageRect);
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(wizd);
int dx = areaRect.width();
int dy = areaRect.height();
@@ -2256,7 +2256,7 @@ void Wiz::fillWizLine(const WizParameters *params) {
}
uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum);
if (dataPtr) {
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
int w = READ_LE_UINT32(wizh + 0x4);
@@ -2274,7 +2274,7 @@ void Wiz::fillWizLine(const WizParameters *params) {
if (params->processFlags & kWPFFillColor) {
color = params->fillColor;
}
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(wizd);
int x1 = params->box2.left;
int y1 = params->box2.top;
@@ -2309,7 +2309,7 @@ void Wiz::fillWizPixel(const WizParameters *params) {
if (params->processFlags & kWPFNewState) {
state = params->img.state;
}
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
int w = READ_LE_UINT32(wizh + 0x4);
@@ -2327,7 +2327,7 @@ void Wiz::fillWizPixel(const WizParameters *params) {
color = params->fillColor;
}
if (imageRect.contains(px, py)) {
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0);
assert(wizd);
*(wizd + py * w + px) = color;
}
@@ -2342,7 +2342,7 @@ void Wiz::remapWizImagePal(const WizParameters *params) {
const uint8 *index = params->remapIndex;
uint8 *iwiz = _vm->getResourceAddress(rtImage, params->img.resNum);
assert(iwiz);
- uint8 *rmap = _vm->findWrappedBlock(MKID_BE('RMAP'), iwiz, st, 0);
+ uint8 *rmap = _vm->findWrappedBlock(MKTAG('R','M','A','P'), iwiz, st, 0);
assert(rmap);
WRITE_BE_UINT32(rmap, 0x01234567);
while (num--) {
@@ -2380,7 +2380,7 @@ void Wiz::processWizImage(const WizParameters *params) {
if (f) {
uint32 id = f->readUint32BE();
- if (id == MKID_BE('AWIZ') || id == MKID_BE('MULT')) {
+ if (id == MKTAG('A','W','I','Z') || id == MKTAG('M','U','L','T')) {
uint32 size = f->readUint32BE();
f->seek(0, SEEK_SET);
byte *p = _vm->_res->createResource(rtImage, params->img.resNum, size);
@@ -2510,7 +2510,7 @@ void Wiz::processWizImage(const WizParameters *params) {
void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
w = READ_LE_UINT32(wizh + 0x4);
h = READ_LE_UINT32(wizh + 0x8);
@@ -2519,7 +2519,7 @@ void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) {
void Wiz::getWizImageSpot(int resId, int state, int32 &x, int32 &y) {
uint8 *dataPtr = _vm->getResourceAddress(rtImage, resId);
assert(dataPtr);
- uint8 *spotPtr = _vm->findWrappedBlock(MKID_BE('SPOT'), dataPtr, state, 0);
+ uint8 *spotPtr = _vm->findWrappedBlock(MKTAG('S','P','O','T'), dataPtr, state, 0);
if (spotPtr) {
x = READ_LE_UINT32(spotPtr + 0);
y = READ_LE_UINT32(spotPtr + 4);
@@ -2537,17 +2537,17 @@ int Wiz::getWizImageData(int resNum, int state, int type) {
switch (type) {
case 0:
- wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0);
+ wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0);
assert(wizh);
return READ_LE_UINT32(wizh + 0x0);
case 1:
- return (_vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0) != NULL) ? 1 : 0;
+ return (_vm->findWrappedBlock(MKTAG('R','G','B','S'), dataPtr, state, 0) != NULL) ? 1 : 0;
case 2:
- return (_vm->findWrappedBlock(MKID_BE('RMAP'), dataPtr, state, 0) != NULL) ? 1 : 0;
+ return (_vm->findWrappedBlock(MKTAG('R','M','A','P'), dataPtr, state, 0) != NULL) ? 1 : 0;
case 3:
- return (_vm->findWrappedBlock(MKID_BE('TRNS'), dataPtr, state, 0) != NULL) ? 1 : 0;
+ return (_vm->findWrappedBlock(MKTAG('T','R','N','S'), dataPtr, state, 0) != NULL) ? 1 : 0;
case 4:
- return (_vm->findWrappedBlock(MKID_BE('XMAP'), dataPtr, state, 0) != NULL) ? 1 : 0;
+ return (_vm->findWrappedBlock(MKTAG('X','M','A','P'), dataPtr, state, 0) != NULL) ? 1 : 0;
default:
error("getWizImageData: Unknown type %d", type);
}
@@ -2556,14 +2556,14 @@ int Wiz::getWizImageData(int resNum, int state, int type) {
int Wiz::getWizImageStates(int resNum) {
const uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
assert(dataPtr);
- if (READ_BE_UINT32(dataPtr) == MKID_BE('MULT')) {
+ if (READ_BE_UINT32(dataPtr) == MKTAG('M','U','L','T')) {
const byte *offs, *wrap;
- wrap = _vm->findResource(MKID_BE('WRAP'), dataPtr);
+ wrap = _vm->findResource(MKTAG('W','R','A','P'), dataPtr);
if (wrap == NULL)
return 1;
- offs = _vm->findResourceData(MKID_BE('OFFS'), wrap);
+ offs = _vm->findResourceData(MKTAG('O','F','F','S'), wrap);
if (offs == NULL)
return 1;
@@ -2577,12 +2577,12 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags
int ret = 0;
uint8 *data = _vm->getResourceAddress(rtImage, resNum);
assert(data);
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), data, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
int w = READ_LE_UINT32(wizh + 0x4);
int h = READ_LE_UINT32(wizh + 0x8);
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), data, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0);
assert(wizd);
if (x >= 0 && x < w && y >= 0 && y < h) {
if (flags & kWIFFlipX) {
@@ -2627,12 +2627,12 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) {
uint16 color = 0;
uint8 *data = _vm->getResourceAddress(rtImage, resNum);
assert(data);
- uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), data, state, 0);
+ uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
int w = READ_LE_UINT32(wizh + 0x4);
int h = READ_LE_UINT32(wizh + 0x8);
- uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), data, state, 0);
+ uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0);
assert(wizd);
switch (c) {
case 0:
@@ -2671,13 +2671,13 @@ int ScummEngine_v90he::computeWizHistogram(int resNum, int state, int x, int y,
Common::Rect rCapt(x, y, w + 1, h + 1);
uint8 *data = getResourceAddress(rtImage, resNum);
assert(data);
- uint8 *wizh = findWrappedBlock(MKID_BE('WIZH'), data, state, 0);
+ uint8 *wizh = findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0);
assert(wizh);
int c = READ_LE_UINT32(wizh + 0x0);
w = READ_LE_UINT32(wizh + 0x4);
h = READ_LE_UINT32(wizh + 0x8);
Common::Rect rWiz(w, h);
- uint8 *wizd = findWrappedBlock(MKID_BE('WIZD'), data, state, 0);
+ uint8 *wizd = findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0);
assert(wizd);
if (rCapt.intersects(rWiz)) {
rCapt.clip(rWiz);
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index 6c626cdf4e..07fd99c809 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -150,22 +150,22 @@ bool IMuseInternal::isMT32(int sound) {
tag = READ_BE_UINT32(ptr + 4);
switch (tag) {
- case MKID_BE('ADL '):
- case MKID_BE('ASFX'): // Special AD class for old AdLib sound effects
- case MKID_BE('SPK '):
+ case MKTAG('A','D','L',' '):
+ case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects
+ case MKTAG('S','P','K',' '):
return false;
- case MKID_BE('AMI '):
- case MKID_BE('ROL '):
+ case MKTAG('A','M','I',' '):
+ case MKTAG('R','O','L',' '):
return true;
- case MKID_BE('MAC '): // Occurs in the Mac version of FOA and MI2
+ case MKTAG('M','A','C',' '): // Occurs in the Mac version of FOA and MI2
return true;
- case MKID_BE('GMD '):
+ case MKTAG('G','M','D',' '):
return false;
- case MKID_BE('MIDI'): // Occurs in Sam & Max
+ case MKTAG('M','I','D','I'): // Occurs in Sam & Max
// HE games use Roland music
if (ptr[12] == 'H' && ptr[13] == 'S')
return true;
@@ -197,20 +197,20 @@ bool IMuseInternal::isMIDI(int sound) {
tag = READ_BE_UINT32(ptr + 4);
switch (tag) {
- case MKID_BE('ADL '):
- case MKID_BE('ASFX'): // Special AD class for old AdLib sound effects
- case MKID_BE('SPK '):
+ case MKTAG('A','D','L',' '):
+ case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects
+ case MKTAG('S','P','K',' '):
return false;
- case MKID_BE('AMI '):
- case MKID_BE('ROL '):
+ case MKTAG('A','M','I',' '):
+ case MKTAG('R','O','L',' '):
return true;
- case MKID_BE('MAC '): // Occurs in the Mac version of FOA and MI2
+ case MKTAG('M','A','C',' '): // Occurs in the Mac version of FOA and MI2
return true;
- case MKID_BE('GMD '):
- case MKID_BE('MIDI'): // Occurs in Sam & Max
+ case MKTAG('G','M','D',' '):
+ case MKTAG('M','I','D','I'): // Occurs in Sam & Max
return true;
}
diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp
index 516a0497fa..3831689def 100644
--- a/engines/scumm/imuse_digi/dimuse.cpp
+++ b/engines/scumm/imuse_digi/dimuse.cpp
@@ -31,6 +31,7 @@
#include "scumm/sound.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
#include "scumm/imuse_digi/dimuse_track.h"
#include "audio/audiostream.h"
diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
index f10f17f3d8..cb894d77cc 100644
--- a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
@@ -28,6 +28,7 @@
#include "scumm/util.h"
#include "scumm/file.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
namespace Scumm {
@@ -92,7 +93,7 @@ int BundleDirCache::matchFile(const char *filename) {
error("BundleDirCache::matchFileFile() Can't find free slot for file bundle dir cache");
tag = file.readUint32BE();
- if (tag == MKID_BE('LB23'))
+ if (tag == MKTAG('L','B','2','3'))
_budleDirCache[freeSlot].isCompressed = true;
offset = file.readUint32BE();
@@ -112,7 +113,7 @@ int BundleDirCache::matchFile(const char *filename) {
int32 z = 0;
int32 z2;
- if (tag == MKID_BE('LB23')) {
+ if (tag == MKTAG('L','B','2','3')) {
file.read(_budleDirCache[freeSlot].bundleTable[i].filename, 24);
} else {
for (z2 = 0; z2 < 8; z2++)
@@ -224,7 +225,7 @@ bool BundleMgr::loadCompTable(int32 index) {
assert(_numCompItems > 0);
_file->seek(8, SEEK_CUR);
- if (tag != MKID_BE('COMP')) {
+ if (tag != MKTAG('C','O','M','P')) {
error("BundleMgr::loadCompTable() Compressed sound %d (%s:%d) invalid (%s)", index, _file->getName(), _bundleTable[index].offset, tag2str(tag));
return false;
}
diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.h b/engines/scumm/imuse_digi/dimuse_bndmgr.h
index a78697a854..bed1ac6549 100644
--- a/engines/scumm/imuse_digi/dimuse_bndmgr.h
+++ b/engines/scumm/imuse_digi/dimuse_bndmgr.h
@@ -107,14 +107,6 @@ public:
int32 decompressSampleByCurIndex(int32 offset, int32 size, byte **compFinal, int headerSize, bool headerOutside);
};
-namespace BundleCodecs {
-
-uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size);
-void initializeImcTables();
-int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize);
-
-} // End of namespace BundleCodecs
-
} // End of namespace Scumm
#endif
diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp
index 62a006c56b..fd9deb7b44 100644
--- a/engines/scumm/imuse_digi/dimuse_codecs.cpp
+++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp
@@ -25,6 +25,9 @@
#include "common/scummsys.h"
#include "common/endian.h"
#include "common/util.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
+
+#include "audio/decoders/adpcm_intern.h"
namespace Scumm {
@@ -59,23 +62,10 @@ uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size) {
* varies the size of each "packet" between 2 and 7 bits.
*/
-static byte _imcTableEntryBitCount[89];
-
-static const int16 imcTable[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14,
- 16, 17, 19, 21, 23, 25, 28, 31,
- 34, 37, 41, 45, 50, 55, 60, 66,
- 73, 80, 88, 97, 107, 118, 130, 143,
- 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658,
- 724, 796, 876, 963, 1060, 1166, 1282, 1411,
- 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
- 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
- 7132, 7845, 8630, 9493,10442,11487,12635,13899,
- 15289,16818,18500,20350,22385,24623,27086,29794,
- 32767
-};
+static byte *_destImcTable = NULL;
+static uint32 *_destImcTable2 = NULL;
+// This table is the "big brother" of Audio::ADPCMStream::_stepAdjustTable.
static const byte imxOtherTable[6][64] = {
{
0xFF,
@@ -116,23 +106,47 @@ static const byte imxOtherTable[6][64] = {
}
};
+void releaseImcTables() {
+ free(_destImcTable);
+ free(_destImcTable2);
+}
+
void initializeImcTables() {
int pos;
- for (pos = 0; pos < ARRAYSIZE(imcTable); ++pos) {
- byte put = 0;
- int32 tableValue = ((imcTable[pos] * 4) / 7) / 2;
+ if (!_destImcTable) _destImcTable = (byte *)calloc(89, sizeof(byte));
+ if (!_destImcTable2) _destImcTable2 = (uint32 *)calloc(89 * 64, sizeof(uint32));
+
+ for (pos = 0; pos <= 88; ++pos) {
+ byte put = 1;
+ int32 tableValue = ((Audio::Ima_ADPCMStream::_imaTable[pos] * 4) / 7) / 2;
while (tableValue != 0) {
tableValue /= 2;
put++;
}
- if (put < 2) {
- put = 2;
+ if (put < 3) {
+ put = 3;
+ }
+ if (put > 8) {
+ put = 8;
}
- if (put > 7) {
- put = 7;
+ _destImcTable[pos] = put - 1;
+ }
+
+ for (int n = 0; n < 64; n++) {
+ for (pos = 0; pos <= 88; ++pos) {
+ int32 count = 32;
+ int32 put = 0;
+ int32 tableValue = Audio::Ima_ADPCMStream::_imaTable[pos];
+ do {
+ if ((count & n) != 0) {
+ put += tableValue;
+ }
+ count /= 2;
+ tableValue /= 2;
+ } while (count != 0);
+ _destImcTable2[n + pos * 64] = put;
}
- _imcTableEntryBitCount[pos] = put;
}
}
@@ -183,8 +197,128 @@ static int32 compDecode(byte *src, byte *dst) {
}
#undef NextBit
+int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) {
+ byte *src;
+
+ // Decoder for the the IMA ADPCM variants used in COMI.
+ // Contrary to regular IMA ADPCM, this codec uses a variable
+ // bitsize for the encoded data.
+
+ const int MAX_CHANNELS = 2;
+ int32 outputSamplesLeft;
+ int32 destPos;
+ int16 firstWord;
+ byte initialTablePos[MAX_CHANNELS] = {0, 0};
+ int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
+ int32 initialOutputWord[MAX_CHANNELS] = {0, 0};
+ int32 totalBitOffset, curTablePos, outputWord;
+ byte *dst;
+ int i;
+
+ // We only support mono and stereo
+ assert(channels == 1 || channels == 2);
+
+ src = compInput;
+ dst = compOutput;
+ outputSamplesLeft = 0x1000;
+
+ // Every data packet contains 0x2000 bytes of audio data
+ // when extracted. In order to encode bigger data sets,
+ // one has to split the data into multiple blocks.
+ //
+ // Every block starts with a 2 byte word. If that word is
+ // non-zero, it indicates the size of a block of raw audio
+ // data (not encoded) following it. That data we simply copy
+ // to the output buffer and the proceed by decoding the
+ // remaining data.
+ //
+ // If on the other hand the word is zero, then what follows
+ // are 7*channels bytes containing seed data for the decoder.
+ firstWord = READ_BE_UINT16(src);
+ src += 2;
+ if (firstWord != 0) {
+ // Copy raw data
+ memcpy(dst, src, firstWord);
+ dst += firstWord;
+ src += firstWord;
+ assert((firstWord & 1) == 0);
+ outputSamplesLeft -= firstWord / 2;
+ } else {
+ // Read the seed values for the decoder.
+ for (i = 0; i < channels; i++) {
+ initialTablePos[i] = *src;
+ src += 1;
+ initialimcTableEntry[i] = READ_BE_UINT32(src);
+ src += 4;
+ initialOutputWord[i] = READ_BE_UINT32(src);
+ src += 4;
+ }
+ }
+
+ totalBitOffset = 0;
+ // The channels are encoded separately.
+ for (int chan = 0; chan < channels; chan++) {
+ // Read initial state (this makes it possible for the data stream
+ // to be split & spread across multiple data chunks.
+ curTablePos = initialTablePos[chan];
+ //imcTableEntry = initialimcTableEntry[chan];
+ outputWord = initialOutputWord[chan];
+
+ // We need to interleave the channels in the output; we achieve
+ // that by using a variables dest offset:
+ destPos = chan * 2;
+
+ const int bound = (channels == 1)
+ ? outputSamplesLeft
+ : ((chan == 0)
+ ? (outputSamplesLeft+1) / 2
+ : outputSamplesLeft / 2);
+ for (i = 0; i < bound; ++i) {
+ // Determine the size (in bits) of the next data packet
+ const int32 curTableEntryBitCount = _destImcTable[curTablePos];
+ assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7);
+
+ // Read the next data packet
+ const byte *readPos = src + (totalBitOffset >> 3);
+ const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7));
+ const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount));
+
+ // Advance read position to the next data packet
+ totalBitOffset += curTableEntryBitCount;
+
+ // Decode the data packet into a delta value for the output signal.
+ const byte signBitMask = (1 << (curTableEntryBitCount - 1));
+ const byte dataBitMask = (signBitMask - 1);
+ const byte data = (packet & dataBitMask);
+
+ const int32 tmpA = (data << (7 - curTableEntryBitCount));
+ const int32 imcTableEntry = Audio::Ima_ADPCMStream::_imaTable[curTablePos] >> (curTableEntryBitCount - 1);
+ int32 delta = imcTableEntry + _destImcTable2[tmpA + (curTablePos * 64)];
+
+ // The topmost bit in the data packet tells is a sign bit
+ if ((packet & signBitMask) != 0) {
+ delta = -delta;
+ }
+
+ // Accumulate the delta onto the output data
+ outputWord += delta;
+
+ // Clip outputWord to 16 bit signed, and write it into the destination stream
+ outputWord = CLIP<int32>(outputWord, -0x8000, 0x7fff);
+ WRITE_BE_UINT16(dst + destPos, outputWord);
+ destPos += channels << 1;
+
+ // Adjust the curTablePos
+ curTablePos += (int8)imxOtherTable[curTableEntryBitCount - 2][data];
+ curTablePos = CLIP<int32>(curTablePos, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1);
+ }
+ }
+
+ return 0x2000;
+}
+
int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize) {
- int32 outputSize, channels;
+ int32 outputSize;
int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z;
byte *src, *t_table, *p, *ptr;
byte t_tmp1, t_tmp2;
@@ -506,132 +640,7 @@ int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inpu
case 13:
case 15:
- if (codec == 13) {
- channels = 1;
- } else {
- channels = 2;
- }
-
- {
- // Decoder for the the IMA ADPCM variants used in COMI.
- // Contrary to regular IMA ADPCM, this codec uses a variable
- // bitsize for the encoded data.
-
- const int MAX_CHANNELS = 2;
- int32 outputSamplesLeft;
- int32 destPos;
- int16 firstWord;
- byte initialTablePos[MAX_CHANNELS] = {0, 0};
- //int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
- int32 initialOutputWord[MAX_CHANNELS] = {0, 0};
- int32 totalBitOffset, curTablePos, outputWord;
- byte *dst;
- int i;
-
- // We only support mono and stereo
- assert(channels == 1 || channels == 2);
-
- src = compInput;
- dst = compOutput;
- outputSize = 0x2000;
- outputSamplesLeft = 0x1000;
-
- // Every data packet contains 0x2000 bytes of audio data
- // when extracted. In order to encode bigger data sets,
- // one has to split the data into multiple blocks.
- //
- // Every block starts with a 2 byte word. If that word is
- // non-zero, it indicates the size of a block of raw audio
- // data (not encoded) following it. That data we simply copy
- // to the output buffer and the proceed by decoding the
- // remaining data.
- //
- // If on the other hand the word is zero, then what follows
- // are 7*channels bytes containing seed data for the decoder.
- firstWord = READ_BE_UINT16(src);
- src += 2;
- if (firstWord != 0) {
- // Copy raw data
- memcpy(dst, src, firstWord);
- dst += firstWord;
- src += firstWord;
- assert((firstWord & 1) == 0);
- outputSamplesLeft -= firstWord / 2;
- } else {
- // Read the seed values for the decoder.
- for (i = 0; i < channels; i++) {
- initialTablePos[i] = *src;
- src += 1;
- //initialimcTableEntry[i] = READ_BE_UINT32(src);
- src += 4;
- initialOutputWord[i] = READ_BE_UINT32(src);
- src += 4;
- }
- }
-
- totalBitOffset = 0;
- // The channels are encoded separately.
- for (int chan = 0; chan < channels; chan++) {
- // Read initial state (this makes it possible for the data stream
- // to be split & spread across multiple data chunks.
- curTablePos = initialTablePos[chan];
- //imcTableEntry = initialimcTableEntry[chan];
- outputWord = initialOutputWord[chan];
-
- // We need to interleave the channels in the output; we achieve
- // that by using a variables dest offset:
- destPos = chan * 2;
-
- const int bound = (channels == 1)
- ? outputSamplesLeft
- : ((chan == 0)
- ? (outputSamplesLeft+1) / 2
- : outputSamplesLeft / 2);
- for (i = 0; i < bound; ++i) {
- // Determine the size (in bits) of the next data packet
- const int32 curTableEntryBitCount = _imcTableEntryBitCount[curTablePos];
- assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7);
-
- // Read the next data packet
- const byte *readPos = src + (totalBitOffset >> 3);
- const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7));
- const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount));
-
- // Advance read position to the next data packet
- totalBitOffset += curTableEntryBitCount;
-
- // Decode the data packet into a delta value for the output signal.
- const byte signBitMask = (1 << (curTableEntryBitCount - 1));
- const byte dataBitMask = (signBitMask - 1);
- const byte data = (packet & dataBitMask);
-
- int32 delta = imcTable[curTablePos] * (2 * data + 1) >> (curTableEntryBitCount - 1);
-
- // The topmost bit in the data packet tells is a sign bit
- if ((packet & signBitMask) != 0) {
- delta = -delta;
- }
-
- // Accumulate the delta onto the output data
- outputWord += delta;
-
- // Clip outputWord to 16 bit signed, and write it into the destination stream
- if (outputWord > 0x7fff)
- outputWord = 0x7fff;
- if (outputWord < -0x8000)
- outputWord = -0x8000;
- WRITE_BE_UINT16(dst + destPos, outputWord);
- destPos += channels << 1;
-
- // Adjust the curTablePos
- curTablePos += (int8)imxOtherTable[curTableEntryBitCount - 2][data];
- if (curTablePos < 0)
- curTablePos = 0;
- else if (curTablePos >= ARRAYSIZE(imcTable))
- curTablePos = ARRAYSIZE(imcTable) - 1;
- }
- }
- }
+ outputSize = decompressADPCM(compInput, compOutput, (codec == 13) ? 1 : 2);
break;
default:
diff --git a/engines/scumm/imuse_digi/dimuse_codecs.h b/engines/scumm/imuse_digi/dimuse_codecs.h
new file mode 100644
index 0000000000..71fd24c3ac
--- /dev/null
+++ b/engines/scumm/imuse_digi/dimuse_codecs.h
@@ -0,0 +1,44 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef SCUMM_IMUSE_DIGI_CODECS_H
+#define SCUMM_IMUSE_DIGI_CODECS_H
+
+#include "common/scummsys.h"
+
+namespace Scumm {
+
+namespace BundleCodecs {
+
+uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size);
+int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize);
+
+void initializeImcTables();
+void releaseImcTables();
+
+} // End of namespace BundleCodecs
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index 00074a951a..2cd90c4f2b 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -34,8 +34,9 @@
#include "scumm/scumm.h"
#include "scumm/util.h"
#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_sndmgr.h"
#include "scumm/imuse_digi/dimuse_bndmgr.h"
+#include "scumm/imuse_digi/dimuse_codecs.h"
+#include "scumm/imuse_digi/dimuse_sndmgr.h"
namespace Scumm {
@@ -56,6 +57,7 @@ ImuseDigiSndMgr::~ImuseDigiSndMgr() {
}
delete _cacheBundleDir;
+ BundleCodecs::releaseImcTables();
}
void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs, int &numMarkers) {
@@ -65,32 +67,32 @@ void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, i
do {
tag = READ_BE_UINT32(ptr); ptr += 4;
switch (tag) {
- case MKID_BE('STOP'):
- case MKID_BE('FRMT'):
- case MKID_BE('DATA'):
+ case MKTAG('S','T','O','P'):
+ case MKTAG('F','R','M','T'):
+ case MKTAG('D','A','T','A'):
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
if (!scumm_stricmp((const char *)(ptr + 8), "exit"))
numMarkers++;
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
- case MKID_BE('REGN'):
+ case MKTAG('R','E','G','N'):
numRegions++;
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
- case MKID_BE('JUMP'):
+ case MKTAG('J','U','M','P'):
numJumps++;
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
- case MKID_BE('SYNC'):
+ case MKTAG('S','Y','N','C'):
numSyncs++;
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
default:
error("ImuseDigiSndMgr::countElements() Unknown sfx header '%s'", tag2str(tag));
}
- } while (tag != MKID_BE('DATA'));
+ } while (tag != MKTAG('D','A','T','A'));
}
void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::SeekableReadStream *file, SoundDesc *sound, int32 offset, int32 size) {
@@ -98,7 +100,7 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::SeekableReadStream *file, Sou
file->seek(offset, SEEK_SET);
uint32 tag = file->readUint32BE();
- assert(tag == MKID_BE('RMAP'));
+ assert(tag == MKTAG('R','M','A','P'));
int32 version = file->readUint32BE();
if (version != 3) {
if (version == 2) {
@@ -153,7 +155,7 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::SeekableReadStream *file, Sou
}
void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
- if (READ_BE_UINT32(ptr) == MKID_BE('Crea')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('C','r','e','a')) {
bool quit = false;
int len;
@@ -222,7 +224,7 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
}
offset += len;
}
- } else if (READ_BE_UINT32(ptr) == MKID_BE('iMUS')) {
+ } else if (READ_BE_UINT32(ptr) == MKTAG('i','M','U','S')) {
uint32 tag;
int32 size = 0;
byte *s_ptr = ptr;
@@ -250,13 +252,13 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
do {
tag = READ_BE_UINT32(ptr); ptr += 4;
switch (tag) {
- case MKID_BE('FRMT'):
+ case MKTAG('F','R','M','T'):
ptr += 12;
sound->bits = READ_BE_UINT32(ptr); ptr += 4;
sound->freq = READ_BE_UINT32(ptr); ptr += 4;
sound->channels = READ_BE_UINT32(ptr); ptr += 4;
break;
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
if (!scumm_stricmp((const char *)(ptr + 8), "exit")) {
sound->marker[curIndexMarker].pos = READ_BE_UINT32(ptr + 4);
sound->marker[curIndexMarker].length = strlen((const char *)(ptr + 8)) + 1;
@@ -267,16 +269,16 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
}
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
- case MKID_BE('STOP'):
+ case MKTAG('S','T','O','P'):
size = READ_BE_UINT32(ptr); ptr += size + 4;
break;
- case MKID_BE('REGN'):
+ case MKTAG('R','E','G','N'):
ptr += 4;
sound->region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4;
sound->region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4;
curIndexRegion++;
break;
- case MKID_BE('JUMP'):
+ case MKTAG('J','U','M','P'):
ptr += 4;
sound->jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4;
sound->jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4;
@@ -284,7 +286,7 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
sound->jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
curIndexJump++;
break;
- case MKID_BE('SYNC'):
+ case MKTAG('S','Y','N','C'):
size = READ_BE_UINT32(ptr); ptr += 4;
sound->sync[curIndexSync].size = size;
sound->sync[curIndexSync].ptr = new byte[size];
@@ -293,13 +295,13 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) {
curIndexSync++;
ptr += size;
break;
- case MKID_BE('DATA'):
+ case MKTAG('D','A','T','A'):
ptr += 4;
break;
default:
error("ImuseDigiSndMgr::prepareSound(%d/%s) Unknown sfx header '%s'", sound->soundId, sound->name, tag2str(tag));
}
- } while (tag != MKID_BE('DATA'));
+ } while (tag != MKTAG('D','A','T','A'));
sound->offsetData = ptr - s_ptr;
} else {
error("ImuseDigiSndMgr::prepareSound(): Unknown sound format");
diff --git a/engines/scumm/insane/insane.cpp b/engines/scumm/insane/insane.cpp
index f2e50382b3..a82c0ae408 100644
--- a/engines/scumm/insane/insane.cpp
+++ b/engines/scumm/insane/insane.cpp
@@ -1413,7 +1413,7 @@ int32 Insane::smush_setupSanWithFlu(const char *filename, int32 setupsan2, int32
_smush_setupsan1 = setupsan1;
/* skip FLUP marker */
- if (READ_BE_UINT32(fluPtr) == MKID_BE('FLUP'))
+ if (READ_BE_UINT32(fluPtr) == MKTAG('F','L','U','P'))
tmp += 8;
_smush_setupsan2 = setupsan2;
diff --git a/engines/scumm/nut_renderer.cpp b/engines/scumm/nut_renderer.cpp
index d56017c6f5..7f250e45e0 100644
--- a/engines/scumm/nut_renderer.cpp
+++ b/engines/scumm/nut_renderer.cpp
@@ -95,7 +95,7 @@ void NutRenderer::loadFont(const char *filename) {
}
uint32 tag = file.readUint32BE();
- if (tag != MKID_BE('ANIM')) {
+ if (tag != MKTAG('A','N','I','M')) {
error("NutRenderer::loadFont() there is no ANIM chunk in font header");
}
@@ -104,7 +104,7 @@ void NutRenderer::loadFont(const char *filename) {
file.read(dataSrc, length);
file.close();
- if (READ_BE_UINT32(dataSrc) != MKID_BE('AHDR')) {
+ if (READ_BE_UINT32(dataSrc) != MKTAG('A','H','D','R')) {
error("NutRenderer::loadFont() there is no AHDR chunk in font header");
}
@@ -142,12 +142,12 @@ void NutRenderer::loadFont(const char *filename) {
offset = 0;
for (l = 0; l < _numChars; l++) {
offset += READ_BE_UINT32(dataSrc + offset + 4) + 8;
- if (READ_BE_UINT32(dataSrc + offset) != MKID_BE('FRME')) {
+ if (READ_BE_UINT32(dataSrc + offset) != MKTAG('F','R','M','E')) {
error("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset);
break;
}
offset += 8;
- if (READ_BE_UINT32(dataSrc + offset) != MKID_BE('FOBJ')) {
+ if (READ_BE_UINT32(dataSrc + offset) != MKTAG('F','O','B','J')) {
error("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset);
break;
}
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index c44043ca81..c2547f74f4 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -416,7 +416,7 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
debug(0, "getObjectXYPos: Can't find object %d", object);
return;
}
- imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), ptr);
+ imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr);
assert(imhd);
if (_game.version == 8) {
switch (FROM_LE_32(imhd->v8.version)) {
@@ -655,7 +655,7 @@ void ScummEngine::drawObject(int obj, int arg) {
flags |= Gdi::dbDrawMaskOnAll;
#ifdef ENABLE_HE
- if (_game.heversion >= 70 && findResource(MKID_BE('SMAP'), ptr) == NULL)
+ if (_game.heversion >= 70 && findResource(MKTAG('S','M','A','P'), ptr) == NULL)
_gdi->drawBMAPObject(ptr, &_virtscr[kMainVirtScreen], obj, od.x_pos, od.y_pos, od.width, od.height);
else
#endif
@@ -762,12 +762,12 @@ void ScummEngine::resetRoomObjects() {
for (i = 0; i < _numObjectsInRoom; i++) {
od = &_objs[findLocalObjectSlot()];
- ptr = obcds.findNext(MKID_BE('OBCD'));
+ ptr = obcds.findNext(MKTAG('O','B','C','D'));
if (ptr == NULL)
error("Room %d missing object code block(s)", _roomResource);
od->OBCDoffset = ptr - rootptr;
- cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), ptr);
+ cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), ptr);
if (_game.version >= 7)
od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id));
@@ -779,7 +779,7 @@ void ScummEngine::resetRoomObjects() {
if (_dumpScripts) {
char buf[32];
sprintf(buf, "roomobj-%d-", _roomResource);
- ptr = findResource(MKID_BE('VERB'), ptr);
+ ptr = findResource(MKTAG('V','E','R','B'), ptr);
dumpResource(buf, od->obj_nr, ptr);
}
@@ -788,7 +788,7 @@ void ScummEngine::resetRoomObjects() {
searchptr = room;
ResourceIterator obims(room, false);
for (i = 0; i < _numObjectsInRoom; i++) {
- ptr = obims.findNext(MKID_BE('OBIM'));
+ ptr = obims.findNext(MKTAG('O','B','I','M'));
if (ptr == NULL)
error("Room %d missing image blocks(s)", _roomResource);
@@ -870,7 +870,7 @@ void ScummEngine_v4::resetRoomObjects() {
for (i = 0; i < _numObjectsInRoom; i++) {
od = &_objs[findLocalObjectSlot()];
- ptr = obcds.findNext(MKID_BE('OBCD'));
+ ptr = obcds.findNext(MKTAG('O','B','C','D'));
if (ptr == NULL)
error("Room %d missing object code block(s)", _roomResource);
@@ -887,7 +887,7 @@ void ScummEngine_v4::resetRoomObjects() {
for (i = 0; i < _numObjectsInRoom; i++) {
// In the PC Engine version of Loom, there aren't image blocks
// for all objects.
- ptr = obims.findNext(MKID_BE('OBIM'));
+ ptr = obims.findNext(MKTAG('O','B','I','M'));
if (ptr == NULL)
break;
@@ -991,11 +991,11 @@ void ScummEngine::resetRoomObject(ObjectData *od, const byte *room, const byte *
searchptr = room;
}
- cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), searchptr + od->OBCDoffset);
+ cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), searchptr + od->OBCDoffset);
if (cdhd == NULL)
error("Room %d missing CDHD blocks(s)", _roomResource);
if (od->OBIMoffset)
- imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), room + od->OBIMoffset);
+ imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), room + od->OBIMoffset);
od->flags = Gdi::dbAllowMaskOr;
@@ -1194,7 +1194,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
return (objptr + offset);
}
- return findResourceData(MKID_BE('OBNA'), objptr);
+ return findResourceData(MKTAG('O','B','N','A'), objptr);
}
void ScummEngine::setObjectName(int obj) {
@@ -1278,7 +1278,7 @@ const byte *ScummEngine::getOBIMFromObjectData(const ObjectData &od) {
if (od.fl_object_index) {
ptr = getResourceAddress(rtFlObject, od.fl_object_index);
- ptr = findResource(MKID_BE('OBIM'), ptr);
+ ptr = findResource(MKTAG('O','B','I','M'), ptr);
} else {
ptr = getResourceAddress(rtRoom, _roomResource);
if (ptr)
@@ -1288,23 +1288,23 @@ const byte *ScummEngine::getOBIMFromObjectData(const ObjectData &od) {
}
static const uint32 IMxx_tags[] = {
- MKID_BE('IM00'),
- MKID_BE('IM01'),
- MKID_BE('IM02'),
- MKID_BE('IM03'),
- MKID_BE('IM04'),
- MKID_BE('IM05'),
- MKID_BE('IM06'),
- MKID_BE('IM07'),
- MKID_BE('IM08'),
- MKID_BE('IM09'),
- MKID_BE('IM0A'),
- MKID_BE('IM0B'),
- MKID_BE('IM0C'),
- MKID_BE('IM0D'),
- MKID_BE('IM0E'),
- MKID_BE('IM0F'),
- MKID_BE('IM10')
+ MKTAG('I','M','0','0'),
+ MKTAG('I','M','0','1'),
+ MKTAG('I','M','0','2'),
+ MKTAG('I','M','0','3'),
+ MKTAG('I','M','0','4'),
+ MKTAG('I','M','0','5'),
+ MKTAG('I','M','0','6'),
+ MKTAG('I','M','0','7'),
+ MKTAG('I','M','0','8'),
+ MKTAG('I','M','0','9'),
+ MKTAG('I','M','0','A'),
+ MKTAG('I','M','0','B'),
+ MKTAG('I','M','0','C'),
+ MKTAG('I','M','0','D'),
+ MKTAG('I','M','0','E'),
+ MKTAG('I','M','0','F'),
+ MKTAG('I','M','1','0')
};
const byte *ScummEngine::getObjectImage(const byte *ptr, int state) {
@@ -1317,15 +1317,15 @@ const byte *ScummEngine::getObjectImage(const byte *ptr, int state) {
// The OBIM contains an IMAG, which in turn contains a WRAP, which contains
// an OFFS chunk and multiple BOMP/SMAP chunks. To find the right BOMP/SMAP,
// we use the offsets in the OFFS chunk,
- ptr = findResource(MKID_BE('IMAG'), ptr);
+ ptr = findResource(MKTAG('I','M','A','G'), ptr);
if (!ptr)
return 0;
- ptr = findResource(MKID_BE('WRAP'), ptr);
+ ptr = findResource(MKTAG('W','R','A','P'), ptr);
if (!ptr)
return 0;
- ptr = findResource(MKID_BE('OFFS'), ptr);
+ ptr = findResource(MKTAG('O','F','F','S'), ptr);
if (!ptr)
return 0;
@@ -1348,7 +1348,7 @@ int ScummEngine::getObjectImageCount(int object) {
return 0;
ptr = getOBIMFromObjectData(_objs[objnum]);
- imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), ptr);
+ imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr);
if (!imhd)
return 0;
@@ -1365,7 +1365,7 @@ int ScummEngine::getObjectImageCount(int object) {
int ScummEngine_v8::getObjectIdFromOBIM(const byte *obim) {
// In V8, IMHD has no obj_id, but rather a name string. We map the name
// back to an object id using a table derived from the DOBJ resource.
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim);
+ const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim);
ObjectNameId *found = (ObjectNameId *)bsearch(imhd->v8.name, _objectIDMap, _objectIDMapSize,
sizeof(ObjectNameId), (int (*)(const void*, const void*))strcmp);
assert(found);
@@ -1373,7 +1373,7 @@ int ScummEngine_v8::getObjectIdFromOBIM(const byte *obim) {
}
int ScummEngine_v7::getObjectIdFromOBIM(const byte *obim) {
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim);
+ const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim);
return READ_LE_UINT16(&imhd->v7.obj_id);
}
#endif
@@ -1382,7 +1382,7 @@ int ScummEngine::getObjectIdFromOBIM(const byte *obim) {
if (_game.features & GF_SMALL_HEADER)
return READ_LE_UINT16(obim + 6);
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim);
+ const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim);
return READ_LE_UINT16(&imhd->old.obj_id);
}
@@ -1400,7 +1400,7 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id,
if (findWhat & foCodeHeader) {
fo->obcd = obcdptr = getOBCDFromObject(id);
assert(obcdptr);
- fo->cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), obcdptr);
+ fo->cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), obcdptr);
}
if (findWhat & foImageHeader) {
fo->obim = obimptr = getOBIMFromObjectData(_objs[id2]);
@@ -1416,7 +1416,7 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id,
if (_game.features & GF_OLD_BUNDLE) {
numobj = roomptr[20];
} else {
- const RoomHeader *roomhdr = (const RoomHeader *)findResourceData(MKID_BE('RMHD'), roomptr);
+ const RoomHeader *roomhdr = (const RoomHeader *)findResourceData(MKTAG('R','M','H','D'), roomptr);
if (_game.version == 8)
numobj = READ_LE_UINT32(&(roomhdr->v8.numObjects));
@@ -1467,10 +1467,10 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id,
assert(searchptr);
ResourceIterator obcds(searchptr, (_game.features & GF_SMALL_HEADER) != 0);
for (i = 0; i < numobj; i++) {
- obcdptr = obcds.findNext(MKID_BE('OBCD'));
+ obcdptr = obcds.findNext(MKTAG('O','B','C','D'));
if (obcdptr == NULL)
error("findObjectInRoom: Not enough code blocks in room %d", room);
- cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), obcdptr);
+ cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), obcdptr);
if (_game.features & GF_SMALL_HEADER)
id2 = READ_LE_UINT16(obcdptr + 6);
@@ -1495,7 +1495,7 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id,
if (findWhat & foImageHeader) {
ResourceIterator obims(roomptr, (_game.features & GF_SMALL_HEADER) != 0);
for (i = 0; i < numobj; i++) {
- obimptr = obims.findNext(MKID_BE('OBIM'));
+ obimptr = obims.findNext(MKTAG('O','B','I','M'));
if (obimptr == NULL)
error("findObjectInRoom: Not enough image blocks in room %d", room);
obim_id = getObjectIdFromOBIM(obimptr);
@@ -1699,7 +1699,7 @@ void ScummEngine_v6::drawBlastObject(BlastObject *eo) {
if (!img)
img = getObjectImage(ptr, 1); // Backward compatibility with samnmax blast objects
assert(img);
- bomp = findResourceData(MKID_BE('BOMP'), img);
+ bomp = findResourceData(MKTAG('B','O','M','P'), img);
}
if (!bomp)
@@ -1843,7 +1843,7 @@ void ScummEngine::loadFlObject(uint object, uint room) {
char buf[32];
const byte *ptr = foir.obcd;
sprintf(buf, "roomobj-%d-", room);
- ptr = findResource(MKID_BE('VERB'), ptr);
+ ptr = findResource(MKTAG('V','E','R','B'), ptr);
dumpResource(buf, object, ptr);
}
@@ -1869,7 +1869,7 @@ void ScummEngine::loadFlObject(uint object, uint room) {
assert(flob);
// Copy object code + object image to floating object
- WRITE_UINT32(flob, MKID_BE('FLOB'));
+ WRITE_UINT32(flob, MKTAG('F','L','O','B'));
WRITE_BE_UINT32(flob + 4, flob_size);
memcpy(flob + 8, foir.obcd, obcd_size);
memcpy(flob + 8 + obcd_size, foir.obim, obim_size);
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 18784151b7..e81212fec8 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -1029,7 +1029,7 @@ void ScummEngine::setCurrentPalette(int palindex) {
void ScummEngine::setRoomPalette(int palindex, int room) {
const byte *roomptr = getResourceAddress(rtRoom, room);
assert(roomptr);
- const byte *pals = findResource(MKID_BE('PALS'), roomptr);
+ const byte *pals = findResource(MKTAG('P','A','L','S'), roomptr);
assert(pals);
const byte *rgbs = findPalInPals(pals, palindex);
assert(rgbs);
@@ -1040,11 +1040,11 @@ const byte *ScummEngine::findPalInPals(const byte *pal, int idx) {
const byte *offs;
uint32 size;
- pal = findResource(MKID_BE('WRAP'), pal);
+ pal = findResource(MKTAG('W','R','A','P'), pal);
if (pal == NULL)
return NULL;
- offs = findResourceData(MKID_BE('OFFS'), pal);
+ offs = findResourceData(MKTAG('O','F','F','S'), pal);
if (offs == NULL)
return NULL;
diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/player_towns.cpp
index 06f97fd671..8922ff1730 100644
--- a/engines/scumm/player_towns.cpp
+++ b/engines/scumm/player_towns.cpp
@@ -622,7 +622,7 @@ int Player_Towns_v2::getSoundStatus(int sound) const {
void Player_Towns_v2::startSound(int sound) {
uint8 *ptr = _vm->getResourceAddress(rtSound, sound);
- if (READ_BE_UINT32(ptr) == MKID_BE('TOWS')) {
+ if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S')) {
_soundOverride[sound].type = 7;
uint8 velo = _soundOverride[sound].velo ? _soundOverride[sound].velo - 1: (ptr[10] + ptr[11] + 1) >> 1;
uint8 pan = _soundOverride[sound].pan ? _soundOverride[sound].pan - 1 : 64;
@@ -630,7 +630,7 @@ void Player_Towns_v2::startSound(int sound) {
_soundOverride[sound].velo = _soundOverride[sound].pan = 0;
playPcmTrack(sound, ptr + 8, velo, pan, ptr[52], pri);
- } else if (READ_BE_UINT32(ptr) == MKID_BE('SBL ')) {
+ } else if (READ_BE_UINT32(ptr) == MKTAG('S','B','L',' ')) {
_soundOverride[sound].type = 5;
playVocTrack(ptr + 27);
@@ -680,7 +680,7 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
case 258:
if (_soundOverride[args[1]].type == 0) {
ptr = _vm->getResourceAddress(rtSound, args[1]);
- if (READ_BE_UINT32(ptr) == MKID_BE('TOWS'))
+ if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S'))
_soundOverride[args[1]].type = 7;
}
if (_soundOverride[args[1]].type == 7) {
@@ -692,7 +692,7 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) {
case 259:
if (_soundOverride[args[1]].type == 0) {
ptr = _vm->getResourceAddress(rtSound, args[1]);
- if (READ_BE_UINT32(ptr) == MKID_BE('TOWS'))
+ if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S'))
_soundOverride[args[1]].type = 7;
}
if (_soundOverride[args[1]].type == 7) {
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 5bc643a5d1..c872a83d14 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -259,26 +259,26 @@ void ScummEngine::readIndexFile() {
if (_fileHandle->eos() || _fileHandle->err())
break;
switch (blocktype) {
- case MKID_BE('DOBJ'):
+ case MKTAG('D','O','B','J'):
_numGlobalObjects = _fileHandle->readUint16LE();
itemsize -= 2;
break;
- case MKID_BE('DROO'):
+ case MKTAG('D','R','O','O'):
_numRooms = _fileHandle->readUint16LE();
itemsize -= 2;
break;
- case MKID_BE('DSCR'):
+ case MKTAG('D','S','C','R'):
_numScripts = _fileHandle->readUint16LE();
itemsize -= 2;
break;
- case MKID_BE('DCOS'):
+ case MKTAG('D','C','O','S'):
_numCostumes = _fileHandle->readUint16LE();
itemsize -= 2;
break;
- case MKID_BE('DSOU'):
+ case MKTAG('D','S','O','U'):
_numSounds = _fileHandle->readUint16LE();
itemsize -= 2;
break;
@@ -351,7 +351,7 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) {
int num;
char *ptr;
switch (blocktype) {
- case MKID_BE('ANAM'): // Used by: The Dig, FT
+ case MKTAG('A','N','A','M'): // Used by: The Dig, FT
debug(9, "found ANAM block, reading audio names");
num = _fileHandle->readUint16LE();
ptr = (char*)malloc(num * 9);
@@ -359,7 +359,7 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) {
_imuseDigital->setAudioNames(num, ptr);
break;
- case MKID_BE('DRSC'): // Used by: COMI
+ case MKTAG('D','R','S','C'): // Used by: COMI
readResTypeList(rtRoomScripts);
break;
@@ -372,37 +372,37 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) {
void ScummEngine_v70he::readIndexBlock(uint32 blocktype, uint32 itemsize) {
int i;
switch (blocktype) {
- case MKID_BE('DIRI'):
+ case MKTAG('D','I','R','I'):
readResTypeList(rtRoomImage);
break;
- case MKID_BE('DIRM'):
+ case MKTAG('D','I','R','M'):
readResTypeList(rtImage);
break;
- case MKID_BE('DIRT'):
+ case MKTAG('D','I','R','T'):
readResTypeList(rtTalkie);
break;
- case MKID_BE('DLFL'):
+ case MKTAG('D','L','F','L'):
i = _fileHandle->readUint16LE();
_fileHandle->seek(-2, SEEK_CUR);
_heV7RoomOffsets = (byte *)calloc(2 + (i * 4), 1);
_fileHandle->read(_heV7RoomOffsets, (2 + (i * 4)) );
break;
- case MKID_BE('DISK'):
+ case MKTAG('D','I','S','K'):
i = _fileHandle->readUint16LE();
_heV7DiskOffsets = (byte *)calloc(i, 1);
_fileHandle->read(_heV7DiskOffsets, i);
break;
- case MKID_BE('SVER'):
+ case MKTAG('S','V','E','R'):
// Index version number
_fileHandle->seek(itemsize - 8, SEEK_CUR);
break;
- case MKID_BE('INIB'):
+ case MKTAG('I','N','I','B'):
_fileHandle->seek(itemsize - 8, SEEK_CUR);
debug(2, "INIB index block not yet handled, skipping");
break;
@@ -415,17 +415,17 @@ void ScummEngine_v70he::readIndexBlock(uint32 blocktype, uint32 itemsize) {
void ScummEngine::readIndexBlock(uint32 blocktype, uint32 itemsize) {
int i;
switch (blocktype) {
- case MKID_BE('DCHR'):
- case MKID_BE('DIRF'):
+ case MKTAG('D','C','H','R'):
+ case MKTAG('D','I','R','F'):
readResTypeList(rtCharset);
break;
- case MKID_BE('DOBJ'):
+ case MKTAG('D','O','B','J'):
debug(9, "found DOBJ block, reading object table");
readGlobalObjects();
break;
- case MKID_BE('RNAM'):
+ case MKTAG('R','N','A','M'):
// Names of rooms. Maybe we should put them into a table, for use by the debugger?
if (_game.heversion >= 80) {
for (int room; (room = _fileHandle->readUint16LE()); ) {
@@ -449,32 +449,32 @@ void ScummEngine::readIndexBlock(uint32 blocktype, uint32 itemsize) {
}
break;
- case MKID_BE('DROO'):
- case MKID_BE('DIRR'):
+ case MKTAG('D','R','O','O'):
+ case MKTAG('D','I','R','R'):
readResTypeList(rtRoom);
break;
- case MKID_BE('DSCR'):
- case MKID_BE('DIRS'):
+ case MKTAG('D','S','C','R'):
+ case MKTAG('D','I','R','S'):
readResTypeList(rtScript);
break;
- case MKID_BE('DCOS'):
- case MKID_BE('DIRC'):
+ case MKTAG('D','C','O','S'):
+ case MKTAG('D','I','R','C'):
readResTypeList(rtCostume);
break;
- case MKID_BE('MAXS'):
+ case MKTAG('M','A','X','S'):
readMAXS(itemsize);
allocateArrays();
break;
- case MKID_BE('DIRN'):
- case MKID_BE('DSOU'):
+ case MKTAG('D','I','R','N'):
+ case MKTAG('D','S','O','U'):
readResTypeList(rtSound);
break;
- case MKID_BE('AARY'):
+ case MKTAG('A','A','R','Y'):
readArrayFromIndexFile();
break;
@@ -1287,14 +1287,14 @@ void ScummEngine::allocateArrays() {
_arraySlot = (byte *)calloc(_numArray, 1);
}
- _res->allocResTypeData(rtCostume, (_game.features & GF_NEW_COSTUMES) ? MKID_BE('AKOS') : MKID_BE('COST'),
+ _res->allocResTypeData(rtCostume, (_game.features & GF_NEW_COSTUMES) ? MKTAG('A','K','O','S') : MKTAG('C','O','S','T'),
_numCostumes, "costume", 1);
- _res->allocResTypeData(rtRoom, MKID_BE('ROOM'), _numRooms, "room", 1);
- _res->allocResTypeData(rtRoomImage, MKID_BE('RMIM'), _numRooms, "room image", 1);
- _res->allocResTypeData(rtRoomScripts, MKID_BE('RMSC'), _numRooms, "room script", 1);
- _res->allocResTypeData(rtSound, MKID_BE('SOUN'), _numSounds, "sound", 2);
- _res->allocResTypeData(rtScript, MKID_BE('SCRP'), _numScripts, "script", 1);
- _res->allocResTypeData(rtCharset, MKID_BE('CHAR'), _numCharsets, "charset", 1);
+ _res->allocResTypeData(rtRoom, MKTAG('R','O','O','M'), _numRooms, "room", 1);
+ _res->allocResTypeData(rtRoomImage, MKTAG('R','M','I','M'), _numRooms, "room image", 1);
+ _res->allocResTypeData(rtRoomScripts, MKTAG('R','M','S','C'), _numRooms, "room script", 1);
+ _res->allocResTypeData(rtSound, MKTAG('S','O','U','N'), _numSounds, "sound", 2);
+ _res->allocResTypeData(rtScript, MKTAG('S','C','R','P'), _numScripts, "script", 1);
+ _res->allocResTypeData(rtCharset, MKTAG('C','H','A','R'), _numCharsets, "charset", 1);
_res->allocResTypeData(rtObjectName, 0, _numNewNames, "new name", 0);
_res->allocResTypeData(rtInventory, 0, _numInventory, "inventory", 0);
_res->allocResTypeData(rtTemp, 0, 10, "temp", 0);
@@ -1304,8 +1304,8 @@ void ScummEngine::allocateArrays() {
_res->allocResTypeData(rtString, 0, _numArray, "array", 0);
_res->allocResTypeData(rtFlObject, 0, _numFlObject, "flobject", 0);
_res->allocResTypeData(rtMatrix, 0, 10, "boxes", 0);
- _res->allocResTypeData(rtImage, MKID_BE('AWIZ'), _numImages, "images", 1);
- _res->allocResTypeData(rtTalkie, MKID_BE('TLKE'), _numTalkies, "talkie", 1);
+ _res->allocResTypeData(rtImage, MKTAG('A','W','I','Z'), _numImages, "images", 1);
+ _res->allocResTypeData(rtTalkie, MKTAG('T','L','K','E'), _numTalkies, "talkie", 1);
}
void ScummEngine_v70he::allocateArrays() {
@@ -1464,35 +1464,35 @@ const byte *findResourceSmall(uint32 tag, const byte *searchin) {
uint16 newTag2Old(uint32 newTag) {
switch (newTag) {
- case (MKID_BE('RMHD')):
+ case (MKTAG('R','M','H','D')):
return (0x4448); // HD
- case (MKID_BE('IM00')):
+ case (MKTAG('I','M','0','0')):
return (0x4D42); // BM
- case (MKID_BE('EXCD')):
+ case (MKTAG('E','X','C','D')):
return (0x5845); // EX
- case (MKID_BE('ENCD')):
+ case (MKTAG('E','N','C','D')):
return (0x4E45); // EN
- case (MKID_BE('SCAL')):
+ case (MKTAG('S','C','A','L')):
return (0x4153); // SA
- case (MKID_BE('LSCR')):
+ case (MKTAG('L','S','C','R')):
return (0x534C); // LS
- case (MKID_BE('OBCD')):
+ case (MKTAG('O','B','C','D')):
return (0x434F); // OC
- case (MKID_BE('OBIM')):
+ case (MKTAG('O','B','I','M')):
return (0x494F); // OI
- case (MKID_BE('SMAP')):
+ case (MKTAG('S','M','A','P')):
return (0x4D42); // BM
- case (MKID_BE('CLUT')):
+ case (MKTAG('C','L','U','T')):
return (0x4150); // PA
- case (MKID_BE('BOXD')):
+ case (MKTAG('B','O','X','D')):
return (0x5842); // BX
- case (MKID_BE('CYCL')):
+ case (MKTAG('C','Y','C','L')):
return (0x4343); // CC
- case (MKID_BE('EPAL')):
+ case (MKTAG('E','P','A','L')):
return (0x5053); // SP
- case (MKID_BE('TILE')):
+ case (MKTAG('T','I','L','E')):
return (0x4C54); // TL
- case (MKID_BE('ZP00')):
+ case (MKTAG('Z','P','0','0')):
return (0x505A); // ZP
default:
return (0);
diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp
index 58b6cdb105..06fa0f2c39 100644
--- a/engines/scumm/room.cpp
+++ b/engines/scumm/room.cpp
@@ -264,7 +264,7 @@ void ScummEngine::setupRoomSubBlocks() {
//
// Determine the room dimensions (width/height)
//
- rmhd = (const RoomHeader *)findResourceData(MKID_BE('RMHD'), roomptr);
+ rmhd = (const RoomHeader *)findResourceData(MKTAG('R','M','H','D'), roomptr);
if (_game.version == 8) {
_roomWidth = READ_LE_UINT32(&(rmhd->v8.width));
@@ -286,18 +286,18 @@ void ScummEngine::setupRoomSubBlocks() {
if (_game.version == 8) {
_IM00_offs = getObjectImage(roomptr, 1) - roomptr;
} else if (_game.features & GF_SMALL_HEADER) {
- _IM00_offs = findResourceData(MKID_BE('IM00'), roomptr) - roomptr;
+ _IM00_offs = findResourceData(MKTAG('I','M','0','0'), roomptr) - roomptr;
} else if (_game.heversion >= 70) {
byte *roomImagePtr = getResourceAddress(rtRoomImage, _roomResource);
- _IM00_offs = findResource(MKID_BE('IM00'), roomImagePtr) - roomImagePtr;
+ _IM00_offs = findResource(MKTAG('I','M','0','0'), roomImagePtr) - roomImagePtr;
} else {
- _IM00_offs = findResource(MKID_BE('IM00'), findResource(MKID_BE('RMIM'), roomptr)) - roomptr;
+ _IM00_offs = findResource(MKTAG('I','M','0','0'), findResource(MKTAG('R','M','I','M'), roomptr)) - roomptr;
}
//
// Look for an exit script
//
- ptr = findResourceData(MKID_BE('EXCD'), roomResPtr);
+ ptr = findResourceData(MKTAG('E','X','C','D'), roomResPtr);
if (ptr)
_EXCD_offs = ptr - roomResPtr;
if (_dumpScripts && _EXCD_offs)
@@ -306,7 +306,7 @@ void ScummEngine::setupRoomSubBlocks() {
//
// Look for an entry script
//
- ptr = findResourceData(MKID_BE('ENCD'), roomResPtr);
+ ptr = findResourceData(MKTAG('E','N','C','D'), roomResPtr);
if (ptr)
_ENCD_offs = ptr - roomResPtr;
if (_dumpScripts && _ENCD_offs)
@@ -326,7 +326,7 @@ void ScummEngine::setupRoomSubBlocks() {
if (_game.features & GF_SMALL_HEADER) {
ResourceIterator localScriptIterator(searchptr, true);
- while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) {
+ while ((ptr = localScriptIterator.findNext(MKTAG('L','S','C','R'))) != NULL) {
int id = 0;
ptr += _resourceHeaderSize; /* skip tag & size */
id = ptr[0];
@@ -341,7 +341,7 @@ void ScummEngine::setupRoomSubBlocks() {
}
} else if (_game.heversion >= 90) {
ResourceIterator localScriptIterator2(searchptr, false);
- while ((ptr = localScriptIterator2.findNext(MKID_BE('LSC2'))) != NULL) {
+ while ((ptr = localScriptIterator2.findNext(MKTAG('L','S','C','2'))) != NULL) {
int id = 0;
ptr += _resourceHeaderSize; /* skip tag & size */
@@ -359,7 +359,7 @@ void ScummEngine::setupRoomSubBlocks() {
}
ResourceIterator localScriptIterator(searchptr, false);
- while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) {
+ while ((ptr = localScriptIterator.findNext(MKTAG('L','S','C','R'))) != NULL) {
int id = 0;
ptr += _resourceHeaderSize; /* skip tag & size */
@@ -376,7 +376,7 @@ void ScummEngine::setupRoomSubBlocks() {
} else {
ResourceIterator localScriptIterator(searchptr, false);
- while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) {
+ while ((ptr = localScriptIterator.findNext(MKTAG('L','S','C','R'))) != NULL) {
int id = 0;
ptr += _resourceHeaderSize; /* skip tag & size */
@@ -403,18 +403,18 @@ void ScummEngine::setupRoomSubBlocks() {
}
// Locate the EGA palette (currently unused).
- ptr = findResourceData(MKID_BE('EPAL'), roomptr);
+ ptr = findResourceData(MKTAG('E','P','A','L'), roomptr);
if (ptr)
_EPAL_offs = ptr - roomptr;
// Locate the standard room palette (for V3-V5 games).
- ptr = findResourceData(MKID_BE('CLUT'), roomptr);
+ ptr = findResourceData(MKTAG('C','L','U','T'), roomptr);
if (ptr)
_CLUT_offs = ptr - roomptr;
// Locate the standard room palettes (for V6+ games).
if (_game.version >= 6) {
- ptr = findResource(MKID_BE('PALS'), roomptr);
+ ptr = findResource(MKTAG('P','A','L','S'), roomptr);
if (ptr) {
_PALS_offs = ptr - roomptr;
}
@@ -425,7 +425,7 @@ void ScummEngine::setupRoomSubBlocks() {
if (_game.version == 8)
trans = (byte)READ_LE_UINT32(&(rmhd->v8.transparency));
else {
- ptr = findResourceData(MKID_BE('TRNS'), roomptr);
+ ptr = findResourceData(MKTAG('T','R','N','S'), roomptr);
if (ptr)
trans = ptr[0];
else
@@ -434,7 +434,7 @@ void ScummEngine::setupRoomSubBlocks() {
// Actor Palette in HE 70 games
if (_game.heversion == 70) {
- ptr = findResourceData(MKID_BE('REMP'), roomptr);
+ ptr = findResourceData(MKTAG('R','E','M','P'), roomptr);
if (ptr) {
for (i = 0; i < 256; i++)
_HEV7ActorPalette[i] = *ptr++;
@@ -485,7 +485,7 @@ void ScummEngine::resetRoomSubBlocks() {
_res->nukeResource(rtMatrix, 1);
_res->nukeResource(rtMatrix, 2);
if (_game.features & GF_SMALL_HEADER) {
- ptr = findResourceData(MKID_BE('BOXD'), roomptr);
+ ptr = findResourceData(MKTAG('B','O','X','D'), roomptr);
if (ptr) {
byte numOfBoxes = *ptr;
int size;
@@ -506,21 +506,21 @@ void ScummEngine::resetRoomSubBlocks() {
}
} else {
- ptr = findResourceData(MKID_BE('BOXD'), roomptr);
+ ptr = findResourceData(MKTAG('B','O','X','D'), roomptr);
if (ptr) {
int size = getResourceDataSize(ptr);
_res->createResource(rtMatrix, 2, size);
roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResourceData(MKID_BE('BOXD'), roomptr);
+ ptr = findResourceData(MKTAG('B','O','X','D'), roomptr);
memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
}
- ptr = findResourceData(MKID_BE('BOXM'), roomptr);
+ ptr = findResourceData(MKTAG('B','O','X','M'), roomptr);
if (ptr) {
int size = getResourceDataSize(ptr);
_res->createResource(rtMatrix, 1, size);
roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResourceData(MKID_BE('BOXM'), roomptr);
+ ptr = findResourceData(MKTAG('B','O','X','M'), roomptr);
memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
}
}
@@ -531,7 +531,7 @@ void ScummEngine::resetRoomSubBlocks() {
for (i = 1; i < _res->num[rtScaleTable]; i++)
_res->nukeResource(rtScaleTable, i);
- ptr = findResourceData(MKID_BE('SCAL'), roomptr);
+ ptr = findResourceData(MKTAG('S','C','A','L'), roomptr);
if (ptr) {
int s1, s2, y1, y2;
if (_game.version == 8) {
@@ -558,7 +558,7 @@ void ScummEngine::resetRoomSubBlocks() {
// Color cycling
// HE 7.0 games load resources but don't use them.
if (_game.version >= 4 && _game.heversion <= 62) {
- ptr = findResourceData(MKID_BE('CYCL'), roomptr);
+ ptr = findResourceData(MKTAG('C','Y','C','L'), roomptr);
if (ptr) {
initCycl(ptr);
}
@@ -567,7 +567,7 @@ void ScummEngine::resetRoomSubBlocks() {
#ifdef ENABLE_HE
// Polygons in HE 80+ games
if (_game.heversion >= 80) {
- ptr = findResourceData(MKID_BE('POLD'), roomptr);
+ ptr = findResourceData(MKTAG('P','O','L','D'), roomptr);
if (ptr) {
((ScummEngine_v71he *)this)->_wiz->polygonLoad(ptr);
}
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index fb34255683..3bfe51a77b 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -154,7 +154,7 @@ void ScummEngine::requestLoad(int slot) {
}
static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) {
- hdr.type = MKID_BE('SCVM');
+ hdr.type = MKTAG('S','C','V','M');
hdr.size = 0;
hdr.ver = CURRENT_VER;
@@ -308,7 +308,7 @@ static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &h
hdr.size = in->readUint32LE();
hdr.ver = in->readUint32LE();
in->read(hdr.name, sizeof(hdr.name));
- return !in->err() && hdr.type == MKID_BE('SCVM');
+ return !in->err() && hdr.type == MKTAG('S','C','V','M');
}
bool ScummEngine::loadState(int slot, bool compat) {
@@ -746,7 +746,7 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos
SaveInfoSection section;
section.type = file->readUint32BE();
- if (section.type != MKID_BE('INFO')) {
+ if (section.type != MKTAG('I','N','F','O')) {
return false;
}
@@ -793,7 +793,7 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos
void ScummEngine::saveInfos(Common::WriteStream* file) {
SaveInfoSection section;
- section.type = MKID_BE('INFO');
+ section.type = MKTAG('I','N','F','O');
section.version = INFOSECTION_VERSION;
section.size = SaveInfoSectionSize;
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index c6c1f5f58f..9e02f126cd 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -174,7 +174,7 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) {
else if (_game.features & GF_SMALL_HEADER)
verbptr = objptr + 19;
else
- verbptr = findResource(MKID_BE('VERB'), objptr);
+ verbptr = findResource(MKTAG('V','E','R','B'), objptr);
assert(verbptr);
@@ -921,7 +921,7 @@ void ScummEngine::runExitScript() {
// be limiting ourselves to strictly reading the size from the header?
if (_game.id == GID_INDY3 && !(_game.features & GF_OLD_BUNDLE)) {
byte *roomptr = getResourceAddress(rtRoom, _roomResource);
- const byte *excd = findResourceData(MKID_BE('EXCD'), roomptr) - _resourceHeaderSize;
+ const byte *excd = findResourceData(MKTAG('E','X','C','D'), roomptr) - _resourceHeaderSize;
if (!excd || (getResourceDataSize(excd) < 1)) {
debug(2, "Exit-%d is empty", _roomResource);
return;
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index abe397ba7e..b2df1d0baa 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -3014,7 +3014,7 @@ void ScummEngine_v6::o6_setBoxSet() {
ResourceIterator boxds(room, false);
for (i = 0; i < arg; i++)
- boxd = boxds.findNext(MKID_BE('BOXD'));
+ boxd = boxds.findNext(MKTAG('B','O','X','D'));
if (!boxd)
error("ScummEngine_v6::o6_setBoxSet: Can't find dboxes for set %d", arg);
@@ -3027,7 +3027,7 @@ void ScummEngine_v6::o6_setBoxSet() {
ResourceIterator boxms(room, false);
for (i = 0; i < arg; i++)
- boxm = boxms.findNext(MKID_BE('BOXM'));
+ boxm = boxms.findNext(MKTAG('B','O','X','M'));
if (!boxm)
error("ScummEngine_v6::o6_setBoxSet: Can't find mboxes for set %d", arg);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 7b98c86506..5aea36ef66 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1577,7 +1577,7 @@ void ScummEngine_v3::resetScumm() {
// Load tile set and palette for the distaff
byte *roomptr = getResourceAddress(rtRoom, 90);
assert(roomptr);
- const byte *palPtr = findResourceData(MKID_BE('CLUT'), roomptr);
+ const byte *palPtr = findResourceData(MKTAG('C','L','U','T'), roomptr);
assert(palPtr - 4);
setPCEPaletteFromPtr(palPtr);
_gdi->_distaff = true;
diff --git a/engines/scumm/smush/imuse_channel.cpp b/engines/scumm/smush/imuse_channel.cpp
index a838fdba56..32fa99a870 100644
--- a/engines/scumm/smush/imuse_channel.cpp
+++ b/engines/scumm/smush/imuse_channel.cpp
@@ -29,6 +29,7 @@
#include "scumm/scumm.h" // For DEBUG_SMUSH
#include "scumm/util.h"
#include "scumm/smush/channel.h"
+#include "scumm/imuse_digi/dimuse_codecs.h" // for decode12BitsSample
namespace Scumm {
@@ -64,7 +65,7 @@ bool ImuseChannel::appendData(Common::SeekableReadStream &b, int32 size) {
assert(size > 8);
uint32 imus_type = b.readUint32BE();
/*uint32 imus_size =*/ b.readUint32BE();
- if (imus_type != MKID_BE('iMUS'))
+ if (imus_type != MKTAG('i','M','U','S'))
error("Invalid Chunk for imuse_channel");
size -= 8;
_tbufferSize = size;
@@ -115,7 +116,7 @@ bool ImuseChannel::handleMap(byte *data) {
size -= 8;
switch (subType) {
- case MKID_BE('FRMT'):
+ case MKTAG('F','R','M','T'):
if (subSize != 20)
error("invalid size for FRMT Chunk");
//uint32 imuse_start = READ_BE_UINT32(data);
@@ -125,14 +126,14 @@ bool ImuseChannel::handleMap(byte *data) {
_channels = READ_BE_UINT32(data+16);
assert(_channels == 1 || _channels == 2);
break;
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
// Ignore this
break;
- case MKID_BE('REGN'):
+ case MKTAG('R','E','G','N'):
if (subSize != 8)
error("invalid size for REGN Chunk");
break;
- case MKID_BE('STOP'):
+ case MKTAG('S','T','O','P'):
if (subSize != 4)
error("invalid size for STOP Chunk");
break;
@@ -171,28 +172,10 @@ void ImuseChannel::decode() {
}
}
- // FIXME: Code duplication! See decode12BitsSample() in imuse_digi/dimuse_codecs.cpp
-
- int loop_size = _sbufferSize / 3;
- int new_size = loop_size * 4;
- byte *keep, *decoded;
- uint32 value;
- keep = decoded = (byte *)malloc(new_size);
- assert(keep);
- unsigned char * source = _sbuffer;
-
- while (loop_size--) {
- byte v1 = *source++;
- byte v2 = *source++;
- byte v3 = *source++;
- value = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
- WRITE_BE_UINT16(decoded, value); decoded += 2;
- value = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
- WRITE_BE_UINT16(decoded, value); decoded += 2;
- }
+ byte *keep;
+ _sbufferSize = BundleCodecs::decode12BitsSample(_sbuffer, &keep, _sbufferSize);
free(_sbuffer);
_sbuffer = (byte *)keep;
- _sbufferSize = new_size;
}
bool ImuseChannel::handleSubTags(int32 &offset) {
@@ -201,13 +184,13 @@ bool ImuseChannel::handleSubTags(int32 &offset) {
uint32 size = READ_BE_UINT32(_tbuffer + offset + 4);
uint32 available_size = _tbufferSize - offset;
switch (type) {
- case MKID_BE('MAP '):
+ case MKTAG('M','A','P',' '):
_inData = false;
if (available_size >= (size + 8)) {
handleMap((byte *)_tbuffer + offset);
}
break;
- case MKID_BE('DATA'):
+ case MKTAG('D','A','T','A'):
_inData = true;
_dataSize = size;
offset += 8;
diff --git a/engines/scumm/smush/saud_channel.cpp b/engines/scumm/smush/saud_channel.cpp
index 94df70633f..04ed955224 100644
--- a/engines/scumm/smush/saud_channel.cpp
+++ b/engines/scumm/smush/saud_channel.cpp
@@ -50,7 +50,7 @@ bool SaudChannel::handleSubTags(int32 &offset) {
uint32 available_size = _tbufferSize - offset;
switch (type) {
- case MKID_BE('STRK'):
+ case MKTAG('S','T','R','K'):
_inData = false;
if (available_size >= (size + 8)) {
int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
@@ -60,14 +60,14 @@ bool SaudChannel::handleSubTags(int32 &offset) {
} else
return false;
break;
- case MKID_BE('SMRK'):
+ case MKTAG('S','M','R','K'):
_inData = false;
if (available_size >= (size + 8))
_markReached = true;
else
return false;
break;
- case MKID_BE('SHDR'):
+ case MKTAG('S','H','D','R'):
_inData = false;
if (available_size >= (size + 8)) {
int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
@@ -76,7 +76,7 @@ bool SaudChannel::handleSubTags(int32 &offset) {
} else
return false;
break;
- case MKID_BE('SDAT'):
+ case MKTAG('S','D','A','T'):
_inData = true;
_dataSize = size;
offset += 8;
@@ -123,7 +123,7 @@ bool SaudChannel::appendData(Common::SeekableReadStream &b, int32 size) {
assert(size > 8);
uint32 saud_type = b.readUint32BE();
/*uint32 saud_size =*/ b.readUint32BE();
- if (saud_type != MKID_BE('SAUD'))
+ if (saud_type != MKTAG('S','A','U','D'))
error("Invalid Chunk for SaudChannel : %X", saud_type);
size -= 8;
_dataSize = -2;
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index fe2b9d99ff..0e4f588593 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -190,7 +190,7 @@ static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_enc
theFile.read(filebuffer, length);
filebuffer[length] = 0;
- if (is_encoded && READ_BE_UINT32(filebuffer) == MKID_BE('ETRS')) {
+ if (is_encoded && READ_BE_UINT32(filebuffer) == MKTAG('E','T','R','S')) {
assert(length > ETRS_HEADER_LENGTH);
length -= ETRS_HEADER_LENGTH;
for (int i = 0; i < length; ++i) {
@@ -507,7 +507,7 @@ void SmushPlayer::handleTextResource(uint32 subType, int32 subSize, Common::Seek
const char *str;
char *string = NULL, *string2 = NULL;
- if (subType == MKID_BE('TEXT')) {
+ if (subType == MKTAG('T','E','X','T')) {
string = (char *)malloc(subSize - 16);
str = string;
b.read(string, subSize - 16);
@@ -845,40 +845,40 @@ void SmushPlayer::handleFrame(int32 frameSize, Common::SeekableReadStream &b) {
const int32 subSize = b.readUint32BE();
const int32 subOffset = b.pos();
switch (subType) {
- case MKID_BE('NPAL'):
+ case MKTAG('N','P','A','L'):
handleNewPalette(subSize, b);
break;
- case MKID_BE('FOBJ'):
+ case MKTAG('F','O','B','J'):
handleFrameObject(subSize, b);
break;
#ifdef USE_ZLIB
- case MKID_BE('ZFOB'):
+ case MKTAG('Z','F','O','B'):
handleZlibFrameObject(subSize, b);
break;
#endif
- case MKID_BE('PSAD'):
+ case MKTAG('P','S','A','D'):
if (!_compressedFileMode)
handleSoundFrame(subSize, b);
break;
- case MKID_BE('TRES'):
+ case MKTAG('T','R','E','S'):
handleTextResource(subType, subSize, b);
break;
- case MKID_BE('XPAL'):
+ case MKTAG('X','P','A','L'):
handleDeltaPalette(subSize, b);
break;
- case MKID_BE('IACT'):
+ case MKTAG('I','A','C','T'):
handleIACT(subSize, b);
break;
- case MKID_BE('STOR'):
+ case MKTAG('S','T','O','R'):
handleStore(subSize, b);
break;
- case MKID_BE('FTCH'):
+ case MKTAG('F','T','C','H'):
handleFetch(subSize, b);
break;
- case MKID_BE('SKIP'):
+ case MKTAG('S','K','I','P'):
_vm->_insane->procSKIP(subSize, b);
break;
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
handleTextResource(subType, subSize, b);
break;
default:
@@ -990,7 +990,7 @@ void SmushPlayer::parseNextFrame() {
const uint32 subType = _base->readUint32BE();
const int32 subSize = _base->readUint32BE();
const int32 subOffset = _base->pos();
- assert(subType == MKID_BE('AHDR'));
+ assert(subType == MKTAG('A','H','D','R'));
handleAnimHeader(subSize, *_base);
_base->seek(subOffset + subSize, SEEK_SET);
@@ -1029,10 +1029,10 @@ void SmushPlayer::parseNextFrame() {
debug(3, "Chunk: %s at %x", tag2str(subType), subOffset);
switch (subType) {
- case MKID_BE('AHDR'): // FT INSANE may seek file to the beginning
+ case MKTAG('A','H','D','R'): // FT INSANE may seek file to the beginning
handleAnimHeader(subSize, *_base);
break;
- case MKID_BE('FRME'):
+ case MKTAG('F','R','M','E'):
handleFrame(subSize, *_base);
break;
default:
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 0051319151..54f35c1969 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -206,7 +206,7 @@ void Sound::playSound(int soundID) {
// Support for SFX in Monkey Island 1, Mac version
// This is rather hackish right now, but works OK. SFX are not sounding
// 100% correct, though, not sure right now what is causing this.
- else if (READ_BE_UINT32(ptr) == MKID_BE('Mac1')) {
+ else if (READ_BE_UINT32(ptr) == MKTAG('M','a','c','1')) {
// Read info from the header
size = READ_BE_UINT32(ptr+0x60);
rate = READ_BE_UINT16(ptr+0x64);
@@ -245,7 +245,7 @@ void Sound::playSound(int soundID) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
}
// Support for sampled sound effects in Monkey Island 1 and 2
- else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKID_BE('SBL ')) {
+ else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKTAG('S','B','L',' ')) {
debugC(DEBUG_SOUND, "Using SBL sound effect");
// SBL resources essentially contain VOC sound data.
@@ -316,7 +316,7 @@ void Sound::playSound(int soundID) {
stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
_mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
}
- else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKID_BE('SOUN')) {
+ else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKTAG('S','O','U','N')) {
if (_vm->_game.version != 3)
ptr += 2;
@@ -415,7 +415,7 @@ void Sound::playSound(int soundID) {
// Rather it seems that starting a new music is supposed to
// automatically stop the old song.
if (_vm->_imuse) {
- if (READ_BE_UINT32(ptr) != MKID_BE('ASFX'))
+ if (READ_BE_UINT32(ptr) != MKTAG('A','S','F','X'))
_vm->_imuse->stopAllSounds();
}
}
@@ -1090,15 +1090,15 @@ int ScummEngine::readSoundResource(int idx) {
debugC(DEBUG_RESOURCE, " basetag: %s, total_size=%d", tag2str(basetag), total_size);
switch (basetag) {
- case MKID_BE('MIDI'):
- case MKID_BE('iMUS'):
+ case MKTAG('M','I','D','I'):
+ case MKTAG('i','M','U','S'):
if (_musicType != MDT_PCSPK && _musicType != MDT_PCJR) {
_fileHandle->seek(-8, SEEK_CUR);
_fileHandle->read(_res->createResource(rtSound, idx, total_size + 8), total_size + 8);
return 1;
}
break;
- case MKID_BE('SOU '):
+ case MKTAG('S','O','U',' '):
best_pri = -1;
while (pos < total_size) {
tag = _fileHandle->readUint32BE();
@@ -1108,32 +1108,32 @@ int ScummEngine::readSoundResource(int idx) {
pri = -1;
switch (tag) {
- case MKID_BE('TOWS'):
+ case MKTAG('T','O','W','S'):
pri = 16;
break;
- case MKID_BE('SBL '):
+ case MKTAG('S','B','L',' '):
pri = 15;
break;
- case MKID_BE('ADL '):
+ case MKTAG('A','D','L',' '):
pri = 1;
if (_musicType == MDT_ADLIB)
pri = 10;
break;
- case MKID_BE('AMI '):
+ case MKTAG('A','M','I',' '):
pri = 3;
break;
- case MKID_BE('ROL '):
+ case MKTAG('R','O','L',' '):
pri = 3;
if (_native_mt32)
pri = 5;
break;
- case MKID_BE('GMD '):
+ case MKTAG('G','M','D',' '):
pri = 4;
break;
- case MKID_BE('MAC '): // Occurs in Mac MI2, FOA
+ case MKTAG('M','A','C',' '): // Occurs in Mac MI2, FOA
pri = 2;
break;
- case MKID_BE('SPK '):
+ case MKTAG('S','P','K',' '):
pri = -1;
// if (_musicType == MDT_PCSPK || _musicType == MDT_PCJR)
// pri = 11;
@@ -1163,7 +1163,7 @@ int ScummEngine::readSoundResource(int idx) {
return 1;
}
break;
- case MKID_BE('Mac0'):
+ case MKTAG('M','a','c','0'):
_fileHandle->seek(-12, SEEK_CUR);
total_size = _fileHandle->readUint32BE() - 8;
ptr = (byte *)calloc(total_size, 1);
@@ -1173,11 +1173,11 @@ int ScummEngine::readSoundResource(int idx) {
free(ptr);
return 1;
- case MKID_BE('Mac1'):
- case MKID_BE('RIFF'):
- case MKID_BE('TALK'):
- case MKID_BE('DIGI'):
- case MKID_BE('Crea'):
+ case MKTAG('M','a','c','1'):
+ case MKTAG('R','I','F','F'):
+ case MKTAG('T','A','L','K'):
+ case MKTAG('D','I','G','I'):
+ case MKTAG('C','r','e','a'):
case 0x460e200d: // WORKAROUND bug # 1311447
_fileHandle->seek(-12, SEEK_CUR);
total_size = _fileHandle->readUint32BE();
@@ -1186,7 +1186,7 @@ int ScummEngine::readSoundResource(int idx) {
//dumpResource("sound-", idx, ptr);
return 1;
- case MKID_BE('HSHD'):
+ case MKTAG('H','S','H','D'):
// HE sound type without SOUN header
_fileHandle->seek(-16, SEEK_CUR);
total_size = max_total_size + 8;
@@ -1195,7 +1195,7 @@ int ScummEngine::readSoundResource(int idx) {
//dumpResource("sound-", idx, ptr);
return 1;
- case MKID_BE('FMUS'): {
+ case MKTAG('F','M','U','S'): {
// Used in 3DO version of puttputt joins the parade and probably others
// Specifies a separate file to be used for music from what I gather.
int tmpsize;
@@ -1406,20 +1406,20 @@ static byte *writeVLQ(byte *ptr, int value) {
static byte Mac0ToGMInstrument(uint32 type, int &transpose) {
transpose = 0;
switch (type) {
- case MKID_BE('MARI'): return 12;
- case MKID_BE('PLUC'): return 45;
- case MKID_BE('HARM'): return 22;
- case MKID_BE('PIPE'): return 19;
- case MKID_BE('TROM'): transpose = -12; return 57;
- case MKID_BE('STRI'): return 48;
- case MKID_BE('HORN'): return 60;
- case MKID_BE('VIBE'): return 11;
- case MKID_BE('SHAK'): return 77;
- case MKID_BE('PANP'): return 75;
- case MKID_BE('WHIS'): return 76;
- case MKID_BE('ORGA'): return 17;
- case MKID_BE('BONG'): return 115;
- case MKID_BE('BASS'): transpose = -24; return 35;
+ case MKTAG('M','A','R','I'): return 12;
+ case MKTAG('P','L','U','C'): return 45;
+ case MKTAG('H','A','R','M'): return 22;
+ case MKTAG('P','I','P','E'): return 19;
+ case MKTAG('T','R','O','M'): transpose = -12; return 57;
+ case MKTAG('S','T','R','I'): return 48;
+ case MKTAG('H','O','R','N'): return 60;
+ case MKTAG('V','I','B','E'): return 11;
+ case MKTAG('S','H','A','K'): return 77;
+ case MKTAG('P','A','N','P'): return 75;
+ case MKTAG('W','H','I','S'): return 76;
+ case MKTAG('O','R','G','A'): return 17;
+ case MKTAG('B','O','N','G'): return 115;
+ case MKTAG('B','A','S','S'): transpose = -24; return 35;
default:
error("Unknown Mac0 instrument %s found", tag2str(type));
}
@@ -1504,13 +1504,13 @@ static void convertMac0Resource(ResourceManager *res, int idx, byte *src_ptr, in
// Parse the three channels
for (i = 0; i < 3; i++) {
- assert(READ_BE_UINT32(src_ptr) == MKID_BE('Chan'));
+ assert(READ_BE_UINT32(src_ptr) == MKTAG('C','h','a','n'));
len = READ_BE_UINT32(src_ptr + 4);
track_len[i] = len - 24;
track_instr[i] = Mac0ToGMInstrument(READ_BE_UINT32(src_ptr + 8), track_transpose[i]);
track_data[i] = src_ptr + 12;
src_ptr += len;
- looped = (READ_BE_UINT32(src_ptr - 8) == MKID_BE('Loop'));
+ looped = (READ_BE_UINT32(src_ptr - 8) == MKTAG('L','o','o','p'));
// For each note event, we need up to 6 bytes for the
// Note On (3 VLQ, 3 event), and 6 bytes for the Note
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index e8f75dd901..6d5eb3fad7 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -1499,7 +1499,7 @@ void ScummEngine::drawVerbBitmap(int verb, int x, int y) {
}
imptr = getObjectImage(obim, 1);
} else {
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim);
+ const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim);
if (_game.version >= 7) {
imgw = READ_LE_UINT16(&imhd->v7.width) / 8;
imgh = READ_LE_UINT16(&imhd->v7.height) / 8;
diff --git a/engines/sword1/control.h b/engines/sword1/control.h
index a6ccb09a04..2e5bfc7197 100644
--- a/engines/sword1/control.h
+++ b/engines/sword1/control.h
@@ -44,7 +44,7 @@ class Mouse;
class Music;
class Sound;
-#define SAVEGAME_HEADER MKID_BE('BS_1')
+#define SAVEGAME_HEADER MKTAG('B','S','_','1')
#define SAVEGAME_VERSION 2
#define MAX_BUTTONS 16
diff --git a/engines/sword1/screen.cpp b/engines/sword1/screen.cpp
index 24fd5b502f..1906fcb7fd 100644
--- a/engines/sword1/screen.cpp
+++ b/engines/sword1/screen.cpp
@@ -899,7 +899,7 @@ uint8* Screen::psxShrinkedBackgroundToIndexed(uint8 *psxBackground, uint32 bakXr
uint8 *fullres_buffer = (uint8 *)malloc(bakXres * (yresInTiles + 1) * 32);
memset(fullres_buffer, 0, bakXres * (yresInTiles + 1) * 32);
- bool isCompressed = (READ_LE_UINT32(psxBackground) == MKID_BE('COMP'));
+ bool isCompressed = (READ_LE_UINT32(psxBackground) == MKTAG('C','O','M','P'));
totTiles -= xresInTiles;
psxBackground += 4; //We skip the id tag
diff --git a/engines/tinsel/adpcm.cpp b/engines/tinsel/adpcm.cpp
new file mode 100644
index 0000000000..ec51d150dc
--- /dev/null
+++ b/engines/tinsel/adpcm.cpp
@@ -0,0 +1,168 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tinsel/adpcm.h"
+
+namespace Tinsel {
+
+static const double TinselFilterTable[4][2] = {
+ {0, 0 },
+ {0.9375, 0},
+ {1.796875, -0.8125},
+ {1.53125, -0.859375}
+};
+
+void Tinsel_ADPCMStream::readBufferTinselHeader() {
+ uint8 start = _stream->readByte();
+ uint8 filterVal = (start & 0xC0) >> 6;
+
+ if ((start & 0x20) != 0) {
+ //Lower 6 bit are negative
+
+ // Negate
+ start = ~(start | 0xC0) + 1;
+
+ _status.predictor = 1 << start;
+ } else {
+ // Lower 6 bit are positive
+
+ // Truncate
+ start &= 0x1F;
+
+ _status.predictor = ((double) 1.0) / (1 << start);
+ }
+
+ _status.K0 = TinselFilterTable[filterVal][0];
+ _status.K1 = TinselFilterTable[filterVal][1];
+}
+
+int16 Tinsel_ADPCMStream::decodeTinsel(int16 code, double eVal) {
+ double sample;
+
+ sample = (double) code;
+ sample *= eVal * _status.predictor;
+ sample += (_status.d0 * _status.K0) + (_status.d1 * _status.K1);
+
+ _status.d1 = _status.d0;
+ _status.d0 = sample;
+
+ return (int16) CLIP<double>(sample, -32768.0, 32767.0);
+}
+
+int Tinsel4_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
+ int samples;
+ uint16 data;
+ const double eVal = 1.142822265;
+
+ samples = 0;
+
+ assert(numSamples % 2 == 0);
+
+ while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
+ if (_blockPos[0] == _blockAlign) {
+ readBufferTinselHeader();
+ _blockPos[0] = 0;
+ }
+
+ for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples += 2, _blockPos[0]++) {
+ // Read 1 byte = 8 bits = two 4 bit blocks
+ data = _stream->readByte();
+ buffer[samples] = decodeTinsel((data << 8) & 0xF000, eVal);
+ buffer[samples+1] = decodeTinsel((data << 12) & 0xF000, eVal);
+ }
+ }
+
+ return samples;
+}
+
+int Tinsel6_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
+ int samples;
+ const double eVal = 1.032226562;
+
+ samples = 0;
+
+ while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
+ if (_blockPos[0] == _blockAlign) {
+ readBufferTinselHeader();
+ _blockPos[0] = 0;
+ _chunkPos = 0;
+ }
+
+ for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _chunkPos = (_chunkPos + 1) % 4) {
+
+ switch (_chunkPos) {
+ case 0:
+ _chunkData = _stream->readByte();
+ buffer[samples] = decodeTinsel((_chunkData << 8) & 0xFC00, eVal);
+ break;
+ case 1:
+ _chunkData = (_chunkData << 8) | (_stream->readByte());
+ buffer[samples] = decodeTinsel((_chunkData << 6) & 0xFC00, eVal);
+ _blockPos[0]++;
+ break;
+ case 2:
+ _chunkData = (_chunkData << 8) | (_stream->readByte());
+ buffer[samples] = decodeTinsel((_chunkData << 4) & 0xFC00, eVal);
+ _blockPos[0]++;
+ break;
+ case 3:
+ _chunkData = (_chunkData << 8);
+ buffer[samples] = decodeTinsel((_chunkData << 2) & 0xFC00, eVal);
+ _blockPos[0]++;
+ break;
+ }
+
+ }
+
+ }
+
+ return samples;
+}
+
+int Tinsel8_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
+ int samples;
+ byte data;
+ const double eVal = 1.007843258;
+
+ samples = 0;
+
+ while (samples < numSamples && !_stream->eos() && _stream->pos() < _endpos) {
+ if (_blockPos[0] == _blockAlign) {
+ readBufferTinselHeader();
+ _blockPos[0] = 0;
+ }
+
+ for (; samples < numSamples && _blockPos[0] < _blockAlign && !_stream->eos() && _stream->pos() < _endpos; samples++, _blockPos[0]++) {
+ // Read 1 byte = 8 bits = one 8 bit block
+ data = _stream->readByte();
+ buffer[samples] = decodeTinsel(data << 8, eVal);
+ }
+ }
+
+ return samples;
+}
+
+
+} // End of namespace Tinsel
diff --git a/engines/tinsel/adpcm.h b/engines/tinsel/adpcm.h
new file mode 100644
index 0000000000..79d537eef6
--- /dev/null
+++ b/engines/tinsel/adpcm.h
@@ -0,0 +1,105 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TINSEL_ADPCM_H
+#define TINSEL_ADPCM_H
+
+#include "audio/decoders/adpcm_intern.h"
+
+namespace Tinsel {
+
+class Tinsel_ADPCMStream : public Audio::ADPCMStream {
+protected:
+ struct {
+ // Tinsel
+ double predictor;
+ double K0, K1;
+ double d0, d1;
+ } _status;
+
+ void reset() {
+ ADPCMStream::reset();
+ memset(&_status, 0, sizeof(_status));
+ }
+
+ int16 decodeTinsel(int16, double);
+ void readBufferTinselHeader();
+
+public:
+ Tinsel_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
+ : ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
+
+ if (blockAlign == 0)
+ error("Tinsel_ADPCMStream(): blockAlign isn't specified");
+
+ if (channels != 1)
+ error("Tinsel_ADPCMStream(): Tinsel ADPCM only supports mono");
+
+ memset(&_status, 0, sizeof(_status));
+ }
+
+};
+
+class Tinsel4_ADPCMStream : public Tinsel_ADPCMStream {
+public:
+ Tinsel4_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
+ : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {}
+
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+};
+
+class Tinsel6_ADPCMStream : public Tinsel_ADPCMStream {
+protected:
+ uint8 _chunkPos;
+ uint16 _chunkData;
+
+ void reset() {
+ ADPCMStream::reset();
+ _chunkPos = 0;
+ _chunkData = 0;
+ }
+
+public:
+ Tinsel6_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
+ : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {
+ _chunkPos = 0;
+ _chunkData = 0;
+ }
+
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+};
+
+class Tinsel8_ADPCMStream : public Tinsel_ADPCMStream {
+public:
+ Tinsel8_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
+ : Tinsel_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) {}
+
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+};
+
+
+} // End of namespace Tinsel
+
+#endif
diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index 560216aadb..f895ecd2da 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -39,9 +39,6 @@ namespace Tinsel {
// current background
const BACKGND *pCurBgnd = NULL;
-// FIXME: Not yet used
-static bool bEntireRedraw;
-
/**
* Called to initialise a background.
* @param pBgnd Pointer to data struct for current background
@@ -257,9 +254,4 @@ void DrawBackgnd() {
ResetClipRect();
}
-void ForceEntireRedraw() {
- bEntireRedraw = true;
-}
-
-
} // End of namespace Tinsel
diff --git a/engines/tinsel/background.h b/engines/tinsel/background.h
index 81b490488e..d0b27e6e40 100644
--- a/engines/tinsel/background.h
+++ b/engines/tinsel/background.h
@@ -110,8 +110,6 @@ OBJECT *GetBgObject();
SCNHANDLE BgPal();
-void ForceEntireRedraw();
-
int BgWidth();
int BgHeight();
diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp
index 3f56288aca..b5b84ceaee 100644
--- a/engines/tinsel/bmv.cpp
+++ b/engines/tinsel/bmv.cpp
@@ -1025,7 +1025,6 @@ bool BMVPlayer::DoSoundFrame() {
void BMVPlayer::CopyMovieToScreen() {
// Not if not up and running yet!
if (!screenBuffer || (currentFrame == 0)) {
- ForceEntireRedraw();
DrawBackgnd();
return;
}
@@ -1046,21 +1045,6 @@ void BMVPlayer::CopyMovieToScreen() {
}
/**
- * LookAtBuffers
- */
-void BMVPlayer::LookAtBuffers() {
- // FIXME: What's the point of this function???
- // Maybe to ensure the relevant data is loaded into cache by the CPU?
- static int junk; // FIXME: Avoid non-const global vars
- int i;
-
- if (bigBuffer) {
- for (i = 0; i < NUM_SLOTS; i++)
- junk += bigBuffer[i*SLOT_SIZE];
- }
-}
-
-/**
* Handles playback of any active movie. Called from the foreground 24 times a second.
*/
void BMVPlayer::FettleBMV() {
@@ -1078,8 +1062,6 @@ void BMVPlayer::FettleBMV() {
return;
}
- LookAtBuffers();
-
if (!stream.isOpen()) {
int i;
diff --git a/engines/tinsel/bmv.h b/engines/tinsel/bmv.h
index 2644504cab..99a43e0740 100644
--- a/engines/tinsel/bmv.h
+++ b/engines/tinsel/bmv.h
@@ -151,7 +151,6 @@ private:
bool MaintainBuffer();
bool DoBMVFrame();
bool DoSoundFrame();
- void LookAtBuffers();
};
diff --git a/engines/tinsel/drives.cpp b/engines/tinsel/drives.cpp
index 6e30caf006..ab606f3159 100644
--- a/engines/tinsel/drives.cpp
+++ b/engines/tinsel/drives.cpp
@@ -38,7 +38,6 @@ namespace Tinsel {
// FIXME: Avoid non-const global vars
char currentCD = '1';
-static uint32 cdFlags[] = { fCd1, fCd2, fCd3, fCd4, fCd5, fCd6, fCd7, fCd8 };
static bool bChangingCD = false;
static char nextCD = '\0';
@@ -75,6 +74,8 @@ int GetCurrentCD() {
return (currentCD - '1' + 1);
}
+static const uint32 cdFlags[] = { fCd1, fCd2, fCd3, fCd4, fCd5, fCd6, fCd7, fCd8 };
+
void SetCD(int flags) {
if (flags & cdFlags[currentCD - '1'])
return;
diff --git a/engines/tinsel/dw.h b/engines/tinsel/dw.h
index 8bd7ca1a4e..aed4c50408 100644
--- a/engines/tinsel/dw.h
+++ b/engines/tinsel/dw.h
@@ -42,8 +42,6 @@ typedef int HPOLYGON;
#define LF_CHAR '\x0a' // line feed
// file names
-#define SAMPLE_FILE "english.smp" // all samples
-#define SAMPLE_INDEX "english.idx" // sample index filename
#define MIDI_FILE "midi.dat" // all MIDI sequences
#define INDEX_FILENAME "index" // name of index file
#define PSX_INDEX_FILENAME "index.dat" // name of index file in psx version
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index a48fd2ca1f..f2db42bede 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -65,8 +65,6 @@ enum {
fLoaded = 0x20000000L ///< set when file data has been loaded
};
#define FSIZE_MASK 0x00FFFFFFL ///< mask to isolate the filesize
-#define MALLOC_MASK 0xFF000000L ///< mask to isolate the memory allocation flags
-//#define HANDLEMASK 0xFF800000L ///< get handle of address
//----------------- LOCAL GLOBAL DATA --------------------
@@ -80,7 +78,6 @@ static uint numHandles = 0;
static uint32 cdPlayHandle = (uint32)-1;
-static int cdPlayFileNum, cdPlaySceneNum;
static SCNHANDLE cdBaseHandle = 0, cdTopHandle = 0;
static Common::File *cdGraphStream = 0;
@@ -235,7 +232,7 @@ void LoadCDGraphData(MEMHANDLE *pH) {
// clear the loading flag
// pH->filesize &= ~fLoading;
- if (bytes != ((cdTopHandle-cdBaseHandle) & OFFSETMASK))
+ if (bytes != ((cdTopHandle - cdBaseHandle) & OFFSETMASK))
// file is corrupt
error(FILE_READ_ERROR, "CD play file");
}
@@ -248,7 +245,7 @@ void LoadCDGraphData(MEMHANDLE *pH) {
* @param next Handle of end of range + 1
*/
void LoadExtraGraphData(SCNHANDLE start, SCNHANDLE next) {
- if (cdPlayFileNum == cdPlaySceneNum && start == cdBaseHandle)
+ if (start == cdBaseHandle)
return;
OpenCDGraphFile();
@@ -264,7 +261,6 @@ void LoadExtraGraphData(SCNHANDLE start, SCNHANDLE next) {
}
void SetCdPlaySceneDetails(int fileNum, const char *fileName) {
- cdPlaySceneNum = fileNum;
strcpy(szCdPlayFile, fileName);
}
diff --git a/engines/tinsel/module.mk b/engines/tinsel/module.mk
index 2778cec3df..2ab94b830a 100644
--- a/engines/tinsel/module.mk
+++ b/engines/tinsel/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/tinsel
MODULE_OBJS := \
actors.o \
+ adpcm.o \
anim.o \
background.o \
bg.o \
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index ea5d88ce1c..12bcff829b 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -38,6 +38,7 @@
#include "common/file.h"
#include "common/memstream.h"
+#include "tinsel/adpcm.h"
#include "tinsel/config.h"
#include "tinsel/sound.h"
#include "tinsel/music.h"
@@ -65,10 +66,6 @@ struct SOUND_BUFFER {
// FIXME: Avoid non-const global vars
-// get set when music driver is installed
-//static MDI_DRIVER *mDriver;
-//static HSEQUENCE mSeqHandle;
-
// MIDI buffer
static SOUND_BUFFER midiBuffer = { 0, 0 };
@@ -152,8 +149,6 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
// the index and length of the last tune loaded
static uint32 dwLastMidiIndex = 0; // FIXME: Avoid non-const global vars
- //static uint32 dwLastSeqLen;
-
uint32 dwSeqLen = 0; // length of the sequence
// Support for external music from the music enhancement project
@@ -471,7 +466,6 @@ PCMMusicPlayer::PCMMusicPlayer() {
_silenceSamples = 0;
_curChunk = 0;
- _fileName = 0;
_state = S_IDLE;
_mState = S_IDLE;
_scriptNum = -1;
@@ -494,15 +488,13 @@ PCMMusicPlayer::PCMMusicPlayer() {
PCMMusicPlayer::~PCMMusicPlayer() {
_vm->_mixer->stopHandle(_handle);
-
- delete[] _fileName;
}
void PCMMusicPlayer::startPlay(int id) {
- if (!_fileName)
+ if (_filename.empty())
return;
- debugC(DEBUG_DETAILED, kTinselDebugMusic, "Playing PCM music %s, index %d", _fileName, id);
+ debugC(DEBUG_DETAILED, kTinselDebugMusic, "Playing PCM music %s, index %d", _filename.c_str(), id);
Common::StackLock slock(_mutex);
@@ -617,8 +609,7 @@ void PCMMusicPlayer::setMusicSceneDetails(SCNHANDLE hScript,
_hScript = hScript;
_hSegment = hSegment;
- _fileName = new char[strlen(fileName) + 1];
- strcpy(_fileName, fileName);
+ _filename = fileName;
// Start scene with music not dimmed
_dimmed = false;
@@ -774,19 +765,19 @@ bool PCMMusicPlayer::getNextChunk() {
sampleLength = FROM_LE_32(musicSegments[snum].sampleLength);
sampleCLength = (((sampleLength + 63) & ~63)*33)/64;
- if (!file.open(_fileName))
- error(CANNOT_FIND_FILE, _fileName);
+ if (!file.open(_filename))
+ error(CANNOT_FIND_FILE, _filename.c_str());
file.seek(sampleOffset);
if (file.eos() || file.err() || (uint32)file.pos() != sampleOffset)
- error(FILE_IS_CORRUPT, _fileName);
+ error(FILE_IS_CORRUPT, _filename.c_str());
buffer = (byte *) malloc(sampleCLength);
assert(buffer);
// read all of the sample
if (file.read(buffer, sampleCLength) != sampleCLength)
- error(FILE_IS_CORRUPT, _fileName);
+ error(FILE_IS_CORRUPT, _filename.c_str());
debugC(DEBUG_DETAILED, kTinselDebugMusic, "Creating ADPCM music chunk with size %d, "
"offset %d (script %d.%d)", sampleCLength, sampleOffset,
@@ -795,8 +786,8 @@ bool PCMMusicPlayer::getNextChunk() {
sampleStream = new Common::MemoryReadStream(buffer, sampleCLength, DisposeAfterUse::YES);
delete _curChunk;
- _curChunk = makeADPCMStream(sampleStream, DisposeAfterUse::YES, sampleCLength,
- Audio::kADPCMTinsel8, 22050, 1, 32);
+ _curChunk = new Tinsel8_ADPCMStream(sampleStream, DisposeAfterUse::YES, sampleCLength,
+ 22050, 1, 32);
_state = S_MID;
return true;
diff --git a/engines/tinsel/music.h b/engines/tinsel/music.h
index af089caf24..9003e60078 100644
--- a/engines/tinsel/music.h
+++ b/engines/tinsel/music.h
@@ -148,7 +148,7 @@ protected:
int32 _scriptIndex;
SCNHANDLE _hScript;
SCNHANDLE _hSegment;
- char *_fileName;
+ Common::String _filename;
uint8 _volume;
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index c965666e84..3182593a88 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -77,9 +77,6 @@ SRSTATE SRstate = SR_IDLE;
// in DOS_DW.C
extern void syncSCdata(Common::Serializer &s);
-// in DOS_MAIN.C
-//char HardDriveLetter();
-
// in PCODE.C
extern void syncGlobInfo(Common::Serializer &s);
@@ -283,32 +280,6 @@ static void syncSavedData(Common::Serializer &s, SAVED_DATA &sd) {
}
}
-
-/**
- * Called when saving a game to a new file.
- * Generates a new, unique, filename.
- */
-static char *NewName() {
- static char result[FNAMELEN]; // FIXME: Avoid non-const global vars
- int i;
- int ano = 1; // Allocated number
-
- while (1) {
- Common::String fname = _vm->getSavegameFilename(ano);
- strcpy(result, fname.c_str());
-
- for (i = 0; i < numSfiles; i++)
- if (!strcmp(savedFiles[i].name, result))
- break;
-
- if (i == numSfiles)
- break;
- ano++;
- }
-
- return result;
-}
-
/**
* Compare two TimeDate structs to see which one was earlier.
* Returns 0 if they are equal, a negative value if a is lower / first, and
@@ -498,19 +469,37 @@ static bool DoRestore() {
*/
static void DoSave() {
Common::OutSaveFile *f;
- const char *fname;
+ char tmpName[FNAMELEN];
// Next getList() must do its stuff again
NeedLoad = true;
- if (SaveSceneName == NULL)
- SaveSceneName = NewName();
+ if (SaveSceneName == NULL) {
+ // Generate a new unique save name
+ int i;
+ int ano = 1; // Allocated number
+
+ while (1) {
+ Common::String fname = _vm->getSavegameFilename(ano);
+ strcpy(tmpName, fname.c_str());
+
+ for (i = 0; i < numSfiles; i++)
+ if (!strcmp(savedFiles[i].name, tmpName))
+ break;
+
+ if (i == numSfiles)
+ break;
+ ano++;
+ }
+
+ SaveSceneName = tmpName;
+ }
+
+
if (SaveSceneDesc[0] == 0)
SaveSceneDesc = "unnamed";
- fname = SaveSceneName;
-
- f = _vm->getSaveFileMan()->openForSaving(fname);
+ f = _vm->getSaveFileMan()->openForSaving(SaveSceneName);
Common::Serializer s(0, f);
if (f == NULL)
@@ -537,12 +526,14 @@ static void DoSave() {
f->finalize();
delete f;
+ SaveSceneName = NULL; // Invalidate save name
return;
save_failure:
if (f) {
delete f;
- _vm->getSaveFileMan()->removeSavefile(fname);
+ _vm->getSaveFileMan()->removeSavefile(SaveSceneName);
+ SaveSceneName = NULL; // Invalidate save name
}
GUI::MessageDialog dialog("Failed to save game state to file.");
dialog.runModal();
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 8f0f4771e3..67e0ea9ffd 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -112,15 +112,11 @@ struct ENTRANCE_STRUC {
static bool ShowPosition = false; // Set when showpos() has been called
#endif
-SCNHANDLE newestScene = 0;
-
int sceneCtr = 0;
static int initialMyEscape;
static SCNHANDLE SceneHandle = 0; // Current scene handle - stored in case of Save_Scene()
-static bool bWatchingOut = false;
-
SCENE_STRUC tempStruc;
struct TP_INIT {
@@ -180,9 +176,6 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
_ctx->myEscape);
CORO_INVOKE_1(Interpret, _ctx->pic);
- if (_ctx->pInit->event == CLOSEDOWN || _ctx->pInit->event == LEAVE_T2)
- bWatchingOut = false;
-
CORO_END_CODE;
}
@@ -193,9 +186,6 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
void SendSceneTinselProcess(TINSEL_EVENT event) {
SCENE_STRUC *ss;
- if (event == CLOSEDOWN || event == LEAVE_T2)
- bWatchingOut = true;
-
if (SceneHandle != (SCNHANDLE)NULL) {
ss = (SCENE_STRUC *) FindChunk(SceneHandle, CHUNK_SCENE);
@@ -206,11 +196,8 @@ void SendSceneTinselProcess(TINSEL_EVENT event) {
init.hTinselCode = ss->hSceneScript;
g_scheduler->createProcess(PID_TCODE, SceneTinselProcess, &init, sizeof(init));
- } else if (event == CLOSEDOWN)
- bWatchingOut = false;
+ }
}
- else if (event == CLOSEDOWN)
- bWatchingOut = false;
}
@@ -249,9 +236,6 @@ static void LoadScene(SCNHANDLE scene, int entry) {
assert(ss != NULL);
if (TinselV2) {
- // Handle to scene description
- newestScene = FROM_LE_32(ss->hSceneDesc);
-
// Music stuff
char *cptr = (char *)FindChunk(scene, CHUNK_MUSIC_FILENAME);
assert(cptr);
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp
index 5fc2820986..1fcdb4dcf9 100644
--- a/engines/tinsel/sound.cpp
+++ b/engines/tinsel/sound.cpp
@@ -26,6 +26,7 @@
#include "tinsel/sound.h"
+#include "tinsel/adpcm.h"
#include "tinsel/dw.h"
#include "tinsel/config.h"
#include "tinsel/music.h"
@@ -319,7 +320,7 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p
#endif
break;
default:
- sampleStream = Audio::makeADPCMStream(compressedStream, DisposeAfterUse::YES, sampleLen, Audio::kADPCMTinsel6, 22050, 1, 24);
+ sampleStream = new Tinsel6_ADPCMStream(compressedStream, DisposeAfterUse::YES, sampleLen, 22050, 1, 24);
break;
}
@@ -530,17 +531,17 @@ void SoundManager::openSampleFiles() {
// Detect format of soundfile by looking at 1st sample-index
switch (TO_BE_32(_sampleIndex[0])) {
- case MKID_BE('MP3 '):
+ case MKTAG('M','P','3',' '):
debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected MP3 sound-data");
_soundMode = kMP3Mode;
break;
- case MKID_BE('OGG '):
+ case MKTAG('O','G','G',' '):
debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected OGG sound-data");
_soundMode = kVorbisMode;
break;
- case MKID_BE('FLAC'):
+ case MKTAG('F','L','A','C'):
debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected FLAC sound-data");
_soundMode = kFLACMode;
break;
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 1b3173719f..e1396f9715 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -218,14 +218,17 @@ void KeyboardProcess(CORO_PARAM, const void *) {
continue;
#endif
+ case Common::KEYCODE_1:
case Common::KEYCODE_F1:
// Options dialog
ProcessKeyEvent(PLR_MENU);
continue;
+ case Common::KEYCODE_5:
case Common::KEYCODE_F5:
// Save game
ProcessKeyEvent(PLR_SAVE);
continue;
+ case Common::KEYCODE_7:
case Common::KEYCODE_F7:
// Load game
ProcessKeyEvent(PLR_LOAD);
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index d76a63c1ae..c2e0bf7b20 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -26,24 +26,10 @@
#include "toon/audio.h"
#include "common/memstream.h"
#include "common/substream.h"
+#include "audio/decoders/adpcm_intern.h"
namespace Toon {
-static int ADPCM_index[8] = {
- -1, -1, -1, -1, 2 , 4 , 6 , 8
-};
-static int ADPCM_table[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
- 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
- 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
- 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
- 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
- 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
- 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
- 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
AudioManager::AudioManager(ToonEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
for (int32 i = 0; i < 16; i++)
_channels[i] = NULL;
@@ -372,7 +358,7 @@ void AudioStreamInstance::decodeADPCM(uint8 *comp, int16 *dest, int32 packetSize
int32 v31 = v30 & 0x8;
int32 v32 = v30 & 0x7;
- int32 v33 = ADPCM_table[v19];
+ int32 v33 = Audio::Ima_ADPCMStream::_imaTable[v19];
int32 v34 = v33 >> 3;
if (v32 & 4)
v34 += v33;
@@ -383,12 +369,8 @@ void AudioStreamInstance::decodeADPCM(uint8 *comp, int16 *dest, int32 packetSize
if (v32 & 1)
v34 += v33 >> 2;
- v19 += ADPCM_index[v32];
- if (v19 < 0)
- v19 = 0;
-
- if (v19 > 88)
- v19 = 88;
+ v19 += Audio::ADPCMStream::_stepAdjustTable[v32];
+ v19 = CLIP<int32>(v19, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1);
if (v31)
v18 -= v34;
diff --git a/engines/toon/hotspot.cpp b/engines/toon/hotspot.cpp
index ec2344d659..0573e92fef 100644
--- a/engines/toon/hotspot.cpp
+++ b/engines/toon/hotspot.cpp
@@ -127,7 +127,7 @@ bool Hotspots::LoadRif(Common::String rifName, Common::String additionalRifName)
decoder.unpackM1(rifData, size, _items);
if (rifsize2) {
RncDecoder decoder2;
- decoder2.unpackM1(rifData2 , size, _items + (rifsize >> 9));
+ decoder2.unpackM1(rifData2 , size2, _items + (rifsize >> 9));
for (int32 i = 0; i < (rifsize2 >> 9); i++) {
HotspotData *hot = _items + (rifsize >> 9) + i;
hot->setData(0, hot->getX1() + 1280);
diff --git a/engines/toon/script.cpp b/engines/toon/script.cpp
index 376b1db621..0242ace7e3 100644
--- a/engines/toon/script.cpp
+++ b/engines/toon/script.cpp
@@ -70,7 +70,7 @@ EMCInterpreter::~EMCInterpreter() {
bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
switch (chunk._type) {
- case MKID_BE('TEXT'):
+ case MKTAG('T','E','X','T'):
delete[] _scriptData->text;
_scriptData->text = new byte[chunk._size];
assert(_scriptData->text);
@@ -78,7 +78,7 @@ bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
error("Couldn't read TEXT chunk from file '%s'", _filename);
break;
- case MKID_BE('ORDR'):
+ case MKTAG('O','R','D','R'):
delete[] _scriptData->ordr;
_scriptData->ordr = new uint16[chunk._size >> 1];
assert(_scriptData->ordr);
@@ -89,7 +89,7 @@ bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
_scriptData->ordr[i] = READ_BE_UINT16(&_scriptData->ordr[i]);
break;
- case MKID_BE('DATA'):
+ case MKTAG('D','A','T','A'):
delete[] _scriptData->data;
_scriptData->data = new uint16[chunk._size >> 1];
assert(_scriptData->data);
diff --git a/engines/toon/script.h b/engines/toon/script.h
index 2a74f9084f..b6d28e1171 100644
--- a/engines/toon/script.h
+++ b/engines/toon/script.h
@@ -87,9 +87,9 @@ public:
// Both lead to some problems in our IFF parser, either reading after the end
// of file or producing a "Chunk overread" error message. To work around this
// we need to adjust the size field properly.
- if (_formType == MKID_BE('EMC2'))
+ if (_formType == MKTAG('E','M','C','2'))
_formChunk.size -= 8;
- else if (_formType == MKID_BE('AVFS'))
+ else if (_formType == MKTAG('A','V','F','S'))
_formChunk.size += 4;
}
};
diff --git a/engines/toon/tools.cpp b/engines/toon/tools.cpp
index bad796158a..da6e0f712e 100644
--- a/engines/toon/tools.cpp
+++ b/engines/toon/tools.cpp
@@ -373,8 +373,21 @@ int32 RncDecoder::unpackM1(const void *input, uint16 inputSize, void *output) {
_dstPtr += inputLength;
_srcPtr += inputLength;
_inputByteLeft -= inputLength;
- uint16 a = READ_LE_UINT16(_srcPtr);
- uint16 b = READ_LE_UINT16(_srcPtr + 2);
+ uint16 a;
+ if (_inputByteLeft <= 0)
+ a = 0;
+ else if (_inputByteLeft == 1)
+ a = *_srcPtr;
+ else
+ a = READ_LE_UINT16(_srcPtr);
+
+ uint16 b;
+ if (_inputByteLeft <= 2)
+ b = 0;
+ else if(_inputByteLeft == 3)
+ b = *(_srcPtr + 2);
+ else
+ b = READ_LE_UINT16(_srcPtr + 2);
_bitBuffl &= ((1 << _bitCount) - 1);
_bitBuffl |= (a << _bitCount);
diff --git a/engines/toon/tools.h b/engines/toon/tools.h
index b716d4813a..1434ca26c7 100644
--- a/engines/toon/tools.h
+++ b/engines/toon/tools.h
@@ -63,7 +63,7 @@ protected:
const uint8 *_srcPtr;
uint8 *_dstPtr;
- uint16 _inputByteLeft;
+ int16 _inputByteLeft;
public:
RncDecoder();
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
new file mode 100644
index 0000000000..fd1dfe9e9d
--- /dev/null
+++ b/engines/tsage/converse.cpp
@@ -0,0 +1,948 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/str-array.h"
+
+#include "tsage/tsage.h"
+#include "tsage/globals.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+#define STRIP_WORD_DELAY 30
+
+
+SequenceManager::SequenceManager() : Action() {
+ Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
+ _sequenceData.clear();
+ _field24 = 0;
+ _sequenceOffset = 0;
+ _resNum = 0;
+ _field26 = 0;
+ _objectIndex = 0;
+ _keepActive = false;
+ setup();
+}
+
+void SequenceManager::setup() {
+ _sequenceOffset = 0;
+ _objectIndex = 0;
+ _sceneObject = _objectList[0];
+}
+
+void SequenceManager::synchronise(Serialiser &s) {
+ s.syncAsSint32LE(_resNum);
+ s.syncAsSint32LE(_sequenceOffset);
+ s.syncAsByte(_keepActive);
+ s.syncAsSint32LE(_field24);
+ s.syncAsSint32LE(_field26);
+
+ s.syncAsSint32LE(_objectIndex);
+ SYNC_POINTER(_sceneObject);
+ for (int i = 0; i < 6; ++i)
+ SYNC_POINTER(_objectList[i]);
+
+ int seqSize = _sequenceData.size();
+ s.syncAsUint32LE(seqSize);
+ if (s.isLoading())
+ _sequenceData.resize(seqSize);
+ if (seqSize > 0)
+ s.syncBytes(&_sequenceData[0], seqSize);
+}
+
+void SequenceManager::remove() {
+ if ((!_sequenceData.empty()) && !_keepActive) {
+ _sequenceData.clear();
+ }
+
+ if (_globals->_sceneObjects->contains(&_sceneText))
+ _sceneText.remove();
+
+ Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
+ Action::remove();
+}
+
+void SequenceManager::signal() {
+ if (_globals->_sceneObjects->contains(&_sceneText))
+ _sceneText.hide();
+
+ bool continueFlag = true;
+ while (continueFlag) {
+ if (_sequenceOffset >=_sequenceData.size()) {
+ // Reached the end of the sequence
+ if (!_keepActive)
+ remove();
+ break;
+ }
+
+ uint16 idx = static_cast<uint16>(getNextValue() - 32000);
+ if (idx > 34)
+ continue;
+
+ int16 v1, v2, v3;
+ switch (idx) {
+ case 0:
+ // Stop sequence
+ continueFlag = false;
+ break;
+ case 1:
+ _sceneObject->animate(ANIM_MODE_1, NULL);
+ break;
+ case 2:
+ _sceneObject->animate(ANIM_MODE_2, NULL);
+ break;
+ case 3:
+ _sceneObject->animate(ANIM_MODE_3);
+ break;
+ case 4:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ _sceneObject->animate(ANIM_MODE_8, v1, v2 ? this : NULL);
+ break;
+ case 5:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ _sceneObject->animate(ANIM_MODE_7, v1, v2 ? this : NULL);
+ break;
+ case 6:
+ v2 = getNextValue();
+ _sceneObject->animate(ANIM_MODE_5, v2 ? this : NULL);
+ break;
+ case 7:
+ v2 = getNextValue();
+ _sceneObject->animate(ANIM_MODE_6, v2 ? this : NULL);
+ break;
+ case 8:
+ v1 = getNextValue();
+ v3 = getNextValue();
+ v2 = getNextValue();
+ _sceneObject->animate(ANIM_MODE_4, v1, v3, v2 ? this : NULL);
+ break;
+ case 9:
+ v1 = getNextValue();
+ v3 = getNextValue();
+ v2 = getNextValue();
+ _globals->_sceneManager._scene->_sceneBounds.moveTo(v3, v2);
+ _globals->_sceneManager._scene->loadScene(v1);
+ break;
+ case 10: {
+ int resNum= getNextValue();
+ int lineNum = getNextValue();
+ int colour = getNextValue();
+ int xp = getNextValue();
+ int yp = getNextValue();
+ int width = getNextValue();
+ setMessage(resNum, lineNum, colour, Common::Point(xp, yp), width);
+ break;
+ }
+ case 11:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ setAction(globalManager(), v2 ? this : NULL, v1, _objectList[0], _objectList[1], _objectList[2], _objectList[3], NULL);
+ break;
+ case 12:
+ v1 = getNextValue();
+ setDelay(v1);
+ break;
+ case 13: {
+ v1 = getNextValue();
+ v3 = getNextValue();
+ v2 = getNextValue();
+ NpcMover *mover = new NpcMover();
+ Common::Point destPos(v1, v3);
+ _sceneObject->addMover(mover, &destPos, v2 ? this : NULL);
+ break;
+ }
+ case 14:
+ v1 = getNextValue();
+ _sceneObject->_numFrames = v1;
+ break;
+ case 15:
+ v1 = getNextValue();
+ _sceneObject->_field7A = v1;
+ break;
+ case 16:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ _sceneObject->_moveDiff = Common::Point(v1, v2);
+ break;
+ case 17:
+ _sceneObject->hide();
+ break;
+ case 18:
+ _sceneObject->show();
+ break;
+ case 19:
+ v1 = getNextValue();
+ _sceneObject->setVisage(v1);
+ break;
+ case 20:
+ v1 = getNextValue();
+ _sceneObject->setStrip(v1);
+ break;
+ case 21:
+ v1 = getNextValue();
+ _sceneObject->setFrame(v1);
+ break;
+ case 22:
+ v1 = getNextValue();
+ _sceneObject->setPriority2(v1);
+ break;
+ case 23:
+ v1 = getNextValue();
+ _sceneObject->changeZoom(v1);
+ break;
+ case 24:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ v3 = getNextValue();
+ _sceneObject->setPosition(Common::Point(v1, v2), v3);
+ break;
+ case 25: {
+ int yStart = getNextValue();
+ int minPercent = getNextValue();
+ int yEnd = getNextValue();
+ int maxPercent = getNextValue();
+ _globals->_sceneManager._scene->setZoomPercents(yStart, minPercent, yEnd, maxPercent);
+ break;
+ }
+ case 26:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ _soundHandler.startSound(v1, v2 ? this : NULL, 127);
+ break;
+ case 27: {
+ v1 = getNextValue();
+ v3 = getNextValue();
+ v2 = getNextValue();
+ PlayerMover *mover = new PlayerMover();
+ Common::Point destPos(v1, v3);
+ _sceneObject->addMover(mover, &destPos, v2 ? this : NULL);
+ break;
+ }
+ case 28:
+ _objectIndex = getNextValue();
+ _sceneObject = _objectList[_objectIndex];
+ assert(_sceneObject);
+ break;
+ case 29:
+ _sceneObject->animate(ANIM_MODE_NONE);
+ break;
+ case 30:
+ v1 = getNextValue();
+ _globals->_scrollFollower = (v1 == -1) ? NULL : _objectList[v1];
+ break;
+ case 31:
+ _sceneObject->setObjectWrapper(new SceneObjectWrapper());
+ break;
+ case 32:
+ _sceneObject->setObjectWrapper(NULL);
+ break;
+ case 33:
+ v1 = getNextValue();
+ if (_keepActive)
+ setDelay(1);
+ else {
+ _sceneText.remove();
+ _globals->_sceneManager._scene->_stripManager.start(v1, this);
+ }
+ break;
+ case 34: {
+ v1 = getNextValue();
+ v2 = getNextValue();
+ int objIndex1 = getNextValue();
+ int objIndex2 = getNextValue();
+ int objIndex3 = getNextValue();
+ int objIndex4 = getNextValue();
+ int objIndex5 = getNextValue();
+
+ setAction(globalManager(), v2 ? this : NULL, v1, _objectList[objIndex1], _objectList[objIndex2],
+ _objectList[objIndex3], _objectList[objIndex4], _objectList[objIndex5]);
+ break;
+ }
+ default:
+ error("SequenceManager::signal - Unknown action %d at offset %xh", idx, _sequenceOffset - 2);
+ break;
+ }
+ }
+}
+
+void SequenceManager::process(Event &event) {
+ if (((event.eventType == EVENT_BUTTON_DOWN) || (event.eventType == EVENT_KEYPRESS)) &&
+ !event.handled && _globals->_sceneObjects->contains(&_sceneText)) {
+ // Remove the text item
+ _sceneText.remove();
+ } else {
+ Action::process(event);
+ }
+}
+
+
+void SequenceManager::attached(EventHandler *newOwner, EventHandler *fmt, va_list va) {
+ // Get the sequence number to use
+ _resNum = va_arg(va, int);
+
+ byte *seqData = _vm->_dataManager->getResource(RES_SEQUENCE, _resNum, 0);
+ uint seqSize = _vm->_memoryManager.getSize(seqData);
+
+ _sequenceData.resize(seqSize);
+ Common::copy(seqData, seqData + seqSize, &_sequenceData[0]);
+
+ DEALLOCATE(seqData);
+
+ Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
+ for (int idx = 0; idx < 6; ++idx) {
+ _objectList[idx] = va_arg(va, SceneObject *);
+ if (!_objectList[idx])
+ break;
+ }
+
+ setup();
+ // TODO: This is not particulary nice, since dummy is uninitialized.
+ // Since the default Action implementation does not access the va_list
+ // parameter it should be fine though. Still it would be nice to find
+ // a better solution to this.
+ va_list dummy;
+ Action::attached(newOwner, fmt, dummy);
+}
+
+/**
+ * Returns the next Id in the sequence
+ */
+uint16 SequenceManager::getNextValue() {
+ uint16 result = READ_LE_UINT16(&_sequenceData[0] + _sequenceOffset);
+ _sequenceOffset += 2;
+ return result;
+}
+
+void SequenceManager::setMessage(int resNum, int lineNum, int colour, const Common::Point &pt, int width) {
+ _sceneText._colour1 = colour;
+ _sceneText._colour2 = 0;
+ _sceneText._colour3 = 0;
+ _sceneText._fontNumber = 2;
+ _sceneText._width = width;
+
+ // Get the display message
+ Common::String msg = _vm->_dataManager->getMessage(resNum, lineNum);
+
+ // Get the needed rect, and move it to the desired position
+ Rect textRect;
+ _globals->gfxManager().getStringBounds(msg.c_str(), textRect, width);
+ Rect sceneBounds = _globals->_sceneManager._scene->_sceneBounds;
+ sceneBounds.collapse(4, 2);
+ textRect.moveTo(pt);
+ textRect.contain(sceneBounds);
+
+ // Set the text message
+ _sceneText.setup(msg);
+ _sceneText.setPosition(Common::Point(textRect.left, textRect.top));
+ _sceneText.setPriority2(255);
+ _sceneText.show();
+
+ // Set the delay based on the number of words
+ int numWords = 0;
+ const char *msgP = msg.c_str();
+ while (*msgP) {
+ if (*msgP++ == ' ')
+ ++numWords;
+ }
+
+ setDelay(numWords * 18 + 120);
+}
+
+SequenceManager *SequenceManager::globalManager() {
+ return &_globals->_sequenceManager;
+}
+
+/*--------------------------------------------------------------------------*/
+
+ConversationChoiceDialog::ConversationChoiceDialog() {
+ _stdColour = 23;
+ _highlightColour = _globals->_scenePalette._colours.background;
+ _fontNumber = 1;
+}
+
+int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
+ _gfxManager._font.setFontNumber(_fontNumber);
+
+ _bounds = Rect(20, 0, 20, 0);
+ _choiceList.clear();
+
+ // Set up the list of choices
+ int yp = 0;
+ for (uint idx = 0; idx < choiceList.size(); ++idx) {
+ Rect tempRect;
+ _gfxManager._font.getStringBounds(choiceList[idx].c_str(), tempRect, 265);
+ tempRect.moveTo(25, yp + 10);
+
+ _choiceList.push_back(ChoiceEntry(choiceList[idx], tempRect));
+ yp += tempRect.height() + 5;
+ _bounds.extend(tempRect);
+ }
+ _selectedIndex = _choiceList.size();
+
+ // Set the position for the dialog
+ _bounds.bottom -= 10;
+ yp = 180 - _bounds.height();
+ _bounds.translate(0, yp);
+ _bounds.right = _bounds.left + 280;
+
+ // Draw the dialog
+ draw();
+ _globals->_events.showCursor();
+
+ // Event handling loop
+ Event event;
+ while (!_vm->getEventManager()->shouldQuit()) {
+ while (!_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) &&
+ !_vm->getEventManager()->shouldQuit())
+ ;
+ if (_vm->getEventManager()->shouldQuit())
+ break;
+
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode >= Common::KEYCODE_1) &&
+ (event.kbd.keycode <= (Common::KEYCODE_0 + (int)_choiceList.size()))) {
+ // Selected an option by number
+ _selectedIndex = event.kbd.keycode - Common::KEYCODE_1;
+ break;
+ } else if ((_selectedIndex != _choiceList.size()) && ((event.eventType == EVENT_BUTTON_DOWN) ||
+ (event.eventType == EVENT_BUTTON_UP))) {
+ // Item selected
+ break;
+ } else {
+ // Check if any item is highlighted
+ event.mousePos.x -= _gfxManager._bounds.left;
+ event.mousePos.y -= _gfxManager._bounds.top;
+
+ uint idx = 0;
+ while ((idx < _choiceList.size()) && !_choiceList[idx]._bounds.contains(event.mousePos.x, event.mousePos.y))
+ ++idx;
+
+ if (idx != _selectedIndex) {
+ if (_selectedIndex != _choiceList.size()) {
+ // De-highlight previously selected item
+ _gfxManager._font._colours.foreground = _stdColour;
+ _gfxManager._font.writeLines(_choiceList[_selectedIndex]._msg.c_str(),
+ _choiceList[_selectedIndex]._bounds, ALIGN_LEFT);
+ }
+
+ _selectedIndex = idx;
+
+ if (_selectedIndex != _choiceList.size()) {
+ // Highlight the new item
+ _gfxManager._font._colours.foreground = _highlightColour;
+ _gfxManager._font.writeLines(_choiceList[idx]._msg.c_str(), _choiceList[idx]._bounds, ALIGN_LEFT);
+ }
+
+ }
+ }
+ }
+
+ // Remove the dialog
+ remove();
+
+ return _selectedIndex;
+}
+
+void ConversationChoiceDialog::draw() {
+ // Make a backup copy of the area the dialog will occupy
+ Rect tempRect = _bounds;
+ tempRect.collapse(-10, -10);
+ _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), tempRect);
+
+ // Fill in the contents of the entire dialog
+ _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ drawFrame();
+
+ _gfxManager._bounds = tempRect;
+ _gfxManager._font._colours.foreground = _stdColour;
+ _gfxManager.activate();
+
+ // Loop through writing the conversation choices
+ for (uint idx = 0; idx < _choiceList.size(); ++idx) {
+ Common::String strNum = Common::String::format("%d", idx + 1);
+
+ // Write the choice number
+ _gfxManager._font.setPosition(13, _choiceList[idx]._bounds.top);
+ _gfxManager._font.writeString(strNum.c_str());
+
+ _gfxManager._font.writeLines(_choiceList[idx]._msg.c_str(), _choiceList[idx]._bounds, ALIGN_LEFT);
+ }
+
+ _gfxManager.deactivate();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Obj44::load(const byte *dataP) {
+ _id = READ_LE_UINT16(dataP);
+ for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx)
+ _field2[idx] = READ_LE_UINT16(dataP + 2 + idx * 2);
+
+ const byte *listP = dataP + 0x10;
+ for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx, listP += 10) {
+ _list[idx]._id = READ_LE_UINT16(listP);
+ _list[idx]._scriptOffset = READ_LE_UINT16(listP + 2);
+ }
+
+ _speakerOffset = READ_LE_UINT16(dataP + 0x42);
+}
+
+void Obj44::synchronise(Serialiser &s) {
+ s.syncAsSint32LE(_id);
+ for (int i = 0; i < OBJ44_LIST_SIZE; ++i)
+ s.syncAsSint32LE(_field2[i]);
+ for (int i = 0; i < OBJ44_LIST_SIZE; ++i)
+ _list[OBJ44_LIST_SIZE].synchronise(s);
+ s.syncAsUint32LE(_speakerOffset);
+}
+
+/*--------------------------------------------------------------------------*/
+
+StripManager::StripManager() {
+ _callbackObject = NULL;
+ _activeSpeaker = NULL;
+ reset();
+}
+
+StripManager::~StripManager() {
+}
+
+void StripManager::start(int stripNum, EventHandler *owner, StripCallback *callback) {
+ reset();
+
+ _stripNum = stripNum;
+ _callbackObject = callback;
+ _sceneNumber = _globals->_sceneManager._sceneNumber;
+ _sceneBounds = _globals->_sceneManager._scene->_sceneBounds;
+ _script.clear();
+
+ assert(owner);
+ owner->setAction(this, owner);
+}
+
+void StripManager::reset() {
+ _actionIndex = 0;
+ _delayFrames = 0;
+ _owner = NULL;
+ _fmt = NULL;
+ _field2E6 = false;
+ _stripNum = -1;
+ _obj44Index = 0;
+ _field2E8 = 0;
+ _field20 = 0;
+ _activeSpeaker = NULL;
+ _textShown = false;
+ _callbackObject = NULL;
+
+ _obj44List.clear();
+ if (!_script.empty()) {
+ _script.clear();
+ }
+}
+
+void StripManager::load() {
+ // Get the script
+ byte *script = _vm->_dataManager->getResource(RES_STRIP, _stripNum, 2);
+ uint scriptSize = _vm->_memoryManager.getSize(script);
+
+ _script.resize(scriptSize);
+ Common::copy(script, script + scriptSize, &_script[0]);
+
+ DEALLOCATE(script);
+
+ // Get the object list
+ byte *obj44List = _vm->_dataManager->getResource(RES_STRIP, _stripNum, 1);
+ int dataSize = _vm->_memoryManager.getSize(obj44List);
+ assert((dataSize % 0x44) == 0);
+
+ byte *dataP = obj44List;
+ for (int idx = 0; idx < (dataSize / 0x44); ++idx, dataP += 0x44) {
+ Obj44 obj;
+ obj.load(dataP);
+ _obj44List.push_back(obj);
+ }
+
+ DEALLOCATE(obj44List);
+}
+
+void StripManager::synchronise(Serialiser &s) {
+ s.syncAsSint32LE(_stripNum);
+ s.syncAsSint32LE(_obj44Index);
+ s.syncAsSint32LE(_field20);
+ s.syncAsSint32LE(_sceneNumber);
+ _sceneBounds.synchronise(s);
+ SYNC_POINTER(_activeSpeaker);
+ s.syncAsByte(_textShown);
+ s.syncAsByte(_field2E6);
+ s.syncAsSint32LE(_field2E8);
+
+ // Synchronise the item list
+ int arrSize = _obj44List.size();
+ s.syncAsUint16LE(arrSize);
+ if (s.isLoading())
+ _obj44List.resize(arrSize);
+ for (int i = 0; i < arrSize; ++i)
+ _obj44List[i].synchronise(s);
+
+ // Synhcronise script data
+ int scriptSize = _script.size();
+ s.syncAsUint16LE(scriptSize);
+ if (s.isLoading())
+ _script.resize(scriptSize);
+ if (scriptSize > 0)
+ s.syncBytes(&_script[0], scriptSize);
+
+ // Add speaker list
+ arrSize = _speakerList.size();
+ s.syncAsUint16LE(arrSize);
+ if (s.isLoading())
+ _speakerList.resize(arrSize);
+ for (int i = 0; i < arrSize; ++i)
+ SYNC_POINTER(_speakerList[i]);
+
+ SYNC_POINTER(_callbackObject);
+}
+
+void StripManager::remove() {
+ if (_textShown) {
+ if (_activeSpeaker)
+ _activeSpeaker->removeText();
+ _textShown = false;
+ }
+
+ if (_activeSpeaker)
+ _activeSpeaker->remove();
+
+ if (_sceneNumber != _globals->_sceneManager._scene->_sceneNumber) {
+ _globals->_sceneManager._scene->_sceneBounds = _sceneBounds;
+ _globals->_sceneManager._scene->loadScene(_sceneNumber);
+ }
+
+ Action::remove();
+}
+
+void StripManager::signal() {
+ if (_textShown) {
+ _activeSpeaker->removeText();
+ _textShown = false;
+ }
+
+ if (_obj44Index < 0) {
+ EventHandler *owner = _fmt;
+ int stripNum = ABS(_obj44Index);
+ remove();
+
+ start(stripNum, owner);
+ return;
+ } else if (_obj44Index == 10000) {
+ // Reached end of strip
+ remove();
+ return;
+ }
+
+ // Run strip
+
+ if (_obj44List.size() == 0)
+ // Load the data for the strip
+ load();
+
+ Obj44 &obj44 = _obj44List[_obj44Index];
+ _field2E8 = obj44._id;
+ Common::StringArray choiceList;
+
+ // Build up a list of script entries
+ int idx;
+ for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
+ if (!obj44._list[idx]._id)
+ break;
+
+ // Get the next one
+ choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset);
+ }
+
+ int strIndex = 0;
+ if (choiceList.size() > 1)
+ // Get the user to select a conversation option
+ strIndex = _choiceDialog.execute(choiceList);
+
+ if ((choiceList.size() != 1) && !_field2E6)
+ _delayFrames = 1;
+ else {
+ Speaker *speakerP = getSpeaker((const char *)&_script[0] + obj44._speakerOffset);
+ if (!speakerP)
+ error("Speaker not found. Screenplay: %s %d", (const char *)&_script[0] + obj44._speakerOffset, _stripNum);
+
+ if (speakerP != _activeSpeaker) {
+ if (_activeSpeaker)
+ _activeSpeaker->remove();
+ _activeSpeaker = speakerP;
+
+ if ((_activeSpeaker->_newSceneNumber == -1) && (_globals->_sceneManager._scene->_sceneNumber != _sceneNumber)) {
+ _globals->_sceneManager._scene->_sceneBounds = _sceneBounds;
+ _globals->_sceneManager._scene->loadScene(_sceneNumber);
+ }
+
+ _activeSpeaker->proc12(this);
+ }
+
+ if (_callbackObject) {
+ for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) {
+ if (!obj44._field2[idx])
+ break;
+
+ _callbackObject->stripCallback(obj44._field2[idx]);
+ }
+ }
+
+ _textShown = true;
+ _activeSpeaker->setText(choiceList[strIndex]);
+ }
+
+ _obj44Index = getNewIndex(obj44._list[strIndex]._id);
+ if (_obj44Index == 10001) {
+ MessageDialog::show("Strip Failure: Node not found", OK_BTN_STRING);
+ _obj44Index = 0;
+ }
+}
+
+void StripManager::process(Event &event) {
+ Action::process(event);
+ if (event.handled)
+ return;
+
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ if (_obj44Index != 10000) {
+ int currIndex = _obj44Index;
+ while (!_obj44List[_obj44Index + 1]._id) {
+ _obj44Index = getNewIndex(_obj44List[_obj44Index]._id);
+ if ((_obj44Index < 0) || (_obj44Index == 10000))
+ break;
+ currIndex = _obj44Index;
+ }
+
+ _field2E8 = _obj44List[currIndex]._id;
+ }
+
+ // Signal the end of the strip
+ _delayFrames = 0;
+ event.handled = true;
+ signal();
+ } else if (event.eventType & (EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) {
+ // Move to next sequence in the strip
+ _delayFrames = 0;
+ event.handled = true;
+ signal();
+ }
+}
+
+void StripManager::addSpeaker(Speaker *speaker) {
+ assert(_speakerList.size() < 100);
+ _speakerList.push_back(speaker);
+}
+
+Speaker *StripManager::getSpeaker(const char *speakerName) {
+ for (uint idx = 0; idx < _speakerList.size(); ++idx) {
+ if (!strcmp(_speakerList[idx]->_speakerName.c_str(), speakerName))
+ return _speakerList[idx];
+ }
+
+ return NULL;
+}
+
+int StripManager::getNewIndex(int id) {
+ if (id == 10000)
+ return id;
+
+ for (uint idx = 0; idx < _obj44List.size(); ++idx) {
+ if (_obj44List[idx]._id == id) {
+ return (id == 0) ? 10001 : idx;
+ }
+ }
+
+ return 10001;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Speaker::Speaker() : EventHandler() {
+ _newSceneNumber = -1;
+ _hideObjects = true;
+ _field18 = 0;
+ _textWidth = 140;
+ _textPos = Common::Point(10, 20);
+ _fontNumber = 2;
+ _textMode = ALIGN_LEFT;
+ _colour1 = _colour2 = _colour3 = _globals->_scenePalette._colours.foreground;
+ _action = NULL;
+ _speakerName = "SPEAKER";
+}
+
+void Speaker::synchronise(Serialiser &s) {
+ _fieldA.synchronise(s);
+ SYNC_POINTER(_field18);
+ s.syncString(_speakerName);
+ s.syncAsSint32LE(_newSceneNumber);
+ s.syncAsSint32LE(_oldSceneNumber);
+ _sceneBounds.synchronise(s);
+ s.syncAsSint32LE(_textWidth);
+ s.syncAsSint16LE(_textPos.x); s.syncAsSint16LE(_textPos.y);
+ s.syncAsSint32LE(_fontNumber);
+ SYNC_ENUM(_textMode, TextAlign);
+ s.syncAsSint16LE(_colour1);
+ s.syncAsSint16LE(_colour2);
+ s.syncAsSint16LE(_colour3);
+ s.syncAsByte(_hideObjects);
+}
+
+void Speaker::remove() {
+ if (_hideObjects)
+ SceneObjectList::deactivate();
+}
+
+void Speaker::proc12(Action *action) {
+ _action = action;
+ if (_newSceneNumber != -1) {
+ _oldSceneNumber = _globals->_sceneManager._sceneNumber;
+ _sceneBounds = _globals->_sceneManager._scene->_sceneBounds;
+ _globals->_sceneManager._scene->loadScene(_newSceneNumber);
+ }
+
+ if (_hideObjects)
+ // Activate the object list for display
+ _objectList.activate();
+
+ // Draw the speaker objects without any fading
+ FadeMode fadeMode = _globals->_sceneManager._fadeMode;
+ _globals->_sceneManager._fadeMode = FADEMODE_IMMEDIATE;
+ _globals->_sceneObjects->draw();
+ _globals->_sceneManager._fadeMode = fadeMode;
+}
+
+void Speaker::setText(const Common::String &msg) {
+ _globals->_sceneObjects->draw();
+
+ _sceneText._colour1 = _colour1;
+ _sceneText._colour2 = _colour2;
+ _sceneText._colour3 = _colour3;
+ _sceneText._width = _textWidth;
+ _sceneText._fontNumber = _fontNumber;
+ _sceneText._textMode = _textMode;
+ _sceneText.setup(msg);
+ _sceneText.setPosition(_textPos);
+ _sceneText.setPriority2(256);
+
+ // Count the number of words (by spaces) in the string
+ const char *msgP = msg.c_str();
+ int spaceCount = 0;
+ while (*msgP) {
+ if (*msgP++ == ' ')
+ ++spaceCount;
+ }
+
+ int numFrames = spaceCount * STRIP_WORD_DELAY + 120;
+ if (_action)
+ _action->setDelay(numFrames);
+}
+
+void Speaker::removeText() {
+ _sceneText.remove();
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerGameText::SpeakerGameText() : Speaker() {
+ _speakerName = "GAMETEXT";
+ _textPos = Common::Point(40, 40);
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 7;
+ _textWidth = 230;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScreenSpeaker::ScreenSpeaker() : Speaker() {
+ _npc = NULL;
+ _textMode = ALIGN_CENTRE;
+}
+
+void ScreenSpeaker::setText(const Common::String &msg) {
+ GfxManager gfxMan;
+ gfxMan.activate();
+ gfxMan._font.setFontNumber(_fontNumber);
+ Rect textRect;
+
+ _globals->gfxManager().getStringBounds(msg.c_str(), textRect, _textWidth);
+ if (_npc) {
+ textRect.centre(_npc->_position.x, _npc->_bounds.top - (textRect.height() / 2 + 10));
+ } else {
+ textRect.centre(_globals->_sceneManager._scene->_sceneBounds.left +
+ (_globals->_sceneManager._scene->_sceneBounds.width() / 2),
+ _globals->_sceneManager._scene->_sceneBounds.top);
+ }
+
+ Rect rect2 = _globals->_sceneManager._scene->_sceneBounds;
+ rect2.collapse(10, 6);
+ textRect.contain(rect2);
+
+ _textPos.x = textRect.left;
+ _textPos.y = textRect.top;
+ Speaker::setText(msg);
+
+ gfxMan.deactivate();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SpeakerAction::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(60) + 60);
+ break;
+ case 1:
+ static_cast<SceneObject *>(_owner)->setFrame(1);
+ static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_5, this, NULL);
+ break;
+ case 2:
+ setDelay(_globals->_randomSource.getRandomNumber(10));
+ _actionIndex = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void AnimatedSpeaker::removeText() {
+ Speaker::removeText();
+ _object1.remove();
+ _object2.remove();
+
+ _objectList.draw();
+}
+
+} // end of namespace tSage
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
new file mode 100644
index 0000000000..4d6e51a6b8
--- /dev/null
+++ b/engines/tsage/converse.h
@@ -0,0 +1,229 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_CONVERSE_H
+#define TSAGE_CONVERSE_H
+
+#include "tsage/core.h"
+#include "tsage/dialogs.h"
+
+namespace tSage {
+
+class StripCallback : public Action {
+public:
+ virtual void stripCallback(int v) = 0;
+};
+
+class SequenceManager : public Action {
+private:
+ void setup();
+ uint16 getNextValue();
+ void setMessage(int resNum, int lineNum, int colour, const Common::Point &pt, int width);
+ SequenceManager *globalManager();
+public:
+ SceneText _sceneText;
+ int _resNum;
+ uint _sequenceOffset;
+ bool _keepActive;
+ int _field24;
+ int _field26;
+ Common::Array<byte> _sequenceData;
+ int _objectIndex;
+ SceneObject *_sceneObject;
+ SceneObject *_objectList[6];
+ SoundHandler _soundHandler;
+public:
+ SequenceManager();
+
+ virtual Common::String getClassName() { return "SequenceManager"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void attached(EventHandler *newOwner, EventHandler *fmt, va_list va);
+};
+
+
+class Speaker : public EventHandler {
+public:
+ Rect _fieldA;
+ Action *_field18;
+ Common::String _speakerName;
+ int _newSceneNumber;
+ int _oldSceneNumber;
+ SceneObjectList _objectList;
+ Rect _sceneBounds;
+ SceneText _sceneText;
+ int _textWidth;
+ Common::Point _textPos;
+ int _fontNumber;
+ TextAlign _textMode;
+ int _colour1, _colour2, _colour3;
+ bool _hideObjects;
+public:
+ Speaker();
+
+ virtual Common::String getClassName() { return "Speaker"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void remove();
+ virtual void proc12(Action *action);
+ virtual void setText(const Common::String &msg);
+ virtual void removeText();
+
+ void setTextPos(const Common::Point &pt) { _textPos = pt; }
+};
+
+class SpeakerGameText : public Speaker {
+public:
+ SpeakerGameText();
+
+ virtual Common::String getClassName() { return "SpeakerGameText"; }
+};
+
+class ScreenSpeaker : public Speaker {
+public:
+ SceneItem *_npc;
+public:
+ ScreenSpeaker();
+
+ virtual Common::String getClassName() { return "ScreenSpeaker"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerAction : public Action {
+public:
+ virtual void signal();
+
+ virtual Common::String getClassName() { return "SpeakerAction"; }
+};
+
+class AnimatedSpeaker : public Speaker {
+public:
+ SceneObject _object1;
+ SceneObject _object2;
+ SpeakerAction _speakerAction;
+public:
+ virtual Common::String getClassName() { return "AnimatedSpeaker"; }
+ virtual void removeText();
+};
+
+class ChoiceEntry {
+public:
+ Common::String _msg;
+ Rect _bounds;
+
+ ChoiceEntry() {}
+ ChoiceEntry(const Common::String &msg, const Rect &bounds) {
+ _msg = msg;
+ _bounds = bounds;
+ }
+};
+
+class ConversationChoiceDialog : public ModalDialog {
+public:
+ int _stdColour;
+ int _highlightColour;
+ int _fontNumber;
+ int _savedFgColour;
+ int _savedFontNumber;
+ Common::Array<ChoiceEntry> _choiceList;
+ uint _selectedIndex;
+public:
+ ConversationChoiceDialog();
+
+ void setColours(int stdColour, int highlightColour) {
+ _stdColour = stdColour;
+ _highlightColour = highlightColour;
+ }
+ void setFontNumber(int fontNum) { _fontNumber = fontNum; }
+ int execute(const Common::StringArray &choiceList);
+
+ virtual void draw();
+};
+
+class Obj0A : public Serialisable {
+public:
+ int _id;
+ uint _scriptOffset;
+
+ virtual void synchronise(Serialiser &s) {
+ s.syncAsSint32LE(_id);
+ s.syncAsUint32LE(_scriptOffset);
+ }
+};
+
+#define OBJ44_LIST_SIZE 5
+
+class Obj44 : public Serialisable {
+public:
+ int _id;
+ int _field2[OBJ44_LIST_SIZE];
+ Obj0A _list[OBJ44_LIST_SIZE];
+ uint _speakerOffset;
+public:
+ void load(const byte *dataP);
+ virtual void synchronise(Serialiser &s);
+};
+
+class StripManager : public Action {
+private:
+ void reset();
+ void load();
+ Speaker *getSpeaker(const char *speakerName);
+ int getNewIndex(int newId);
+public:
+ int _stripNum;
+ int _obj44Index;
+ int _field20;
+ int _sceneNumber;
+ Rect _sceneBounds;
+ ConversationChoiceDialog _choiceDialog;
+ Common::Array<Speaker *> _speakerList;
+ StripCallback *_callbackObject;
+ Speaker *_activeSpeaker;
+ bool _textShown;
+ bool _field2E6;
+ int _field2E8;
+ Common::Array<Obj44> _obj44List;
+ Common::Array<byte> _script;
+public:
+ StripManager();
+ virtual ~StripManager();
+
+ virtual void synchronise(Serialiser &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+
+ void start(int stripNum, EventHandler *owner, StripCallback *callback = NULL);
+ void setCallback(StripCallback *callback) { _callbackObject = callback; }
+ void setColours(int stdColour, int highlightColour) { _choiceDialog.setColours(stdColour, highlightColour); }
+ void setFontNumber(int fontNum) { _choiceDialog.setFontNumber(fontNum); }
+ void addSpeaker(Speaker *speaker);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
new file mode 100644
index 0000000000..81088b4eaa
--- /dev/null
+++ b/engines/tsage/core.cpp
@@ -0,0 +1,3735 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/system.h"
+#include "common/config-manager.h"
+#include "common/translation.h"
+#include "engines/engine.h"
+#include "gui/saveload.h"
+#include "tsage/tsage.h"
+#include "tsage/core.h"
+#include "tsage/dialogs.h"
+#include "tsage/events.h"
+#include "tsage/scenes.h"
+#include "tsage/staticres.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+// The engine uses ScumMVM screen buffering, so all logic is hardcoded to use pane buffer 0
+#define CURRENT_PANENUM 0
+
+/*--------------------------------------------------------------------------*/
+
+InvObject::InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType cursorId, const Common::String description) :
+ _sceneNumber(sceneNumber), _rlbNum(rlbNum), _cursorNum(cursorNum), _cursorId(cursorId),
+ _description(description) {
+ _displayResNum = 3;
+ _iconResNum = 5;
+
+ // Decode the image for the inventory item to get it's display bounds
+ uint size;
+ byte *imgData = _vm->_dataManager->getSubResource(_displayResNum, _rlbNum, _cursorNum, &size);
+ GfxSurface s = surfaceFromRes(imgData);
+ _bounds = s.getBounds();
+
+ DEALLOCATE(imgData);
+}
+
+void InvObject::setCursor() {
+ _globals->_events._currentCursor = _cursorId;
+
+ if (_iconResNum != -1) {
+ GfxSurface s = surfaceFromRes(_iconResNum, _rlbNum, _cursorNum);
+
+ Graphics::Surface src = s.lockSurface();
+ _globals->_events.setCursor(src, s._transColour, s._centroid, _cursorId);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+InvObjectList::InvObjectList() :
+ _stunner(2280, 1, 2, OBJECT_STUNNER, "This is your stunner."),
+ _scanner(1, 1, 3, OBJECT_SCANNER, "A combination scanner comm unit."),
+ _stasisBox(5200, 1, 4, OBJECT_STASIS_BOX, "A stasis box."),
+ _infoDisk(40, 1, 1, OBJECT_INFODISK, "The infodisk you took from the assassin."),
+ _stasisNegator(0, 2, 2, OBJECT_STASIS_NEGATOR, "The stasis field negator."),
+ _keyDevice(4250, 1, 6, OBJECT_KEY_DEVICE, "A magnetic key device."),
+ _medkit(2280, 1, 7, OBJECT_MEDKIT, "Your medkit."),
+ _ladder(4100, 1, 8, OBJECT_LADDER, "The chief's ladder."),
+ _rope(4150, 1, 9, OBJECT_ROPE, "The chief's rope."),
+ _key(7700, 1, 11, OBJECT_KEY, "A key."),
+ _translator(7700, 1, 13, OBJECT_TRANSLATOR, "The dolphin translator box."),
+ _ale(2150, 1, 10, OBJECT_ALE, "A bottle of ale."),
+ _paper(7700, 1, 12, OBJECT_PAPER, "A slip of paper with the numbers 2,4, and 3 written on it."),
+ _waldos(0, 1, 14, OBJECT_WALDOS, "A pair of waldos from the ruined probe."),
+ _stasisBox2(8100, 1, 4, OBJECT_STASIS_BOX2, "A stasis box."),
+ _ring(8100, 2, 5, OBJECT_RING, "This is a signet ring sent to you by Louis Wu."),
+ _cloak(9850, 2, 6, OBJECT_CLOAK, "A fine silk cloak."),
+ _tunic(9450, 2, 7, OBJECT_TUNIC, "The patriarch's soiled tunic."),
+ _candle(9500, 2, 8, OBJECT_CANDLE, "A tallow candle."),
+ _straw(9400, 2, 9, OBJECT_STRAW, "Clean, dry straw."),
+ _scimitar(9850, 1, 18, OBJECT_SCIMITAR, "A scimitar from the Patriarch's closet."),
+ _sword(9850, 1, 17, OBJECT_SWORD, "A short sword from the Patriarch's closet."),
+ _helmet(9500, 2, 4, OBJECT_HELMET, "Some type of helmet."),
+ _items(4300, 2, 10, OBJECT_ITEMS, "Two interesting items from the Tnuctipun vessel."),
+ _concentrator(4300, 2, 11, OBJECT_CONCENTRATOR, "The Tnuctipun anti-matter concentrator contained in a stasis field."),
+ _nullifier(5200, 2, 12, OBJECT_NULLIFIER, "A purported neural wave nullifier."),
+ _peg(4045, 2, 16, OBJECT_PEG, "A peg with a symbol."),
+ _vial(5100, 2, 17, OBJECT_VIAL, "A vial of the bat creatures anti-pheromone drug."),
+ _jacket(9850, 3, 1, OBJECT_JACKET, "A natty padded jacket."),
+ _tunic2(9850, 3, 2, OBJECT_TUNIC2, "A very hairy tunic."),
+ _bone(5300, 3, 5, OBJECT_BONE, "A very sharp bone."),
+ _jar(7700, 3, 4, OBJECT_JAR, "An jar filled with a green substance."),
+ _emptyJar(7700, 3, 3, OBJECT_EMPTY_JAR, "An empty jar.") {
+
+ // Add the items to the list
+ _itemList.push_back(&_stunner);
+ _itemList.push_back(&_scanner);
+ _itemList.push_back(&_stasisBox);
+ _itemList.push_back(&_infoDisk);
+ _itemList.push_back(&_stasisNegator);
+ _itemList.push_back(&_keyDevice);
+ _itemList.push_back(&_medkit);
+ _itemList.push_back(&_ladder);
+ _itemList.push_back(&_rope);
+ _itemList.push_back(&_key);
+ _itemList.push_back(&_translator);
+ _itemList.push_back(&_ale);
+ _itemList.push_back(&_paper);
+ _itemList.push_back(&_waldos);
+ _itemList.push_back(&_stasisBox2);
+ _itemList.push_back(&_ring);
+ _itemList.push_back(&_cloak);
+ _itemList.push_back(&_tunic);
+ _itemList.push_back(&_candle);
+ _itemList.push_back(&_straw);
+ _itemList.push_back(&_scimitar);
+ _itemList.push_back(&_sword);
+ _itemList.push_back(&_helmet);
+ _itemList.push_back(&_items);
+ _itemList.push_back(&_concentrator);
+ _itemList.push_back(&_nullifier);
+ _itemList.push_back(&_peg);
+ _itemList.push_back(&_vial);
+ _itemList.push_back(&_jacket);
+ _itemList.push_back(&_tunic2);
+ _itemList.push_back(&_bone);
+ _itemList.push_back(&_jar);
+ _itemList.push_back(&_emptyJar);
+
+ _selectedItem = NULL;
+}
+
+void InvObjectList::synchronise(Serialiser &s) {
+ SavedObject::synchronise(s);
+ SYNC_POINTER(_selectedItem);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void EventHandler::dispatch() {
+ if (_action) _action->dispatch();
+}
+
+void EventHandler::setAction(Action *action, EventHandler *fmt, ...) {
+ if (_action) {
+ _action->_fmt = NULL;
+ _action->remove();
+ }
+
+ _action = action;
+ if (action) {
+ va_list va;
+ va_start(va, fmt);
+ _action->attached(this, fmt, va);
+ va_end(va);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Action::Action() {
+ _actionIndex = 0;
+ _owner = NULL;
+ _fmt = NULL;
+}
+
+void Action::synchronise(Serialiser &s) {
+ EventHandler::synchronise(s);
+ if (s.isLoading())
+ remove();
+
+ SYNC_POINTER(_owner);
+ s.syncAsSint32LE(_actionIndex);
+ s.syncAsSint32LE(_delayFrames);
+ s.syncAsUint32LE(_startFrame);
+ s.syncAsSint16LE(_field16);
+ SYNC_POINTER(_fmt);
+}
+
+void Action::remove() {
+ if (_action)
+ _action->remove();
+
+ if (_owner) {
+ _owner->_action = NULL;
+ _owner = NULL;
+ } else {
+ _globals->_sceneManager.removeAction(this);
+ }
+
+ _field16 = 0;
+ if (_fmt)
+ _fmt->signal();
+}
+
+void Action::process(Event &event) {
+ if (_action)
+ _action->process(event);
+}
+
+void Action::dispatch() {
+ if (_action)
+ _action->dispatch();
+
+ if (_delayFrames) {
+ uint32 frameNumber = _globals->_events.getFrameNumber();
+
+ if (frameNumber >= _startFrame) {
+ _delayFrames -= frameNumber - _startFrame;
+ _startFrame = frameNumber;
+ if (_delayFrames <= 0) {
+ _delayFrames = 0;
+ signal();
+ }
+ }
+ }
+}
+
+void Action::attached(EventHandler *newOwner, EventHandler *fmt, va_list va) {
+ _actionIndex = 0;
+ _delayFrames = 0;
+ _startFrame = _globals->_events.getFrameNumber();
+ _owner = newOwner;
+ _fmt = fmt;
+ _field16 = 1;
+ signal();
+}
+
+void Action::setDelay(int numFrames) {
+ _delayFrames = numFrames;
+ _startFrame = _globals->_events.getFrameNumber();
+}
+
+/*--------------------------------------------------------------------------*/
+
+ObjectMover::~ObjectMover() {
+ if (_sceneObject->_mover == this)
+ _sceneObject->_mover = NULL;
+}
+
+void ObjectMover::synchronise(Serialiser &s) {
+ EventHandler::synchronise(s);
+
+ s.syncAsSint16LE(_destPosition.x); s.syncAsSint16LE(_destPosition.y);
+ s.syncAsSint16LE(_moveDelta.x); s.syncAsSint16LE(_moveDelta.y);
+ s.syncAsSint16LE(_moveSign.x); s.syncAsSint16LE(_moveSign.y);
+ s.syncAsSint32LE(_minorDiff);
+ s.syncAsSint32LE(_majorDiff);
+ s.syncAsSint32LE(_field1A);
+ SYNC_POINTER(_action);
+ SYNC_POINTER(_sceneObject);
+}
+
+void ObjectMover::remove() {
+ if (_sceneObject->_mover == this)
+ _sceneObject->_mover = NULL;
+
+ delete this;
+}
+
+void ObjectMover::dispatch() {
+ Common::Point currPos = _sceneObject->_position;
+ int yDiff = _sceneObject->_yDiff;
+
+ if (dontMove())
+ return;
+
+ _sceneObject->_regionIndex = 0;
+ if (_moveDelta.x >= _moveDelta.y) {
+ int xAmount = _moveSign.x * _sceneObject->_moveDiff.x * _sceneObject->_percent / 100;
+ if (!xAmount)
+ xAmount = _moveSign.x;
+ currPos.x += xAmount;
+
+ int yAmount = ABS(_destPosition.y - currPos.y);
+ int yChange = _majorDiff / ABS(xAmount);
+ int ySign;
+
+ if (!yChange)
+ ySign = _moveSign.y;
+ else {
+ int v = yAmount / yChange;
+ _field1A += yAmount % yChange;
+ if (_field1A >= yChange) {
+ ++v;
+ _field1A -= yChange;
+ }
+
+ ySign = _moveSign.y * v;
+ }
+
+ currPos.y += ySign;
+ _majorDiff -= ABS(xAmount);
+
+ } else {
+ int yAmount = _moveSign.y * _sceneObject->_moveDiff.y * _sceneObject->_percent / 100;
+ if (!yAmount)
+ yAmount = _moveSign.y;
+ currPos.y += yAmount;
+
+ int xAmount = ABS(_destPosition.x - currPos.x);
+ int xChange = _majorDiff / ABS(yAmount);
+ int xSign;
+
+ if (!xChange)
+ xSign = _moveSign.x;
+ else {
+ int v = xAmount / xChange;
+ _field1A += xAmount % xChange;
+ if (_field1A >= xChange) {
+ ++v;
+ _field1A -= xChange;
+ }
+
+ xSign = _moveSign.x * v;
+ }
+
+ currPos.x += xSign;
+ _majorDiff -= ABS(yAmount);
+ }
+
+ _sceneObject->_regionIndex = _sceneObject->checkRegion(currPos);
+ if (!_sceneObject->_regionIndex) {
+ _sceneObject->setPosition(currPos, yDiff);
+ _sceneObject->getHorizBounds();
+
+ if (dontMove()) {
+ _sceneObject->_position = _destPosition;
+ endMove();
+ }
+ } else {
+ endMove();
+ }
+}
+
+void ObjectMover::setup(const Common::Point &destPos) {
+ _sceneObject->calcAngle(destPos);
+
+ if ((_sceneObject->_objectWrapper) && !(_sceneObject->_flags & OBJFLAG_SUPPRESS_DISPATCH))
+ _sceneObject->_objectWrapper->dispatch();
+
+ // Get the difference
+ int diffX = destPos.x - _sceneObject->_position.x;
+ int diffY = destPos.y - _sceneObject->_position.y;
+ int xSign = (diffX < 0) ? -1 : (diffX > 0 ? 1 : 0);
+ int ySign = (diffY < 0) ? -1 : (diffY > 0 ? 1 : 0);
+ diffX = ABS(diffX);
+ diffY = ABS(diffY);
+
+ if (diffX < diffY) {
+ _minorDiff = diffX / 2;
+ _majorDiff = diffY;
+ } else {
+ _minorDiff = diffY / 2;
+ _majorDiff = diffX;
+ }
+
+ // Set the destination position
+ _destPosition = destPos;
+ _moveDelta = Common::Point(diffX, diffY);
+ _moveSign = Common::Point(xSign, ySign);
+ _field1A = 0;
+
+ if (!diffX && !diffY)
+ // Object is already at the correct destination
+ endMove();
+}
+
+bool ObjectMover::dontMove() const {
+ return (_majorDiff <= 0);
+}
+
+void ObjectMover::endMove() {
+ EventHandler *actionP = _action;
+ remove();
+
+ if (actionP)
+ actionP->signal();
+}
+
+/*--------------------------------------------------------------------------*/
+
+ObjectMover2::ObjectMover2() : ObjectMover() {
+ _destObject = NULL;
+}
+
+void ObjectMover2::synchronise(Serialiser &s) {
+ ObjectMover::synchronise(s);
+
+ SYNC_POINTER(_destObject);
+ s.syncAsSint32LE(_minArea);
+ s.syncAsSint32LE(_maxArea);
+}
+
+void ObjectMover2::dispatch() {
+ int area = _sceneObject->getSpliceArea(_destObject);
+ if (area > _maxArea) {
+ // Setup again for the new destination
+ setup(_destObject->_position);
+ ObjectMover::dispatch();
+ } else if (area >= _minArea) {
+ // Keep dispatching
+ ObjectMover::dispatch();
+ } else {
+ // Within minimum, so end move
+ endMove();
+ }
+}
+
+void ObjectMover2::startMove(SceneObject *sceneObj, va_list va) {
+ // Set up fields
+ _sceneObject = sceneObj;
+
+ _minArea = va_arg(va, int);
+ _maxArea = va_arg(va, int);
+ _destObject = va_arg(va, SceneObject *);
+
+ setup(_destObject->_position);
+}
+
+void ObjectMover2::endMove() {
+ _sceneObject->_regionIndex = 0x40;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void ObjectMover3::dispatch() {
+ int area = _sceneObject->getSpliceArea(_destObject);
+ if (area <= _minArea) {
+ endMove();
+ } else {
+ setup(_destObject->_position);
+ ObjectMover::dispatch();
+ }
+}
+
+void ObjectMover3::startMove(SceneObject *sceneObj, va_list va) {
+ _sceneObject = sceneObj;
+ _destObject = va_arg(va, SceneObject *);
+ _minArea = va_arg(va, int);
+ _action = va_arg(va, Action *);
+
+ setup(_destObject->_position);
+}
+
+void ObjectMover3::endMove() {
+ ObjectMover::endMove();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void NpcMover::startMove(SceneObject *sceneObj, va_list va) {
+ _sceneObject = sceneObj;
+
+ Common::Point *destPos = va_arg(va, Common::Point *);
+ _action = va_arg(va, Action *);
+
+ setup(*destPos);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void PlayerMover::synchronise(Serialiser &s) {
+ NpcMover::synchronise(s);
+
+ s.syncAsSint16LE(_finalDest.x); s.syncAsSint16LE(_finalDest.y);
+ s.syncAsSint32LE(_routeIndex);
+
+ for (int i = 0; i < MAX_ROUTE_SIZE; ++i) {
+ s.syncAsSint16LE(_routeList[i].x); s.syncAsSint16LE(_routeList[i].y);
+ }
+}
+
+void PlayerMover::startMove(SceneObject *sceneObj, va_list va) {
+ _sceneObject = sceneObj;
+ Common::Point *pt = va_arg(va, Common::Point *);
+ _finalDest = *pt;
+ _action = va_arg(va, Action *);
+
+ setDest(_finalDest);
+}
+
+void PlayerMover::endMove() {
+ while (++_routeIndex != 0) {
+ if ((_routeList[_routeIndex].x == ROUTE_END_VAL) ||
+ (_routeList[_routeIndex].y == ROUTE_END_VAL) ||
+ (_sceneObject->_regionIndex)) {
+ // Movement route is completely finished
+ ObjectMover::endMove();
+ return;
+ }
+
+ if ((_routeList[_routeIndex].x != _sceneObject->_position.x) ||
+ (_routeList[_routeIndex].y != _sceneObject->_position.y))
+ break;
+ }
+
+ // Set up the new interim destination along the route
+ _globals->_walkRegions._routeEnds.moveSrc = _globals->_walkRegions._routeEnds.moveDest;
+ _globals->_walkRegions._routeEnds.moveDest = _routeList[_routeIndex];
+ setup(_routeList[_routeIndex]);
+ dispatch();
+}
+
+void PlayerMover::setDest(const Common::Point &destPos) {
+ _routeList[0] = _sceneObject->_position;
+
+ if (_globals->_walkRegions._resNum == -1) {
+ // Scene has no walk regions defined, so player can walk anywhere directly
+ _routeList[0] = destPos;
+ _routeList[1] = Common::Point(ROUTE_END_VAL, ROUTE_END_VAL);
+ } else {
+ // Figure out a path to the destination (or as close as possible to it)
+ pathfind(_routeList, _sceneObject->_position, destPos, _globals->_walkRegions._routeEnds);
+ }
+
+ _routeIndex = 0;
+ _globals->_walkRegions._routeEnds.moveSrc = _sceneObject->_position;
+ _globals->_walkRegions._routeEnds.moveDest = _routeList[0];
+ setup(_routeList[0]);
+}
+
+#define REGION_LIST_SIZE 20
+
+void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Common::Point destPos, RouteEnds routeEnds) {
+ Common::List<int> regionIndexes;
+ RouteEnds tempRouteEnds;
+ int routeRegions[REGION_LIST_SIZE];
+ Common::Point objPos;
+
+ // Get the region the source is in
+ int srcRegion = _globals->_walkRegions.indexOf(srcPos);
+ if (srcRegion == -1) {
+ srcRegion = findClosestRegion(srcPos, regionIndexes);
+ }
+
+ // Main loop for building up the path
+ routeRegions[0] = 0;
+ while (!routeRegions[0]) {
+ // Check the destination region
+ int destRegion = _globals->_walkRegions.indexOf(destPos, &regionIndexes);
+
+ if ((srcRegion == -1) && (destRegion == -1)) {
+ // Both source and destination are outside walkable areas
+ } else if (srcRegion == -1) {
+ // Source is outside walkable areas
+ tempRouteEnds = routeEnds;
+ objPos = _sceneObject->_position;
+
+ Common::Point newPos;
+ findLinePoint(&tempRouteEnds, &objPos, 1, &newPos);
+ int srcId = _globals->_walkRegions.indexOf(newPos);
+
+ if (srcId == -1) {
+ tempRouteEnds.moveDest = tempRouteEnds.moveSrc;
+ tempRouteEnds.moveSrc = routeEnds.moveDest;
+
+ findLinePoint(&tempRouteEnds, &objPos, 1, &newPos);
+ srcRegion = _globals->_walkRegions.indexOf(newPos);
+
+ if (srcRegion == -1)
+ srcRegion = checkMover(srcPos, destPos);
+ }
+
+ } else if (destRegion == -1) {
+ // Destination is outside walkable areas
+ destRegion = findClosestRegion(destPos, regionIndexes);
+ if (destRegion == -1) {
+ // No further route found, so end it
+ *routeList++ = srcPos;
+ break;
+ } else {
+ _finalDest = destPos;
+ }
+ }
+
+ if (srcRegion == destRegion) {
+ *routeList++ = (srcRegion == -1) ? srcPos : destPos;
+ break;
+ }
+
+ int var6;
+ proc1(routeRegions, srcRegion, destRegion, var6);
+
+ if (!routeRegions[0]) {
+ regionIndexes.push_back(destRegion);
+ continue;
+ }
+
+ _globals->_walkRegions._field18[0]._pt1 = srcPos;
+ _globals->_walkRegions._field18[0]._pt2 = srcPos;
+ _globals->_walkRegions._field18[1]._pt1 = destPos;
+ _globals->_walkRegions._field18[1]._pt2 = destPos;
+
+ int tempList[REGION_LIST_SIZE];
+ tempList[0] = 0;
+ int endIndex = 0;
+ int idx = 1;
+
+ do {
+ int breakEntry = routeRegions[idx];
+ int breakEntry2 = routeRegions[idx + 1];
+
+ int listIndex = 0;
+ while (_globals->_walkRegions._idxList[_globals->_walkRegions[breakEntry]._idxListIndex + listIndex] !=
+ breakEntry2)
+ ++listIndex;
+
+ tempList[idx] = _globals->_walkRegions._idxList2[_globals->_walkRegions[breakEntry]._idxList2Index
+ + listIndex];
+
+ ++endIndex;
+ } while (routeRegions[++idx] != destRegion);
+
+ tempList[idx] = 1;
+ idx = 0;
+ for (int listIndex = 1; listIndex <= endIndex; ++listIndex) {
+ int var10 = tempList[listIndex];
+ int var12 = tempList[listIndex + 1];
+
+ if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt1,
+ _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2) &&
+ sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt2,
+ _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2))
+ continue;
+
+ Common::Point tempPt;
+ if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[1]._pt1,
+ _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2, &tempPt)) {
+ // Add point to the route list
+ _globals->_walkRegions._field18[0]._pt1 = tempPt;
+ *routeList++ = tempPt;
+ } else {
+ int v16 =
+ (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt1) << 1) +
+ (findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[1]._pt1) << 1) +
+ findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt1) +
+ findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt2);
+
+ int v1A =
+ (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt2) << 1) +
+ (findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[1]._pt2) << 1) +
+ findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt1) +
+ findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt2);
+
+ if (v16 < v1A) {
+ checkMovement2(_globals->_walkRegions._field18[var10]._pt1,
+ _globals->_walkRegions._field18[var10]._pt2, 1, objPos);
+ } else {
+ checkMovement2(_globals->_walkRegions._field18[var10]._pt2,
+ _globals->_walkRegions._field18[var10]._pt1, 1, objPos);
+ }
+
+ _globals->_walkRegions._field18[0]._pt1 = objPos;
+ *routeList++ = objPos;
+ }
+ }
+
+ // Add in the route entry
+ *routeList++ = _globals->_walkRegions._field18[1]._pt1;
+ }
+
+ // Mark the end of the path
+ *routeList = Common::Point(ROUTE_END_VAL, ROUTE_END_VAL);
+}
+
+int PlayerMover::regionIndexOf(const Common::Point &pt) {
+ for (uint idx = 0; idx < _globals->_walkRegions._regionList.size(); ++idx) {
+ if (_globals->_walkRegions._regionList[idx].contains(pt))
+ return idx + 1;
+ }
+
+ return 0;
+}
+
+int PlayerMover::findClosestRegion(Common::Point &pt, const Common::List<int> &indexList) {
+ int newY = pt.y;
+ int result = 0;
+
+ for (int idx = 1; idx < SCREEN_WIDTH; ++idx, newY += idx) {
+ int newX = pt.x + idx;
+ result = regionIndexOf(newX, pt.y);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newY = pt.y + idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newX -= idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newX -= idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newY -= idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newY -= idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newX += idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ newX += idx;
+ result = regionIndexOf(newX, newY);
+
+ if ((result == 0) || contains(indexList, result)) {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Found an index
+ pt.x = newX;
+ pt.y = newY;
+ return result;
+ }
+
+ return (result == 0) ? -1 : result;
+}
+
+Common::Point *PlayerMover::findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos) {
+ int xp = objPos->x + (((routeEnds->moveDest.y - routeEnds->moveSrc.y) * 9) / 8);
+ int yp = objPos->y - (((routeEnds->moveDest.x - routeEnds->moveSrc.x) * 8) / 9);
+
+ int xDiff = xp - objPos->x;
+ int yDiff = yp - objPos->y;
+ int xDirection = (xDiff == 0) ? 0 : ((xDiff < 0) ? 1 : -1);
+ int yDirection = (yDiff == 0) ? 0 : ((yDiff < 0) ? 1 : -1);
+ xDiff = ABS(xDiff);
+ yDiff = ABS(yDiff);
+ int majorChange = MAX(xDiff, yDiff) / 2;
+
+ int outX = objPos->x;
+ int outY = objPos->y;
+
+ while (length-- > 0) {
+ if (xDiff < yDiff) {
+ outY += yDirection;
+ majorChange += xDiff;
+ if (majorChange > yDiff) {
+ majorChange -= yDiff;
+ outX += xDirection;
+ }
+ } else {
+ outX += xDirection;
+ majorChange += yDiff;
+ if (majorChange > xDiff) {
+ majorChange -= xDiff;
+ outY += yDirection;
+ }
+ }
+ }
+
+ outPos->x = outX;
+ outPos->y = outY;
+ return outPos;
+}
+
+int PlayerMover::checkMover(Common::Point &srcPos, const Common::Point &destPos) {
+ int regionIndex = 0;
+ Common::Point objPos = _sceneObject->_position;
+ uint32 regionBitList = _sceneObject->_regionBitList;
+ _sceneObject->_regionBitList = 0;
+
+ _sceneObject->_position.x = srcPos.x;
+ _sceneObject->_position.y = srcPos.y;
+ _sceneObject->_mover = NULL;
+
+ NpcMover *mover = new NpcMover();
+ _sceneObject->addMover(mover, &destPos, NULL);
+
+ // Handle automatic movement of the player until a walkable region is reached,
+ // or the end point of the movement is
+ do {
+ _sceneObject->_mover->dispatch();
+
+ // Scan walk regions for point
+ for (uint idx = 0; idx < _globals->_walkRegions._regionList.size(); ++idx) {
+ if (_globals->_walkRegions[idx].contains(_sceneObject->_position)) {
+ regionIndex = idx + 1;
+ srcPos = _sceneObject->_position;
+ break;
+ }
+ }
+ } while ((regionIndex == 0) && (_sceneObject->_mover) && !_vm->shouldQuit());
+
+ _sceneObject->_position = objPos;
+ _sceneObject->_regionBitList = regionBitList;
+
+ if (_sceneObject->_mover)
+ _sceneObject->_mover->remove();
+
+ _sceneObject->_mover = this;
+ return regionIndex;
+}
+
+void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) {
+ Common::Point objPos = _sceneObject->_position;
+ _sceneObject->_position = srcPos;
+ uint32 regionBitList = _sceneObject->_regionBitList;
+ _sceneObject->_position = srcPos;
+ _sceneObject->_mover = NULL;
+
+ NpcMover *mover = new NpcMover();
+ _sceneObject->addMover(mover, &destPos, NULL);
+
+ while ((numSteps > 0) && ((_sceneObject->_position.x != destPos.x) || (_sceneObject->_position.y != destPos.y))) {
+ _sceneObject->_mover->dispatch();
+ --numSteps;
+ }
+
+ ptOut = _sceneObject->_position;
+ _sceneObject->_position = objPos;
+ _sceneObject->_regionBitList = regionBitList;
+
+ if (_sceneObject->_mover)
+ _sceneObject->_mover->remove();
+
+ _sceneObject->_mover = this;
+}
+
+int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) {
+ int tempList[REGION_LIST_SIZE + 1];
+ v = 0;
+ for (int idx = 0; idx <= *routeList; ++idx)
+ tempList[idx] = routeList[idx];
+
+ if (*routeList == REGION_LIST_SIZE)
+ // Sequence too long
+ return 32000;
+
+ int regionIndex;
+ for (regionIndex = 1; regionIndex <= *tempList; ++regionIndex) {
+ if (routeList[regionIndex] == srcRegion)
+ // Current path returns to original source region, so don't allow it
+ return 32000;
+ }
+
+ WalkRegion &srcWalkRegion = _globals->_walkRegions[srcRegion];
+ int distance;
+ if (!routeList[0]) {
+ // No route
+ distance = 0;
+ } else {
+ WalkRegion &region = _globals->_walkRegions[routeList[*routeList]];
+ distance = findDistance(srcWalkRegion._pt, region._pt);
+ }
+
+ tempList[++*tempList] = srcRegion;
+ int newIndex = *tempList;
+
+ if (srcRegion == destRegion) {
+ v = 1;
+ for (int idx = newIndex; idx <= *tempList; ++idx) {
+ routeList[idx] = tempList[idx];
+ ++*routeList;
+ }
+ return distance;
+ } else {
+ int foundIndex = 0;
+ int idx = 0;
+ int currDest;
+ while ((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + idx]) != 0) {
+ if (currDest == destRegion) {
+ foundIndex = idx;
+ break;
+ }
+
+ ++idx;
+ }
+
+ int resultOffset = 31990;
+ while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (v == 0)) {
+ int newDistance = proc1(tempList, currDest, destRegion, v);
+
+ if ((newDistance <= resultOffset) || v) {
+ routeList[0] = newIndex - 1;
+
+ for (int i = newIndex; i <= tempList[0]; ++i) {
+ routeList[i] = tempList[i];
+ ++routeList[0];
+ }
+
+ resultOffset = newDistance;
+ }
+
+ tempList[0] = newIndex;
+ ++foundIndex;
+ }
+
+ v = 0;
+ return resultOffset + distance;
+ }
+}
+
+int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2) {
+ int diff = ABS(pt1.x - pt2.x);
+ double xx = diff * diff;
+ diff = ABS(pt1.y - pt2.y);
+ double yy = diff * 8.0 / 7.0;
+ yy *= yy;
+
+ return (int)sqrt(xx + yy);
+}
+
+bool PlayerMover::sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+ const Common::Point &pt4, Common::Point *ptOut) {
+ double diff1 = pt2.x - pt1.x;
+ double diff2 = pt2.y - pt1.y;
+ double diff3 = pt4.x - pt3.x;
+ double diff4 = pt4.y - pt3.y;
+ double var10 = 0.0, var8 = 0.0;
+ double var18 = 0.0, var20 = 0.0;
+
+ if (diff1 != 0.0) {
+ var8 = diff2 / diff1;
+ var18 = pt1.y - (pt1.x * var8);
+ }
+ if (diff3 != 0.0) {
+ var10 = diff4 / diff3;
+ var20 = pt3.y - (pt3.x * var10);
+ }
+
+ if (var8 == var10)
+ return false;
+
+ double var48, var50;
+ if (diff1 == 0) {
+ if (diff3 == 0)
+ return false;
+
+ var48 = pt1.x;
+ var50 = var10 * var48 + var20;
+ } else {
+ var48 = (diff3 == 0) ? pt3.x : (var20 - var18) / (var8 - var10);
+ var50 = var8 * var48 + var18;
+ }
+
+ bool var52 = false, var56 = false, var54 = false, var58 = false;
+ Common::Point tempPt((int)(var48 + 0.5), (int)(var50 + 0.5));
+
+ if ((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x))
+ var56 = true;
+ else if ((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x))
+ var56 = true;
+ if (var56) {
+ if ((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y))
+ var58 = true;
+ else if ((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y))
+ var58 = true;
+ }
+
+ if ((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x))
+ var52 = true;
+ else if ((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x))
+ var52 = true;
+ if (var52) {
+ if ((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y))
+ var54 = true;
+ else if ((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y))
+ var54 = true;
+ }
+
+ if (var52 && var54 && var56 && var58) {
+ if (ptOut)
+ *ptOut = tempPt;
+ return true;
+ }
+
+ return false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void PlayerMover2::synchronise(Serialiser &s) {
+ SYNC_POINTER(_destObject);
+ s.syncAsSint16LE(_field7E);
+ s.syncAsSint16LE(_minArea);
+}
+
+void PlayerMover2::dispatch() {
+ int total = _sceneObject->getSpliceArea(_destObject);
+
+ if (total <= _minArea)
+ endMove();
+ else {
+ setDest(_destObject->_position);
+ ObjectMover::dispatch();
+ }
+}
+
+void PlayerMover2::startMove(SceneObject *sceneObj, va_list va) {
+ _sceneObject = sceneObj;
+ _field7E = va_arg(va, int);
+ _minArea = va_arg(va, int);
+ _destObject = va_arg(va, SceneObject *);
+
+ PlayerMover::setDest(_destObject->_position);
+}
+
+void PlayerMover2::endMove() {
+ _sceneObject->_regionIndex = 0x40;
+}
+
+/*--------------------------------------------------------------------------*/
+
+PaletteModifier::PaletteModifier() {
+ _scenePalette = NULL;
+ _action = NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+
+PaletteRotation::PaletteRotation() : PaletteModifier() {
+ _disabled = false;
+ _delayFrames = 0;
+ _delayCtr = 0;
+ _frameNumber = _globals->_events.getFrameNumber();
+}
+
+void PaletteRotation::synchronise(Serialiser &s) {
+ PaletteModifier::synchronise(s);
+
+ s.syncAsByte(_disabled);
+ s.syncAsSint32LE(_delayFrames);
+ s.syncAsSint32LE(_delayCtr);
+ s.syncAsUint32LE(_frameNumber);
+ s.syncAsSint32LE(_currIndex);
+ s.syncAsSint32LE(_start);
+ s.syncAsSint32LE(_end);
+ s.syncAsSint32LE(_rotationMode);
+ s.syncAsSint32LE(_duration);
+ for (int i = 0; i < 256; ++i) {
+ s.syncAsByte(_palette[i].r);
+ s.syncAsByte(_palette[i].g);
+ s.syncAsByte(_palette[i].b);
+ }
+}
+
+void PaletteRotation::signal() {
+ if (_delayCtr) {
+ uint32 frameNumber = _globals->_events.getFrameNumber();
+
+ if (frameNumber >= _frameNumber) {
+ _delayCtr = frameNumber - _frameNumber;
+ _frameNumber = frameNumber;
+
+ if (_delayCtr < 0)
+ _delayCtr = 0;
+ }
+ }
+
+ if (_delayCtr)
+ return;
+ _delayCtr = _delayFrames;
+ if (_disabled)
+ return;
+
+ bool flag = true;
+ switch (_rotationMode) {
+ case -1:
+ if (--_currIndex < _start) {
+ flag = decDuration();
+ if (flag)
+ _currIndex = _end - 1;
+ }
+ break;
+ case 1:
+ if (++_currIndex >= _end) {
+ flag = decDuration();
+ if (flag)
+ _currIndex = _start;
+ }
+ break;
+ case 2:
+ if (++_currIndex >= _end) {
+ flag = decDuration();
+ if (flag) {
+ _currIndex = _end - 2;
+ _rotationMode = 3;
+ }
+ }
+ break;
+ case 3:
+ if (--_currIndex < _start) {
+ flag = decDuration();
+ if (flag) {
+ _currIndex = _start + 1;
+ _rotationMode = 2;
+ }
+ }
+ break;
+ }
+
+ if (flag) {
+ int count2 = _currIndex - _start;
+ int count = _end - _currIndex;
+ g_system->getPaletteManager()->setPalette((const byte *)&_palette[_currIndex], _start, count);
+
+ if (count2) {
+ g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start], _start + count, count2);
+ }
+ }
+}
+
+void PaletteRotation::remove() {
+ Action *action = _action;
+ g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start], _start, _end - _start);
+
+ _scenePalette->_listeners.remove(this);
+
+ delete this;
+ if (action)
+ action->signal();
+}
+
+void PaletteRotation::set(ScenePalette *palette, int start, int end, int rotationMode, int duration, Action *action) {
+ _duration = duration;
+ _disabled = false;
+ _action = action;
+ _scenePalette = palette;
+
+ Common::copy(&palette->_palette[0], &palette->_palette[256], &_palette[0]);
+
+ _start = start;
+ _end = end + 1;
+ _rotationMode = rotationMode;
+
+ switch (_rotationMode) {
+ case -1:
+ case 3:
+ _currIndex = _end;
+ break;
+ default:
+ _currIndex = _start;
+ break;
+ }
+}
+
+void PaletteRotation::setPalette(ScenePalette *palette, bool disabled) {
+ _scenePalette = palette;
+ _disabled = disabled;
+ _delayFrames = 100;
+}
+
+bool PaletteRotation::decDuration() {
+ if (_duration) {
+ if (--_duration == 0) {
+ remove();
+ return false;
+ }
+ }
+ return true;
+}
+
+void PaletteRotation::setDelay(int amount) {
+ _delayFrames = _delayCtr = amount;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void PaletteUnknown::synchronise(Serialiser &s) {
+ PaletteModifier::synchronise(s);
+
+ s.syncAsSint16LE(_step);
+ s.syncAsSint16LE(_percent);
+ s.syncAsSint16LE(_field12);
+ s.syncAsSint16LE(_field14);
+ for (int i = 0; i < 256; ++i) {
+ s.syncAsByte(_palette[i].r);
+ s.syncAsByte(_palette[i].g);
+ s.syncAsByte(_palette[i].b);
+ }
+}
+
+void PaletteUnknown::signal() {
+ _percent -= _step;
+ if (_percent > 0) {
+ _scenePalette->fade((byte *)_palette, true /* 256 */, _percent);
+ } else {
+ remove();
+ }
+}
+
+void PaletteUnknown::remove() {
+ if (_scenePalette) {
+ for (int i = 0; i < 256; i++)
+ _scenePalette->_palette[i] = _palette[i];
+ _scenePalette->refresh();
+ _scenePalette->_listeners.remove(this);
+ delete this;
+ }
+
+ if (_action)
+ _action->signal();
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScenePalette::ScenePalette() {
+ // Set a default gradiant range
+ for (int idx = 0; idx < 256; ++idx)
+ _palette[idx].r = _palette[idx].g = _palette[idx].b = idx;
+
+ _field412 = 0;
+}
+
+ScenePalette::ScenePalette(int paletteNum) {
+ loadPalette(paletteNum);
+}
+
+bool ScenePalette::loadPalette(int paletteNum) {
+ byte *palData = _vm->_dataManager->getResource(RES_PALETTE, paletteNum, 0, true);
+ if (!palData)
+ return false;
+
+ int palStart = READ_LE_UINT16(palData);
+ int palSize = READ_LE_UINT16(palData + 2);
+ assert(palSize <= 256);
+
+ RGB8 *destP = &_palette[palStart];
+ RGB8 *srcP = (RGB8 *)(palData + 6);
+
+ Common::copy(&srcP[0], &srcP[palSize], destP);
+
+ DEALLOCATE(palData);
+ return true;
+}
+
+void ScenePalette::refresh() {
+ // Set indexes for standard colours to closest colour in the palette
+ _colours.background = indexOf(255, 255, 255); // White background
+ _colours.foreground = indexOf(0, 0, 0); // Black foreground
+ _redColour = indexOf(180, 0, 0); // Red-ish
+ _greenColour = indexOf(0, 180, 0); // Green-ish
+ _blueColour = indexOf(0, 0, 180); // Blue-ish
+ _aquaColour = indexOf(0, 180, 180); // Aqua
+ _purpleColour = indexOf(180, 0, 180); // Purple
+ _limeColour = indexOf(180, 180, 0); // Lime
+
+ // Refresh the palette
+ g_system->getPaletteManager()->setPalette((const byte *)&_palette[0], 0, 256);
+}
+
+/**
+ * Loads a section of the palette into the game palette
+ */
+void ScenePalette::setPalette(int index, int count) {
+ g_system->getPaletteManager()->setPalette((const byte *)&_palette[index], index, count);
+}
+
+/**
+ * Returns the palette index with the closest matching colour to that specified
+ * @param r R component
+ * @param g G component
+ * @param b B component
+ * @param threshold Closeness threshold.
+ * @remarks A threshold may be provided to specify how close the matching colour must be
+ */
+uint8 ScenePalette::indexOf(uint r, uint g, uint b, int threshold) {
+ int palIndex = -1;
+
+ for (int i = 0; i < 256; ++i) {
+ int rDiff = abs(_palette[i].r - (int)r);
+ int gDiff = abs(_palette[i].g - (int)g);
+ int bDiff = abs(_palette[i].b - (int)b);
+
+ int idxThreshold = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
+ if (idxThreshold <= threshold) {
+ threshold = idxThreshold;
+ palIndex = i;
+ }
+ }
+
+ return palIndex;
+}
+
+/**
+ * Loads the specified range of the palette with the current system palette
+ * @param start Start index
+ * @param count Number of palette entries
+ */
+void ScenePalette::getPalette(int start, int count) {
+ g_system->getPaletteManager()->grabPalette((byte *)&_palette[start], start, count);
+}
+
+void ScenePalette::signalListeners() {
+ for (SynchronisedList<PaletteModifier *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) {
+ (*i)->signal();
+ }
+}
+
+void ScenePalette::clearListeners() {
+ SynchronisedList<PaletteModifier *>::iterator i = _listeners.begin();
+ while (i != _listeners.end()) {
+ PaletteModifier *obj = *i;
+ ++i;
+ obj->remove();
+ }
+}
+
+void ScenePalette::fade(const byte *adjustData, bool fullAdjust, int percent) {
+ RGB8 tempPalette[256];
+
+ // Ensure the percent adjustment is within 0 - 100%
+ percent = CLIP(percent, 0, 100);
+
+ for (int palIndex = 0; palIndex < 256; ++palIndex) {
+ const byte *srcP = (const byte *)&_palette[palIndex];
+ byte *destP = (byte *)&tempPalette[palIndex].r;
+
+ for (int rgbIndex = 0; rgbIndex < 3; ++rgbIndex, ++srcP, ++destP) {
+ *destP = *srcP - ((*srcP - adjustData[rgbIndex]) * (100 - percent)) / 100;
+ }
+
+ if (fullAdjust)
+ adjustData += 3;
+ }
+
+ // Set the altered pale4tte
+ g_system->getPaletteManager()->setPalette((const byte *)&tempPalette[0], 0, 256);
+ g_system->updateScreen();
+}
+
+PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode, int duration, Action *action) {
+ PaletteRotation *obj = new PaletteRotation();
+
+ if ((rotationMode == 2) || (rotationMode == 3))
+ duration <<= 1;
+
+ obj->set(this, start, end, rotationMode, duration, action);
+ _listeners.push_back(obj);
+ return obj;
+}
+
+PaletteUnknown *ScenePalette::addUnkPal(RGB8 *arrBufferRGB, int unkNumb, bool disabled, Action *action) {
+ PaletteUnknown *paletteUnk = new PaletteUnknown();
+ paletteUnk->_action = action;
+ for (int i = 0; i < 256; i++) {
+ if (unkNumb <= 1)
+ paletteUnk->_palette[i] = arrBufferRGB[i];
+ else
+ paletteUnk->_palette[i] = arrBufferRGB[0];
+ }
+// PaletteRotation::setPalette(this, disabled);
+ _globals->_scenePalette._listeners.push_back(paletteUnk);
+ return paletteUnk;
+}
+
+
+void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) {
+ ScenePalette tempPalette;
+
+ if (_globals->_sceneManager._hasPalette) {
+ if ((fadeMode == FADEMODE_GRADUAL) || (fadeMode == FADEMODE_IMMEDIATE)) {
+ // Fade out any active palette
+ tempPalette.getPalette();
+ uint32 adjustData = 0;
+
+ for (int percent = 100; percent >= 0; percent -= 5) {
+ if (fadeMode == FADEMODE_IMMEDIATE)
+ percent = 0;
+ tempPalette.fade((byte *)&adjustData, false, percent);
+ g_system->delayMillis(10);
+ }
+ } else {
+ _globals->_scenePalette.refresh();
+ _globals->_sceneManager._hasPalette = false;
+ }
+ }
+
+ _globals->_screenSurface.copyFrom(_globals->_sceneManager._scene->_backSurface,
+ bounds, Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), NULL);
+
+ for (SynchronisedList<PaletteModifier *>::iterator i = tempPalette._listeners.begin(); i != tempPalette._listeners.end(); ++i)
+ delete *i;
+ tempPalette._listeners.clear();
+}
+
+void ScenePalette::synchronise(Serialiser &s) {
+ for (int i = 0; i < 256; ++i) {
+ s.syncAsByte(_palette[i].r);
+ s.syncAsByte(_palette[i].g);
+ s.syncAsByte(_palette[i].b);
+ }
+ s.syncAsSint32LE(_colours.foreground);
+ s.syncAsSint32LE(_colours.background);
+
+ s.syncAsSint32LE(_field412);
+ s.syncAsByte(_redColour);
+ s.syncAsByte(_greenColour);
+ s.syncAsByte(_blueColour);
+ s.syncAsByte(_aquaColour);
+ s.syncAsByte(_purpleColour);
+ s.syncAsByte(_limeColour);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneItem::synchronise(Serialiser &s) {
+ EventHandler::synchronise(s);
+
+ _bounds.synchronise(s);
+ s.syncString(_msg);
+ s.syncAsSint32LE(_fieldE);
+ s.syncAsSint32LE(_field10);
+ s.syncAsSint16LE(_position.x); s.syncAsSint32LE(_position.y);
+ s.syncAsSint16LE(_yDiff);
+ s.syncAsSint32LE(_sceneRegionId);
+}
+
+void SceneItem::remove() {
+ _globals->_sceneItems.remove(this);
+}
+
+void SceneItem::doAction(int action) {
+ const char *msg = NULL;
+
+ switch ((int)action) {
+ case CURSOR_LOOK:
+ msg = LOOK_SCENE_HOTSPOT;
+ break;
+ case CURSOR_USE:
+ msg = USE_SCENE_HOTSPOT;
+ break;
+ case CURSOR_TALK:
+ msg = TALK_SCENE_HOTSPOT;
+ break;
+ case 0x1000:
+ msg = SPECIAL_SCENE_HOTSPOT;
+ break;
+ default:
+ msg = DEFAULT_SCENE_HOTSPOT;
+ break;
+ }
+
+ GUIErrorMessage(msg);
+}
+
+bool SceneItem::contains(const Common::Point &pt) {
+ const Rect &sceneBounds = _globals->_sceneManager._scene->_sceneBounds;
+
+ if (_sceneRegionId == 0)
+ return _bounds.contains(pt.x + sceneBounds.left, pt.y + sceneBounds.top);
+ else
+ return _globals->_sceneRegions.indexOf(Common::Point(pt.x + sceneBounds.left,
+ pt.y + sceneBounds.top)) == _sceneRegionId;
+}
+
+void SceneItem::display(int resNum, int lineNum, ...) {
+ Common::String msg = !resNum ? Common::String() : _vm->_dataManager->getMessage(resNum, lineNum);
+
+ if (_globals->_sceneObjects->contains(&_globals->_sceneText)) {
+ _globals->_sceneText.remove();
+ _globals->_sceneObjects->draw();
+ }
+
+ GfxFontBackup font;
+ Common::Point pos(160, 100);
+ Rect textRect;
+ int maxWidth = 120;
+ bool keepOnscreen = false;
+ bool centreText = true;
+
+ if (resNum) {
+ va_list va;
+ va_start(va, lineNum);
+
+ int mode;
+ do {
+ // Get next instruction
+ mode = va_arg(va, int);
+
+ switch (mode) {
+ case SET_WIDTH:
+ // Set width
+ maxWidth = va_arg(va, int);
+ _globals->_sceneText._width = maxWidth;
+ break;
+ case SET_X:
+ // Set the X Position
+ pos.x = va_arg(va, int);
+ break;
+ case SET_Y:
+ // Set the Y Position
+ pos.y = va_arg(va, int);
+ break;
+ case SET_FONT:
+ // Set the font number
+ _globals->_sceneText._fontNumber = va_arg(va, int);
+ _globals->gfxManager()._font.setFontNumber(_globals->_sceneText._fontNumber);
+ break;
+ case SET_BG_COLOUR: {
+ // Set the background colour
+ int bgColour = va_arg(va, int);
+ _globals->gfxManager()._font._colours.background = bgColour;
+ if (!bgColour)
+ _globals->gfxManager().setFillFlag(false);
+ break;
+ }
+ case SET_FG_COLOUR:
+ // Set the foreground colour
+ _globals->_sceneText._colour1 = va_arg(va, int);
+ _globals->gfxManager()._font._colours.foreground = _globals->_sceneText._colour1;
+ break;
+ case SET_KEEP_ONSCREEN:
+ // Suppresses immediate display
+ keepOnscreen = va_arg(va, int) != 0;
+ break;
+ case SET_EXT_BGCOLOUR: {
+ // Set secondary bg colour
+ int v = va_arg(va, int);
+ _globals->_sceneText._colour2 = v;
+ _globals->gfxManager()._font._colours2.background = v;
+ break;
+ }
+ case SET_EXT_FGCOLOUR: {
+ // Set secondary fg colour
+ int v = va_arg(va, int);
+ _globals->_sceneText._colour3 = v;
+ _globals->gfxManager()._font._colours.foreground = v;
+ break;
+ }
+ case SET_POS_MODE:
+ // Set whether a custom x/y is used
+ centreText = va_arg(va, int) != 0;
+ break;
+ case SET_TEXT_MODE:
+ // Set the text mode
+ _globals->_sceneText._textMode = (TextAlign)va_arg(va, int);
+ break;
+ default:
+ break;
+ }
+ } while (mode != LIST_END);
+
+ va_end(va);
+ }
+
+ if (resNum) {
+ // Get required bounding size
+ _globals->gfxManager().getStringBounds(msg.c_str(), textRect, maxWidth);
+ textRect.centre(pos.x, pos.y);
+
+ textRect.contain(_globals->gfxManager()._bounds);
+ if (centreText) {
+ _globals->_sceneText._colour1 = _globals->_sceneText._colour2;
+ _globals->_sceneText._colour2 = 0;
+ _globals->_sceneText._colour3 = 0;
+ }
+
+ _globals->_sceneText.setup(msg);
+ if (centreText) {
+ _globals->_sceneText.setPosition(Common::Point(
+ _globals->_sceneManager._scene->_sceneBounds.left + textRect.left,
+ _globals->_sceneManager._scene->_sceneBounds.top + textRect.top), 0);
+ } else {
+ _globals->_sceneText.setPosition(pos, 0);
+ }
+
+ _globals->_sceneText.setPriority2(255);
+ _globals->_sceneObjects->draw();
+ }
+
+ // Unless the flag is set to keep the message on-screen, show it until a mouse or keypress, then remove it
+ if (!keepOnscreen && !msg.empty()) {
+ Event event;
+
+ // Keep event on-screen until a mouse or keypress
+ while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event,
+ EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) {
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+
+ _globals->_sceneText.remove();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneHotspot::doAction(int action) {
+ switch ((int)action) {
+ case CURSOR_LOOK:
+ display(1, 0, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ display(1, 5, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_TALK:
+ display(1, 15, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_WALK:
+ break;
+ default:
+ display(2, action, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void NamedHotspot::doAction(int action) {
+ switch (action) {
+ case CURSOR_WALK:
+ // Nothing
+ break;
+ case CURSOR_LOOK:
+ if (_lookLineNum == -1)
+ SceneHotspot::doAction(action);
+ else
+ SceneItem::display(_resnum, _lookLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (_useLineNum == -1)
+ SceneHotspot::doAction(action);
+ else
+ SceneItem::display(_resnum, _useLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void NamedHotspot::setup(const int ys, const int xe, const int ye, const int xs, const int resnum, const int lookLineNum, const int useLineNum) {
+ setBounds(ys, xe, ye, xs);
+ _resnum = resnum;
+ _lookLineNum = lookLineNum;
+ _useLineNum = useLineNum;
+ _globals->_sceneItems.addItems(this, NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneObjectWrapper::setSceneObject(SceneObject *so) {
+ _sceneObject = so;
+ so->_strip = 1;
+ so->_flags |= OBJFLAG_PANES;
+}
+
+void SceneObjectWrapper::synchronise(Serialiser &s) {
+ EventHandler::synchronise(s);
+ SYNC_POINTER(_sceneObject);
+}
+
+void SceneObjectWrapper::remove() {
+ delete this;
+}
+
+void SceneObjectWrapper::dispatch() {
+ _visageImages.setVisage(_sceneObject->_visage);
+ int frameCount = _visageImages.getFrameCount();
+ int angle = _sceneObject->_angle;
+ int strip = _sceneObject->_strip;
+
+ if (frameCount == 4) {
+ if ((angle > 314) || (angle < 45))
+ strip = 4;
+ if ((angle > 44) && (angle < 135))
+ strip = 1;
+ if ((angle >= 135) && (angle < 225))
+ strip = 3;
+ if ((angle >= 225) && (angle < 315))
+ strip = 2;
+ } else if (frameCount == 8) {
+ if ((angle > 330) || (angle < 30))
+ strip = 4;
+ if ((angle >= 30) && (angle < 70))
+ strip = 7;
+ if ((angle >= 70) && (angle < 110))
+ strip = 1;
+ if ((angle >= 110) && (angle < 150))
+ strip = 5;
+ if ((angle >= 150) && (angle < 210))
+ strip = 3;
+ if ((angle >= 210) && (angle < 250))
+ strip = 6;
+ if ((angle >= 250) && (angle < 290))
+ strip = 2;
+ if ((angle >= 290) && (angle < 331))
+ strip = 8;
+ }
+
+ if (strip > frameCount)
+ strip = frameCount;
+
+ _sceneObject->setStrip(strip);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneObject::SceneObject() : SceneHotspot() {
+ _endAction = NULL;
+ _mover = NULL;
+ _objectWrapper = NULL;
+ _flags = 0;
+ _walkStartFrame = 0;
+ _animateMode = ANIM_MODE_NONE;
+ _updateStartFrame = 0;
+ _moveDiff.x = 5;
+ _moveDiff.y = 3;
+ _numFrames = 10;
+ _numFrames = 10;
+ _field7A = 10;
+ _regionBitList = 0;
+ _sceneRegionId = 0;
+ _percent = 100;
+ _flags |= OBJFLAG_PANES;
+
+ _frameChange = 0;
+}
+
+SceneObject::SceneObject(const SceneObject &so) : SceneHotspot() {
+ *this = so;
+ if (_objectWrapper)
+ // Create a fresh object wrapper for this object
+ _objectWrapper = new SceneObjectWrapper();
+}
+
+SceneObject::~SceneObject() {
+ delete _mover;
+ delete _objectWrapper;
+}
+
+int SceneObject::getNewFrame() {
+ int frameNum = _frame + _frameChange;
+
+ if (_frameChange > 0) {
+ if (frameNum > getFrameCount()) {
+ frameNum = 1;
+ if (_animateMode == ANIM_MODE_1)
+ ++frameNum;
+ }
+ } else if (frameNum < 1) {
+ frameNum = getFrameCount();
+ }
+
+ return frameNum;
+}
+
+int SceneObject::getFrameCount() {
+ _visageImages.setVisage(_visage, _strip);
+ return _visageImages.getFrameCount();
+}
+
+void SceneObject::animEnded() {
+ _animateMode = ANIM_MODE_NONE;
+ if (_endAction)
+ _endAction->signal();
+}
+
+int SceneObject::changeFrame() {
+ int frameNum = _frame;
+ uint32 mouseCtr = _globals->_events.getFrameNumber();
+
+ if ((_updateStartFrame <= mouseCtr) || (_animateMode == ANIM_MODE_1)) {
+ if (_numFrames > 0) {
+ int v = 60 / _numFrames;
+ _updateStartFrame = mouseCtr + v;
+
+ frameNum = getNewFrame();
+ }
+ }
+
+ return frameNum;
+}
+
+void SceneObject::setPosition(const Common::Point &p, int yDiff) {
+ _position = p;
+ _yDiff = yDiff;
+ _flags |= OBJFLAG_PANES;
+}
+
+void SceneObject::setZoom(int percent) {
+ assert((percent >= -1) && (percent < 999));
+ if (percent != _percent) {
+ _percent = percent;
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+void SceneObject::updateZoom() {
+ changeZoom(_percent);
+}
+
+void SceneObject::changeZoom(int percent) {
+ if (percent == -1)
+ _flags &= ~OBJFLAG_ZOOMED;
+ else {
+ _flags |= OBJFLAG_ZOOMED;
+ setZoom(percent);
+ }
+}
+
+void SceneObject::setStrip(int stripNum) {
+ if (stripNum != _strip) {
+ _strip = stripNum;
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+void SceneObject::setStrip2(int stripNum) {
+ if (stripNum == -1)
+ _flags &= ~OBJFLAG_SUPPRESS_DISPATCH;
+ else {
+ _flags |= OBJFLAG_SUPPRESS_DISPATCH;
+ setStrip(stripNum);
+ }
+}
+
+void SceneObject::setFrame(int frameNum) {
+ if (frameNum != _frame) {
+ _frame = frameNum;
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+void SceneObject::setFrame2(int frameNum) {
+ if (frameNum != -1) {
+ _flags |= OBJFLAG_NO_UPDATES;
+ setFrame(frameNum);
+ } else {
+ _flags &= ~OBJFLAG_NO_UPDATES;
+ }
+}
+
+void SceneObject::setPriority(int priority) {
+ if (priority != _priority) {
+ _priority = priority;
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+void SceneObject::setPriority2(int priority) {
+ if (priority == -1) {
+ _flags &= ~OBJFLAG_FIXED_PRIORITY;
+ } else {
+ _flags |= OBJFLAG_FIXED_PRIORITY;
+ setPriority(priority);
+ }
+}
+
+void SceneObject::setVisage(int visage) {
+ if (visage != _visage) {
+ _visage = visage;
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+void SceneObject::setObjectWrapper(SceneObjectWrapper *objWrapper) {
+ if (_objectWrapper)
+ _objectWrapper->remove();
+ _objectWrapper = objWrapper;
+ if (objWrapper)
+ objWrapper->setSceneObject(this);
+}
+
+void SceneObject::addMover(ObjectMover *mover, ...) {
+ if (_mover)
+ _mover->remove();
+ _mover = mover;
+
+ if (mover) {
+ // Set up the assigned mover
+ _walkStartFrame = _globals->_events.getFrameNumber();
+ if (_field7A != 0)
+ _walkStartFrame = 60 / _field7A;
+
+ // Signal the mover that movement is beginning
+ va_list va;
+ va_start(va, mover);
+ mover->startMove(this, va);
+ va_end(va);
+ }
+}
+
+void SceneObject::getHorizBounds() {
+ Rect tempRect;
+
+ GfxSurface frame = getFrame();
+ tempRect.resize(frame, _position.x, _position.y - _yDiff, _percent);
+
+ _xs = tempRect.left;
+ _xe = tempRect.right;
+}
+
+int SceneObject::getRegionIndex() {
+ return _globals->_sceneRegions.indexOf(_position);
+}
+
+int SceneObject::checkRegion(const Common::Point &pt) {
+ Rect tempRect;
+ int regionIndex = 0;
+
+ // Temporarily change the position
+ Common::Point savedPos = _position;
+ _position = pt;
+
+ int regIndex = _globals->_sceneRegions.indexOf(pt);
+ if (_regionBitList & (1 << regIndex))
+ regionIndex = regIndex;
+
+ // Restore position
+ _position = savedPos;
+
+ // Get the object's frame bounds
+ GfxSurface frame = getFrame();
+ tempRect.resize(frame, _position.x, _position.y - _yDiff, _percent);
+
+ int yPos, newY;
+ if ((_position.y - _yDiff) <= (pt.y - _yDiff)) {
+ yPos = _position.y - _yDiff;
+ newY = pt.y;
+ } else {
+ yPos = pt.y - _yDiff;
+ newY = _position.y;
+ }
+ newY -= _yDiff;
+
+ SynchronisedList<SceneObject *>::iterator i;
+ for (i = _globals->_sceneObjects->begin(); (regionIndex == 0) && (i != _globals->_sceneObjects->end()); ++i) {
+ if ((*i) && ((*i)->_flags & OBJFLAG_CHECK_REGION)) {
+ int objYDiff = (*i)->_position.y - _yDiff;
+ if ((objYDiff >= yPos) && (objYDiff <= newY) &&
+ ((*i)->_xs < tempRect.right) && ((*i)->_xe > tempRect.left)) {
+ // Found index
+ regionIndex = -1; //****DEBUG*** = *i;
+ break;
+ }
+ }
+ }
+
+ return regionIndex;
+}
+
+void SceneObject::animate(AnimateMode animMode, ...) {
+ _animateMode = animMode;
+ _updateStartFrame = _globals->_events.getFrameNumber();
+ if (_numFrames)
+ _updateStartFrame += 60 / _numFrames;
+
+ va_list va;
+ va_start(va, animMode);
+
+ switch (_animateMode) {
+ case ANIM_MODE_NONE:
+ _endAction = NULL;
+ break;
+
+ case ANIM_MODE_1:
+ _frameChange = 1;
+ _field2E = _position;
+ _endAction = 0;
+ break;
+
+ case ANIM_MODE_2:
+ _frameChange = 1;
+ _endAction = NULL;
+ break;
+
+ case ANIM_MODE_3:
+ _frameChange = -1;
+ _endAction = NULL;
+ break;
+
+ case ANIM_MODE_4:
+ _endFrame = va_arg(va, int);
+ _frameChange = va_arg(va, int);
+ _endAction = va_arg(va, Action *);
+ if (_endFrame == _frame)
+ setFrame(getNewFrame());
+ break;
+
+ case ANIM_MODE_5:
+ _frameChange = 1;
+ _endFrame = getFrameCount();
+ _endAction = va_arg(va, Action *);
+ if (_endFrame == _frame)
+ setFrame(getNewFrame());
+ break;
+
+ case ANIM_MODE_6:
+ _frameChange = -1;
+ _endAction = va_arg(va, Action *);
+ _endFrame = 1;
+ if (_frame == _endFrame)
+ setFrame(getNewFrame());
+ break;
+
+ case ANIM_MODE_7:
+ _endFrame = va_arg(va, int);
+ _endAction = va_arg(va, Action *);
+ _frameChange = 1;
+ break;
+
+ case ANIM_MODE_8:
+ _field68 = va_arg(va, int);
+ _endAction = va_arg(va, Action *);
+ _frameChange = 1;
+ _endFrame = getFrameCount();
+ if (_frame == _endFrame)
+ setFrame(getNewFrame());
+ break;
+ }
+}
+
+SceneObject *SceneObject::clone() const {
+ SceneObject *obj = new SceneObject(*this);
+ return obj;
+}
+
+void SceneObject::checkAngle(const SceneObject *obj) {
+ _angle = GfxManager::getAngle(_position, obj->_position);
+
+ if (_objectWrapper)
+ _objectWrapper->dispatch();
+}
+
+void SceneObject::hide() {
+ _flags |= OBJFLAG_HIDE;
+ if (_flags & OBJFLAG_HIDING)
+ _flags |= OBJFLAG_PANES;
+}
+
+void SceneObject::show() {
+ if (_flags & OBJFLAG_HIDE) {
+ _flags &= ~OBJFLAG_HIDE;
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+int SceneObject::getSpliceArea(const SceneObject *obj) {
+ int xd = ABS(_position.x - obj->_position.x);
+ int yd = ABS(_position.y - obj->_position.y);
+
+ return (xd * xd + yd) / 2;
+}
+
+void SceneObject::synchronise(Serialiser &s) {
+ SceneHotspot::synchronise(s);
+
+ s.syncAsUint32LE(_updateStartFrame);
+ s.syncAsUint32LE(_walkStartFrame);
+ s.syncAsSint16LE(_field2E.x); s.syncAsSint16LE(_field2E.y);
+ s.syncAsSint16LE(_percent);
+ s.syncAsSint16LE(_priority);
+ s.syncAsSint16LE(_angle);
+ s.syncAsUint32LE(_flags);
+ s.syncAsSint16LE(_xs);
+ s.syncAsSint16LE(_xe);
+ _paneRects[0].synchronise(s);
+ _paneRects[1].synchronise(s);
+ s.syncAsSint32LE(_visage);
+ SYNC_POINTER(_objectWrapper);
+ s.syncAsSint32LE(_strip);
+ SYNC_ENUM(_animateMode, AnimateMode);
+ s.syncAsSint32LE(_frame);
+ s.syncAsSint32LE(_endFrame);
+ s.syncAsSint32LE(_field68);
+ s.syncAsSint32LE(_frameChange);
+ s.syncAsSint32LE(_numFrames);
+ s.syncAsSint32LE(_regionIndex);
+ SYNC_POINTER(_mover);
+ s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y);
+ s.syncAsSint32LE(_field7A);
+ SYNC_POINTER(_endAction);
+ s.syncAsUint32LE(_regionBitList);
+}
+
+void SceneObject::postInit(SceneObjectList *OwnerList) {
+ if (!OwnerList)
+ OwnerList = _globals->_sceneObjects;
+
+ if (!OwnerList->contains(this)) {
+ _percent = 100;
+ _priority = 255;
+ _flags = 4;
+ _visage = 0;
+ _strip = 1;
+ _frame = 1;
+ _objectWrapper = NULL;
+ _animateMode = ANIM_MODE_NONE;
+ _endAction = 0;
+ _mover = NULL;
+ _yDiff = 0;
+ _moveDiff.x = 5;
+ _moveDiff.y = 3;
+ _field7A = 10;
+ _regionIndex = 0x40;
+ _numFrames = 10;
+ _regionBitList = 0;
+
+ OwnerList->push_back(this);
+ _flags |= OBJFLAG_PANES;
+ }
+}
+
+void SceneObject::remove() {
+ SceneItem::remove();
+ if (_globals->_sceneObjects->contains(this))
+ // For objects in the object list, flag the object for removal in the next drawing, so that
+ // the drawing code has a chance to restore the area previously covered by the object
+ _flags |= OBJFLAG_PANES | OBJFLAG_REMOVE | OBJFLAG_HIDE;
+ else
+ // Not in the list, so immediately remove the object
+ removeObject();
+}
+
+void SceneObject::dispatch() {
+ uint32 currTime = _globals->_events.getFrameNumber();
+ if (_action)
+ _action->dispatch();
+
+ if (_mover && (_walkStartFrame <= currTime)) {
+ if (_field7A) {
+ int frameInc = 60 / _field7A;
+ _walkStartFrame = currTime + frameInc;
+ }
+ _mover->dispatch();
+ }
+
+ if (!(_flags & OBJFLAG_NO_UPDATES)) {
+ switch (_animateMode) {
+ case ANIM_MODE_1:
+ if (isNoMover())
+ setFrame(1);
+ else if ((_field2E.x != _position.x) || (_field2E.y != _position.y)) {
+ setFrame(changeFrame());
+ _field2E = _position;
+
+ }
+ break;
+
+ case ANIM_MODE_2:
+ case ANIM_MODE_3:
+ setFrame(changeFrame());
+
+ break;
+ case ANIM_MODE_4:
+ case ANIM_MODE_5:
+ case ANIM_MODE_6:
+ if (_frame == _endFrame)
+ animEnded();
+ else
+ setFrame(changeFrame());
+ break;
+
+ case ANIM_MODE_7:
+ if (changeFrame() != _frame) {
+ // Pick a new random frame
+ int frameNum = 0;
+ do {
+ int count = getFrameCount();
+ frameNum = _globals->_randomSource.getRandomNumber(count - 1);
+ } while (frameNum == _frame);
+
+ setFrame(frameNum);
+ if (_endFrame) {
+ if (--_endFrame == 0)
+ animEnded();
+ }
+ }
+ break;
+
+ case ANIM_MODE_8:
+ if (_frame == _endFrame) {
+ if (_frameChange != -1) {
+ _frameChange = -1;
+ _endFrame = 1;
+
+ setFrame(changeFrame());
+ } else if (!_field68 || (--_field68 > 0)) {
+ _frameChange = 1;
+ _endFrame = getFrameCount();
+
+ setFrame(changeFrame());
+ } else {
+ animEnded();
+ }
+ } else {
+ setFrame(changeFrame());
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Handle updating the zoom and/or priority
+ if (!(_flags & OBJFLAG_ZOOMED)) {
+ int yp = CLIP((int)_position.y, 0, 255);
+ setZoom(_globals->_sceneManager._scene->_zoomPercents[yp]);
+ }
+ if (!(_flags & OBJFLAG_FIXED_PRIORITY)) {
+ setPriority(_position.y);
+ }
+}
+
+void SceneObject::calcAngle(const Common::Point &pt) {
+ int newAngle = GfxManager::getAngle(_position, pt);
+ if (newAngle != -1)
+ _angle = newAngle;
+}
+
+void SceneObject::removeObject() {
+ _globals->_sceneItems.remove(this);
+ _globals->_sceneObjects->remove(this);
+
+ if (_visage) {
+ _vm->_memoryManager.deallocate(_visage);
+ _visage = 0;
+ }
+
+ if (_objectWrapper) {
+ _objectWrapper->remove();
+ _objectWrapper = NULL;
+ }
+ if (_mover) {
+ _mover->remove();
+ _mover = NULL;
+ }
+ if (_flags & 0x800)
+ destroy();
+}
+
+GfxSurface SceneObject::getFrame() {
+ _visageImages.setVisage(_visage, _strip);
+ return _visageImages.getFrame(_frame);
+}
+
+void SceneObject::reposition() {
+ GfxSurface frame = getFrame();
+ _bounds.resize(frame, _position.x, _position.y - _yDiff, _percent);
+ _xs = _bounds.left;
+ _xe = _bounds.right;
+}
+
+/**
+ * Draws an object into the scene
+ */
+void SceneObject::draw() {
+ Rect destRect = _bounds;
+ destRect.translate(-_globals->_sceneManager._scene->_sceneBounds.left,
+ -_globals->_sceneManager._scene->_sceneBounds.top);
+ Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(_priority);
+ GfxSurface frame = getFrame();
+ _globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+}
+
+/**
+ * Refreshes the background around the area of a scene object prior to it's being redrawn,
+ * in case it is moving
+ */
+void SceneObject::updateScreen() {
+ Rect srcRect = _paneRects[CURRENT_PANENUM];
+ const Rect &sceneBounds = _globals->_sceneManager._scene->_sceneBounds;
+ srcRect.left = (srcRect.left / 4) * 4;
+ srcRect.right = ((srcRect.right + 3) / 4) * 4;
+ srcRect.clip(_globals->_sceneManager._scene->_sceneBounds);
+
+ if (srcRect.isValidRect()) {
+ Rect destRect = srcRect;
+ destRect.translate(-sceneBounds.left, -sceneBounds.top);
+ srcRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y);
+
+ _globals->_screenSurface.copyFrom(_globals->_sceneManager._scene->_backSurface, srcRect, destRect);
+ }
+}
+
+void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority) {
+ postInit();
+ setVisage(visage);
+ setStrip(stripFrameNum);
+ setFrame(frameNum);
+ setPosition(Common::Point(posX, posY), 0);
+ setPriority2(priority);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneObjectList::draw() {
+ Common::Array<SceneObject *> objList;
+ int paneNum = 0;
+ int xAmount = 0, yAmount = 0;
+
+ if (_objList.size() == 0) {
+ // Alternate draw mode
+
+ if (_globals->_paneRefreshFlag[paneNum] == 1) {
+ // Load the background
+ _globals->_sceneManager._scene->refreshBackground(0, 0);
+
+ Rect tempRect = _globals->_sceneManager._scene->_sceneBounds;
+ tempRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y);
+ ScenePalette::changeBackground(tempRect, _globals->_sceneManager._fadeMode);
+ } else {
+ _globals->_paneRegions[CURRENT_PANENUM].draw();
+ }
+
+ _globals->_paneRegions[CURRENT_PANENUM].setRect(0, 0, 0, 0);
+ _globals->_sceneManager.fadeInIfNecessary();
+
+ } else {
+ // If there is a scroll follower, check whether it has moved off-screen
+ if (_globals->_scrollFollower) {
+ const Rect &scrollerRect = _globals->_sceneManager._scrollerRect;
+ Common::Point objPos(
+ _globals->_scrollFollower->_position.x - _globals->_sceneManager._scene->_sceneBounds.left,
+ _globals->_scrollFollower->_position.y - _globals->_sceneManager._scene->_sceneBounds.top);
+ int loadCount = 0;
+
+ if (objPos.x >= scrollerRect.right) {
+ xAmount = 8;
+ loadCount = 20;
+ }
+ if (objPos.x < scrollerRect.left) {
+ xAmount = -8;
+ loadCount = 20;
+ }
+ if (objPos.y >= scrollerRect.bottom) {
+ yAmount = 2;
+ loadCount = 25;
+ }
+ if (objPos.y < scrollerRect.top) {
+ yAmount = -2;
+ loadCount = 25;
+ }
+
+ if (loadCount > 0)
+ _globals->_sceneManager.setBgOffset(Common::Point(xAmount, yAmount), loadCount);
+ }
+
+ if (_globals->_sceneManager._sceneLoadCount > 0) {
+ --_globals->_sceneManager._sceneLoadCount;
+ _globals->_sceneManager._scene->loadBackground(_globals->_sceneManager._sceneBgOffset.x,
+ _globals->_sceneManager._sceneBgOffset.y);
+ }
+
+ // Set up the flag mask
+ uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1;
+
+ // Initial loop to set up object list and update object position, priority, and flags
+ for (SynchronisedList<SceneObject *>::iterator i = _globals->_sceneObjects->begin();
+ i != _globals->_sceneObjects->end(); ++i) {
+ SceneObject *obj = *i;
+ objList.push_back(obj);
+
+ if (!(obj->_flags & OBJFLAG_HIDE))
+ obj->_flags &= ~OBJFLAG_HIDING;
+
+ // Reposition the bounds of the object to match the desired position
+ obj->reposition();
+
+ // Handle updating object priority
+ if (!(obj->_flags & OBJFLAG_FIXED_PRIORITY)) {
+ obj->_priority = MIN((int)obj->_position.y - 1,
+ (int)_globals->_sceneManager._scene->_backgroundBounds.bottom);
+ }
+
+ if ((_globals->_paneRefreshFlag[paneNum] != 0) || !_globals->_paneRegions[paneNum].empty()) {
+ obj->_flags |= flagMask;
+ }
+ }
+
+ // Check for any intersections, and then sort the object list by priority
+ checkIntersection(objList, objList.size(), CURRENT_PANENUM);
+ sortList(objList);
+
+ if (_globals->_paneRefreshFlag[paneNum] == 1) {
+ // Load the background
+ _globals->_sceneManager._scene->refreshBackground(0, 0);
+ }
+
+ _globals->_sceneManager._scene->_sceneBounds.left &= ~3;
+ _globals->_sceneManager._scene->_sceneBounds.right &= ~3;
+ _globals->_sceneOffset.x &= ~3;
+
+ if (_globals->_paneRefreshFlag[paneNum] != 0) {
+ // Change the background
+ Rect tempRect = _globals->_sceneManager._scene->_sceneBounds;
+ tempRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y);
+ ScenePalette::changeBackground(tempRect, _globals->_sceneManager._fadeMode);
+ } else {
+ for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
+ SceneObject *obj = objList[objIndex];
+
+ if ((obj->_flags & flagMask) && obj->_paneRects[paneNum].isValidRect())
+ obj->updateScreen();
+ }
+
+ _globals->_paneRegions[paneNum].draw();
+ }
+
+ _globals->_paneRegions[paneNum].setRect(0, 0, 0, 0);
+redraw:
+ // Main draw loop
+ for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
+ SceneObject *obj = objList[objIndex];
+
+ if ((obj->_flags & flagMask) && !(obj->_flags & OBJFLAG_HIDE)) {
+ obj->_paneRects[paneNum] = obj->_bounds;
+ obj->draw();
+ }
+ }
+
+ // Update the palette
+ _globals->_sceneManager.fadeInIfNecessary();
+ _globals->_sceneManager._loadMode = 0;
+ _globals->_paneRefreshFlag[paneNum] = 0;
+
+ // Loop through the object list, removing any objects and refreshing the screen as necessary
+ for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
+ SceneObject *obj = objList[objIndex];
+
+ if (obj->_flags & OBJFLAG_HIDE)
+ obj->_flags |= OBJFLAG_HIDING;
+ obj->_flags &= ~flagMask;
+ if (obj->_flags & OBJFLAG_REMOVE) {
+ obj->_flags |= OBJFLAG_PANES;
+
+ checkIntersection(objList, objIndex, CURRENT_PANENUM);
+
+ obj->updateScreen();
+ obj->removeObject();
+
+ // FIXME: Currently, removing objects causes screen flickers when the removed object intersects
+ // another drawn object, since the background is briefly redrawn over the object. For now, I'm
+ // using a forced jump back to redraw objects. In the long term, I should figure out how the
+ // original game does this properly
+ objList.remove_at(objIndex);
+ goto redraw;
+ }
+ }
+ }
+}
+
+void SceneObjectList::checkIntersection(Common::Array<SceneObject *> &ObjList, uint ObjIndex, int PaneNum) {
+ uint32 flagMask = (PaneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1;
+ SceneObject *obj = (ObjIndex == ObjList.size()) ? NULL : ObjList[ObjIndex];
+ Rect rect1;
+
+ for (uint idx = 0; idx < ObjList.size(); ++idx) {
+ SceneObject *currObj = ObjList[idx];
+
+ if (ObjIndex == ObjList.size()) {
+ if (currObj->_flags & flagMask)
+ checkIntersection(ObjList, idx, PaneNum);
+ } else if (idx != ObjIndex) {
+ Rect &paneRect = obj->_paneRects[PaneNum];
+ Rect objBounds = currObj->_bounds;
+ if (paneRect.isValidRect())
+ objBounds.extend(paneRect);
+
+ Rect objBounds2 = currObj->_bounds;
+ if (paneRect.isValidRect())
+ objBounds2.extend(paneRect);
+
+ objBounds.left &= ~3;
+ objBounds.right += 3;
+ objBounds.right &= ~3;
+ objBounds2.left &= ~3;
+ objBounds2.right += 3;
+ objBounds2.right &= ~3;
+
+ if (objBounds.intersects(objBounds2) && !(currObj->_flags & flagMask)) {
+ currObj->_flags |= flagMask;
+ checkIntersection(ObjList, idx, PaneNum);
+ }
+ }
+ }
+}
+
+struct SceneObjectLess {
+ bool operator()(const SceneObject *x, const SceneObject *y) const {
+ if (y->_priority > x->_priority)
+ return true;
+ else if ((y->_priority == x->_priority) && (y->_position.y > x->_position.y))
+ return true;
+ else if ((y->_priority == x->_priority) && (y->_position.y == x->_position.y) &&
+ (y->_yDiff > x->_yDiff))
+ return true;
+
+ return false;
+ }
+};
+
+void SceneObjectList::sortList(Common::Array<SceneObject *> &ObjList) {
+ Common::sort(ObjList.begin(), ObjList.end(), SceneObjectLess());
+}
+
+void SceneObjectList::activate() {
+ SceneObjectList *objectList = _globals->_sceneObjects;
+ _globals->_sceneObjects = this;
+ _globals->_sceneObjects_queue.push_front(this);
+
+ // Flag all the objects as modified
+ SynchronisedList<SceneObject *>::iterator i;
+ for (i = begin(); i != end(); ++i) {
+ (*i)->_flags |= OBJFLAG_PANES;
+ }
+
+ // Replicate all existing objects on the old object list
+ for (i = objectList->begin(); i != objectList->end(); ++i) {
+ SceneObject *sceneObj = (*i)->clone();
+ sceneObj->_flags |= OBJFLAG_HIDE | OBJFLAG_REMOVE | OBJFLAG_CLONED;
+ push_front(sceneObj);
+ }
+}
+
+void SceneObjectList::deactivate() {
+ if (_globals->_sceneObjects_queue.size() <= 1)
+ return;
+
+ SceneObjectList *objectList = *_globals->_sceneObjects_queue.begin();
+ _globals->_sceneObjects_queue.pop_front();
+ _globals->_sceneObjects = *_globals->_sceneObjects_queue.begin();
+
+ SynchronisedList<SceneObject *>::iterator i;
+ for (i = objectList->begin(); i != objectList->end(); ++i) {
+ if (!((*i)->_flags & OBJFLAG_CLONED)) {
+ SceneObject *sceneObj = (*i)->clone();
+ sceneObj->_flags |= OBJFLAG_HIDE | OBJFLAG_REMOVE | OBJFLAG_CLONED;
+ _globals->_sceneObjects->push_front(sceneObj);
+ }
+ }
+}
+
+void SceneObjectList::synchronise(Serialiser &s) {
+ _objList.synchronise(s);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneText::SceneText() : SceneObject() {
+ _fontNumber = 2;
+ _width = 160;
+ _textMode = ALIGN_LEFT;
+ _colour2 = 0;
+ _colour3 = 0;
+}
+
+SceneText::~SceneText() {
+}
+
+void SceneText::setup(const Common::String &msg) {
+ GfxManager gfxMan(_textSurface);
+ gfxMan.activate();
+ Rect textRect;
+
+ gfxMan._font.setFontNumber(_fontNumber);
+ gfxMan._font._colours.foreground = _colour1;
+ gfxMan._font._colours2.background = _colour2;
+ gfxMan._font._colours2.foreground = _colour3;
+
+ gfxMan.getStringBounds(msg.c_str(), textRect, _width);
+
+ // Set up a new blank surface to hold the text
+ _textSurface.create(textRect.width(), textRect.height());
+ _textSurface._transColour = 0xff;
+ _textSurface.fillRect(textRect, _textSurface._transColour);
+
+ // Write the text to the surface
+ gfxMan._bounds = textRect;
+ gfxMan._font.writeLines(msg.c_str(), textRect, _textMode);
+
+ // Do post-init, which adds this SceneText object to the scene
+ postInit();
+ gfxMan.deactivate();
+}
+
+void SceneText::synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+
+ s.syncAsSint16LE(_fontNumber);
+ s.syncAsSint16LE(_width);
+ s.syncAsSint16LE(_colour1);
+ s.syncAsSint16LE(_colour2);
+ s.syncAsSint16LE(_colour3);
+ SYNC_ENUM(_textMode, TextAlign);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Visage::Visage() {
+ _resNum = 0;
+ _rlbNum = 0;
+ _data = NULL;
+}
+
+Visage::Visage(const Visage &v) {
+ _resNum = v._resNum;
+ _rlbNum = v._rlbNum;
+ _data = v._data;
+ if (_data)
+ _vm->_memoryManager.incLocks(_data);
+}
+
+Visage &Visage::operator=(const Visage &s) {
+ _resNum = s._resNum;
+ _rlbNum = s._rlbNum;
+ _data = s._data;
+ if (_data)
+ _vm->_memoryManager.incLocks(_data);
+
+ return *this;
+}
+
+void Visage::setVisage(int resNum, int rlbNum) {
+ if ((_resNum != resNum) || (_rlbNum != rlbNum)) {
+ _resNum = resNum;
+ _rlbNum = rlbNum;
+ DEALLOCATE(_data);
+ _data = _vm->_dataManager->getResource(RES_VISAGE, resNum, rlbNum);
+ assert(_data);
+ }
+}
+
+Visage::~Visage() {
+ DEALLOCATE(_data);
+}
+
+GfxSurface Visage::getFrame(int frameNum) {
+ int numFrames = READ_LE_UINT16(_data);
+ if (frameNum > numFrames)
+ frameNum = numFrames;
+ if (frameNum > 0)
+ --frameNum;
+
+ int offset = READ_UINT32(_data + 2 + frameNum * 4);
+ byte *frameData = _data + offset;
+
+ return surfaceFromRes(frameData);
+}
+
+int Visage::getFrameCount() const {
+ return READ_LE_UINT16(_data);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Player::postInit(SceneObjectList *OwnerList) {
+ SceneObject::postInit();
+
+ _canWalk = true;
+ _uiEnabled = true;
+ _percent = 100;
+ _field8C = 10;
+ _moveDiff.x = 4;
+ _moveDiff.y = 2;
+}
+
+void Player::disableControl() {
+ _canWalk = false;
+ _uiEnabled = false;
+ _globals->_events.setCursor(CURSOR_NONE);
+}
+
+void Player::enableControl() {
+ _canWalk = true;
+ _uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_WALK);
+
+ switch (_globals->_events.getCursor()) {
+ case CURSOR_WALK:
+ case CURSOR_LOOK:
+ case CURSOR_USE:
+ case CURSOR_TALK:
+ _globals->_events.setCursor(_globals->_events.getCursor());
+ break;
+ default:
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ }
+}
+
+void Player::process(Event &event) {
+ if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN) &&
+ (_globals->_events.getCursor() == CURSOR_WALK) && _globals->_player._canWalk &&
+ (_position != event.mousePos) && _globals->_sceneObjects->contains(this)) {
+
+ PlayerMover *newMover = new PlayerMover();
+ Common::Point destPos(event.mousePos.x + _globals->_sceneManager._scene->_sceneBounds.left,
+ event.mousePos.y + _globals->_sceneManager._scene->_sceneBounds.top);
+
+ addMover(newMover, &destPos, NULL);
+ event.handled = true;
+ }
+}
+
+void Player::synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+
+ s.syncAsByte(_canWalk);
+ s.syncAsByte(_uiEnabled);
+ s.syncAsSint16LE(_field8C);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Region::Region(int resNum, int rlbNum, ResourceType ctlType) {
+ _regionId = rlbNum;
+
+ byte *regionData = _vm->_dataManager->getResource(ctlType, resNum, rlbNum);
+ assert(regionData);
+
+ // Set the region bounds
+ _bounds.top = READ_LE_UINT16(regionData + 6);
+ _bounds.left = READ_LE_UINT16(regionData + 8);
+ _bounds.bottom = READ_LE_UINT16(regionData + 10);
+ _bounds.right = READ_LE_UINT16(regionData + 12);
+
+ // Special handling for small size regions
+ _regionSize = READ_LE_UINT16(regionData);
+ if (_regionSize == 14)
+ // No line slices
+ return;
+
+ // Set up the line slices
+ for (int y = 0; y < (_regionSize == 22 ? 1 : _bounds.height()); ++y) {
+ int slicesCount = READ_LE_UINT16(regionData + 16 + y * 4);
+ int slicesOffset = READ_LE_UINT16(regionData + 14 + y * 4);
+ assert(slicesCount < 100);
+ LineSliceSet sliceSet;
+ sliceSet.load(slicesCount, regionData + 14 + slicesOffset);
+
+ _ySlices.push_back(sliceSet);
+ }
+
+ DEALLOCATE(regionData);
+}
+
+/**
+ * Returns true if the given region contains the specified point
+ * @param pt Specified position
+ */
+bool Region::contains(const Common::Point &pt) {
+ // First check if the point falls inside the overall bounding rectangle
+ if (!_bounds.contains(pt) || _ySlices.empty())
+ return false;
+
+ // Get the correct Y line to use
+ const LineSliceSet &line = getLineSlices(pt.y);
+
+ // Loop through the horizontal slice list to see if the point falls in one
+ for (uint idx = 0; idx < line.items.size(); ++idx) {
+ if ((pt.x >= line.items[idx].xs) && (pt.x < line.items[idx].xe))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Returns true if the given region is empty
+ */
+bool Region::empty() const {
+ return !_bounds.isValidRect() && (_regionSize == 14);
+}
+
+void Region::clear() {
+ _bounds.set(0, 0, 0, 0);
+ _regionId = 0;
+ _regionSize = 0;
+}
+
+void Region::setRect(const Rect &r) {
+ setRect(r.left, r.top, r.right, r.bottom);
+}
+
+void Region::setRect(int xs, int ys, int xe, int ye) {
+ bool validRect = (ys < ye) && (xs < xe);
+ _ySlices.clear();
+
+ if (!validRect) {
+ _regionSize = 14;
+ _bounds.set(0, 0, 0, 0);
+ } else {
+ _regionSize = 22;
+ _bounds.set(xs, ys, xe, ye);
+
+ LineSliceSet sliceSet;
+ sliceSet.load2(1, xs, xe);
+
+ _ySlices.push_back(sliceSet);
+ }
+}
+
+const LineSliceSet &Region::getLineSlices(int yp) {
+ return _ySlices[(_regionSize == 22) ? 0 : yp - _bounds.top];
+}
+
+LineSliceSet Region::sectPoints(int yp, const LineSliceSet &sliceSet) {
+ if ((yp < _bounds.top) || (yp >= _bounds.bottom))
+ return LineSliceSet();
+
+ const LineSliceSet &ySet = getLineSlices(yp);
+ return mergeSlices(sliceSet, ySet);
+}
+
+LineSliceSet Region::mergeSlices(const LineSliceSet &set1, const LineSliceSet &set2) {
+ LineSliceSet result;
+
+ uint set1Index = 0, set2Index = 0;
+
+ while ((set1Index < set1.items.size()) && (set2Index < set2.items.size())) {
+ if (set1.items[set1Index].xe <= set2.items[set2Index].xs) {
+ ++set1Index;
+ } else if (set2.items[set2Index].xe <= set1.items[set1Index].xs) {
+ ++set2Index;
+ } else {
+ bool set1Flag = set1.items[set1Index].xs >= set2.items[set2Index].xs;
+ const LineSlice &slice = set1Flag ? set1.items[set1Index] : set2.items[set2Index];
+
+ result.add(slice.xs, MIN(set1.items[set1Index].xe, set2.items[set2Index].xe));
+ if (set1Flag)
+ ++set1Index;
+ else
+ ++set2Index;
+ }
+ }
+
+ return result;
+}
+
+/**
+ * Copies the background covered by the given region to the screen surface
+ */
+void Region::draw() {
+ Rect &sceneBounds = _globals->_sceneManager._scene->_sceneBounds;
+
+ for (int yp = sceneBounds.top; yp < sceneBounds.bottom; ++yp) {
+ // Generate a line slice set
+ LineSliceSet tempSet;
+ tempSet.add(sceneBounds.left, sceneBounds.right);
+ LineSliceSet newSet = sectPoints(yp, tempSet);
+
+ // Loop through the calculated slices
+ for (uint idx = 0; idx < newSet.items.size(); ++idx) {
+ Rect rect1(newSet.items[idx].xs, yp, newSet.items[idx].xe, yp + 1);
+ rect1.left &= ~3;
+ rect1.right = (rect1.right + 3) & ~3;
+
+ Rect rect2 = rect1;
+ rect1.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y);
+ rect2.translate(-sceneBounds.left, -sceneBounds.top);
+
+ _globals->gfxManager().getSurface().copyFrom(_globals->_sceneManager._scene->_backSurface,
+ rect1, rect2);
+ }
+ }
+}
+
+void Region::uniteLine(int yp, LineSliceSet &sliceSet) {
+ // TODO: More properly implement like the original
+
+ // First expand the bounds as necessary to fit in the row
+ if (_ySlices.empty()) {
+ _bounds = Rect(sliceSet.items[0].xs, yp, sliceSet.items[sliceSet.items.size() - 1].xe, yp + 1);
+ _ySlices.push_back(LineSliceSet());
+ }
+ while (yp < _bounds.top) {
+ _ySlices.insert_at(0, LineSliceSet());
+ --_bounds.top;
+ }
+ while (yp >= _bounds.bottom) {
+ _ySlices.push_back(LineSliceSet());
+ ++_bounds.bottom;
+ }
+
+ // Merge the existing line set into the line
+ LineSliceSet &destSet = _ySlices[yp - _bounds.top];
+ for (uint srcIndex = 0; srcIndex < sliceSet.items.size(); ++srcIndex) {
+ LineSlice &srcSlice = sliceSet.items[srcIndex];
+
+ // Check if overlaps existing slices
+ uint destIndex = 0;
+ while (destIndex < destSet.items.size()) {
+ LineSlice &destSlice = destSet.items[destIndex];
+ if (((srcSlice.xs >= destSlice.xs) && (srcSlice.xs <= destSlice.xe)) ||
+ ((srcSlice.xe >= destSlice.xs) && (srcSlice.xe <= destSlice.xe)) ||
+ ((srcSlice.xs < destSlice.xs) && (srcSlice.xe > destSlice.xe))) {
+ // Intersecting, so merge them
+ destSlice.xs = MIN(srcSlice.xs, destSlice.xs);
+ destSlice.xe = MAX(srcSlice.xe, destSlice.xe);
+ break;
+ }
+ ++destIndex;
+ }
+ if (destIndex == destSet.items.size()) {
+ // No intersecting region found, so add it to the list
+ destSet.items.push_back(srcSlice);
+ }
+ }
+
+ // Check whether to expand the left/bounds bounds
+ if (destSet.items[0].xs < _bounds.left)
+ _bounds.left = destSet.items[0].xs;
+ if (destSet.items[destSet.items.size() - 1].xe > _bounds.right)
+ _bounds.right = destSet.items[destSet.items.size() - 1].xe;
+}
+
+void Region::uniteRect(const Rect &rect) {
+ for (int yp = rect.top; yp < rect.bottom; ++yp) {
+ LineSliceSet sliceSet;
+ sliceSet.add(rect.left, rect.right);
+ uniteLine(yp, sliceSet);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void SceneRegions::load(int sceneNum) {
+ clear();
+
+ byte *regionData = _vm->_dataManager->getResource(RES_CONTROL, sceneNum, 9999, true);
+
+ if (regionData) {
+ int regionCount = READ_LE_UINT16(regionData);
+ for (int regionCtr = 0; regionCtr < regionCount; ++regionCtr) {
+ int rlbNum = READ_LE_UINT16(regionData + regionCtr * 6 + 2);
+
+ push_back(Region(sceneNum, rlbNum));
+ }
+
+ DEALLOCATE(regionData);
+ }
+}
+
+int SceneRegions::indexOf(const Common::Point &pt) {
+ for (SceneRegions::iterator i = begin(); i != end(); ++i) {
+ if ((*i).contains(pt))
+ return (*i)._regionId;
+ }
+
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SoundHandler::SoundHandler() {
+ _action = NULL;
+ _field280 = -1;
+ if (_globals)
+ _globals->_sceneListeners.push_back(this);
+}
+
+SoundHandler::~SoundHandler() {
+ if (_globals)
+ _globals->_sceneListeners.remove(this);
+}
+
+void SoundHandler::dispatch() {
+ EventHandler::dispatch();
+ int v = _sound.proc12();
+
+ if (v != -1) {
+ _field280 = v;
+ _sound.proc2(-1);
+
+ if (_action)
+ _action->signal();
+ }
+
+ if (_field280 != -1) {
+ // FIXME: Hardcoded to only flag a sound ended if an action has been set
+ if (_action) {
+// if (!_sound.proc3()) {
+ _field280 = -1;
+ if (_action) {
+ _action->signal();
+ _action = NULL;
+ }
+ }
+ }
+}
+
+void SoundHandler::startSound(int soundNum, Action *action, int volume) {
+ _action = action;
+ _field280 = 0;
+ setVolume(volume);
+ _sound.startSound(soundNum);
+
+ warning("TODO: SoundHandler::startSound");
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+void SceneItemList::addItems(SceneItem *first, ...) {
+ va_list va;
+ va_start(va, first);
+
+ SceneItem *p = first;
+ while (p) {
+ push_back(p);
+ p = va_arg(va, SceneItem *);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+RegionSupportRec WalkRegion::_processList[PROCESS_LIST_SIZE];
+
+void RegionSupportRec::process() {
+ if (_xDiff < _yDiff) {
+ _halfDiff += _xDiff;
+ if (_halfDiff > _yDiff) {
+ _halfDiff -= _yDiff;
+ _xp += _xDirection;
+ }
+ } else {
+ do {
+ _xp += _xDirection;
+ _halfDiff += _yDiff;
+ } while (_halfDiff <= _xDiff);
+ _halfDiff -= _xDiff;
+ }
+ --_yDiff2;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void WalkRegion::loadRegion(byte *dataP, int size) {
+ // First clear the region
+ clear();
+
+ // Decode the data for the region
+ int dataCount, regionHeight;
+ loadProcessList(dataP, size, dataCount, regionHeight);
+
+ int processIndex = 0, idx2 = 0, count;
+ for (int yp = _processList[0]._yp; yp < regionHeight; ++yp) {
+ process3(yp, dataCount, processIndex, idx2);
+ process4(yp, processIndex, idx2, count);
+
+ loadRecords(yp, count, processIndex);
+ }
+}
+
+void WalkRegion::loadProcessList(byte *dataP, int dataSize, int &dataIndex, int &regionHeight) {
+ dataIndex = 0;
+ int x1 = READ_LE_UINT16(dataP + (dataSize - 1) * 4);
+ int y1 = READ_LE_UINT16(dataP + (dataSize - 1) * 4 + 2);
+ regionHeight = y1;
+
+ for (int idx = 0; idx < dataSize; ++idx) {
+ int xp = READ_LE_UINT16(dataP + idx * 4);
+ int yp = READ_LE_UINT16(dataP + idx * 4 + 2);
+ if (yp != y1) {
+ /*
+ * Commented out: doesn't seem to be used
+ int v;
+ if (idx == (dataSize - 1))
+ v = READ_LE_UINT16(dataP + 2);
+ else
+ v = process1(idx, dataP, dataSize);
+ warning("TODO: v not used? - %d", v);
+ */
+ process2(dataIndex, x1, y1, xp, yp);
+ ++dataIndex;
+ }
+
+ // Keep regionHeight as the maximum of any y
+ if (yp > regionHeight)
+ regionHeight = yp;
+
+ x1 = xp;
+ y1 = yp;
+ }
+}
+
+int WalkRegion::process1(int idx, byte *dataP, int dataSize) {
+ int idx2 = idx + 1;
+ if (idx2 == dataSize)
+ idx2 = 0;
+
+ while (READ_LE_UINT16(dataP + idx2 * 4 + 2) == READ_LE_UINT16(dataP + idx * 4 + 2)) {
+ if (idx2 == (dataSize - 1))
+ idx2 = 0;
+ else
+ ++idx2;
+ }
+
+ return READ_LE_UINT16(dataP + idx2 * 4 + 2);
+}
+
+void WalkRegion::process2(int dataIndex, int x1, int y1, int x2, int y2) {
+ int xDiff = ABS(x2 - x1);
+ int yDiff = ABS(y2 - y1);
+ int halfDiff = MAX(xDiff, yDiff) / 2;
+ int yMax = MIN(y1, y2);
+
+ while (dataIndex && (_processList[dataIndex - 1]._yp > yMax)) {
+ _processList[dataIndex] = _processList[dataIndex - 1];
+ --dataIndex;
+ }
+ _processList[dataIndex]._yp = yMax;
+
+ _processList[dataIndex]._xp = (y1 >= y2) ? x2 : x1;
+ _processList[dataIndex]._xDiff = xDiff;
+ _processList[dataIndex]._yDiff = yDiff;
+ _processList[dataIndex]._halfDiff = halfDiff;
+
+ int xTemp = (y1 >= y2) ? x1 - x2 : x2 - x1;
+ _processList[dataIndex]._xDirection = (xTemp == 0) ? 0 : ((xTemp < 0) ? -1 : 1);
+ _processList[dataIndex]._yDiff2 = yDiff;
+}
+
+void WalkRegion::process3(int yp, int dataCount, int &idx1, int &idx2) {
+ while ((idx2 < (dataCount - 1)) && (_processList[idx2 + 1]._yp <= yp))
+ ++idx2;
+ while (!_processList[idx1]._yDiff2)
+ ++idx1;
+}
+
+void WalkRegion::process4(int yp, int idx1, int idx2, int &count) {
+ count = 0;
+ for (int idx = idx1; idx <= idx2; ++idx) {
+ if (_processList[idx]._yDiff2 > 0)
+ ++count;
+ process5(idx, idx1);
+ }
+}
+
+void WalkRegion::process5(int idx1, int idx2) {
+ while ((idx1 > idx2) && (_processList[idx1 - 1]._xp > _processList[idx1]._xp)) {
+ SWAP(_processList[idx1], _processList[idx1 - 1]);
+ --idx1;
+ }
+}
+
+void WalkRegion::loadRecords(int yp, int size, int processIndex) {
+ LineSliceSet sliceSet;
+ int sliceCount = size / 2;
+
+ for (int idx = 0; idx < sliceCount; ++idx, ++processIndex) {
+ while (!_processList[processIndex]._yDiff2)
+ ++processIndex;
+
+ int sliceXs = _processList[processIndex]._xp;
+ _processList[processIndex].process();
+
+ do {
+ ++processIndex;
+ } while (!_processList[processIndex]._yDiff2);
+
+ int sliceXe = _processList[processIndex]._xp;
+ _processList[processIndex].process();
+
+ sliceSet.items.push_back(LineSlice(sliceXs, sliceXe));
+ }
+
+ uniteLine(yp, sliceSet);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void WRField18::load(byte *data) {
+ _pt1.x = READ_LE_UINT16(data);
+ _pt1.y = READ_LE_UINT16(data + 2);
+ _pt2.x = READ_LE_UINT16(data + 4);
+ _pt2.y = READ_LE_UINT16(data + 6);
+ _v = READ_LE_UINT16(data + 8);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void WalkRegions::clear() {
+ _regionList.clear();
+ _field18.clear();
+ _idxList.clear();
+ _idxList2.clear();
+}
+
+void WalkRegions::load(int sceneNum) {
+ clear();
+
+ _resNum = sceneNum;
+ byte *regionData = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 1, true);
+ if (!regionData) {
+ // No data, so return
+ _resNum = -1;
+ return;
+ }
+
+ byte *dataP;
+ int dataSize;
+
+ // Load the field 18 list
+ dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 2);
+ dataSize = _vm->_memoryManager.getSize(dataP);
+ assert(dataSize % 10 == 0);
+
+ byte *p = dataP;
+ for (int idx = 0; idx < (dataSize / 10); ++idx, p += 10) {
+ WRField18 rec;
+ rec.load(p);
+ _field18.push_back(rec);
+ }
+
+ DEALLOCATE(dataP);
+
+ // Load the idx list
+ dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 3);
+ dataSize = _vm->_memoryManager.getSize(dataP);
+ assert(dataSize % 2 == 0);
+
+ p = dataP;
+ for (int idx = 0; idx < (dataSize / 2); ++idx, p += 2)
+ _idxList.push_back(READ_LE_UINT16(p));
+
+ DEALLOCATE(dataP);
+
+ // Load the secondary idx list
+ dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 4);
+ dataSize = _vm->_memoryManager.getSize(dataP);
+ assert(dataSize % 2 == 0);
+
+ p = dataP;
+ for (int idx = 0; idx < (dataSize / 2); ++idx, p += 2)
+ _idxList2.push_back(READ_LE_UINT16(p));
+
+ DEALLOCATE(dataP);
+
+ // Handle the loading of the actual regions themselves
+ dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 5);
+
+ byte *pWalkRegion = regionData + 16;
+ byte *srcP = dataP;
+ for (; (int16)READ_LE_UINT16(pWalkRegion) != -20000; pWalkRegion += 16) {
+ WalkRegion wr;
+
+ // Set the Walk region specific fields
+ wr._pt.x = (int16)READ_LE_UINT16(pWalkRegion);
+ wr._pt.y = (int16)READ_LE_UINT16(pWalkRegion + 2);
+ wr._idxListIndex = READ_LE_UINT32(pWalkRegion + 4);
+ wr._idxList2Index = READ_LE_UINT32(pWalkRegion + 8);
+
+ // Region in the region data
+ int size = READ_LE_UINT16(srcP);
+ srcP += 2;
+ wr.loadRegion(srcP, size);
+
+ srcP += size * 4;
+ _regionList.push_back(wr);
+ }
+
+ DEALLOCATE(dataP);
+ DEALLOCATE(regionData);
+}
+
+/**
+ * Returns the index of the walk region that contains the given point
+ * @param pt Point to locate
+ * @param indexList List of region indexes that should be ignored
+ */
+int WalkRegions::indexOf(const Common::Point &pt, const Common::List<int> *indexList) {
+ for (uint idx = 0; idx < _regionList.size(); ++idx) {
+ if ((!indexList || contains(*indexList, int(idx + 1))) && _regionList[idx].contains(pt))
+ return idx + 1;
+ }
+
+ return -1;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void ScenePriorities::load(int resNum) {
+ _resNum = resNum;
+ clear();
+
+ byte *regionData = _vm->_dataManager->getResource(RES_PRIORITY, resNum, 9999, true);
+
+ if (regionData) {
+ int regionCount = READ_LE_UINT16(regionData);
+ for (int regionCtr = 0; regionCtr < regionCount; ++regionCtr) {
+ int rlbNum = READ_LE_UINT16(regionData + regionCtr * 6 + 2);
+
+ push_back(Region(resNum, rlbNum, RES_PRIORITY));
+ }
+
+ DEALLOCATE(regionData);
+ }
+}
+
+Region *ScenePriorities::find(int priority) {
+ // If no priority regions are loaded, then return the placeholder region
+ if (empty())
+ return &_defaultPriorityRegion;
+
+ if (priority > 255)
+ priority = 255;
+
+ // Loop through the regions to find the closest for the givne priority level
+ int minRegionId = 9998;
+ Region *region = NULL;
+ for (ScenePriorities::iterator i = begin(); i != end(); ++i) {
+ Region *r = &(*i);
+ int regionId = r->_regionId;
+
+ if ((regionId > priority) && (regionId < minRegionId)) {
+ minRegionId = regionId;
+ region = r;
+ }
+ }
+
+ assert(region);
+ return region;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void FloatSet::add(double v1, double v2, double v3) {
+ _float1 += v1;
+ _float2 += v2;
+ _float3 += v3;
+}
+
+void FloatSet::proc1(double v) {
+ double diff = (cos(v) * _float1) - (sin(v) * _float2);
+ _float2 = (sin(v) * _float1) + (cos(v) * _float2);
+ _float1 = diff;
+}
+
+double FloatSet::sqrt(FloatSet &floatSet) {
+ double f1Diff = _float1 - floatSet._float1;
+ double f2Diff = _float2 - floatSet._float2;
+ double f3Diff = _float3 - floatSet._float3;
+
+ return ::sqrt(f1Diff * f1Diff + f2Diff * f2Diff + f3Diff * f3Diff);
+}
+
+/*--------------------------------------------------------------------------*/
+
+GameHandler::GameHandler() : EventHandler() {
+ _nextWaitCtr = 1;
+ _waitCtr.setCtr(1);
+ _field14 = 10;
+}
+
+GameHandler::~GameHandler() {
+ if (_globals)
+ _globals->_game.removeHandler(this);
+}
+
+void GameHandler::execute() {
+ if (_waitCtr.decCtr() == 0) {
+ _waitCtr.setCtr(_nextWaitCtr);
+ dispatch();
+ }
+}
+
+void GameHandler::synchronise(Serialiser &s) {
+ _lockCtr.synchronise(s);
+ _waitCtr.synchronise(s);
+ s.syncAsSint16LE(_nextWaitCtr);
+ s.syncAsSint16LE(_field14);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneHandler::SceneHandler() {
+ _saveGameSlot = -1;
+ _loadGameSlot = -1;
+}
+
+void SceneHandler::registerHandler() {
+ postInit();
+ _globals->_game.addHandler(this);
+}
+
+void SceneHandler::postInit(SceneObjectList *OwnerList) {
+ _delayTicks = 2;
+
+ _globals->_scenePalette.loadPalette(0);
+ _globals->_scenePalette.refresh();
+
+ // TODO: Bunch of other scene related setup goes here
+ _globals->_soundManager.postInit();
+
+ // Set some default flags and cursor
+ _globals->setFlag(12);
+ _globals->setFlag(34);
+ _globals->_events.setCursor(CURSOR_WALK);
+
+ // Set the screen to scroll in response to the player moving off-screen
+ _globals->_scrollFollower = &_globals->_player;
+
+ // Set the object's that will be in the player's inventory by default
+ _globals->_inventory._stunner._sceneNumber = 1;
+ _globals->_inventory._scanner._sceneNumber = 1;
+ _globals->_inventory._ring._sceneNumber = 1;
+
+ // Switch to the title screen
+ _globals->_sceneManager.setNewScene(1000);
+}
+
+void SceneHandler::process(Event &event) {
+ // Main keypress handler
+ if ((event.eventType == EVENT_KEYPRESS) && !event.handled) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F1:
+ // F1 - Help
+ _globals->_events.setCursor(CURSOR_ARROW);
+ MessageDialog::show(HELP_MSG, OK_BTN_STRING);
+ break;
+
+ case Common::KEYCODE_F2: {
+ // F2 - Sound Options
+ ConfigDialog *dlg = new ConfigDialog();
+ dlg->runModal();
+ delete dlg;
+ _globals->_events.setCursorFromFlag();
+ break;
+ }
+
+ case Common::KEYCODE_F3:
+ // F3 - Quit
+ _globals->_game.quitGame();
+ event.handled = false;
+ break;
+
+ case Common::KEYCODE_F4:
+ // F4 - Restart
+ _globals->_game.restartGame();
+ _globals->_events.setCursorFromFlag();
+ break;
+
+ case Common::KEYCODE_F7:
+ // F7 - Restore
+ _globals->_game.restoreGame();
+ _globals->_events.setCursorFromFlag();
+ break;
+
+ case Common::KEYCODE_F10:
+ // F10 - Pause
+ GfxDialog::setPalette();
+ MessageDialog::show(GAME_PAUSED_MSG, OK_BTN_STRING);
+ _globals->_events.setCursorFromFlag();
+ break;
+
+ default:
+ break;
+ }
+
+ _globals->_events.setCursorFromFlag();
+ }
+
+ // Check for displaying right-click dialog
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (event.btnState == BTNSHIFT_RIGHT) &&
+ _globals->_player._uiEnabled) {
+ RightClickDialog *dlg = new RightClickDialog();
+ dlg->execute();
+ delete dlg;
+
+ event.handled = true;
+ return;
+ }
+
+ // If there is an active scene, pass the event to it
+ if (_globals->_sceneManager._scene)
+ _globals->_sceneManager._scene->process(event);
+
+ if (!event.handled) {
+ // Separate check for F5 - Save key
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_F5)) {
+ // F5 - Save
+ _globals->_game.saveGame();
+ event.handled = true;
+ _globals->_events.setCursorFromFlag();
+ }
+
+ // Check for debugger
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_d) &&
+ (event.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _vm->_debugger->attach();
+ _vm->_debugger->onFrame();
+ }
+
+ // Mouse press handling
+ if (_globals->_player._uiEnabled && (event.eventType == EVENT_BUTTON_DOWN) &&
+ !_globals->_sceneItems.empty()) {
+ // Scan the item list to find one the mouse is within
+ SynchronisedList<SceneItem *>::iterator i = _globals->_sceneItems.begin();
+ while ((i != _globals->_sceneItems.end()) && !(*i)->contains(event.mousePos))
+ ++i;
+
+ if (i != _globals->_sceneItems.end()) {
+ // Pass the action to the item
+ (*i)->doAction(_globals->_events.getCursor());
+ event.handled = _globals->_events.getCursor() != CURSOR_WALK;
+
+ if (_globals->_player._uiEnabled && _globals->_player._canWalk &&
+ (_globals->_events.getCursor() != CURSOR_LOOK)) {
+ _globals->_events.setCursor(CURSOR_WALK);
+ } else if (_globals->_player._canWalk && (_globals->_events.getCursor() != CURSOR_LOOK)) {
+ _globals->_events.setCursor(CURSOR_WALK);
+ } else if (_globals->_player._uiEnabled && (_globals->_events.getCursor() != CURSOR_LOOK)) {
+ _globals->_events.setCursor(CURSOR_USE);
+ }
+ }
+
+ // Handle player processing
+ _globals->_player.process(event);
+ }
+ }
+}
+
+void SceneHandler::dispatch() {
+ // Handle game saving and loading
+ if (_saveGameSlot != -1) {
+ int saveSlot = _saveGameSlot;
+ _saveGameSlot = -1;
+ if (_saver->save(saveSlot, _saveName) != Common::kNoError)
+ GUIErrorMessage(SAVE_ERROR_MSG);
+ }
+ if (_loadGameSlot != -1) {
+ int loadSlot = _loadGameSlot;
+ _loadGameSlot = -1;
+ _saver->restore(loadSlot);
+ _globals->_events.setCursorFromFlag();
+ }
+
+ _globals->_soundManager.dispatch();
+ _globals->_scenePalette.signalListeners();
+
+ // Dispatch to any objects registered in the scene
+ _globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
+
+ // If a scene is active, then dispatch to it
+ if (_globals->_sceneManager._scene)
+ _globals->_sceneManager._scene->dispatch();
+
+ //TODO: Figure out purpose of the given list
+ //_globals->_regions.forEach(SceneHandler::handleListener);
+
+ Event event;
+ while (_globals->_events.getEvent(event))
+ process(event);
+
+ // Handle drawing the contents of the scene
+ if (_globals->_sceneManager._scene)
+ _globals->_sceneObjects->draw();
+
+ // Check to see if any scene change is required
+ _globals->_sceneManager.checkScene();
+
+ // Signal the ScummVM debugger
+ _vm->_debugger->onFrame();
+
+ // Delay between frames
+ _globals->_events.delay(_delayTicks);
+}
+
+void SceneHandler::dispatchObject(EventHandler *obj) {
+ obj->dispatch();
+}
+
+void SceneHandler::saveListener(Serialiser &ser) {
+ warning("TODO: SceneHandler::saveListener");
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Game::execute() {
+ // Main game loop
+ bool activeFlag = false;
+ do {
+ // Process all currently atcive game handlers
+ activeFlag = false;
+ for (SynchronisedList<GameHandler *>::iterator i = _handlers.begin(); i != _handlers.end(); ++i) {
+ GameHandler *gh = *i;
+ if (gh->_lockCtr.getCtr() == 0) {
+ gh->execute();
+ activeFlag = true;
+ }
+ }
+ } while (activeFlag && !_vm->getEventManager()->shouldQuit());
+}
+
+void Game::restartGame() {
+ if (MessageDialog::show(RESTART_MSG, CANCEL_BTN_STRING, RESTART_BTN_STRING) == 1)
+ _globals->_game.restart();
+}
+
+void Game::saveGame() {
+ if (_globals->getFlag(50))
+ MessageDialog::show(SAVING_NOT_ALLOWED_MSG, OK_BTN_STRING);
+ else {
+ // Show the save dialog
+ handleSaveLoad(true, _globals->_sceneHandler._saveGameSlot, _globals->_sceneHandler._saveName);
+ }
+}
+
+void Game::restoreGame() {
+ if (_globals->getFlag(50))
+ MessageDialog::show(RESTORING_NOT_ALLOWED_MSG, OK_BTN_STRING);
+ else {
+ // Show the load dialog
+ handleSaveLoad(false, _globals->_sceneHandler._loadGameSlot, _globals->_sceneHandler._saveName);
+ }
+}
+
+void Game::quitGame() {
+ if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1)
+ _vm->quitGame();
+}
+
+void Game::handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName) {
+ const EnginePlugin *plugin = 0;
+ EngineMan.findGame(_vm->getGameId(), &plugin);
+ GUI::SaveLoadChooser *dialog;
+ if (saveFlag)
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
+ else
+ dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"));
+
+ dialog->setSaveMode(saveFlag);
+
+ saveSlot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ saveName = dialog->getResultString();
+
+ delete dialog;
+}
+
+void Game::restart() {
+ _globals->_scenePalette.clearListeners();
+ _globals->_soundHandler.proc3();
+
+ // Reset the flags
+ _globals->reset();
+ _globals->setFlag(34);
+
+ // Clear save/load slots
+ _globals->_sceneHandler._saveGameSlot = -1;
+ _globals->_sceneHandler._loadGameSlot = -1;
+
+ _globals->_stripNum = 0;
+ _globals->_events.setCursor(CURSOR_WALK);
+
+ // Reset item properties
+ _globals->_inventory._stunner._sceneNumber = 1;
+ _globals->_inventory._scanner._sceneNumber = 1;
+ _globals->_inventory._stasisBox._sceneNumber = 5200;
+ _globals->_inventory._infoDisk._sceneNumber = 40;
+ _globals->_inventory._stasisNegator._sceneNumber = 0;
+ _globals->_inventory._keyDevice._sceneNumber = 0;
+ _globals->_inventory._medkit._sceneNumber = 2280;
+ _globals->_inventory._ladder._sceneNumber = 4100;
+ _globals->_inventory._rope._sceneNumber = 4150;
+ _globals->_inventory._key._sceneNumber = 7700;
+ _globals->_inventory._translator._sceneNumber = 2150;
+ _globals->_inventory._paper._sceneNumber = 7700;
+ _globals->_inventory._waldos._sceneNumber = 0;
+ _globals->_inventory._ring._sceneNumber = 1;
+ _globals->_inventory._stasisBox2._sceneNumber = 8100;
+ _globals->_inventory._cloak._sceneNumber = 9850;
+ _globals->_inventory._tunic._sceneNumber = 9450;
+ _globals->_inventory._candle._sceneNumber = 9500;
+ _globals->_inventory._straw._sceneNumber = 9400;
+ _globals->_inventory._scimitar._sceneNumber = 9850;
+ _globals->_inventory._sword._sceneNumber = 9850;
+ _globals->_inventory._helmet._sceneNumber = 9500;
+ _globals->_inventory._items._sceneNumber = 4300;
+ _globals->_inventory._concentrator._sceneNumber = 4300;
+ _globals->_inventory._nullifier._sceneNumber = 4300;
+ _globals->_inventory._peg._sceneNumber = 4045;
+ _globals->_inventory._vial._sceneNumber = 5100;
+ _globals->_inventory._jacket._sceneNumber = 9850;
+ _globals->_inventory._tunic2._sceneNumber = 9850;
+ _globals->_inventory._bone._sceneNumber = 5300;
+ _globals->_inventory._jar._sceneNumber = 7700;
+ _globals->_inventory._emptyJar._sceneNumber = 7700;
+
+ // Change to the first game scene
+ _globals->_sceneManager.changeScene(30);
+}
+
+void Game::endGame(int resNum, int lineNum) {
+ _globals->_events.setCursor(CURSOR_WALK);
+ Common::String msg = _vm->_dataManager->getMessage(resNum, lineNum);
+ bool savesExist = _saver->savegamesExist();
+
+ if (!savesExist) {
+ // No savegames exist, so prompt the user to restart or quit
+ if (MessageDialog::show(msg, QUIT_BTN_STRING, RESTART_BTN_STRING) == 0)
+ _vm->quitGame();
+ else
+ restart();
+ } else {
+ // Savegames exist, so prompt for Restore/Restart
+ bool breakFlag;
+ do {
+ if (MessageDialog::show(msg, RESTART_BTN_STRING, RESTORE_BTN_STRING) == 0) {
+ breakFlag = true;
+ } else {
+ handleSaveLoad(false, _globals->_sceneHandler._loadGameSlot, _globals->_sceneHandler._saveName);
+ breakFlag = _globals->_sceneHandler._loadGameSlot > 0;
+ }
+ } while (!breakFlag);
+ }
+
+ _globals->_events.setCursorFromFlag();
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
new file mode 100644
index 0000000000..77923606d1
--- /dev/null
+++ b/engines/tsage/core.h
@@ -0,0 +1,956 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_CORE_H
+#define TSAGE_CORE_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/error.h"
+#include "common/list.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+#include "tsage/events.h"
+#include "tsage/graphics.h"
+#include "tsage/resources.h"
+#include "tsage/saveload.h"
+#include "tsage/sound.h"
+
+namespace tSage {
+
+#define MAX_FLAGS 256
+
+class EventHandler;
+class SceneObject;
+class SceneObjectList;
+class ObjectMover;
+class Action;
+class Serialiser;
+
+class InvObject : public SavedObject {
+public:
+ int _sceneNumber;
+ int _displayResNum;
+ int _rlbNum;
+ int _cursorNum;
+ Rect _bounds;
+ CursorType _cursorId;
+ Common::String _description;
+ int _iconResNum;
+public:
+ InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType cursorId, const Common::String description);
+
+ bool inInventory() const { return _sceneNumber == 1; }
+ void setCursor();
+
+ virtual Common::String getClassName() { return "InvObject"; }
+ virtual void synchronise(Serialiser &s) {
+ s.syncAsUint16LE(_sceneNumber);
+ }
+};
+
+class InvObjectList : public SavedObject {
+public:
+ InvObject _stunner;
+ InvObject _scanner;
+ InvObject _stasisBox;
+ InvObject _infoDisk;
+ InvObject _stasisNegator;
+ InvObject _keyDevice;
+ InvObject _medkit;
+ InvObject _ladder;
+ InvObject _rope;
+ InvObject _key;
+ InvObject _translator;
+ InvObject _ale;
+ InvObject _paper;
+ InvObject _waldos;
+ InvObject _stasisBox2;
+ InvObject _ring;
+ InvObject _cloak;
+ InvObject _tunic;
+ InvObject _candle;
+ InvObject _straw;
+ InvObject _scimitar;
+ InvObject _sword;
+ InvObject _helmet;
+ InvObject _items;
+ InvObject _concentrator;
+ InvObject _nullifier;
+ InvObject _peg;
+ InvObject _vial;
+ InvObject _jacket;
+ InvObject _tunic2;
+ InvObject _bone;
+ InvObject _jar;
+ InvObject _emptyJar;
+
+ SynchronisedList<InvObject *> _itemList;
+ InvObject *_selectedItem;
+public:
+ InvObjectList();
+
+ virtual Common::String getClassName() { return "InvObjectList"; }
+ virtual void synchronise(Serialiser &s);
+};
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * Basic reference counter class
+ */
+class RefCounter : public Serialisable {
+private:
+ int _ctr;
+public:
+ RefCounter() { clear(); }
+ virtual ~RefCounter() {}
+
+ RefCounter(int v) { _ctr = v; }
+
+ void clear() { _ctr = 0; }
+ void setCtr(int v) { _ctr = v; }
+ int decCtr() {
+ if (_ctr > 0) --_ctr;
+ return _ctr;
+ }
+ int incCtr() { return ++_ctr; }
+ int getCtr() const { return _ctr; }
+
+ virtual void synchronise(Serialiser &s) { s.syncAsSint16LE(_ctr); }
+};
+
+class EventHandler : public SavedObject {
+public:
+ Action *_action;
+
+ EventHandler() : SavedObject() { _action = NULL; }
+ virtual ~EventHandler() { destroy(); }
+
+ virtual void synchronise(Serialiser &s) { SYNC_POINTER(_action); }
+ virtual Common::String getClassName() { return "EventHandler"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL) {}
+ virtual void remove() {}
+ virtual void signal() {}
+ virtual void process(Event &event) {}
+ virtual void dispatch();
+ virtual void setAction(Action *action) { setAction(action, NULL); }
+ virtual void setAction(Action *action, EventHandler *fmt, ...);
+ virtual void destroy() {};
+};
+
+class Action : public EventHandler {
+public:
+ EventHandler *_owner;
+ int _actionIndex;
+ int _delayFrames;
+ uint32 _startFrame;
+ int _field16;
+ EventHandler *_fmt;
+
+ Action();
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "Action"; }
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void attached(EventHandler *newOwner, EventHandler *fmt, va_list va);
+
+ void attach(EventHandler *newOwner, EventHandler *fmt, ...) {
+ va_list va;
+ va_start(va, fmt);
+ attached(newOwner, fmt, va);
+ va_end(va);
+ }
+ int getActionIndex() const { return _actionIndex; }
+ void setActionIndex(int index) { _actionIndex = index; }
+ void setDelay(int numFrames);
+};
+
+class ActionExt : public Action {
+public:
+ int _state;
+};
+
+class ObjectMover : public EventHandler {
+public:
+ Common::Point _destPosition;
+ Common::Point _moveDelta;
+ Common::Point _moveSign;
+ int _minorDiff;
+ int _majorDiff;
+ int _field1A;
+ Action *_action;
+ SceneObject *_sceneObject;
+public:
+ ObjectMover() { _action = NULL; _sceneObject = NULL; }
+ virtual ~ObjectMover();
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "ObjectMover"; }
+ virtual void remove();
+ virtual void dispatch();
+ virtual void startMove(SceneObject *sceneObj, va_list va) {}
+ virtual void setup(const Common::Point &destPos);
+ virtual bool dontMove() const;
+ virtual void endMove();
+};
+
+class ObjectMover2 : public ObjectMover {
+public:
+ SceneObject *_destObject;
+ int _minArea;
+ int _maxArea;
+public:
+ ObjectMover2();
+ virtual ~ObjectMover2() {}
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "ObjectMover2"; }
+ virtual void dispatch();
+ virtual void startMove(SceneObject *sceneObj, va_list va);
+ virtual void endMove();
+};
+
+class ObjectMover3 : public ObjectMover2 {
+public:
+ virtual Common::String getClassName() { return "ObjectMover3"; }
+ virtual void dispatch();
+ virtual void startMove(SceneObject *sceneObj, va_list va);
+ virtual void endMove();
+};
+
+class NpcMover : public ObjectMover {
+public:
+ virtual Common::String getClassName() { return "NpcMover"; }
+ virtual void startMove(SceneObject *sceneObj, va_list va);
+};
+
+#define MAX_ROUTE_SIZE 20
+#define ROUTE_END_VAL -20000
+
+class RouteEnds {
+public:
+ Common::Point moveSrc;
+ Common::Point moveDest;
+};
+
+class PlayerMover : public NpcMover {
+protected:
+ void setDest(const Common::Point &destPos);
+ void pathfind(Common::Point *routeList, Common::Point srcPos, Common::Point destPos, RouteEnds routeEnds);
+ int regionIndexOf(const Common::Point &pt);
+ int regionIndexOf(int xp, int yp) { return regionIndexOf(Common::Point(xp, yp)); }
+ int findClosestRegion(Common::Point &pt, const Common::List<int> &indexList);
+ int checkMover(Common::Point &srcPos, const Common::Point &destPos);
+ void checkMovement2(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut);
+ int proc1(int *routeList, int srcRegion, int destRegion, int &v);
+
+ static Common::Point *findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos);
+ static int findDistance(const Common::Point &pt1, const Common::Point &pt2);
+ static bool sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3,
+ const Common::Point &pt4, Common::Point *ptOut = NULL);
+public:
+ Common::Point _finalDest;
+ Common::Point _routeList[MAX_ROUTE_SIZE];
+ int _routeIndex;
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "PlayerMover"; }
+ virtual void startMove(SceneObject *sceneObj, va_list va);
+ virtual void endMove();
+};
+
+class PlayerMover2 : public PlayerMover {
+public:
+ SceneObject *_destObject;
+ int _field7E;
+ int _minArea;
+ PlayerMover2() : PlayerMover() { _destObject = NULL; }
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "PlayerMover2"; }
+ virtual void dispatch();
+ virtual void startMove(SceneObject *sceneObj, va_list va);
+ virtual void endMove();
+};
+
+/*--------------------------------------------------------------------------*/
+
+class ScenePalette;
+
+class PaletteModifier : public SavedObject {
+public:
+ ScenePalette *_scenePalette;
+ Action *_action;
+public:
+ PaletteModifier();
+
+ virtual void synchronise(Serialiser &s) {
+ SYNC_POINTER(_scenePalette);
+ SYNC_POINTER(_action);
+ }
+ virtual void signal() = 0;
+ virtual void remove() = 0;
+};
+
+class PaletteRotation : public PaletteModifier {
+public:
+ bool _disabled;
+ int _delayFrames;
+ int _delayCtr;
+ uint32 _frameNumber;
+ int _currIndex;
+ int _start;
+ int _end;
+ int _rotationMode;
+ int _duration;
+ RGB8 _palette[256];
+public:
+ PaletteRotation();
+
+ virtual Common::String getClassName() { return "PaletteRotation"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+ virtual void remove();
+
+ void setDisabled(bool v) { _disabled = v; }
+ void set(ScenePalette *palette, int start, int end, int rotationMode, int duration, Action *action);
+ void setPalette(ScenePalette *palette, bool disabled);
+ bool decDuration();
+ void setDelay(int amount);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class PaletteUnknown : public PaletteModifier {
+public:
+ int _step, _percent, _field12, _field14;
+ RGB8 _palette[256];
+public:
+ virtual Common::String getClassName() { return "PaletteUnknown"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+ virtual void remove();
+};
+
+enum FadeMode {FADEMODE_NONE = 0, FADEMODE_GRADUAL = 1, FADEMODE_IMMEDIATE = 2};
+
+class ScenePalette : public SavedObject {
+public:
+ RGB8 _palette[256];
+ GfxColours _colours;
+ SynchronisedList<PaletteModifier *> _listeners;
+ int _field412;
+
+ uint8 _redColour;
+ uint8 _greenColour;
+ uint8 _blueColour;
+ uint8 _aquaColour;
+ uint8 _purpleColour;
+ uint8 _limeColour;
+public:
+ ScenePalette();
+ ScenePalette(int paletteNum);
+
+ bool loadPalette(int paletteNum);
+ void refresh();
+ void setPalette(int index, int count);
+ uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff);
+ void getPalette(int start = 0, int count = 256);
+ void signalListeners();
+ void clearListeners();
+ void fade(const byte *adjustData, bool fullAdjust, int percent);
+ PaletteRotation *addRotation(int start, int end, int rotationMode, int duration = 0, Action *action = NULL);
+ PaletteUnknown *addUnkPal(RGB8 *arrBufferRGB, int unkNumb, bool disabled, Action *action);
+
+ static void changeBackground(const Rect &bounds, FadeMode fadeMode);
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "ScenePalette"; }
+};
+
+// DisplayParamType constant set. This must not be an enum
+const int SET_WIDTH = 0;
+const int SET_X = 1;
+const int SET_Y = 2;
+const int SET_FONT = 3;
+const int SET_BG_COLOUR = 4;
+const int SET_FG_COLOUR = 5;
+const int SET_KEEP_ONSCREEN = 6;
+const int SET_EXT_BGCOLOUR = 7;
+const int SET_EXT_FGCOLOUR = 8;
+const int SET_POS_MODE = 9;
+const int SET_TEXT_MODE = 10;
+const int LIST_END = -999;
+
+class SceneItem : public EventHandler {
+public:
+ Rect _bounds;
+ Common::String _msg;
+ int _fieldE, _field10;
+ Common::Point _position;
+ int _yDiff;
+ int _sceneRegionId;
+public:
+ SceneItem() : EventHandler() { _msg = "Feature"; _action = NULL; _sceneRegionId = 0; }
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "SceneItem"; }
+ virtual void remove();
+ virtual void destroy() {}
+ virtual void startMover(CursorType action) { doAction(action); }
+ virtual void doAction(int action);
+
+ bool contains(const Common::Point &pt);
+ void setBounds(const Rect &newBounds) { _bounds = newBounds; }
+ void setBounds(const int ys, const int xe, const int ye, const int xs) { _bounds = Rect(MIN(xs, xe), MIN(ys, ye), MAX(xs, xe), MAX(ys, ye)); }
+ static void display(int resNum, int lineNum, ...);
+ static void display2(int resNum, int lineNum) {
+ display(resNum, lineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+};
+
+class SceneItemExt : public SceneItem {
+public:
+ int _state;
+
+ virtual Common::String getClassName() { return "SceneItemExt"; }
+ virtual void synchronise(Serialiser &s) {
+ SceneItem::synchronise(s);
+ s.syncAsSint16LE(_state);
+ }
+};
+
+class SceneHotspot : public SceneItem {
+public:
+ SceneHotspot() : SceneItem() {}
+
+ virtual Common::String getClassName() { return "SceneHotspot"; }
+ virtual void doAction(int action);
+};
+
+class NamedHotspot : public SceneHotspot {
+public:
+ int _resnum, _lookLineNum, _useLineNum;
+ NamedHotspot() : SceneHotspot() {}
+
+ void setup(const int ys, const int xe, const int ye, const int xs, const int resnum, const int lookLineNum, const int useLineNum);
+ virtual void doAction(int action);
+ virtual Common::String getClassName() { return "NamedHotspot"; }
+};
+
+enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MODE_3 = 3,
+ ANIM_MODE_4 = 4, ANIM_MODE_5 = 5, ANIM_MODE_6 = 6, ANIM_MODE_7 = 7, ANIM_MODE_8 = 8};
+
+class SceneObject;
+
+class Visage {
+private:
+ byte *_data;
+public:
+ int _resNum;
+ int _rlbNum;
+public:
+ Visage();
+ Visage(const Visage &v);
+ ~Visage();
+
+ void setVisage(int resNum, int rlbNum = 9999);
+ GfxSurface getFrame(int frameNum);
+ int getFrameCount() const;
+ Visage &operator=(const Visage &s);
+};
+
+class SceneObjectWrapper : public EventHandler {
+private:
+ Visage _visageImages;
+public:
+ SceneObject *_sceneObject;
+public:
+ SceneObjectWrapper() { _sceneObject = NULL; }
+ virtual ~SceneObjectWrapper() {}
+
+ void setSceneObject(SceneObject *so);
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "SceneObjectWrapper"; }
+ virtual void remove();
+ virtual void dispatch();
+};
+
+enum ObjectFlags {OBJFLAG_FIXED_PRIORITY = 1, OBJFLAG_NO_UPDATES = 2, OBJFLAG_ZOOMED = 4,
+ OBJFLAG_SUPPRESS_DISPATCH = 8, OBJFLAG_HIDE = 0x100, OBJFLAG_HIDING = 0x200, OBJFLAG_REMOVE = 0x400,
+ OBJFLAG_CLONED = 0x800, OBJFLAG_CHECK_REGION = 0x1000, OBJFLAG_PANE_0 = 0x4000, OBJFLAG_PANE_1 = 0x8000,
+ OBJFLAG_PANES = OBJFLAG_PANE_0 | OBJFLAG_PANE_1
+};
+
+class SceneObject : public SceneHotspot {
+private:
+ Visage _visageImages;
+
+ int getNewFrame();
+ void animEnded();
+ int changeFrame();
+ bool isNoMover() const { return !_mover || (_regionIndex > 0); }
+public:
+ uint32 _updateStartFrame;
+ uint32 _walkStartFrame;
+ Common::Point _field2E;
+ int _percent;
+ int _priority;
+ int _angle;
+ uint32 _flags;
+ int _xs, _xe;
+ Rect _paneRects[2];
+ int _visage;
+ SceneObjectWrapper *_objectWrapper;
+ int _strip;
+ AnimateMode _animateMode;
+ int _frame;
+ int _endFrame;
+ int _field68;
+ int _frameChange;
+ int _numFrames;
+ int _regionIndex;
+ EventHandler *_mover;
+ Common::Point _moveDiff;
+ int _field7A;
+ Action *_endAction;
+ uint32 _regionBitList;
+public:
+ SceneObject();
+ SceneObject(const SceneObject &so);
+ virtual ~SceneObject();
+
+ void setPosition(const Common::Point &p, int yDiff = 0);
+ void setStrip(int frameNum);
+ void setStrip2(int frameNum);
+ void setZoom(int percent);
+ void updateZoom();
+ void changeZoom(int percent);
+ void setFrame(int frameNum);
+ void setFrame2(int frameNum);
+ void setPriority(int priority);
+ void setPriority2(int priority);
+ void setVisage(int visage);
+ void setObjectWrapper(SceneObjectWrapper *objWrapper);
+ void addMover(ObjectMover *mover, ...);
+ void getHorizBounds();
+ int getRegionIndex();
+ int checkRegion(const Common::Point &pt);
+ void animate(AnimateMode animMode, ...);
+ SceneObject *clone() const;
+ void checkAngle(const SceneObject *obj);
+ void hide();
+ void show();
+ int getSpliceArea(const SceneObject *obj);
+ int getFrameCount();
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "SceneObject"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void process(Event &event) { event.handled = true; }
+ virtual void dispatch();
+ virtual void calcAngle(const Common::Point &pt);
+ virtual void removeObject();
+ virtual GfxSurface getFrame();
+ virtual void reposition();
+ virtual void draw();
+ virtual void proc19() {}
+ virtual void updateScreen();
+ void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority);
+};
+
+class SceneObjectExt : public SceneObject {
+public:
+ int _state;
+
+ virtual void synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ s.syncAsSint16LE(_state);
+ }
+ virtual Common::String getClassName() { return "SceneObjectExt"; }
+};
+
+class SceneText : public SceneObject {
+public:
+ int _fontNumber;
+ int _width;
+ TextAlign _textMode;
+ int _colour1;
+ int _colour2;
+ int _colour3;
+ GfxSurface _textSurface;
+public:
+ SceneText();
+ ~SceneText();
+
+ void setup(const Common::String &msg);
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "SceneText"; }
+ virtual GfxSurface getFrame() { return _textSurface; }
+};
+
+class Player : public SceneObject {
+public:
+ bool _canWalk;
+ bool _uiEnabled;
+ int _field8C;
+public:
+ Player() : SceneObject() {}
+
+ virtual Common::String getClassName() { return "Player"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+
+ void disableControl();
+ void enableControl();
+};
+
+/*--------------------------------------------------------------------------*/
+
+class LineSliceSet {
+public:
+ Common::Array<LineSlice> items;
+
+ void load(int size, const byte *srcP) {
+ for (int i = 0; i < size; ++i, srcP += 4)
+ items.push_back(LineSlice(READ_LE_UINT16(srcP), READ_LE_UINT16(srcP + 2)));
+ }
+ void load2(int size, ...) {
+ va_list va;
+ va_start(va, size);
+
+ while (size-- > 0) {
+ int xs = va_arg(va, int);
+ int xe = va_arg(va, int);
+ items.push_back(LineSlice(xs, xe));
+ }
+ }
+
+ void add(LineSlice &slice) { items.push_back(slice); }
+ void add(int xs, int xe) { items.push_back(LineSlice(xs, xe)); }
+ static LineSliceSet mergeSlices(const LineSliceSet &set1, LineSliceSet &set2);
+};
+
+class Region {
+public:
+ int _regionSize;
+ int _regionId;
+ Rect _bounds;
+ Common::Array<LineSliceSet> _ySlices;
+public:
+ Region() { _regionSize = 0; _regionId = 0; }
+ Region(int resNum, int rlbNum, ResourceType ctlType = RES_CONTROL);
+
+ bool contains(const Common::Point &pt);
+ bool empty() const;
+ void clear();
+ void setRect(const Rect &r);
+ void setRect(int xs, int ys, int xe, int ye);
+ const LineSliceSet &getLineSlices(int yp);
+ LineSliceSet sectPoints(int yp, const LineSliceSet &sliceSet);
+ void draw();
+ void uniteLine(int yp, LineSliceSet &sliceSet);
+ void uniteRect(const Rect &rect);
+
+ static LineSliceSet mergeSlices(const LineSliceSet &set1, const LineSliceSet &set2);
+};
+
+class SceneRegions : public Common::List<Region> {
+public:
+ void load(int sceneNum);
+
+ int indexOf(const Common::Point &pt);
+};
+
+class SceneObjectList : public SavedObject {
+private:
+ void checkIntersection(Common::Array<SceneObject *> &ObjList, uint ObjIndex, int PaneNum);
+
+ SynchronisedList<SceneObject *> _objList;
+ bool _listAltered;
+public:
+ SceneObjectList() { _listAltered = false; }
+ void sortList(Common::Array<SceneObject *> &ObjList);
+
+ virtual Common::String getClassName() { return "SceneObjectList"; }
+ virtual void synchronise(Serialiser &s);
+
+ void draw();
+ void activate();
+ static void deactivate();
+
+ typedef void (*EventHandlerFn)(EventHandler *fn);
+ void recurse(EventHandlerFn Fn) {
+ // Loop through each object
+ _listAltered = false;
+ for (SynchronisedList<SceneObject *>::iterator i = _objList.begin(); i != _objList.end() && !_listAltered; ) {
+ SceneObject *o = *i;
+ ++i;
+ Fn(o);
+ }
+ }
+ SynchronisedList<SceneObject *>::iterator begin() { return _objList.begin(); }
+ SynchronisedList<SceneObject *>::iterator end() { return _objList.end(); }
+ bool contains(SceneObject *sceneObj) { return tSage::contains(_objList, sceneObj); }
+ void push_back(SceneObject *sceneObj) { _objList.push_back(sceneObj); }
+ void push_front(SceneObject *sceneObj) { _objList.push_front(sceneObj); }
+ void remove(SceneObject *sceneObj) {
+ _objList.remove(sceneObj);
+ _listAltered = true;
+ }
+};
+
+class ScenePriorities : public Common::List<Region> {
+public:
+ int _resNum;
+ int _field14;
+ int _field16;
+ Region _defaultPriorityRegion;
+public:
+ void load(int resNum);
+
+ Region *find(int priority);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class GameSoundHandler {
+public:
+ void proc1() {
+ warning("TODO: GameSoundHandler::proc1");
+ }
+ void proc5(int v) {
+ warning("TODO: GameSoundHandler::proc5");
+ }
+ void proc11(int v1, int v2, int v3, int v4) {
+ warning("TODO: GameSoundHandler::proc11");
+ }
+ int proc12() {
+ // TODO
+ return -1;
+ }
+ void proc2(int v) {
+ // TODO
+ }
+ int proc3() {
+ return 0;
+ }
+ void setVolume(int volume) {
+ warning("TODO GameSoundHandler::setVolume");
+ }
+ void startSound(int soundNum) {
+ warning("TODO GameSoundHandler::startSound");
+ }
+};
+
+class SoundHandler : public EventHandler {
+public:
+ GameSoundHandler _sound;
+ Action *_action;
+ int _field280;
+public:
+ SoundHandler();
+ ~SoundHandler();
+
+ void startSound(int soundNum, Action *action = NULL, int volume = 127);
+ void proc1(Action *action) {
+ proc11(0, 5, 10, 1, action);
+ }
+ void proc2(int v) {
+ warning("TODO: SoundHandler::proc2");
+ }
+ void proc3() {
+ warning("TODO: SoundHandler::proc5");
+ }
+ void proc4() {
+ _sound.proc1();
+ }
+ void proc5(int v) {
+ _sound.proc5(v);
+ }
+ void proc11(int v1, int v2, int v3, int v4, Action *action) {
+ if (action)
+ _action = action;
+
+ _sound.proc11(v1, v2, v3, v4);
+ }
+ void setVolume(int volume) { _sound.setVolume(volume); }
+
+ virtual Common::String getClassName() { return "SoundHandler"; }
+ virtual void dispatch();
+};
+
+/*--------------------------------------------------------------------------*/
+
+class SceneItemList : public SynchronisedList<SceneItem *> {
+public:
+ void addItems(SceneItem *first, ...);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class RegionSupportRec {
+public:
+ int _yp;
+ int _xp;
+ int _xDiff;
+ int _yDiff;
+ int _xDirection;
+ int _halfDiff;
+ int _yDiff2;
+
+ void process();
+};
+
+#define PROCESS_LIST_SIZE 100
+
+class WalkRegion : public Region {
+private:
+ static RegionSupportRec _processList[PROCESS_LIST_SIZE];
+ void loadProcessList(byte *dataP, int dataSize, int &dataIndex, int &regionHeight);
+ int process1(int idx, byte *dataP, int dataSize);
+ void process2(int dataIndex, int x1, int y1, int x2, int y2);
+ void process3(int yp, int dataCount, int &idx1, int &idx2);
+ void process4(int yp, int idx1, int idx2, int &count);
+ void process5(int idx1, int idx2);
+ void loadRecords(int yp, int size, int processIndex);
+ void process6(RegionSupportRec &rec);
+public:
+ Common::Point _pt;
+ int _idxListIndex;
+ int _idxList2Index;
+public:
+ void loadRegion(byte *dataP, int size);
+};
+
+class WRField18 {
+public:
+ Common::Point _pt1, _pt2;
+ int _v;
+public:
+ void load(byte *data);
+};
+
+class WalkRegions {
+public:
+ int _resNum;
+ RouteEnds _routeEnds;
+ Common::Array<WalkRegion> _regionList;
+ Common::Array<WRField18> _field18;
+ Common::Array<int> _idxList;
+ Common::Array<int> _idxList2;
+public:
+ WalkRegions() { _resNum = -1; }
+
+ void clear();
+ void load(int sceneNum);
+ int indexOf(const Common::Point &pt, const Common::List<int> *indexList = NULL);
+ WalkRegion &operator[](int idx) {
+ assert((idx >= 1) && (idx <= (int)_regionList.size()));
+ return _regionList[idx - 1];
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+class FloatSet {
+public:
+ double _float1, _float2, _float3, _float4;
+
+ FloatSet() { _float1 = _float2 = _float3 = _float4 = 0; }
+ void add(double v1, double v2, double v3);
+ void proc1(double v);
+ double sqrt(FloatSet &floatSet);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class GameHandler : public EventHandler {
+public:
+ RefCounter _lockCtr;
+ RefCounter _waitCtr;
+ int _nextWaitCtr;
+ int _field14;
+public:
+ GameHandler();
+ virtual ~GameHandler();
+ void execute();
+
+ virtual void synchronise(Serialiser &s);
+ virtual Common::String getClassName() { return "GameHandler"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL) {}
+ virtual void dispatch() {}
+};
+
+class SceneHandler : public GameHandler {
+public:
+ int _saveGameSlot;
+ int _loadGameSlot;
+ int _delayTicks;
+ Common::String _saveName;
+public:
+ SceneHandler();
+ void registerHandler();
+
+ virtual Common::String getClassName() { return "SceneHandler"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+ virtual void dispatch();
+
+ static void dispatchObject(EventHandler *obj);
+ static void saveListener(Serialiser &ser);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class Game {
+private:
+ SynchronisedList<GameHandler *> _handlers;
+
+ static bool notLockedFn(GameHandler *g);
+ void restart();
+ void handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName);
+public:
+ void addHandler(GameHandler *entry) { _handlers.push_back(entry); }
+ void removeHandler(GameHandler *entry) { _handlers.remove(entry); }
+
+ void execute();
+ void restartGame();
+ void saveGame();
+ void restoreGame();
+ void quitGame();
+ void endGame(int resNum, int lineNum);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp
new file mode 100644
index 0000000000..d04fd71461
--- /dev/null
+++ b/engines/tsage/debugger.cpp
@@ -0,0 +1,172 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/debugger.h"
+#include "common/config-manager.h"
+#include "common/endian.h"
+#include "tsage/globals.h"
+#include "tsage/graphics.h"
+
+
+namespace tSage {
+
+Debugger::Debugger() : GUI::Debugger() {
+ DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
+ DCmd_Register("scene", WRAP_METHOD(Debugger, Cmd_Scene));
+ DCmd_Register("walk_regions", WRAP_METHOD(Debugger, Cmd_WalkRegions));
+ DCmd_Register("priority_regions", WRAP_METHOD(Debugger, Cmd_PriorityRegions));
+ DCmd_Register("item", WRAP_METHOD(Debugger, Cmd_Item));
+}
+
+static int strToInt(const char *s) {
+ if (!*s)
+ // No string at all
+ return 0;
+ else if (toupper(s[strlen(s) - 1]) != 'H')
+ // Standard decimal string
+ return atoi(s);
+
+ // Hexadecimal string
+ uint tmp = 0;
+ int read = sscanf(s, "%xh", &tmp);
+ if (read < 1)
+ error("strToInt failed on string \"%s\"", s);
+ return (int)tmp;
+}
+
+/**
+ * This command loads up the specified new scene number
+ */
+bool Debugger::Cmd_Scene(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Usage: %s <scene number> [prior scene #]\n", argv[0]);
+ return true;
+ } else {
+ if (argc == 3)
+ _globals->_sceneManager._sceneNumber = strToInt(argv[2]);
+
+ _globals->_sceneManager.changeScene(strToInt(argv[1]));
+ return false;
+ }
+}
+
+/**
+ * This command draws the walk regions onto the screen
+ */
+bool Debugger::Cmd_WalkRegions(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ // Colour index to use for the first walk region
+ int colour = 16;
+
+ // Lock the background surface for access
+ Graphics::Surface destSurface = _globals->_sceneManager._scene->_backSurface.lockSurface();
+
+ // Loop through drawing each walk region in a different colour to the background surface
+ for (uint regionIndex = 0; regionIndex < _globals->_walkRegions._regionList.size(); ++regionIndex, ++colour) {
+ WalkRegion &wr = _globals->_walkRegions._regionList[regionIndex];
+
+ for (int yp = wr._bounds.top; yp < wr._bounds.bottom; ++yp) {
+ LineSliceSet sliceSet = wr.getLineSlices(yp);
+
+ for (uint idx = 0; idx < sliceSet.items.size(); ++idx)
+ destSurface.hLine(sliceSet.items[idx].xs - _globals->_sceneOffset.x, yp,
+ sliceSet.items[idx].xe - _globals->_sceneOffset.x, colour);
+ }
+ }
+
+ // Release the surface
+ _globals->_sceneManager._scene->_backSurface.unlockSurface();
+
+ // Mark the scene as requiring a full redraw
+ _globals->_paneRefreshFlag[0] = 2;
+
+ return false;
+}
+
+/*
+ * This command draws the priority regions onto the screen
+ */
+bool Debugger::Cmd_PriorityRegions(int argc, const char **argv) {
+ int regionNum = 0;
+
+ // Check for an optional specific region to display
+ if (argc == 2)
+ regionNum = strToInt(argv[1]);
+
+ // Colour index to use for the first priority region
+ int colour = 16;
+ int count = 0;
+
+ // Lock the background surface for access
+ Graphics::Surface destSurface = _globals->_sceneManager._scene->_backSurface.lockSurface();
+
+ Common::List<Region>::iterator i = _globals->_sceneManager._scene->_priorities.begin();
+ Common::String regionsDesc;
+
+ for (; i != _globals->_sceneManager._scene->_priorities.end(); ++i, ++colour, ++count) {
+ Region &r = *i;
+
+ if ((regionNum == 0) || (regionNum == (count + 1))) {
+ for (int y = 0; y < destSurface.h; ++y) {
+ byte *destP = (byte *)destSurface.getBasePtr(0, y);
+
+ for (int x = 0; x < destSurface.w; ++x) {
+ if (r.contains(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + x,
+ _globals->_sceneManager._scene->_sceneBounds.top + y)))
+ *destP = colour;
+ ++destP;
+ }
+ }
+ }
+
+ regionsDesc += Common::String::format("Region Priority = %d bounds=%d,%d,%d,%d\n",
+ r._regionId, r._bounds.left, r._bounds.top, r._bounds.right, r._bounds.bottom);
+ }
+
+ // Release the surface
+ _globals->_sceneManager._scene->_backSurface.unlockSurface();
+
+ // Mark the scene as requiring a full redraw
+ _globals->_paneRefreshFlag[0] = 2;
+
+ DebugPrintf("Total regions = %d\n", count);
+ DebugPrintf("%s", regionsDesc.c_str());
+
+ return true;
+}
+
+/**
+ * Give a specified item to the player
+ */
+bool Debugger::Cmd_Item(int argc, const char **argv) {
+ _globals->_inventory._infoDisk._sceneNumber = 1;
+ return true;
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/debugger.h b/engines/tsage/debugger.h
new file mode 100644
index 0000000000..c94d77b2ab
--- /dev/null
+++ b/engines/tsage/debugger.h
@@ -0,0 +1,48 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_DEBUGGER_H
+#define TSAGE_DEBUGGER_H
+
+#include "common/scummsys.h"
+#include "gui/debugger.h"
+
+namespace tSage {
+
+class Debugger : public GUI::Debugger {
+public:
+ Debugger();
+ virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ
+
+protected:
+ bool Cmd_Scene(int argc, const char **argv);
+ bool Cmd_WalkRegions(int argc, const char **argv);
+ bool Cmd_PriorityRegions(int argc, const char **argv);
+ bool Cmd_Item(int argc, const char **argv);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
new file mode 100644
index 0000000000..371166d782
--- /dev/null
+++ b/engines/tsage/detection.cpp
@@ -0,0 +1,186 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/system.h"
+#include "common/savefile.h"
+
+#include "engines/advancedDetector.h"
+
+#include "base/plugins.h"
+
+#include "tsage/tsage.h"
+
+namespace tSage {
+
+struct tSageGameDescription {
+ ADGameDescription desc;
+
+ int gameID;
+ uint32 features;
+};
+
+const char *TSageEngine::getGameId() const {
+ return _gameDescription->desc.gameid;
+}
+
+uint32 TSageEngine::getGameID() const {
+ return _gameDescription->gameID;
+}
+
+uint32 TSageEngine::getFeatures() const {
+ return _gameDescription->features;
+}
+
+} // End of namespace tSage
+
+static const PlainGameDescriptor tSageGameTitles[] = {
+ { "tsage", "Unknown Tsunami TSAGE-based Game" },
+ { "ring", "Ringworld: Revenge of the Patriarch" },
+ { "blueforce", "Blue Force" },
+ { 0, 0 }
+};
+
+#include "engines/tsage/detection_tables.h"
+
+static const ADParams detectionParams = {
+ (const byte *)tSage::gameDescriptions,
+ sizeof(tSage::tSageGameDescription),
+ 0,
+ tSageGameTitles,
+ 0,
+ "tsage",
+ NULL,
+ 0,
+ Common::GUIO_NONE,
+ 0,
+ NULL
+};
+
+#define MAX_SAVES 100
+
+class TSageMetaEngine : public AdvancedMetaEngine {
+public:
+ TSageMetaEngine() : AdvancedMetaEngine(detectionParams) {
+ }
+
+ virtual const char *getName() const {
+ return "TsAGE Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "(c) Tsunami Media";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const {
+ switch (f) {
+ case kSupportsListSaves:
+ case kSupportsDeleteSave:
+ case kSupportsLoadingDuringStartup:
+ case kSavesSupportMetaInfo:
+ case kSavesSupportThumbnail:
+ case kSavesSupportCreationDate:
+ case kSavesSupportPlayTime:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new tSage::TSageEngine(syst, (const tSage::tSageGameDescription *)desc);
+ }
+ return desc != 0;
+ }
+
+ static Common::String generateGameStateFileName(const char *target, int slot) {
+ return Common::String::format("%s.%03d", target, slot);
+ }
+
+ virtual SaveStateList listSaves(const char *target) const {
+ Common::String pattern = target;
+ pattern += ".*";
+
+ Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles(pattern);
+ tSage::tSageSavegameHeader header;
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ int slot;
+ const char *ext = strrchr(file->c_str(), '.');
+ if (ext && (slot = atoi(ext + 1)) >= 0 && slot < MAX_SAVES) {
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
+
+ if (in) {
+ if (tSage::Saver::readSavegameHeader(in, header)) {
+ saveList.push_back(SaveStateDescriptor(slot, header.saveName));
+ delete header.thumbnail;
+ }
+
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+ }
+
+ virtual int getMaximumSaveSlot() const {
+ return MAX_SAVES - 1;
+ }
+
+ virtual void removeSaveState(const char *target, int slot) const {
+ Common::String filename = Common::String::format("%s.%03d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(filename);
+ }
+
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const {
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(
+ generateGameStateFileName(target, slot));
+ assert(f);
+
+ tSage::tSageSavegameHeader header;
+ tSage::Saver::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header.saveName);
+ desc.setDeletableFlag(true);
+ desc.setWriteProtectedFlag(false);
+ desc.setThumbnail(header.thumbnail);
+ desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
+ desc.setSaveTime(header.saveHour, header.saveMinutes);
+ desc.setPlayTime(header.totalFrames * GAME_FRAME_TIME);
+
+ return desc;
+ }
+};
+
+#if PLUGIN_ENABLED_DYNAMIC(TSAGE)
+REGISTER_PLUGIN_DYNAMIC(TSAGE, PLUGIN_TYPE_ENGINE, TSageMetaEngine);
+#else
+REGISTER_PLUGIN_STATIC(TSAGE, PLUGIN_TYPE_ENGINE, TSageMetaEngine);
+#endif
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
new file mode 100644
index 0000000000..f932c62367
--- /dev/null
+++ b/engines/tsage/detection_tables.h
@@ -0,0 +1,91 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+namespace tSage {
+
+static const tSageGameDescription gameDescriptions[] = {
+
+ // Ringworld English CD version
+ {
+ {
+ "ring",
+ "CD",
+ AD_ENTRY1s("ring.rlb", "466f0e6492d9d0f34d35c5cd088de90f", 37847618),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_Ringworld,
+ GF_CD
+ },
+ // Ringworld First Wave English CD version
+ {
+ {
+ "ring",
+ "CD",
+ AD_ENTRY1s("ring.rlb", "0a25b4ee58d44a54425c0b47e5096bbc", 37847618),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_Ringworld,
+ GF_CD
+ },
+ // Ringworld English Floppy version
+ {
+ {
+ "ring",
+ "Floppy",
+ AD_ENTRY1s("ring.rlb", "61f78f68a56832ae95fe06748c403234", 8438770),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_Ringworld,
+ GF_FLOPPY
+ },
+
+ // Blue Force
+ {
+ {
+ "blueforce",
+ "",
+ AD_ENTRY1s("blue.rlb", "467da43c848cc0e800b547c59d84ccb1", 10032614),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_BlueForce,
+ GF_FLOPPY
+ },
+
+ { AD_TABLE_END_MARKER, 0, 0 }
+};
+
+} // End of namespace tSage
diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp
new file mode 100644
index 0000000000..b76d60ac48
--- /dev/null
+++ b/engines/tsage/dialogs.cpp
@@ -0,0 +1,598 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/translation.h"
+#include "tsage/tsage.h"
+#include "tsage/core.h"
+#include "tsage/dialogs.h"
+#include "tsage/graphics.h"
+#include "tsage/core.h"
+#include "tsage/staticres.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * This dialog class provides a simple message display with support for either one or two buttons.
+ */
+MessageDialog::MessageDialog(const Common::String &message, const Common::String &btn1Message,
+ const Common::String &btn2Message) : GfxDialog() {
+ // Set up the message
+ addElements(&_msg, &_btn1, NULL);
+
+ _msg.set(message, 200, ALIGN_LEFT);
+ _btn1._bounds.moveTo(_msg._bounds.left, _msg._bounds.bottom + 2);
+ _defaultButton = &_btn1;
+
+ // Set up the first button
+ _btn1.setText(btn1Message);
+ _btn1._bounds.moveTo(_msg._bounds.right - _btn1._bounds.width(), _msg._bounds.bottom);
+
+ if (!btn2Message.empty()) {
+ // Set up the second button
+ _defaultButton = &_btn2;
+ add(&_btn2);
+ _btn2.setText(btn2Message);
+ _btn2._bounds.moveTo(_msg._bounds.right - _btn2._bounds.width(), _msg._bounds.bottom);
+ _btn1._bounds.translate(-(_btn2._bounds.width() + 4), 0);
+ }
+
+ // Do post setup for the dialog
+ setDefaults();
+
+ // Set the dialog's centre
+ setCentre(_globals->_dialogCentre.x, _globals->_dialogCentre.y);
+}
+
+int MessageDialog::show(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message) {
+ // Ensure that the cursor is the arrow
+ CursorType currentCursor = _globals->_events.getCursor();
+ if (currentCursor != CURSOR_ARROW)
+ _globals->_events.setCursor(CURSOR_ARROW);
+ _globals->_events.showCursor();
+
+ int result = show2(message, btn1Message, btn2Message);
+
+ // If the cursor was changed, change it back
+ if (currentCursor != CURSOR_ARROW)
+ _globals->_events.setCursor(currentCursor);
+
+ return result;
+}
+
+int MessageDialog::show2(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message) {
+ MessageDialog *dlg = new MessageDialog(message, btn1Message, btn2Message);
+ dlg->draw();
+
+ GfxButton *selectedButton = dlg->execute();
+ int result = (selectedButton == &dlg->_btn1) ? 0 : 1;
+
+ delete dlg;
+ return result;
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+ConfigDialog::ConfigDialog() : GUI::OptionsDialog("", "GlobalConfig") {
+ //
+ // Sound controllers
+ //
+
+ addVolumeControls(this, "GlobalConfig.");
+ setVolumeSettingsState(true); // could disable controls by GUI options
+
+ //
+ // Add the buttons
+ //
+
+ new GUI::ButtonWidget(this, "GlobalConfig.Ok", _("~O~K"), 0, GUI::kOKCmd);
+ new GUI::ButtonWidget(this, "GlobalConfig.Cancel", _("~C~ancel"), 0, GUI::kCloseCmd);
+}
+
+/*--------------------------------------------------------------------------*/
+
+#define BUTTON_WIDTH 28
+#define BUTTON_HEIGHT 29
+
+RightClickButton::RightClickButton(int buttonIndex, int xp, int yp) : GfxButton() {
+ _buttonIndex = buttonIndex;
+ this->_bounds.left = xp;
+ this->_bounds.top = yp;
+ this->_bounds.setWidth(BUTTON_WIDTH);
+ this->_bounds.setHeight(BUTTON_HEIGHT);
+ _savedButton = NULL;
+}
+
+void RightClickButton::highlight() {
+ if (_savedButton) {
+ // Button was previously highlighted, so de-highlight by restoring saved area
+ _globals->gfxManager().copyFrom(*_savedButton, _bounds.left, _bounds.top);
+ delete _savedButton;
+ _savedButton = NULL;
+ } else {
+ // Highlight button by getting the needed highlighted image resource
+ _savedButton = Surface_getArea(_globals->gfxManager().getSurface(), _bounds);
+
+ uint size;
+ byte *imgData = _vm->_dataManager->getSubResource(7, 2, _buttonIndex, &size);
+
+ GfxSurface btnSelected = surfaceFromRes(imgData);
+ _globals->gfxManager().copyFrom(btnSelected, _bounds.left, _bounds.top);
+
+ DEALLOCATE(imgData);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * This dialog implements the right-click dialog
+ */
+RightClickDialog::RightClickDialog() : GfxDialog(),
+ _walkButton(1, 48, 12), _lookButton(2, 31, 29), _useButton(3, 65, 29),
+ _talkButton(4, 14, 47), _inventoryButton(5, 48, 47), _optionsButton(6, 83, 47) {
+ Rect rectArea, dialogRect;
+
+ // Set the palette and change the cursor
+ _gfxManager.setDialogPalette();
+ _globals->_events.setCursor(CURSOR_ARROW);
+
+ // Get the dialog image
+ _surface = surfaceFromRes(7, 1, 1);
+
+ // Set the dialog position
+ dialogRect.resize(_surface, 0, 0, 100);
+ dialogRect.centre(_globals->_events._mousePos.x, _globals->_events._mousePos.y);
+
+ // Ensure the dialog will be entirely on-screen
+ Rect screenRect = _globals->gfxManager()._bounds;
+ screenRect.collapse(4, 4);
+ dialogRect.contain(screenRect);
+
+ _bounds = dialogRect;
+ _gfxManager._bounds = _bounds;
+
+ _highlightedButton = NULL;
+ _selectedAction = -1;
+}
+
+RightClickDialog::~RightClickDialog() {
+}
+
+RightClickButton *RightClickDialog::findButton(const Common::Point &pt) {
+ RightClickButton *btnList[] = { &_walkButton, &_lookButton, &_useButton, &_talkButton, &_inventoryButton, &_optionsButton };
+
+ for (int i = 0; i < 6; ++i) {
+ btnList[i]->_owner = this;
+
+ if (btnList[i]->_bounds.contains(pt))
+ return btnList[i];
+ }
+
+ return NULL;
+}
+
+void RightClickDialog::draw() {
+ // Save the covered background area
+ _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), _bounds);
+
+ // Draw the dialog image
+ _globals->gfxManager().copyFrom(_surface, _bounds.left, _bounds.top);
+}
+
+bool RightClickDialog::process(Event &event) {
+ switch (event.eventType) {
+ case EVENT_MOUSE_MOVE: {
+ // Check whether a button is highlighted
+ RightClickButton *btn = findButton(event.mousePos);
+
+ if (btn != _highlightedButton) {
+ // De-highlight any previously selected button
+ if (_highlightedButton) {
+ _highlightedButton->highlight();
+ _highlightedButton = NULL;
+ }
+ if (btn) {
+ // Highlight the new button
+ btn->highlight();
+ _highlightedButton = btn;
+ }
+ }
+ event.handled = true;
+ return true;
+ }
+
+ case EVENT_BUTTON_DOWN:
+ // If a button is highlighted, then flag the selected button index
+ if (_highlightedButton)
+ _selectedAction = _highlightedButton->_buttonIndex;
+ else
+ _selectedAction = _lookButton._buttonIndex;
+ event.handled = true;
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+void RightClickDialog::execute() {
+ // Draw the dialog
+ draw();
+
+ // Dialog event handler loop
+ _gfxManager.activate();
+
+ while (!_vm->getEventManager()->shouldQuit() && (_selectedAction == -1)) {
+ Event evt;
+ while (_globals->_events.getEvent(evt, EVENT_MOUSE_MOVE | EVENT_BUTTON_DOWN)) {
+ evt.mousePos.x -= _bounds.left;
+ evt.mousePos.y -= _bounds.top;
+
+ process(evt);
+ }
+
+ g_system->delayMillis(10);
+ g_system->updateScreen();
+ }
+
+ // Execute the specified action
+ switch (_selectedAction) {
+ case 1:
+ // Look action
+ _globals->_events.setCursor(CURSOR_LOOK);
+ break;
+ case 2:
+ // Walk action
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ case 3:
+ // Use cursor
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 4:
+ // Talk cursor
+ _globals->_events.setCursor(CURSOR_TALK);
+ break;
+ case 5:
+ // Inventory dialog
+ InventoryDialog::show();
+ break;
+ case 6:
+ // Dialog options
+ OptionsDialog::show();
+ break;
+ }
+
+ _gfxManager.deactivate();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void ModalDialog::draw() {
+ // Set the palette for use in the dialog
+ setPalette();
+
+ // Make a backup copy of the area the dialog will occupy
+ Rect tempRect = _bounds;
+ tempRect.collapse(-10, -10);
+ _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), tempRect);
+
+ _gfxManager.activate();
+
+ // Fill in the contents of the entire dialog
+ _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ drawFrame();
+
+ // Draw each element in the dialog in order
+ GfxElementList::iterator i;
+ for (i = _elements.begin(); i != _elements.end(); ++i) {
+ (*i)->draw();
+ }
+
+ _gfxManager.deactivate();
+}
+
+void ModalDialog::drawFrame() {
+ Rect origRect = _bounds;
+ _bounds.collapse(-10, -10);
+
+ // Fill the dialog area
+ _globals->gfxManager().fillRect(origRect, 54);
+
+ // Draw top line
+ GfxSurface surface = surfaceFromRes(8, 1, 7);
+ for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
+ surface.draw(Common::Point(xp, _bounds.top));
+ surface.draw(Common::Point(_bounds.right - 20, _bounds.top));
+
+ surface = surfaceFromRes(8, 1, 1);
+ surface.draw(Common::Point(_bounds.left, _bounds.top));
+
+ surface = surfaceFromRes(8, 1, 4);
+ surface.draw(Common::Point(_bounds.right - 10, _bounds.top));
+
+ // Draw vertical edges
+ surface = surfaceFromRes(8, 1, 2);
+ for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
+ surface.draw(Common::Point(_bounds.left, yp));
+ surface.draw(Common::Point(_bounds.left, _bounds.bottom - 20));
+
+ surface = surfaceFromRes(8, 1, 5);
+ for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
+ surface.draw(Common::Point(_bounds.right - 10, yp));
+ surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 20));
+
+ // Draw bottom line
+ surface = surfaceFromRes(8, 1, 8);
+ for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
+ surface.draw(Common::Point(xp, _bounds.bottom - 10));
+ surface.draw(Common::Point(_bounds.right - 20, _bounds.bottom - 10));
+
+ surface = surfaceFromRes(8, 1, 3);
+ surface.draw(Common::Point(_bounds.left, _bounds.bottom - 10));
+
+ surface = surfaceFromRes(8, 1, 6);
+ surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 10));
+
+ // Set the dialog's manager bounds
+ _gfxManager._bounds = origRect;
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool GfxInvImage::process(Event &event) {
+ if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) {
+ event.handled = _bounds.contains(event.mousePos);
+ return event.handled;
+ }
+
+ return false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void InventoryDialog::show(bool allFlag) {
+ if (!allFlag) {
+ // Determine how many items are in the player's inventory
+ int itemCount = 0;
+ SynchronisedList<InvObject *>::iterator i;
+ for (i = _globals->_inventory._itemList.begin(); i != _globals->_inventory._itemList.end(); ++i) {
+ if ((*i)->inInventory())
+ ++itemCount;
+ }
+
+ if (itemCount == 0) {
+ MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING);
+ return;
+ }
+ }
+
+ InventoryDialog *dlg = new InventoryDialog(allFlag);
+ dlg->draw();
+ dlg->execute();
+ delete dlg;
+}
+
+InventoryDialog::InventoryDialog(bool allFlag) {
+ // Determine the maximum size of the image of any item in the player's inventory
+ int imgWidth = 0, imgHeight = 0;
+
+ SynchronisedList<InvObject *>::iterator i;
+ for (i = _globals->_inventory._itemList.begin(); i != _globals->_inventory._itemList.end(); ++i) {
+ InvObject *invObject = *i;
+ if (allFlag || invObject->inInventory()) {
+ // Get the image for the item
+ GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
+
+ // Maintain the dimensions of the largest item image
+ imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width());
+ imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height());
+
+ // Add the item to the display list
+ _images.push_back(GfxInvImage());
+ _images[_images.size() - 1].setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
+ _images[_images.size() - 1]._invObject = invObject;
+ add(&_images[_images.size() - 1]);
+ }
+ }
+ assert(_images.size() > 0);
+
+ // Figure out the number of columns/rows to show all the items
+ int cellsSize = 3;
+ while ((cellsSize * cellsSize) < (int)_images.size())
+ ++cellsSize;
+
+ // Set the position of each inventory item to be displayed
+ int cellX = 0;
+ Common::Point pt(0, 0);
+
+ for (uint idx = 0; idx < _images.size(); ++idx) {
+ if (cellX == cellsSize) {
+ // Move to the start of the next line
+ pt.x = 0;
+ pt.y += imgHeight + 2;
+ cellX = 0;
+ }
+
+ _images[idx]._bounds.moveTo(pt.x, pt.y);
+
+ pt.x += imgWidth + 2;
+ ++cellX;
+ }
+
+ // Set up the buttons
+ pt.y += imgHeight + 2;
+ _btnOk.setText(OK_BTN_STRING);
+ _btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y);
+ _btnLook.setText(LOOK_BTN_STRING);
+ _btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top);
+ addElements(&_btnLook, &_btnOk, NULL);
+
+ frame();
+ setCentre(SCREEN_CENTRE_X, SCREEN_CENTRE_Y);
+}
+
+void InventoryDialog::execute() {
+ if ((_globals->_inventory._selectedItem) && _globals->_inventory._selectedItem->inInventory())
+ _globals->_inventory._selectedItem->setCursor();
+
+ GfxElement *hiliteObj;
+ bool lookFlag = false;
+
+ while (!_vm->getEventManager()->shouldQuit()) {
+ // Get events
+ Event event;
+ while (!_globals->_events.getEvent(event) && !_vm->getEventManager()->shouldQuit())
+ ;
+ if (_vm->getEventManager()->shouldQuit())
+ return;
+
+ hiliteObj = NULL;
+ if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos))
+ break;
+
+ // Pass event to elements
+ event.mousePos.x -= _gfxManager._bounds.left;
+ event.mousePos.y -= _gfxManager._bounds.top;
+
+ for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ if ((*i)->process(event))
+ hiliteObj = *i;
+ }
+
+ if (!event.handled && event.eventType == EVENT_KEYPRESS) {
+ if ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ // Exit the dialog
+ hiliteObj = &_btnOk;
+ break;
+ }
+ }
+
+ if (hiliteObj == &_btnOk) {
+ // Ok button clicked
+ if (lookFlag)
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ } else if (hiliteObj == &_btnLook) {
+ // Look button clicked
+ if (_btnLook._message == LOOK_BTN_STRING) {
+ _btnLook._message = PICK_BTN_STRING;
+ lookFlag = 1;
+ _globals->_events.setCursor(CURSOR_LOOK);
+ } else {
+ _btnLook._message = LOOK_BTN_STRING;
+ lookFlag = 0;
+ _globals->_events.setCursor(CURSOR_WALK);
+ }
+
+ _gfxManager.activate();
+ hiliteObj->draw();
+ _gfxManager.deactivate();
+ } else if (hiliteObj) {
+ // Inventory item selected
+ InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject;
+ if (lookFlag) {
+ _globals->_screenSurface.displayText(invObject->_description);
+ } else {
+ _globals->_inventory._selectedItem = invObject;
+ invObject->setCursor();
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void OptionsDialog::show() {
+ OptionsDialog *dlg = new OptionsDialog();
+ dlg->draw();
+
+ GfxButton *btn = dlg->execute();
+
+ if (btn == &dlg->_btnQuit) {
+ // Quit game
+ if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) {
+ _vm->quitGame();
+ }
+ } else if (btn == &dlg->_btnRestart) {
+ // Restart game
+ _globals->_game.restartGame();
+ } else if (btn == &dlg->_btnSound) {
+ // Sound dialog
+ } else if (btn == &dlg->_btnSave) {
+ // Save button
+ _globals->_game.saveGame();
+ } else if (btn == &dlg->_btnRestore) {
+ // Restore button
+ _globals->_game.restoreGame();
+ }
+
+ dlg->remove();
+ delete dlg;
+}
+
+OptionsDialog::OptionsDialog() {
+ // Set the element text
+ _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT);
+ _btnRestore.setText(RESTORE_BTN_STRING);
+ _btnSave.setText(SAVE_BTN_STRING);
+ _btnRestart.setText(RESTART_BTN_STRING);
+ _btnQuit.setText(QUIT_BTN_STRING);
+ _btnSound.setText(SOUND_BTN_STRING);
+ _btnResume.setText(RESUME_BTN_STRING);
+
+ // Set position of the elements
+ _gfxMessage._bounds.moveTo(0, 1);
+ _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1);
+ _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1);
+ _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1);
+ _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1);
+ _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1);
+ _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1);
+
+ // Set all the buttons to the widest button
+ GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume};
+ int16 btnWidth = 0;
+ for (int idx = 0; idx < 6; ++idx)
+ btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width());
+ for (int idx = 0; idx < 6; ++idx)
+ btnList[idx]->_bounds.setWidth(btnWidth);
+
+ // Add the items to the dialog
+ addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL);
+
+ // Set the dialog size and position
+ frame();
+ setCentre(160, 100);
+}
+
+
+} // End of namespace tSage
diff --git a/engines/tsage/dialogs.h b/engines/tsage/dialogs.h
new file mode 100644
index 0000000000..8e766372b4
--- /dev/null
+++ b/engines/tsage/dialogs.h
@@ -0,0 +1,136 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_DIALOGS_H
+#define TSAGE_DIALOGS_H
+
+#include "gui/options.h"
+#include "tsage/events.h"
+#include "tsage/graphics.h"
+#include "common/list.h"
+#include "common/rect.h"
+#include "common/system.h"
+
+namespace tSage {
+
+class MessageDialog : public GfxDialog {
+public:
+ GfxButton _btn1, _btn2;
+ GfxDialog _dialog;
+ GfxMessage _msg;
+public:
+ MessageDialog(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message = Common::String());
+
+ static int show(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message = Common::String());
+ static int show2(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message = Common::String());
+};
+
+class ConfigDialog : public GUI::OptionsDialog {
+public:
+ ConfigDialog();
+};
+
+class RightClickButton : public GfxButton {
+private:
+ GfxSurface *_savedButton;
+public:
+ int _buttonIndex;
+
+ RightClickButton(int buttonIndex, int xp, int yp);
+ ~RightClickButton() { delete _savedButton; }
+
+ virtual void highlight();
+};
+
+class RightClickDialog : public GfxDialog {
+private:
+ GfxSurface _surface;
+ RightClickButton *_highlightedButton;
+ int _selectedAction;
+ RightClickButton _walkButton, _lookButton, _useButton, _talkButton, _inventoryButton, _optionsButton;
+
+ RightClickButton *findButton(const Common::Point &pt);
+public:
+ RightClickDialog();
+ ~RightClickDialog();
+
+ virtual void draw();
+ virtual bool process(Event &event);
+ void execute();
+};
+
+/*--------------------------------------------------------------------------*/
+
+class ModalDialog : public GfxDialog {
+protected:
+ void drawFrame();
+public:
+ virtual void draw();
+};
+
+/*--------------------------------------------------------------------------*/
+
+class GfxInvImage : public GfxImage {
+public:
+ InvObject *_invObject;
+public:
+ GfxInvImage() : GfxImage(), _invObject(NULL) {}
+
+ virtual bool process(Event &event);
+};
+
+#define MAX_INVOBJECT_DISPLAY 20
+
+class InventoryDialog : public ModalDialog {
+private:
+ Common::Array<GfxInvImage> _images;
+ GfxButton _btnOk, _btnLook;
+public:
+ InventoryDialog(bool allFlag = false);
+ virtual ~InventoryDialog() {}
+ void execute();
+
+ static void show(bool allFlag = false);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class OptionsDialog : public ModalDialog {
+private:
+ GfxButton _btnSave, _btnRestore, _btnRestart;
+ GfxButton _btnQuit, _btnResume;
+ GfxButton _btnSound;
+ GfxMessage _gfxMessage;
+public:
+ OptionsDialog();
+ virtual ~OptionsDialog() {}
+ GfxButton *execute() { return GfxDialog::execute(&_btnResume); }
+
+ static void show();
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
new file mode 100644
index 0000000000..4d2a1cce8c
--- /dev/null
+++ b/engines/tsage/events.cpp
@@ -0,0 +1,247 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/events.h"
+#include "common/singleton.h"
+#include "graphics/cursorman.h"
+#include "common/system.h"
+
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/staticres.h"
+#include "tsage/tsage.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+EventsClass::EventsClass() {
+ _currentCursor = CURSOR_NONE;
+ _frameNumber = 0;
+ _priorFrameTime = 0;
+ _prevDelayFrame = 0;
+ _saver->addListener(this);
+}
+
+bool EventsClass::pollEvent() {
+ uint32 milli = g_system->getMillis();
+ if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
+ _priorFrameTime = milli;
+ ++_frameNumber;
+
+ g_system->updateScreen();
+ }
+
+ if (!g_system->getEventManager()->pollEvent(_event)) return false;
+
+ // Handle keypress
+ switch (_event.type) {
+ case Common::EVENT_QUIT:
+ case Common::EVENT_RTL:
+ break;
+
+ case Common::EVENT_MOUSEMOVE:
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONDOWN:
+ case Common::EVENT_RBUTTONUP:
+ // Keep a copy of the current mouse position
+ _mousePos = _event.mouse;
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void EventsClass::waitForPress(int eventMask) {
+ Event evt;
+ while (!_vm->getEventManager()->shouldQuit() && !getEvent(evt, eventMask))
+ g_system->delayMillis(10);
+}
+
+/**
+ * Standard event retrieval, which only returns keyboard and mouse clicks
+ */
+bool EventsClass::getEvent(Event &evt, int eventMask) {
+ while (pollEvent() && !_vm->getEventManager()->shouldQuit()) {
+ evt.handled = false;
+ evt.eventType = EVENT_NONE;
+ evt.mousePos = _event.mouse;
+ evt.kbd = _event.kbd;
+
+ switch (_event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ evt.eventType = EVENT_MOUSE_MOVE;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ evt.eventType = EVENT_BUTTON_DOWN;
+ evt.btnState = BTNSHIFT_LEFT;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ evt.eventType = EVENT_BUTTON_DOWN;
+ evt.btnState = BTNSHIFT_RIGHT;
+ break;
+ case Common::EVENT_MBUTTONDOWN:
+ evt.eventType = EVENT_BUTTON_DOWN;
+ evt.btnState = BTNSHIFT_MIDDLE;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONUP:
+ case Common::EVENT_MBUTTONUP:
+ evt.eventType = EVENT_BUTTON_UP;
+ evt.btnState = 0;
+ break;
+ case Common::EVENT_KEYDOWN:
+ evt.eventType = EVENT_KEYPRESS;
+ evt.kbd = _event.kbd;
+ break;
+ default:
+ break;
+ }
+
+ if (evt.eventType & eventMask)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Sets the specified cursor
+ *
+ * @cursorType Specified cursor number
+ */
+void EventsClass::setCursor(CursorType cursorType) {
+ _globals->clearFlag(122);
+
+ if ((_currentCursor == cursorType) && CursorMan.isVisible())
+ return;
+
+ if (cursorType == CURSOR_NONE) {
+ if (CursorMan.isVisible())
+ CursorMan.showMouse(false);
+ return;
+ }
+
+ CursorMan.showMouse(true);
+
+ const byte *cursor;
+ bool delFlag = true;
+ uint size;
+
+ switch (cursorType) {
+ case CURSOR_CROSSHAIRS:
+ // Crosshairs cursor
+ cursor = _vm->_dataManager->getSubResource(4, 1, 6, &size);
+ _globals->setFlag(122);
+ break;
+
+ case CURSOR_LOOK:
+ // Look cursor
+ cursor = _vm->_dataManager->getSubResource(4, 1, 5, &size);
+ _currentCursor = CURSOR_LOOK;
+ break;
+
+ case CURSOR_USE:
+ // Use cursor
+ cursor = _vm->_dataManager->getSubResource(4, 1, 4, &size);
+ _currentCursor = CURSOR_USE;
+ break;
+
+ case CURSOR_TALK:
+ // Talk cursor
+ cursor = _vm->_dataManager->getSubResource(4, 1, 3, &size);
+ _currentCursor = CURSOR_TALK;
+ break;
+
+ case CURSOR_ARROW:
+ // Arrow cursor
+ cursor = CURSOR_ARROW_DATA;
+ delFlag = false;
+ break;
+
+ case CURSOR_WALK:
+ default:
+ // Walk cursor
+ cursor = CURSOR_WALK_DATA;
+ _currentCursor = CURSOR_WALK;
+ delFlag = false;
+ break;
+ }
+
+ // Decode the cursor
+ GfxSurface s = surfaceFromRes(cursor);
+
+ Graphics::Surface surface = s.lockSurface();
+ const byte *cursorData = (const byte *)surface.getBasePtr(0, 0);
+ CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColour);
+ s.unlockSurface();
+
+ if (delFlag)
+ DEALLOCATE(cursor);
+}
+
+void EventsClass::setCursor(Graphics::Surface &cursor, int transColour, const Common::Point &hotspot, CursorType cursorId) {
+ const byte *cursorData = (const byte *)cursor.getBasePtr(0, 0);
+ CursorMan.replaceCursor(cursorData, cursor.w, cursor.h, hotspot.x, hotspot.y, transColour);
+
+ _currentCursor = cursorId;
+}
+
+void EventsClass::setCursorFromFlag() {
+ setCursor(_globals->getFlag(122) ? CURSOR_CROSSHAIRS : _currentCursor);
+}
+
+void EventsClass::showCursor() {
+ CursorMan.showMouse(true);
+}
+
+void EventsClass::hideCursor() {
+ CursorMan.showMouse(false);
+}
+
+/**
+ * Delays the game for the specified number of frames, if necessary, from the
+ * previous time the delay method was called
+ */
+void EventsClass::delay(int numFrames) {
+ while (_frameNumber < (_prevDelayFrame + numFrames)) {
+ uint32 delayAmount = CLIP(_priorFrameTime + GAME_FRAME_TIME - g_system->getMillis(),
+ (uint32)0, (uint32)GAME_FRAME_TIME);
+ if (delayAmount > 0)
+ g_system->delayMillis(delayAmount);
+
+ ++_frameNumber;
+ _priorFrameTime = g_system->getMillis();
+ }
+
+ g_system->updateScreen();
+ _prevDelayFrame = _frameNumber;
+ _priorFrameTime = g_system->getMillis();
+}
+
+} // end of namespace tSage
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
new file mode 100644
index 0000000000..202ac9ccd2
--- /dev/null
+++ b/engines/tsage/events.h
@@ -0,0 +1,109 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_EVENTS_H
+#define TSAGE_EVENTS_H
+
+#include "common/events.h"
+#include "common/array.h"
+#include "common/str.h"
+#include "graphics/surface.h"
+#include "tsage/saveload.h"
+
+namespace tSage {
+
+enum EventType {EVENT_NONE = 0, EVENT_BUTTON_DOWN = 1, EVENT_BUTTON_UP = 2, EVENT_KEYPRESS = 4,
+ EVENT_MOUSE_MOVE = 8};
+
+enum ButtonShiftFlags {BTNSHIFT_LEFT = 0, BTNSHIFT_RIGHT = 3, BTNSHIFT_MIDDLE = 4};
+
+// Intrinisc game delay between execution frames. This runs at 60Hz
+#define GAME_FRAME_TIME (1000 / 60)
+
+class GfxManager;
+
+class Event {
+public:
+ EventType eventType;
+ Common::Point mousePos;
+ int btnState;
+ Common::KeyState kbd;
+ int ctr;
+ GfxManager *gfxMan;
+ bool handled;
+};
+
+enum CursorType {
+ OBJECT_STUNNER = 0, OBJECT_SCANNER = 1, OBJECT_STASIS_BOX = 2,
+ OBJECT_INFODISK = 3, OBJECT_STASIS_NEGATOR = 4, OBJECT_KEY_DEVICE = 5, OBJECT_MEDKIT = 6,
+ OBJECT_LADDER = 7, OBJECT_ROPE = 8, OBJECT_KEY = 9, OBJECT_TRANSLATOR = 10, OBJECT_ALE = 11,
+ OBJECT_PAPER = 12, OBJECT_WALDOS = 13, OBJECT_STASIS_BOX2 = 14, OBJECT_RING = 15,
+ OBJECT_CLOAK = 16, OBJECT_TUNIC = 17, OBJECT_CANDLE = 18, OBJECT_STRAW = 19, OBJECT_SCIMITAR = 20,
+ OBJECT_SWORD = 21, OBJECT_HELMET = 22, OBJECT_ITEMS = 23, OBJECT_CONCENTRATOR = 24,
+ OBJECT_NULLIFIER = 25, OBJECT_PEG = 26, OBJECT_VIAL = 27, OBJECT_JACKET = 28,
+ OBJECT_TUNIC2 = 29, OBJECT_BONE = 30, OBJECT_EMPTY_JAR = 31, OBJECT_JAR = 32,
+
+ CURSOR_WALK = 0x100, CURSOR_LOOK = 0x200, CURSOR_700 = 700, CURSOR_USE = 0x400, CURSOR_TALK = 0x800,
+ CURSOR_NONE = -1, CURSOR_CROSSHAIRS = -2, CURSOR_ARROW = -3
+};
+
+class EventsClass : public SaveListener {
+private:
+ Common::Event _event;
+ uint32 _frameNumber;
+ uint32 _prevDelayFrame;
+ uint32 _priorFrameTime;
+public:
+ EventsClass();
+
+ Common::Point _mousePos;
+ CursorType _currentCursor;
+
+ void setCursor(CursorType cursorType);
+ void setCursor(Graphics::Surface &cursor, int transColour, const Common::Point &hotspot, CursorType cursorId);
+ void setCursorFromFlag();
+ CursorType getCursor() const { return _currentCursor; }
+ void showCursor();
+ void hideCursor();
+
+ bool pollEvent();
+ void waitForPress(int eventMask = EVENT_BUTTON_DOWN | EVENT_KEYPRESS);
+
+ bool getEvent(Event &evt, int eventMask = ~EVENT_MOUSE_MOVE);
+ Common::Event event() { return _event; }
+ Common::EventType type() { return _event.type; }
+ uint32 getFrameNumber() const { return _frameNumber; }
+ void delay(int numFrames);
+
+ virtual void listenerSynchronise(Serialiser &s) {
+ s.syncAsUint32LE(_frameNumber);
+ s.syncAsUint32LE(_prevDelayFrame);
+ // TODO: Synchronise unknown stuff
+ }
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
new file mode 100644
index 0000000000..b9abb9d751
--- /dev/null
+++ b/engines/tsage/globals.cpp
@@ -0,0 +1,103 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/globals.h"
+
+namespace tSage {
+
+Globals *_globals = NULL;
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * Instantiates a saved object that can be instantiated
+ */
+static SavedObject *classFactoryProc(const Common::String &className) {
+ if (className == "ObjectMover") return new ObjectMover();
+ if (className == "NpcMover") return new NpcMover();
+ if (className == "ObjectMover2") return new ObjectMover2();
+ if (className == "ObjectMover3") return new ObjectMover3();
+ if (className == "PlayerMover") return new PlayerMover();
+
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Globals::Globals() :
+ _dialogCentre(160, 140),
+ _gfxManagerInstance(_screenSurface) {
+ reset();
+ _stripNum = 0;
+ _gfxFontNumber = 50;
+ _gfxColours.background = 53;
+ _gfxColours.foreground = 18;
+ _fontColours.background = 51;
+ _fontColours.foreground = 54;
+
+ _screenSurface.setScreenSurface();
+ _gfxManagers.push_back(&_gfxManagerInstance);
+
+ _sceneObjects = &_sceneObjectsInstance;
+ _sceneObjects_queue.push_front(_sceneObjects);
+
+ _prevSceneOffset = Common::Point(-1, -1);
+ _sceneListeners.push_back(&_soundHandler);
+ _sceneListeners.push_back(&_sequenceManager._soundHandler);
+}
+
+Globals::~Globals() {
+ _globals = NULL;
+}
+
+void Globals::reset() {
+ Common::set_to(&_flags[0], &_flags[MAX_FLAGS], false);
+ _saver->addFactory(classFactoryProc);
+}
+
+void Globals::synchronise(Serialiser &s) {
+ assert(_gfxManagers.size() == 1);
+
+ _sceneItems.synchronise(s);
+ SYNC_POINTER(_sceneObjects);
+ _sceneObjects_queue.synchronise(s);
+ s.syncAsSint32LE(_gfxFontNumber);
+ s.syncAsSint32LE(_gfxColours.background);
+ s.syncAsSint32LE(_gfxColours.foreground);
+ s.syncAsSint32LE(_fontColours.background);
+ s.syncAsSint32LE(_fontColours.foreground);
+
+ s.syncAsSint16LE(_dialogCentre.x); s.syncAsSint16LE(_dialogCentre.y);
+ _sceneListeners.synchronise(s);
+ for (int i = 0; i < 256; ++i)
+ s.syncAsByte(_flags[i]);
+
+ s.syncAsSint16LE(_sceneOffset.x); s.syncAsSint16LE(_sceneOffset.y);
+ s.syncAsSint16LE(_prevSceneOffset.x); s.syncAsSint16LE(_prevSceneOffset.y);
+ SYNC_POINTER(_scrollFollower);
+ s.syncAsSint32LE(_stripNum);
+}
+
+} // end of namespace tSage
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
new file mode 100644
index 0000000000..59afe140a0
--- /dev/null
+++ b/engines/tsage/globals.h
@@ -0,0 +1,100 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_GLOBALS_H
+#define TSAGE_GLOBALS_H
+
+#include "common/random.h"
+#include "tsage/core.h"
+#include "tsage/dialogs.h"
+#include "tsage/scenes.h"
+#include "tsage/events.h"
+#include "tsage/saveload.h"
+
+namespace tSage {
+
+class Globals : public SavedObject {
+public:
+ GfxSurface _screenSurface;
+ GfxManager _gfxManagerInstance;
+ Common::List<GfxManager *> _gfxManagers;
+ SceneHandler _sceneHandler;
+ Game _game;
+ EventsClass _events;
+ SceneManager _sceneManager;
+ ScenePalette _scenePalette;
+ SceneRegions _sceneRegions;
+ SceneItemList _sceneItems;
+ SceneObjectList _sceneObjectsInstance;
+ SceneObjectList *_sceneObjects;
+ SynchronisedList<SceneObjectList *> _sceneObjects_queue;
+ SceneText _sceneText;
+ int _gfxFontNumber;
+ GfxColours _gfxColours;
+ GfxColours _fontColours;
+ SoundManager _soundManager;
+ Common::Point _dialogCentre;
+ WalkRegions _walkRegions;
+ SynchronisedList<EventHandler *> _sceneListeners;
+ bool _flags[256];
+ Player _player;
+ SoundHandler _soundHandler;
+ InvObjectList _inventory;
+ Region _paneRegions[2];
+ int _paneRefreshFlag[2];
+ Common::Point _sceneOffset;
+ Common::Point _prevSceneOffset;
+ SceneObject *_scrollFollower;
+ SequenceManager _sequenceManager;
+ Common::RandomSource _randomSource;
+ int _stripNum;
+public:
+ Globals();
+ ~Globals();
+
+ void reset();
+ void setFlag(int flagNum) {
+ assert((flagNum > 0) && (flagNum < MAX_FLAGS));
+ _flags[flagNum] = true;
+ }
+ void clearFlag(int flagNum) {
+ assert((flagNum > 0) && (flagNum < MAX_FLAGS));
+ _flags[flagNum] = false;
+ }
+ bool getFlag(int flagNum) const {
+ assert((flagNum > 0) && (flagNum < MAX_FLAGS));
+ return _flags[flagNum];
+ }
+
+ GfxManager &gfxManager() { return **_gfxManagers.begin(); }
+ virtual Common::String getClassName() { return "Globals"; }
+ virtual void synchronise(Serialiser &s);
+};
+
+extern Globals *_globals;
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
new file mode 100644
index 0000000000..641e10b3e9
--- /dev/null
+++ b/engines/tsage/graphics.cpp
@@ -0,0 +1,1430 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/events.h"
+#include "tsage/graphics.h"
+#include "tsage/resources.h"
+#include "tsage/tsage.h"
+#include "tsage/core.h"
+#include "common/algorithm.h"
+#include "graphics/surface.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+/**
+ * Creates a new graphics surface with the specified area of another surface
+ *
+ * @src Source surface
+ * @bounds Area to backup
+ */
+GfxSurface *Surface_getArea(GfxSurface &src, const Rect &bounds) {
+ assert(bounds.isValidRect());
+ GfxSurface *dest = new GfxSurface();
+ dest->create(bounds.width(), bounds.height());
+
+ Graphics::Surface srcSurface = src.lockSurface();
+ Graphics::Surface destSurface = dest->lockSurface();
+
+ byte *srcP = (byte *)srcSurface.getBasePtr(bounds.left, bounds.top);
+ byte *destP = (byte *)destSurface.getBasePtr(0, 0);
+
+ for (int y = bounds.top; y < bounds.bottom; ++y, srcP += srcSurface.pitch, destP += destSurface.pitch)
+ Common::copy(srcP, srcP + destSurface.pitch, destP);
+
+ src.unlockSurface();
+ dest->unlockSurface();
+ return dest;
+}
+
+/**
+ * Translates a raw image resource into a graphics surface. The caller is then responsible
+ * for managing and destroying the surface when done with it
+ *
+ * @imgData Raw image resource
+ * @size Size of the resource
+ */
+GfxSurface surfaceFromRes(const byte *imgData) {
+ Rect r(0, 0, READ_LE_UINT16(imgData), READ_LE_UINT16(imgData + 2));
+ GfxSurface s;
+ s.create(r.width(), r.height());
+ s._centroid.x = READ_LE_UINT16(imgData + 4);
+ s._centroid.y = READ_LE_UINT16(imgData + 6);
+ s._transColour = *(imgData + 8);
+
+ bool rleEncoded = (imgData[9] & 2) != 0;
+
+ const byte *srcP = imgData + 10;
+ Graphics::Surface destSurface = s.lockSurface();
+ byte *destP = (byte *)destSurface.getBasePtr(0, 0);
+
+ if (!rleEncoded) {
+ Common::copy(srcP, srcP + (r.width() * r.height()), destP);
+ } else {
+ Common::set_to(destP, destP + (r.width() * r.height()), s._transColour);
+
+ for (int yp = 0; yp < r.height(); ++yp) {
+ int width = r.width();
+ destP = (byte *)destSurface.getBasePtr(0, yp);
+
+ while (width > 0) {
+ uint8 controlVal = *srcP++;
+ if ((controlVal & 0x80) == 0) {
+ // Copy specified number of bytes
+
+ Common::copy(srcP, srcP + controlVal, destP);
+ width -= controlVal;
+ srcP += controlVal;
+ destP += controlVal;
+ } else if ((controlVal & 0x40) == 0) {
+ // Skip a specified number of output pixels
+ destP += controlVal & 0x3f;
+ width -= controlVal & 0x3f;
+ } else {
+ // Copy a specified pixel a given number of times
+ controlVal &= 0x3f;
+ int pixel = *srcP++;
+
+ Common::set_to(destP, destP + controlVal, pixel);
+ destP += controlVal;
+ width -= controlVal;
+ }
+ }
+ assert(width == 0);
+ }
+ }
+
+ s.unlockSurface();
+ return s;
+}
+
+GfxSurface surfaceFromRes(int resNum, int rlbNum, int subNum) {
+ uint size;
+ byte *imgData = _vm->_dataManager->getSubResource(resNum, rlbNum, subNum, &size);
+ GfxSurface surface = surfaceFromRes(imgData);
+ DEALLOCATE(imgData);
+
+ return surface;
+}
+/*--------------------------------------------------------------------------*/
+
+void Rect::set(int16 x1, int16 y1, int16 x2, int16 y2) {
+ left = x1; top = y1;
+ right = x2; bottom = y2;
+}
+
+/**
+ * Collapses the rectangle in all four directions by the given x and y amounts
+ *
+ * @dx x amount to collapse x edges by
+ * @dy y amount to collapse y edges by
+ */
+void Rect::collapse(int dx, int dy) {
+ left += dx; right -= dx;
+ top += dy; bottom -= dy;
+}
+
+/**
+ * Centres the rectangle at a given position
+ *
+ * @xp x position for new centre
+ * @yp y position for new centre
+ */
+void Rect::centre(int xp, int yp) {
+ moveTo(xp - (width() / 2), yp - (height() / 2));
+}
+
+/**
+ * Centres the rectangle at the centre of a second passed rectangle
+ *
+ * @r Second rectangle whose centre to use
+ */
+void Rect::centre(const Rect &r) {
+ centre(r.left + (r.width() / 2), r.top + (r.height() / 2));
+}
+
+/*
+ * Repositions the bounds if necessary so it falls entirely within the passed bounds
+ *
+ * @r The bounds the current rect should be within
+ */
+void Rect::contain(const Rect &r) {
+ if (left < r.left) translate(r.left - left, 0);
+ if (right > r.right) translate(r.right - right, 0);
+ if (top < r.top) translate(0, r.top - top);
+ if (bottom > r.bottom) translate(0, r.bottom - bottom);
+}
+
+/**
+ * Resizes and positions a given rect based on raw image data and a passed scaling percentage
+ *
+ * @frame Raw image frame
+ * @xp New x position
+ * @yp New y position
+ * @percent Scaling percentage
+ */
+void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) {
+ int xe = surface.getBounds().width() * percent / 100;
+ int ye = surface.getBounds().height() * percent / 100;
+ this->set(0, 0, xe, ye);
+
+ if (!right) ++right;
+ if (!bottom) ++bottom;
+
+ this->moveTo(xp, yp);
+
+ int xd = surface._centroid.x * percent / 100;
+ int yd = surface._centroid.y * percent / 100;
+ this->translate(-xd, -yd);
+}
+
+/**
+ * Expands the pane region to contain the specified Rect
+ */
+void Rect::expandPanes() {
+ _globals->_paneRegions[0].uniteRect(*this);
+ _globals->_paneRegions[1].uniteRect(*this);
+}
+
+/**
+ * Serialises the given rect
+ */
+void Rect::synchronise(Serialiser &s) {
+ s.syncAsSint16LE(left);
+ s.syncAsSint16LE(top);
+ s.syncAsSint16LE(right);
+ s.syncAsSint16LE(bottom);
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) {
+ _disableUpdates = false;
+ _screenSurface = false;
+ _lockSurfaceCtr = 0;
+ _customSurface = NULL;
+ _screenSurfaceP = NULL;
+}
+
+GfxSurface::GfxSurface(const GfxSurface &s) {
+ _lockSurfaceCtr = 0;
+ _customSurface = NULL;
+ this->operator =(s);
+}
+
+GfxSurface::~GfxSurface() {
+ if (_customSurface) {
+ _customSurface->free();
+ delete _customSurface;
+ }
+}
+
+/**
+ * Specifies that the surface will encapsulate the ScummVM screen surface
+ */
+void GfxSurface::setScreenSurface() {
+ _screenSurface = true;
+ _customSurface = NULL;
+ _lockSurfaceCtr = 0;
+}
+
+/**
+ * Specifies that the surface should maintain it's own internal surface
+ */
+void GfxSurface::create(int width, int height) {
+ assert((width >= 0) && (height >= 0));
+ _screenSurface = false;
+ _customSurface = new Graphics::Surface();
+ _customSurface->create(width, height, 1);
+ _bounds = Rect(0, 0, width, height);
+}
+
+/**
+ * Locks the surface for access, and returns a raw ScummVM surface to manipulate it
+ */
+Graphics::Surface GfxSurface::lockSurface() {
+ ++_lockSurfaceCtr;
+
+ Graphics::Surface *src;
+ if (_screenSurface) {
+ if (_lockSurfaceCtr == 1)
+ _screenSurfaceP = g_system->lockScreen();
+ src = _screenSurfaceP;
+ } else
+ src = _customSurface;
+ assert(src);
+
+ // Setup the returned surface either as one pointing to the same pixels as the source, or
+ // as a subset of the source one based on the currently set bounds
+ Graphics::Surface result;
+ result.w = _bounds.width();
+ result.h = _bounds.height();
+ result.pitch = src->pitch;
+ result.bytesPerPixel = src->bytesPerPixel;
+ result.pixels = src->getBasePtr(_bounds.left, _bounds.top);
+
+ return result;
+}
+
+/**
+ * Unlocks the surface after having accessed it with the lockSurface method
+ */
+void GfxSurface::unlockSurface() {
+ assert(_lockSurfaceCtr > 0);
+ --_lockSurfaceCtr;
+
+ if ((_lockSurfaceCtr == 0) && _screenSurface) {
+ g_system->unlockScreen();
+ }
+}
+
+/**
+ * Fills a specified rectangle on the surface with the specified colour
+ *
+ * @bounds Area to fill
+ * @colour Colour to use
+ */
+void GfxSurface::fillRect(const Rect &bounds, int colour) {
+ Graphics::Surface surface = lockSurface();
+ surface.fillRect(bounds, colour);
+ unlockSurface();
+}
+
+GfxSurface &GfxSurface::operator=(const GfxSurface &s) {
+ assert(_lockSurfaceCtr == 0);
+ assert(s._lockSurfaceCtr == 0);
+
+ if (_customSurface) {
+ _customSurface->free();
+ delete _customSurface;
+ }
+
+ _customSurface = s._customSurface;
+ _screenSurface = s._screenSurface;
+ _disableUpdates = s._disableUpdates;
+ _bounds = s._bounds;
+ _centroid = s._centroid;
+ _transColour = s._transColour;
+
+ if (_customSurface) {
+ // Surface owns the internal data, so replicate it so new surface owns it's own
+ _customSurface = new Graphics::Surface();
+ _customSurface->create(s._customSurface->w, s._customSurface->h, 1);
+ const byte *srcP = (const byte *)s._customSurface->getBasePtr(0, 0);
+ byte *destP = (byte *)_customSurface->getBasePtr(0, 0);
+
+ Common::copy(srcP, srcP + (_bounds.width() * _bounds.height()), destP);
+ }
+
+ return *this;
+}
+
+/**
+ * Displays a message on-screen until either a mouse or keypress
+ */
+bool GfxSurface::displayText(const Common::String &msg, const Common::Point &pt) {
+ // Set up a new graphics manager
+ GfxManager gfxManager;
+ gfxManager.activate();
+ gfxManager._font._colours.background = 0;
+ gfxManager._font._colours.foreground = 7;
+ gfxManager._font.setFontNumber(2);
+
+ // Get the area for text display
+ Rect textRect;
+ gfxManager.getStringBounds(msg.c_str(), textRect, 200);
+ textRect.centre(pt.x, pt.y);
+
+ // Make a backup copy of the area the text will occupy
+ Rect saveRect = textRect;
+ saveRect.collapse(-20, -8);
+ GfxSurface *savedArea = Surface_getArea(gfxManager.getSurface(), saveRect);
+
+ // Display the text
+ gfxManager._font.writeLines(msg.c_str(), textRect, ALIGN_LEFT);
+
+ // Write for a mouse or keypress
+ Event event;
+ while (!_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !_vm->getEventManager()->shouldQuit())
+ ;
+
+ // Restore the display area
+ gfxManager.copyFrom(*savedArea, saveRect.left, saveRect.top);
+ delete savedArea;
+
+ gfxManager.deactivate();
+ return (event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_RETURN);
+}
+
+/**
+ * Loads a quarter of a screen from a resource
+ */
+void GfxSurface::loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection) {
+ int screenNum = _globals->_sceneManager._scene->_activeScreenNumber;
+ Rect updateRect(0, 0, 160, 100);
+ updateRect.translate(xHalf * 160, yHalf * 100);
+ int xHalfCount = (_globals->_sceneManager._scene->_backgroundBounds.right + 159) / 160;
+ int yHalfCount = (_globals->_sceneManager._scene->_backgroundBounds.bottom + 99) / 100;
+
+ if (xSection < xHalfCount && ySection < yHalfCount) {
+ int rlbNum = xSection * yHalfCount + ySection;
+ byte *data = _vm->_dataManager->getResource(RES_BITMAP, screenNum, rlbNum);
+
+ for (int y = 0; y < updateRect.height(); ++y) {
+ byte *pSrc = data + y * 160;
+ byte *pDest = (byte *)dest.getBasePtr(updateRect.left, updateRect.top + y);
+
+ for (int x = 0; x < updateRect.width(); ++x, ++pSrc, ++pDest) {
+ *pDest = *pSrc;
+ }
+ }
+
+ DEALLOCATE(data);
+ }
+}
+
+/**
+ * Returns an array indicating which pixels of a source image horizontally or vertically get
+ * included in a scaled image
+ */
+static int *scaleLine(int size, int srcSize) {
+ int scale = 100 * size / srcSize;
+ assert(scale >= 0);
+ int *v = new int[size];
+ Common::set_to(v, &v[size], 0);
+
+ int distCtr = 0;
+ int *destP = v;
+ for (int distIndex = 0; distIndex < srcSize; ++distIndex) {
+ distCtr += scale;
+ while (distCtr >= 100) {
+ assert(destP < &v[size]);
+ *destP++ = distIndex;
+ distCtr -= 100;
+ }
+ }
+
+ return v;
+}
+
+/**
+ * Scales a passed surface, creating a new surface with the result
+ * @param srcImage Source image to scale
+ * @param NewWidth New width for scaled image
+ * @param NewHeight New height for scaled image
+ * @remarks Caller is responsible for freeing the returned surface
+ */
+static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize) {
+ GfxSurface s;
+ s.create(xSize, ySize);
+
+ Graphics::Surface srcImage = src.lockSurface();
+ Graphics::Surface destImage = s.lockSurface();
+
+ int *horizUsage = scaleLine(xSize, srcImage.w);
+ int *vertUsage = scaleLine(ySize, srcImage.h);
+
+ // Loop to create scaled version
+ for (int yp = 0; yp < ySize; ++yp) {
+ const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]);
+ byte *destP = (byte *)destImage.getBasePtr(0, yp);
+
+ for (int xp = 0; xp < xSize; ++xp) {
+ const byte *tempSrcP = srcP + horizUsage[xp];
+ *destP++ = *tempSrcP++;
+ }
+ }
+
+ // Unlock surfaces
+ src.unlockSurface();
+ s.unlockSurface();
+
+ // Delete arrays and return surface
+ delete[] horizUsage;
+ delete[] vertUsage;
+ return s;
+}
+
+/**
+ * Copys an area from one GfxSurface to another
+ */
+void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion) {
+ GfxSurface srcImage;
+
+ if (srcBounds == src.getBounds())
+ srcImage = src;
+ else {
+ // Set the source image to be the subset specified by the source bounds
+ Graphics::Surface srcSurface = src.lockSurface();
+
+ srcImage.create(srcBounds.width(), srcBounds.height());
+ Graphics::Surface destSurface = srcImage.lockSurface();
+
+ const byte *srcP = (const byte *)srcSurface.getBasePtr(srcBounds.left, srcBounds.top);
+ byte *destP = (byte *)destSurface.pixels;
+ for (int yp = srcBounds.top; yp < srcBounds.bottom; ++yp, srcP += srcSurface.pitch, destP += destSurface.pitch) {
+ Common::copy(srcP, srcP + srcBounds.width(), destP);
+ }
+
+ srcImage.unlockSurface();
+ src.unlockSurface();
+ }
+
+ if ((destBounds.width() != srcBounds.width()) || (destBounds.height() != srcBounds.height()))
+ srcImage = ResizeSurface(srcImage, destBounds.width(), destBounds.height());
+
+ Graphics::Surface srcSurface = srcImage.lockSurface();
+ Graphics::Surface destSurface = lockSurface();
+
+ // Adjust bounds to ensure destination will be on-screen
+ int srcX = 0, srcY = 0;
+ if (destBounds.left < 0) {
+ srcX = -destBounds.left;
+ destBounds.left = 0;
+ }
+ if (destBounds.top < 0) {
+ srcY = -destBounds.top;
+ destBounds.top = 0;
+ }
+ if (destBounds.right > destSurface.w)
+ destBounds.right = destSurface.w;
+ if (destBounds.bottom > destSurface.h)
+ destBounds.bottom = destSurface.h;
+
+ if (destBounds.isValidRect()) {
+ const byte *pSrc = (const byte *)srcSurface.getBasePtr(srcX, srcY);
+ byte *pDest = (byte *)destSurface.getBasePtr(destBounds.left, destBounds.top);
+
+ for (int y = 0; y < destBounds.height(); ++y, pSrc += srcSurface.pitch, pDest += destSurface.pitch) {
+
+ if (!priorityRegion && (src._transColour == -1))
+ Common::copy(pSrc, pSrc + destBounds.width(), pDest);
+ else {
+ const byte *tempSrc = pSrc;
+ byte *tempDest = pDest;
+ int xp = destBounds.left;
+
+ while (tempSrc < (pSrc + destBounds.width())) {
+ if (!priorityRegion || !priorityRegion->contains(Common::Point(
+ xp + _globals->_sceneManager._scene->_sceneBounds.left,
+ destBounds.top + y + _globals->_sceneManager._scene->_sceneBounds.top))) {
+ if (*tempSrc != src._transColour)
+ *tempDest = *tempSrc;
+ }
+ ++tempSrc;
+ ++tempDest;
+ ++xp;
+ }
+ }
+ }
+ }
+
+ unlockSurface();
+ srcImage.unlockSurface();
+}
+
+void GfxSurface::draw(const Common::Point &pt, Rect *rect) {
+ Rect tempRect = getBounds();
+ tempRect.translate(-_centroid.x, -_centroid.y);
+ tempRect.translate(pt.x, pt.y);
+
+ if (rect) {
+ // Only copy needed rect out without drawing
+ *rect = tempRect;
+ } else {
+ // Draw image
+ _globals->gfxManager().copyFrom(*this, tempRect, NULL);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxElement::GfxElement() {
+ _owner = NULL;
+ _keycode = 0;
+ _flags = 0;
+}
+
+void GfxElement::setDefaults() {
+ _flags = 0;
+ _fontNumber = _globals->_gfxFontNumber;
+ _colours = _globals->_gfxColours;
+ _fontColours = _globals->_fontColours;
+}
+
+/**
+ * Highlights the specified graphics element
+ */
+void GfxElement::highlight() {
+ // Get a lock on the surface
+ GfxManager &gfxManager = _globals->gfxManager();
+ Graphics::Surface surface = gfxManager.lockSurface();
+
+ // Scan through the contents of the element, switching any occurances of the foreground
+ // colour with the background colour and vice versa
+ Rect tempRect(_bounds);
+ tempRect.collapse(2, 2);
+
+ for (int yp = tempRect.top; yp < tempRect.bottom; ++yp) {
+ byte *lineP = (byte *)surface.getBasePtr(tempRect.left, yp);
+ for (int xp = tempRect.left; xp < tempRect.right; ++xp, ++lineP) {
+ if (*lineP == _colours.background) *lineP = _colours.foreground;
+ else if (*lineP == _colours.foreground) *lineP = _colours.background;
+ }
+ }
+
+ // Release the surface
+ gfxManager.unlockSurface();
+}
+
+/**
+ * Fills the background of the specified element with a border frame
+ */
+void GfxElement::drawFrame() {
+ // Get a lock on the surface and save the active font
+ GfxManager &gfxManager = _globals->gfxManager();
+ gfxManager.lockSurface();
+
+ uint8 bgColour, fgColour;
+ if (_flags & GFXFLAG_THICK_FRAME) {
+ bgColour = 0;
+ fgColour = 0;
+ } else {
+ bgColour = _fontColours.background;
+ fgColour = _fontColours.foreground;
+ }
+
+ Rect tempRect = _bounds;
+ tempRect.collapse(3, 3);
+ tempRect.collapse(-1, -1);
+ gfxManager.fillRect(tempRect, _colours.background);
+
+ --tempRect.bottom; --tempRect.right;
+ gfxManager.fillArea(tempRect.left, tempRect.top, bgColour);
+ gfxManager.fillArea(tempRect.left, tempRect.bottom, fgColour);
+ gfxManager.fillArea(tempRect.right, tempRect.top, fgColour);
+ gfxManager.fillArea(tempRect.right, tempRect.bottom, fgColour);
+
+ tempRect.collapse(-1, -1);
+ gfxManager.fillRect2(tempRect.left + 1, tempRect.top, tempRect.width() - 1, 1, bgColour);
+ gfxManager.fillRect2(tempRect.left, tempRect.top + 1, 1, tempRect.height() - 1, bgColour);
+ gfxManager.fillRect2(tempRect.left + 1, tempRect.bottom, tempRect.width() - 1, 1, fgColour);
+ gfxManager.fillRect2(tempRect.right, tempRect.top + 1, 1, tempRect.height() - 1, fgColour);
+
+ gfxManager.fillArea(tempRect.left, tempRect.top, 0);
+ gfxManager.fillArea(tempRect.left, tempRect.bottom, 0);
+ gfxManager.fillArea(tempRect.right, tempRect.top, 0);
+ gfxManager.fillArea(tempRect.right, tempRect.bottom, 0);
+
+ tempRect.collapse(-1, -1);
+ gfxManager.fillRect2(tempRect.left + 2, tempRect.top, tempRect.width() - 3, 1, 0);
+ gfxManager.fillRect2(tempRect.left, tempRect.top + 2, 1, tempRect.height() - 3, 0);
+ gfxManager.fillRect2(tempRect.left + 2, tempRect.bottom, tempRect.width() - 3, 1, 0);
+ gfxManager.fillRect2(tempRect.right, tempRect.top + 2, 1, tempRect.height() - 3, 0);
+
+ gfxManager.unlockSurface();
+}
+
+/**
+ * Handles events when the control has focus
+ *
+ * @event Event to process
+ */
+bool GfxElement::focusedEvent(Event &event) {
+ bool highlightFlag = false;
+
+ while (!_vm->getEventManager()->shouldQuit()) {
+ g_system->delayMillis(10);
+
+ if (_bounds.contains(event.mousePos)) {
+ if (!highlightFlag) {
+ // First highlight call to show the highlight
+ highlightFlag = true;
+ highlight();
+ }
+ } else if (highlightFlag) {
+ // Mouse is outside the element, so remove the highlight
+ highlightFlag = false;
+ highlight();
+ }
+
+ if (_globals->_events.getEvent(event, EVENT_BUTTON_UP))
+ break;
+ }
+
+ if (highlightFlag) {
+ // Mouse is outside the element, so remove the highlight
+ highlight();
+ }
+
+ return highlightFlag;
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxImage::GfxImage() : GfxElement() {
+ _resNum = 0;
+ _rlbNum = 0;
+ _cursorNum = 0;
+}
+
+void GfxImage::setDetails(int resNum, int rlbNum, int cursorNum) {
+ _resNum = resNum;
+ _rlbNum = rlbNum;
+ _cursorNum = cursorNum;
+ setDefaults();
+}
+
+void GfxImage::setDefaults() {
+ GfxElement::setDefaults();
+
+ // Decode the image
+ uint size;
+ byte *imgData = _vm->_dataManager->getSubResource(_resNum, _rlbNum, _cursorNum, &size);
+ _surface = surfaceFromRes(imgData);
+ DEALLOCATE(imgData);
+
+ // Set up the display bounds
+ Rect imgBounds = _surface.getBounds();
+ imgBounds.moveTo(_bounds.left, _bounds.top);
+ _bounds = imgBounds;
+}
+
+void GfxImage::draw() {
+ Rect tempRect = _bounds;
+ tempRect.translate(_globals->gfxManager()._topLeft.x, _globals->gfxManager()._topLeft.y);
+
+ _globals->gfxManager().copyFrom(_surface, tempRect);
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxMessage::GfxMessage() : GfxElement() {
+ _textAlign = ALIGN_LEFT;
+ _width = 0;
+}
+
+void GfxMessage::set(const Common::String &s, int width, TextAlign textAlign) {
+ _message = s;
+ _width = width;
+ _textAlign = textAlign;
+
+ setDefaults();
+}
+
+void GfxMessage::setDefaults() {
+ GfxElement::setDefaults();
+
+ GfxFontBackup font;
+ GfxManager &gfxManager = _globals->gfxManager();
+ Rect tempRect;
+
+ gfxManager._font.setFontNumber(this->_fontNumber);
+ gfxManager.getStringBounds(_message.c_str(), tempRect, _width);
+
+ tempRect.collapse(-1, -1);
+ tempRect.moveTo(_bounds.left, _bounds.top);
+ _bounds = tempRect;
+}
+
+void GfxMessage::draw() {
+ GfxFontBackup font;
+ GfxManager &gfxManager = _globals->gfxManager();
+
+ // Set the font and colour
+ gfxManager.setFillFlag(false);
+ gfxManager._font.setFontNumber(_fontNumber);
+ gfxManager._font._colours.foreground = this->_colours.foreground;
+
+ // Display the text
+ gfxManager._font.writeLines(_message.c_str(), _bounds, _textAlign);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void GfxButton::setDefaults() {
+ GfxElement::setDefaults();
+
+ GfxFontBackup font;
+ GfxManager &gfxManager = _globals->gfxManager();
+ Rect tempRect;
+
+ // Get the string bounds and round up the x end to a multiple of 16
+ gfxManager._font.setFontNumber(this->_fontNumber);
+ gfxManager._font.getStringBounds(_message.c_str(), tempRect, 240);
+ tempRect.right = ((tempRect.right + 15) / 16) * 16;
+
+ // Set the button bounds to a reduced area
+ tempRect.collapse(-3, -3);
+ tempRect.moveTo(_bounds.left, _bounds.top);
+ _bounds = tempRect;
+}
+
+void GfxButton::draw() {
+ // Get a lock on the surface and save the active font
+ GfxFontBackup font;
+ GfxManager &gfxManager = _globals->gfxManager();
+ gfxManager.lockSurface();
+
+ // Draw a basic frame for the button
+ drawFrame();
+
+ // Set the font and colour
+ gfxManager._font.setFontNumber(_fontNumber);
+ gfxManager._font._colours.foreground = this->_colours.foreground;
+
+ // Display the button's text
+ Rect tempRect(_bounds);
+ tempRect.collapse(3, 3);
+ gfxManager._font.writeLines(_message.c_str(), tempRect, ALIGN_CENTRE);
+
+ gfxManager.unlockSurface();
+}
+
+bool GfxButton::process(Event &event) {
+ switch (event.eventType) {
+ case EVENT_BUTTON_DOWN:
+ if (!event.handled) {
+ if (_bounds.contains(event.mousePos)) {
+ bool result = focusedEvent(event);
+ event.handled = true;
+ return result;
+ }
+ }
+ break;
+
+ case EVENT_KEYPRESS:
+ if (!event.handled && (event.kbd.keycode == _keycode)) {
+ // TODO: Ensure momentary click operation displays
+ highlight();
+ g_system->delayMillis(20);
+ highlight();
+
+ event.handled = true;
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxDialog::GfxDialog() {
+ _savedArea = NULL;
+ _defaultButton = NULL;
+}
+
+GfxDialog::~GfxDialog() {
+ remove();
+}
+
+void GfxDialog::setDefaults() {
+ GfxElement::setDefaults();
+
+ // Initialise the embedded graphics manager
+ _gfxManager.setDefaults();
+
+ // Figure out a rect needed for all the added elements
+ GfxElementList::iterator i;
+ Rect tempRect;
+ for (i = _elements.begin(); i != _elements.end(); ++i)
+ tempRect.extend((*i)->_bounds);
+
+ // Set the dialog boundaries
+ _gfxManager._bounds = tempRect;
+ tempRect.collapse(-6, -6);
+ _bounds = tempRect;
+}
+
+void GfxDialog::remove() {
+ if (_savedArea) {
+ // Restore the area the dialog covered
+ _globals->_gfxManagerInstance.copyFrom(*_savedArea, _bounds.left, _bounds.top);
+
+ delete _savedArea;
+ _savedArea = NULL;
+ }
+}
+
+void GfxDialog::draw() {
+ Rect tempRect(_bounds);
+
+ // Make a backup copy of the area the dialog will occupy
+ _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), _bounds);
+
+ // Set the palette for use in the dialog
+ setPalette();
+
+ _gfxManager.activate();
+
+ // Fill in the contents of the entire dialog
+ _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ drawFrame();
+
+ // Reset the dialog's graphics manager to only draw within the dialog boundaries
+ tempRect.translate(6, 6);
+ _gfxManager._bounds = tempRect;
+
+ // Draw each element in the dialog in order
+ GfxElementList::iterator i;
+ for (i = _elements.begin(); i != _elements.end(); ++i) {
+ (*i)->draw();
+ }
+
+ // If there's a default button, then draw it
+ if (_defaultButton) {
+ _defaultButton->_flags |= GFXFLAG_THICK_FRAME;
+ _defaultButton->draw();
+ }
+
+ _gfxManager.deactivate();
+}
+
+void GfxDialog::add(GfxElement *element) {
+ _elements.push_back(element);
+ element->_owner = this;
+}
+
+void GfxDialog::addElements(GfxElement *ge, ...) {
+ va_list va;
+ va_start(va, ge);
+ GfxElement *gfxElement = ge;
+ while (gfxElement) {
+ add(gfxElement);
+
+ gfxElement = va_arg(va, GfxElement *);
+ }
+
+ va_end(va);
+}
+
+void GfxDialog::setTopLeft(int xp, int yp) {
+ _bounds.moveTo(xp - 6, yp - 6);
+}
+
+void GfxDialog::setCentre(int xp, int yp) {
+ setTopLeft(xp - (_bounds.width() / 2), yp - (_bounds.height() / 2));
+}
+
+GfxButton *GfxDialog::execute(GfxButton *defaultButton) {
+ _gfxManager.activate();
+
+ if (defaultButton != _defaultButton) {
+ if (_defaultButton) {
+ _defaultButton->_flags &= ~GFXFLAG_THICK_FRAME;
+ _defaultButton->draw();
+ }
+ _defaultButton = defaultButton;
+ }
+ if (_defaultButton) {
+ _defaultButton->_flags |= GFXFLAG_THICK_FRAME;
+ _defaultButton->draw();
+ }
+
+ // Event loop
+ GfxButton *selectedButton = NULL;
+
+ while (!_vm->getEventManager()->shouldQuit()) {
+ Event event;
+ while (_globals->_events.getEvent(event)) {
+ // Adjust mouse positions to be relative within the dialog
+ event.mousePos.x -= _gfxManager._bounds.left;
+ event.mousePos.y -= _gfxManager._bounds.top;
+
+ for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ if ((*i)->process(event))
+ selectedButton = static_cast<GfxButton *>(*i);
+ }
+ }
+
+ if (selectedButton)
+ break;
+ else if (!event.handled) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ selectedButton = NULL;
+ break;
+ } else if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_RETURN)) {
+ selectedButton = defaultButton;
+ break;
+ }
+ }
+ }
+
+ _gfxManager.deactivate();
+ if (_defaultButton)
+ _defaultButton->_flags &= ~GFXFLAG_THICK_FRAME;
+
+ return selectedButton;
+}
+
+void GfxDialog::setPalette() {
+ _globals->_scenePalette.loadPalette(0);
+ _globals->_scenePalette.setPalette(0, 1);
+ _globals->_scenePalette.setPalette(_globals->_scenePalette._colours.foreground, 1);
+ _globals->_scenePalette.setPalette(_globals->_fontColours.background, 1);
+ _globals->_scenePalette.setPalette(_globals->_fontColours.foreground, 1);
+ _globals->_scenePalette.setPalette(255, 1);
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxManager::GfxManager() : _surface(_globals->_screenSurface), _oldManager(NULL) {
+ _font.setOwner(this);
+ _font._fillFlag = false;
+ _bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+}
+
+GfxManager::GfxManager(GfxSurface &s) : _surface(s), _oldManager(NULL) {
+ _font.setOwner(this);
+ _font._fillFlag = false;
+}
+
+void GfxManager::setDefaults() {
+ Rect screenBounds(0, 0, g_system->getWidth(), g_system->getHeight());
+
+ _surface.setBounds(screenBounds);
+ _bounds = screenBounds;
+ _pane0Rect4 = screenBounds;
+
+ _font._edgeSize = Common::Point(1, 1);
+ _font._colours = _globals->_fontColours;
+ _font.setFontNumber(_globals->_gfxFontNumber);
+}
+
+void GfxManager::activate() {
+ assert(!contains(_globals->_gfxManagers, this));
+ _globals->_gfxManagers.push_front(this);
+}
+
+void GfxManager::deactivate() {
+ // Assert that there will still be another manager, and we're correctly removing our own
+ assert((_globals->_gfxManagers.size() > 1) && (&_globals->gfxManager() == this));
+ _globals->_gfxManagers.pop_front();
+}
+
+int GfxManager::getStringWidth(const char *s, int numChars) {
+ return _font.getStringWidth(s, numChars);
+}
+
+int GfxManager::getStringWidth(const char *s) {
+ return _font.getStringWidth(s);
+}
+
+void GfxManager::getStringBounds(const char *s, Rect &bounds, int maxWidth) {
+ _font.getStringBounds(s, bounds, maxWidth);
+}
+
+void GfxManager::fillArea(int xp, int yp, int colour) {
+ _surface.setBounds(_bounds);
+ Rect tempRect(xp, yp, xp + _font._edgeSize.x, yp + _font._edgeSize.y);
+ _surface.fillRect(tempRect, colour);
+}
+
+void GfxManager::fillRect(const Rect &bounds, int colour) {
+ _surface.setBounds(_bounds);
+ _surface.fillRect(bounds, colour);
+}
+
+void GfxManager::fillRect2(int xs, int ys, int width, int height, int colour) {
+ _surface.setBounds(_bounds);
+ _surface.fillRect(Rect(xs, ys, xs + width, ys + height), colour);
+}
+
+/**
+ * Sets up the standard palette for dialog displays
+ */
+void GfxManager::setDialogPalette() {
+ // Get the main palette information
+ RGB8 palData[256];
+ uint count, start;
+ _vm->_dataManager->getPalette(0, &palData[0], &start, &count);
+ g_system->getPaletteManager()->setPalette((byte *)&palData[0], start, count);
+
+ // Miscellaneous
+ uint32 white = 0xffffffff;
+ g_system->getPaletteManager()->setPalette((const byte *)&white, 255, 1);
+}
+
+/**
+ * Returns the angle of line connecting two points
+ */
+int GfxManager::getAngle(const Common::Point &p1, const Common::Point &p2) {
+ int xDiff = p2.x - p1.x, yDiff = p1.y - p2.y;
+
+ if (!xDiff && !yDiff)
+ return -1;
+ else if (!xDiff)
+ return (p2.y >= p1.y) ? 180 : 0;
+ else if (!yDiff)
+ return (p2.x >= p1.x) ? 90 : 270;
+ else {
+ int result = (((xDiff * 100) / ((abs(xDiff) + abs(yDiff))) * 90) / 100);
+
+ if (yDiff < 0)
+ result = 180 - result;
+ else if (xDiff < 0)
+ result += 360;
+
+ return result;
+ }
+}
+/*--------------------------------------------------------------------------*/
+
+
+GfxFont::GfxFont() {
+ _fontNumber = 50;
+ _numChars = 0;
+ _bpp = 0;
+ _fontData = NULL;
+ _fillFlag = false;
+}
+
+GfxFont::~GfxFont() {
+ DEALLOCATE(_fontData);
+}
+
+/**
+ * Sets the current active font number
+ *
+ * @fontNumber New font number
+ */
+void GfxFont::setFontNumber(uint32 fontNumber) {
+ if ((_fontNumber == fontNumber) && (_fontData))
+ return;
+
+ DEALLOCATE(_fontData);
+
+ _fontNumber = fontNumber;
+
+ _fontData = _vm->_tSageManager->getResource(RES_FONT, _fontNumber, 0, true);
+ if (!_fontData)
+ _fontData = _vm->_dataManager->getResource(RES_FONT, _fontNumber, 0);
+
+ _numChars = READ_LE_UINT16(_fontData + 4);
+ _fontSize.y = READ_LE_UINT16(_fontData + 6);
+ _fontSize.x = READ_LE_UINT16(_fontData + 8);
+ _bpp = READ_LE_UINT16(_fontData + 10);
+}
+
+/**
+ * Returns the width of the given specified character
+ *
+ * @ch Character to return width of
+ */
+int GfxFont::getCharWidth(char ch) {
+ assert(_numChars > 0);
+ uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)ch * 4);
+ return _fontData[charOffset] & 0x1f;
+}
+
+/**
+ * Returns the width of the given string in the current font
+ *
+ * @s String to return the width of
+ * @numChars Number of characters within the string to use
+ */
+int GfxFont::getStringWidth(const char *s, int numChars) {
+ assert(_numChars > 0);
+ int width = 0;
+
+ for (; numChars > 0; --numChars, ++s) {
+ uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)*s * 4);
+ int charWidth = _fontData[charOffset] & 0x1f;
+
+ width += charWidth;
+ }
+
+ return width;
+}
+
+/**
+ * Returns the width of the given string in the current font
+ *
+ * @s String to return the width of
+ */
+int GfxFont::getStringWidth(const char *s) {
+ return getStringWidth(s, strlen(s));
+}
+
+/**
+ * Returns the maximum number of characters for words that will fit into a given width
+ *
+ * @s Message to be analysed
+ * @maxWidth Maximum allowed width
+ */
+int GfxFont::getStringFit(const char *&s, int maxWidth) {
+ const char *nextWord = NULL;
+ const char *sStart = s;
+ int numChars = 1;
+ int strWidth = 1;
+ char nextChar;
+
+ for (;;) {
+ nextChar = *s++;
+
+ if ((nextChar == '\r') || (nextChar == '\0'))
+ break;
+
+ // Check if it's a word end
+ if (nextChar == ' ') {
+ nextWord = s;
+ }
+
+ strWidth = getStringWidth(sStart, numChars);
+ if (strWidth > maxWidth) {
+ if (nextWord) {
+ s = nextWord;
+ nextChar = ' ';
+ }
+ break;
+ }
+
+ ++numChars;
+ }
+
+ int totalChars = s - sStart;
+ if (nextChar == '\0')
+ --s;
+ if ((nextChar == ' ') || (nextChar == '\r') || (nextChar == '\0'))
+ --totalChars;
+
+ return totalChars;
+}
+
+/**
+ * Fills out the passed rect with the dimensions of a given string word-wrapped to a
+ * maximum specified width
+ *
+ * @s Message to be analysed
+ * @bounds Rectangle to put output size into
+ * @maxWidth Maximum allowed line width in pixels
+ */
+void GfxFont::getStringBounds(const char *s, Rect &bounds, int maxWidth) {
+ if (maxWidth == 0) {
+ // No maximum width, so set bounds for a single line
+ bounds.set(0, 0, getStringWidth(s), getHeight());
+ } else {
+ int numLines = 0;
+ int lineWidth = 0;
+
+ // Loop to figure out the number of lines required, and the maximum line width
+ while (*s) {
+ const char *msg = s;
+ int numChars = getStringFit(msg, maxWidth);
+ lineWidth = MAX(lineWidth, getStringWidth(s, numChars));
+
+ s = msg;
+ ++numLines;
+ }
+
+ bounds.set(0, 0, lineWidth, numLines * getHeight());
+ }
+}
+
+/**
+ * Writes out a character at the currently set position using the active font
+ *
+ * @ch Character to display
+ */
+int GfxFont::writeChar(const char ch) {
+ assert((_fontData != NULL) && ((uint8)ch < _numChars));
+ uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)ch * 4);
+ int charWidth = _fontData[charOffset] & 0x1f;
+ int charHeight = (READ_LE_UINT16(_fontData + charOffset) >> 5) & 0x3f;
+ int yOffset = (_fontData[charOffset + 1] >> 3) & 0x1f;
+ const uint8 *dataP = &_fontData[charOffset + 2];
+
+ // Lock the surface for access
+ Graphics::Surface surfacePtr = _gfxManager->lockSurface();
+
+ Rect charRect;
+ charRect.set(0, 0, charWidth, _fontSize.y);
+ charRect.translate(_topLeft.x + _position.x, _topLeft.y + _position.y + yOffset);
+
+ if (_fillFlag)
+ surfacePtr.fillRect(charRect, _colours.background);
+
+ charRect.bottom = charRect.top + charHeight;
+
+ // Display the character
+ int bitCtr = 0;
+ uint8 v = 0;
+ for (int yp = charRect.top; yp < charRect.bottom; ++yp) {
+ byte *destP = (byte *)surfacePtr.getBasePtr(charRect.left, yp);
+
+ for (int xs = 0; xs < charRect.width(); ++xs, ++destP) {
+ // Get the next colour index to use
+ if ((bitCtr % 8) == 0) v = *dataP++;
+ int colIndex = 0;
+ for (int subCtr = 0; subCtr < _bpp; ++subCtr, ++bitCtr) {
+ colIndex = (colIndex << 1) | (v & 0x80 ? 1 : 0);
+ v <<= 1;
+ }
+
+ switch (colIndex) {
+ //case 0: *destP = _colours.background; break;
+ case 1: *destP = _colours.foreground; break;
+ case 2: *destP = _colours2.background; break;
+ case 3: *destP = _colours2.foreground; break;
+ }
+ }
+ }
+
+ _position.x += charWidth;
+ _gfxManager->unlockSurface();
+ return charWidth;
+}
+
+/**
+ * Writes the specified number of characters from the specified string at the current text position
+ *
+ * @s String to display
+ * @numChars Number of characters to print
+ */
+void GfxFont::writeString(const char *s, int numChars) {
+ // Lock the surface for access
+ _gfxManager->lockSurface();
+
+ while ((numChars-- > 0) && (*s != '\0')) {
+ writeChar(*s);
+ ++s;
+ }
+
+ // Release the surface lock
+ _gfxManager->unlockSurface();
+}
+
+/**
+ * Writes the the specified string at the current text position
+ *
+ * @s String to display
+ */
+void GfxFont::writeString(const char *s) {
+ writeString(s, strlen(s));
+}
+
+/**
+ * Writes a specified string within a given area with support for word wrapping and text alignment types
+ *
+ * @s String to display
+ * @bounds Bounds to display the text within
+ * @align Text alignment mode
+ */
+void GfxFont::writeLines(const char *s, const Rect &bounds, TextAlign align) {
+ int lineNum = 0;
+
+ // Lock the surface for access
+ _gfxManager->lockSurface();
+
+ while (*s) {
+ const char *msgP = s;
+ int numChars = getStringFit(msgP, bounds.width());
+
+ _position.y = bounds.top + lineNum * getHeight();
+
+ switch (align) {
+ case ALIGN_RIGHT:
+ // Right aligned text
+ _position.x = bounds.right - getStringWidth(s, numChars);
+ writeString(s, numChars);
+ break;
+
+ case ALIGN_CENTRE:
+ // Center aligned text
+ _position.x = bounds.left + (bounds.width() / 2) - (getStringWidth(s, numChars) / 2);
+ writeString(s, numChars);
+ break;
+
+ case ALIGN_JUSTIFIED: {
+ // Justified text
+ // Get the number of words in the string portion
+ int charCtr = 0, numWords = 0;
+ while (charCtr < numChars) {
+ if (s[charCtr] == ' ')
+ ++numWords;
+ ++charCtr;
+ }
+ // If end of string, count final word
+ if (*msgP == '\0')
+ ++numWords;
+
+ // Display the words of the string
+ int spareWidth = bounds.width() - getStringWidth(s, numChars);
+ charCtr = 0;
+ _position.x = bounds.left;
+
+ while (charCtr < numChars) {
+ writeChar(s[charCtr]);
+ if ((numWords > 0) && (s[charCtr] == ' ')) {
+ int separationWidth = spareWidth / numWords;
+ spareWidth -= separationWidth;
+ --numWords;
+ _position.x += separationWidth;
+ }
+
+ ++charCtr;
+ }
+ break;
+ }
+
+ case ALIGN_LEFT:
+ default:
+ // Standard text
+ _position.x = bounds.left;
+ writeString(s, numChars);
+ break;
+ }
+
+ // Next line
+ s = msgP;
+ ++lineNum;
+ }
+
+ // Release the surface lock
+ _gfxManager->unlockSurface();
+}
+
+/*--------------------------------------------------------------------------*/
+
+GfxFontBackup::GfxFontBackup() {
+ _edgeSize = _globals->gfxManager()._font._edgeSize;
+ _position = _globals->gfxManager()._font._position;
+ _colours = _globals->gfxManager()._font._colours;
+ _fontNumber = _globals->gfxManager()._font._fontNumber;
+}
+
+GfxFontBackup::~GfxFontBackup() {
+ _globals->gfxManager()._font.setFontNumber(_fontNumber);
+ _globals->gfxManager()._font._edgeSize = _edgeSize;
+ _globals->gfxManager()._font._position = _position;
+ _globals->gfxManager()._font._colours = _colours;
+}
+
+
+} // End of namespace tSage
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
new file mode 100644
index 0000000000..0ad76772b3
--- /dev/null
+++ b/engines/tsage/graphics.h
@@ -0,0 +1,349 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef RING_GRAPHICS_H
+#define RING_GRAPHICS_H
+
+#include "tsage/events.h"
+#include "tsage/saveload.h"
+#include "common/list.h"
+#include "common/rect.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+
+namespace tSage {
+
+class GfxSurface;
+class Region;
+
+/**
+ * Extended Rect class with extra support methods
+ */
+class Rect : public Common::Rect, public Serialisable {
+public:
+ Rect() : Common::Rect() {};
+ Rect(int16 x1, int16 y1, int16 x2, int16 y2) : Common::Rect(x1, y1, x2, y2) {};
+
+ void set(int16 x1, int16 y1, int16 x2, int16 y2);
+ void collapse(int dx, int dy);
+ void centre(int dx, int dy);
+ void centre(const Rect &r);
+ void centre(const Common::Point &pt) { centre(pt.x, pt.y); }
+ void contain(const Rect &r);
+ void resize(const GfxSurface &surface, int xp, int yp, int percent);
+ void expandPanes();
+
+ virtual void synchronise(Serialiser &s);
+};
+
+class GfxColours {
+public:
+ uint8 foreground;
+ uint8 background;
+
+ GfxColours() : foreground(0), background(0) {};
+};
+
+class LineSlice {
+public:
+ int xs, xe;
+
+ LineSlice() { xs = 0; xe = 0; }
+ LineSlice(int xStart, int xEnd) { xs = xStart; xe = xEnd; }
+};
+
+class GfxSurface {
+private:
+ Graphics::Surface *_customSurface;
+ Graphics::Surface *_screenSurfaceP;
+ int _lockSurfaceCtr;
+ bool _screenSurface;
+
+ bool _disableUpdates;
+ Rect _bounds;
+public:
+ Common::Point _centroid;
+ int _transColour;
+public:
+ GfxSurface();
+ GfxSurface(const GfxSurface &s);
+ ~GfxSurface();
+
+ void setScreenSurface();
+ Graphics::Surface lockSurface();
+ void unlockSurface();
+ void create(int width, int height);
+ void setBounds(const Rect &bounds) { _bounds = bounds; };
+ const Rect &getBounds() const { return _bounds; };
+
+ void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion = NULL);
+ void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) {
+ copyFrom(src, src.getBounds(), destBounds, priorityRegion);
+ }
+ void copyFrom(GfxSurface &src, int destX = 0, int destY = 0, Region *priorityRegion = NULL) {
+ Rect tempRect = src.getBounds();
+ tempRect.moveTo(destX, destY);
+ copyFrom(src, tempRect, priorityRegion);
+ }
+ void draw(const Common::Point &pt, Rect *rect = NULL);
+ void fillRect(const Rect &bounds, int colour);
+ GfxSurface &operator=(const GfxSurface &s);
+
+ static void loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection);
+ static bool displayText(const Common::String &msg, const Common::Point &pt = Common::Point(160, 100));
+};
+
+enum TextAlign {ALIGN_LEFT = 0, ALIGN_CENTRE = 1, ALIGN_RIGHT = 2, ALIGN_JUSTIFIED = 3};
+
+class GfxFont {
+ friend class GfxFontBackup;
+private:
+ GfxManager *_gfxManager;
+ // Raw font details
+ const byte *_fontData;
+ int _numChars;
+ Common::Point _fontSize;
+ int _bpp;
+public:
+ // Font fields
+ Common::Point _edgeSize;
+ Common::Point _position;
+ bool _fillFlag;
+ GfxColours _colours;
+ GfxColours _colours2;
+ uint32 _fontNumber;
+ Common::Point _topLeft;
+public:
+ GfxFont();
+ virtual ~GfxFont();
+
+ void setFontNumber(uint32 fontNumber);
+ int32 getHeight() const { return _fontSize.y; }
+ int getCharWidth(char ch);
+ int getStringWidth(const char *s, int numChars);
+ int getStringWidth(const char *s);
+ int getStringFit(const char *&s, int maxWidth);
+ void getStringBounds(const char *s, Rect &bounds, int maxWidth);
+
+ void setOwner(GfxManager *owner) { _gfxManager = owner; }
+ void setPosition(int xp, int yp) { _position.x = xp; _position.y = yp; }
+ int writeChar(const char ch);
+ void writeString(const char *s);
+ void writeString(const char *s, int numChars);
+ void writeLines(const char *s, const Rect &bounds, TextAlign align);
+};
+
+class GfxFontBackup {
+private:
+ GfxSurface *_surface;
+ Common::Point _edgeSize;
+ Common::Point _position;
+ GfxColours _colours;
+ uint32 _fontNumber;
+public:
+ GfxFontBackup();
+ ~GfxFontBackup();
+};
+
+enum GFX_FLAGS {GFXFLAG_THICK_FRAME = 8};
+
+class GfxManager;
+
+class GfxElement {
+public:
+ GfxElement *_owner;
+ Rect _bounds;
+ uint16 _flags;
+ uint16 _fontNumber;
+ GfxColours _colours;
+ GfxColours _fontColours;
+ uint16 _keycode;
+public:
+ GfxElement();
+ virtual ~GfxElement() {}
+
+ void drawFrame();
+
+ // Virtual table method
+ virtual void setDefaults();
+ virtual void remove() { _owner = NULL; }
+ virtual void highlight();
+ virtual void draw() {};
+ virtual bool process(Event &event) { return false; };
+ virtual bool focusedEvent(Event &event);
+};
+
+class GfxImage : public GfxElement {
+public:
+ GfxSurface _surface;
+ int _resNum;
+ int _rlbNum;
+ int _cursorNum;
+public:
+ GfxImage();
+
+ void setDetails(int resNum, int rlbNum, int cursorNum);
+
+ virtual void setDefaults();
+ virtual void draw();
+ virtual bool process(Event &event) { return false; }
+};
+
+class GfxMessage : public GfxElement {
+public:
+ Common::String _message;
+ TextAlign _textAlign;
+ int _width;
+public:
+ GfxMessage();
+ virtual ~GfxMessage() {}
+
+ void set(const Common::String &s, int width, TextAlign textAlign);
+
+ virtual void setDefaults();
+ virtual void draw();
+};
+
+class GfxButton : public GfxElement {
+private:
+ void setFocus();
+public:
+ Common::String _message;
+public:
+ GfxButton() : GfxElement() {};
+ virtual ~GfxButton() {}
+
+ void setText(const Common::String &s) {
+ _message = s;
+ setDefaults();
+ }
+
+ // Virtual table method
+ virtual void setDefaults();
+ virtual void draw();
+ virtual bool process(Event &event);
+};
+
+class GfxManager {
+private:
+ GfxSurface &_surface;
+public:
+ GfxManager *_oldManager;
+ Common::Point _topLeft;
+ Rect _bounds;
+ Rect _pane0Rect4;
+ GfxFont _font;
+public:
+ GfxManager();
+ GfxManager(GfxSurface &s);
+ virtual ~GfxManager() {}
+
+ void setDefaults();
+ void activate();
+ void deactivate();
+
+ // Accessor methods
+ int getStringWidth(const char *s, int numChars);
+ int getStringWidth(const char *s);
+ void getStringBounds(const char *s, Rect &bounds, int maxWidth);
+
+ void setDialogPalette();
+ Graphics::Surface lockSurface() {
+ _surface.setBounds(_bounds);
+ return _surface.lockSurface();
+ }
+ void unlockSurface() { _surface.unlockSurface(); };
+ void fillArea(int xp, int yp, int colour);
+ void fillRect(const Rect &bounds, int colour);
+ void fillRect2(int xs, int ys, int width, int height, int colour);
+ void setFillFlag(bool v) { _font._fillFlag = v; }
+
+ static int getAngle(const Common::Point &p1, const Common::Point &p2);
+
+ // Virtual method table
+ virtual void xorArea(const Common::Rect &r, int colour, int fillMode) {
+ //_surface->xorArea(r, colour, fillMode);
+ }
+ virtual void draw(const Common::Rect &r, void *gfxData, int v1, GfxColours *colours) {
+ //_surface->draw(r, gfxData, v1, colours);
+ }
+ virtual void copy(const byte *src, byte *dest, int size) {
+ Common::copy(src, src + size, dest);
+ }
+ virtual void set(byte *dest, int size, byte val) {
+ Common::set_to(dest, dest + size, val);
+ }
+ void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) {
+ _surface.setBounds(_bounds);
+ _surface.copyFrom(src, destBounds, priorityRegion);
+ }
+ void copyFrom(GfxSurface &src, int destX, int destY) {
+ _surface.setBounds(_bounds);
+ _surface.copyFrom(src, destX, destY);
+ g_system->updateScreen();
+ }
+ GfxSurface &getSurface() {
+ _surface.setBounds(_bounds);
+ return _surface;
+ }
+};
+
+typedef Common::List<GfxElement *> GfxElementList;
+
+class GfxDialog : public GfxElement {
+public:
+ GfxManager _gfxManager;
+ GfxElementList _elements;
+ GfxButton *_defaultButton;
+ GfxSurface *_savedArea;
+public:
+ GfxDialog();
+ virtual ~GfxDialog();
+
+ void add(GfxElement *element);
+ void addElements(GfxElement *ge, ...);
+ void setTopLeft(int xp, int yp);
+ void setCentre(int xp, int yp);
+ void frame() {
+ setDefaults();
+ _bounds.collapse(6, 6);
+ }
+ GfxButton *execute(GfxButton *defaultButton = NULL);
+
+ virtual void setDefaults();
+ virtual void remove();
+ virtual void draw();
+
+ static void setPalette();
+};
+
+GfxSurface *Surface_getArea(GfxSurface &src, const Rect &bounds);
+
+GfxSurface surfaceFromRes(const byte *imgData);
+GfxSurface surfaceFromRes(int resNum, int rlbNum, int subNum);
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk
new file mode 100644
index 0000000000..41a868195b
--- /dev/null
+++ b/engines/tsage/module.mk
@@ -0,0 +1,35 @@
+MODULE := engines/tsage
+
+MODULE_OBJS := \
+ converse.o \
+ core.o \
+ debugger.o \
+ detection.o \
+ dialogs.o \
+ events.o \
+ globals.o \
+ graphics.o \
+ resources.o \
+ ringworld_logic.o \
+ ringworld_scenes1.o \
+ ringworld_scenes2.o \
+ ringworld_scenes3.o \
+ ringworld_scenes4.o \
+ ringworld_scenes5.o \
+ ringworld_scenes6.o \
+ ringworld_scenes8.o \
+ ringworld_scenes10.o \
+ saveload.o \
+ scenes.o \
+ sound.o \
+ staticres.o \
+ tsage.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_TSAGE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
+
diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp
new file mode 100644
index 0000000000..c87c3eaf1e
--- /dev/null
+++ b/engines/tsage/resources.cpp
@@ -0,0 +1,410 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/file.h"
+#include "common/stack.h"
+#include "common/util.h"
+#include "tsage/resources.h"
+
+namespace tSage {
+
+
+MemoryManager::MemoryManager() {
+ _memoryPool = new MemoryHeader*[MEMORY_POOL_SIZE];
+ Common::set_to(&_memoryPool[0], &_memoryPool[MEMORY_POOL_SIZE], (MemoryHeader *)NULL);
+}
+
+MemoryManager::~MemoryManager() {
+ for (int i = 0; i < MEMORY_POOL_SIZE; ++i) {
+ if (_memoryPool[i] != NULL)
+ free(_memoryPool[i]);
+ }
+ delete[] _memoryPool;
+}
+
+uint16 MemoryManager::allocate(uint32 size) {
+ int idx = 0;
+ while ((idx < MEMORY_POOL_SIZE) && (_memoryPool[idx] != NULL))
+ ++idx;
+ if (idx == MEMORY_POOL_SIZE)
+ error("Out of memory handles");
+
+ // Create the new entry
+ _memoryPool[idx] = (MemoryHeader *)malloc(sizeof(MemoryHeader) + size);
+ _memoryPool[idx]->id = MEMORY_ENTRY_ID;
+ _memoryPool[idx]->index = idx;
+ _memoryPool[idx]->lockCtr = 0;
+ _memoryPool[idx]->criticalCtr = 0;
+ _memoryPool[idx]->tag = 0;
+ _memoryPool[idx]->size = size;
+
+ // Return it's index
+ return idx;
+}
+
+byte *MemoryManager::allocate2(uint32 size) {
+ uint32 idx = allocate(size);
+ return lock(idx);
+}
+
+byte *MemoryManager::lock(uint32 handle) {
+ assert((int)handle < MEMORY_POOL_SIZE);
+ return (byte *)_memoryPool[handle] + sizeof(MemoryHeader);
+}
+
+int MemoryManager::indexOf(const byte *p) {
+ for (int idx = 0; idx < MEMORY_POOL_SIZE; ++idx) {
+ if (((byte *)_memoryPool[idx] + sizeof(MemoryHeader)) == p)
+ return idx;
+ }
+
+ return -1;
+}
+
+void MemoryManager::deallocate(const byte *p) {
+ if (!p)
+ return;
+
+ int idx = indexOf(p);
+ assert(idx != -1);
+ if (_memoryPool[idx]->lockCtr-- == 0) {
+ free(_memoryPool[idx]);
+ _memoryPool[idx] = NULL;
+ }
+}
+
+uint32 MemoryManager::getSize(const byte *p) {
+ int idx = indexOf(p);
+ assert(idx >= 0);
+ return _memoryPool[idx]->size;
+}
+
+void MemoryManager::incLocks(const byte *p) {
+ int idx = indexOf(p);
+ assert(idx >= 0);
+ _memoryPool[idx]->lockCtr++;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static uint16 bitMasks[4] = {0x1ff, 0x3ff, 0x7ff, 0xfff};
+
+uint16 BitReader::readToken() {
+ assert((numBits >= 9) && (numBits <= 12));
+ uint16 result = _remainder;
+ int bitsLeft = numBits - _bitsLeft;
+ int bitOffset = _bitsLeft;
+ _bitsLeft = 0;
+
+ while (bitsLeft >= 0) {
+ _remainder = readByte();
+ result |= _remainder << bitOffset;
+ bitsLeft -= 8;
+ bitOffset += 8;
+ }
+
+ _bitsLeft = -bitsLeft;
+ _remainder >>= 8 - _bitsLeft;
+ return result & bitMasks[numBits - 9];
+}
+
+/*-------------------------------------------------------------------------*/
+
+RlbManager::RlbManager(MemoryManager &memManager, const Common::String filename) :
+ _memoryManager(memManager) {
+
+ // If the resource strings list isn't yet loaded, load them
+ if (_resStrings.size() == 0) {
+ Common::File f;
+ if (f.open("tsage.cfg")) {
+ while (!f.eos()) {
+ _resStrings.push_back(f.readLine());
+ }
+ f.close();
+ }
+ }
+
+ if (!_file.open(filename))
+ error("Missing file %s", filename.c_str());
+
+ loadIndex();
+}
+
+RlbManager::~RlbManager() {
+ _resStrings.clear();
+}
+
+void RlbManager::loadSection(uint32 fileOffset) {
+ _resources.clear();
+ _file.seek(fileOffset);
+ _sections.fileOffset = fileOffset;
+
+ if (_file.readUint32BE() != 0x544D492D)
+ error("Data block is not valid Rlb data");
+
+ /*uint8 unknown1 = */_file.readByte();
+ uint16 numEntries = _file.readByte();
+
+ for (uint i = 0; i < numEntries; ++i) {
+ uint16 id = _file.readUint16LE();
+ uint16 size = _file.readUint16LE();
+ uint16 uncSize = _file.readUint16LE();
+ uint8 sizeHi = _file.readByte();
+ uint8 type = _file.readByte() >> 5;
+ assert(type <= 1);
+ uint32 offset = _file.readUint32LE();
+
+ ResourceEntry re;
+ re.id = id;
+ re.fileOffset = offset;
+ re.isCompressed = type != 0;
+ re.size = ((sizeHi & 0xF) << 16) | size;
+ re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize;
+
+ _resources.push_back(re);
+ }
+}
+
+struct DecodeReference {
+ uint16 vWord;
+ uint8 vByte;
+};
+
+/**
+ * Gets a resource from the currently loaded section
+ */
+byte *RlbManager::getResource(uint16 id, bool suppressErrors) {
+ // Scan for an entry for the given Id
+ ResourceEntry *re= NULL;
+ ResourceList::iterator i;
+ for (i = _resources.begin(); i != _resources.end(); ++i) {
+ if ((*i).id == id) {
+ re = &(*i);
+ break;
+ }
+ }
+ if (!re) {
+ if (suppressErrors)
+ return NULL;
+ error("Could not find resource Id #%d", id);
+ }
+
+ if (!re->isCompressed) {
+ // Read in the resource data and return it
+ byte *dataP = _memoryManager.allocate2(re->size);
+ _file.seek(_sections.fileOffset + re->fileOffset);
+ _file.read(dataP, re->size);
+
+ return dataP;
+ }
+
+ /*
+ * Decompress the data block
+ */
+
+ _file.seek(_sections.fileOffset + re->fileOffset);
+ Common::ReadStream *compStream = _file.readStream(re->size);
+ BitReader bitReader(*compStream);
+
+ byte *dataOut = _memoryManager.allocate2(re->uncompressedSize);
+ byte *destP = dataOut;
+ uint bytesWritten = 0;
+
+ uint16 ctrCurrent = 0x102, ctrMax = 0x200;
+ uint16 word_48050 = 0, currentToken = 0, word_48054 =0;
+ byte byte_49068 = 0, byte_49069 = 0;
+ DecodeReference table[0x1000];
+ Common::Stack<uint16> tokenList;
+
+ for (;;) {
+ // Get the next decode token
+ uint16 token = bitReader.readToken();
+
+ // Handle the token
+ if (token == 0x101) {
+ // End of compressed stream
+ break;
+ } else if (token == 0x100) {
+ // Reset bit-rate
+ bitReader.numBits = 9;
+ ctrMax = 0x200;
+ ctrCurrent = 0x102;
+
+ // Set variables with next token
+ currentToken = word_48050 = bitReader.readToken();
+ byte_49069 = byte_49068 = (byte)currentToken;
+
+ ++bytesWritten;
+ assert(bytesWritten <= re->uncompressedSize);
+ *destP++ = byte_49069;
+ } else {
+ word_48054 = word_48050 = token;
+
+ if (token >= ctrCurrent) {
+ word_48050 = currentToken;
+ tokenList.push(byte_49068);
+ }
+
+ while (word_48050 >= 0x100) {
+ assert(word_48050 < 0x1000);
+ tokenList.push(table[word_48050].vByte);
+ word_48050 = table[word_48050].vWord;
+ }
+
+ byte_49069 = byte_49068 = (byte)word_48050;
+ tokenList.push(word_48050);
+
+ // Write out any cached tokens
+ while (!tokenList.empty()) {
+ ++bytesWritten;
+ assert(bytesWritten <= re->uncompressedSize);
+ *destP++ = tokenList.pop();
+ }
+
+ assert(ctrCurrent < 0x1000);
+ table[ctrCurrent].vByte = byte_49069;
+ table[ctrCurrent].vWord = currentToken;
+ ++ctrCurrent;
+
+ currentToken = word_48054;
+ if ((ctrCurrent >= ctrMax) && (bitReader.numBits != 12)) {
+ // Move to the next higher bit-rate
+ ++bitReader.numBits;
+ ctrMax <<= 1;
+ }
+ }
+ }
+
+ assert(bytesWritten == re->uncompressedSize);
+ delete compStream;
+ return dataOut;
+}
+
+/**
+ * Finds the correct section and loads the specified resource within it
+ */
+byte *RlbManager::getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors) {
+ SectionList::iterator i = _sections.begin();
+ while ((i != _sections.end()) && ((*i).resType != resType || (*i).resNum != resNum))
+ ++i;
+ if (i == _sections.end()) {
+ if (suppressErrors)
+ return NULL;
+ error("Unknown resource type %d num %d", resType, resNum);
+ }
+
+ loadSection((*i).fileOffset);
+
+ return getResource(rlbNum, suppressErrors);
+}
+
+void RlbManager::loadIndex() {
+ uint16 resNum, configId, fileOffset;
+
+ // Load the root resources section
+ loadSection(0);
+
+ // Get the single resource from it
+ const byte *pData = getResource(0);
+ const byte *p = pData;
+
+ _sections.clear();
+
+ // Loop through reading the entries
+ while ((resNum = READ_LE_UINT16(p)) != 0xffff) {
+ configId = READ_LE_UINT16(p + 2);
+ fileOffset = READ_LE_UINT16(p + 4);
+ p += 6;
+
+ SectionEntry se;
+ se.resNum = resNum;
+ se.resType = (ResourceType)(configId & 0x1f);
+ se.fileOffset = (((configId >> 5) & 0x7ff) << 16) | fileOffset;
+
+ _sections.push_back(se);
+ }
+
+ _memoryManager.deallocate(pData);
+}
+
+/**
+ * Retrieves the specified palette resource and returns it's data
+ *
+ * @paletteNum Specefies the palette number
+ */
+void RlbManager::getPalette(int paletteNum, RGB8 *palData, uint *startNum, uint *numEntries) {
+ // Get the specified palette
+ byte *dataIn = getResource(RES_PALETTE, 0, paletteNum);
+ assert(dataIn);
+
+ *startNum = READ_LE_UINT16(dataIn);
+ *numEntries = READ_LE_UINT16(dataIn + 2);
+ RGB8 *srcPal = (RGB8 *)(dataIn + 6);
+ assert((*startNum < 256) && ((*startNum + *numEntries) <= 256));
+
+ // Copy over the data
+ Common::copy(&srcPal[0], &srcPal[*numEntries], palData);
+
+ _memoryManager.deallocate(dataIn);
+}
+
+byte *RlbManager::getSubResource(int resNum, int rlbNum, int index, uint *size) {
+ // Get the specified image set
+ byte *dataIn = getResource(RES_VISAGE, resNum, rlbNum);
+ assert(dataIn);
+
+ int numEntries = READ_LE_UINT16(dataIn);
+ uint32 entryOffset = READ_LE_UINT32(dataIn + 2 + (index - 1) * 4);
+ uint32 nextOffset = (index == numEntries) ?
+ _memoryManager.getSize(dataIn) : READ_LE_UINT32(dataIn + 2 + index * 4);
+ *size = nextOffset - entryOffset;
+ assert(*size < (1024 * 1024));
+
+ byte *entry = _memoryManager.allocate2(*size);
+ Common::copy(&dataIn[entryOffset], &dataIn[nextOffset], entry);
+
+ _memoryManager.deallocate(dataIn);
+ return entry;
+}
+
+/**
+ * Retrieves a given message resource, and returns the specified message number
+ */
+Common::String RlbManager::getMessage(int resNum, int lineNum) {
+ byte *msgData = getResource(RES_MESSAGE, resNum, 0);
+ assert(msgData);
+
+ const char *srcP = (const char *)msgData;
+ while (lineNum-- > 0)
+ srcP += strlen(srcP) + 1;
+
+ Common::String result(srcP);
+ _memoryManager.deallocate(msgData);
+ return result;
+}
+
+} // end of namespace tSage
diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h
new file mode 100644
index 0000000000..1af1bb8d2f
--- /dev/null
+++ b/engines/tsage/resources.h
@@ -0,0 +1,176 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef RING_RESOURCES_H
+#define RING_RESOURCES_H
+
+#include "common/scummsys.h"
+#include "common/file.h"
+#include "common/list.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "common/util.h"
+#include "graphics/surface.h"
+
+namespace tSage {
+
+// Magic number used by original game to identify valid memory blocks
+const uint32 MEMORY_ENTRY_ID = 0xE11DA722;
+
+const int MEMORY_POOL_SIZE = 1000;
+
+enum ResourceType { RES_LIBRARY, RES_STRIP, RES_IMAGE, RES_PALETTE, RES_VISAGE, RES_SOUND, RES_MESSAGE,
+ RES_FONT, RES_POINTER, RES_BANK, RES_SND_DRIVER, RES_PRIORITY, RES_CONTROL, RES_WALKRGNS,
+ RES_BITMAP, RES_SAVE, RES_SEQUENCE };
+
+#include "common/pack-start.h" // START STRUCT PACKING
+
+struct RGB8 {
+ uint8 r;
+ uint8 g;
+ uint8 b;
+} PACKED_STRUCT;
+
+#include "common/pack-end.h" // END STRUCT PACKING
+
+class MemoryHeader {
+public:
+ uint32 id;
+ int16 index;
+ int lockCtr;
+ int criticalCtr;
+ uint8 tag;
+ uint32 size;
+
+ MemoryHeader() {
+ id = 0;
+ index = 0;
+ lockCtr = 0;
+ criticalCtr = 0;
+ tag = 0;
+ size = 0;
+ }
+};
+
+class SectionEntry {
+public:
+ ResourceType resType;
+ uint16 resNum;
+ uint32 fileOffset;
+
+ SectionEntry() {
+ resType = RES_LIBRARY;
+ resNum = 0;
+ fileOffset = 0;
+ }
+};
+
+class ResourceEntry {
+public:
+ uint16 id;
+ bool isCompressed;
+ uint32 fileOffset;
+ uint32 size;
+ uint32 uncompressedSize;
+
+ ResourceEntry() {
+ id = 0;
+ isCompressed = false;
+ fileOffset = 0;
+ size = 0;
+ uncompressedSize = 0;
+ }
+};
+
+typedef Common::List<ResourceEntry> ResourceList;
+
+class SectionList : public Common::List<SectionEntry> {
+public:
+ uint32 fileOffset;
+
+ SectionList() {
+ fileOffset = 0;
+ }
+};
+
+class MemoryManager {
+private:
+ MemoryHeader **_memoryPool;
+public:
+ MemoryManager();
+ ~MemoryManager();
+
+ uint16 allocate(uint32 size);
+ byte *allocate2(uint32 size);
+ byte *lock(uint32 handle);
+ int indexOf(const byte *p);
+ void deallocate(const byte *p);
+ void deallocate(uint16 handle) { assert("TODO"); }
+ uint32 getSize(const byte *p);
+ void incLocks(const byte *p);
+};
+
+class BitReader {
+private:
+ Common::ReadStream &_stream;
+ uint8 _remainder, _bitsLeft;
+ byte readByte() { return _stream.eos() ? 0 : _stream.readByte(); }
+public:
+ BitReader(Common::ReadStream &s) : _stream(s) {
+ numBits = 9;
+ _remainder = 0;
+ _bitsLeft = 0;
+ }
+ uint16 readToken();
+
+ int numBits;
+};
+
+class RlbManager {
+private:
+ Common::StringArray _resStrings;
+ MemoryManager &_memoryManager;
+private:
+ Common::File _file;
+ ResourceList _resources;
+ SectionList _sections;
+
+ void loadSection(uint32 fileOffset);
+ void loadIndex();
+public:
+ RlbManager(MemoryManager &memManager, const Common::String filename);
+ ~RlbManager();
+
+ byte *getResource(uint16 id, bool suppressErrors = false);
+ byte *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false);
+ void getPalette(int paletteNum, RGB8 *palData, uint *startNum, uint *numEntries);
+ byte *getSubResource(int resNum, int rlbNum, int index, uint *size);
+ Common::String getMessage(int resNum, int lineNum);
+};
+
+
+} // end of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld_logic.cpp
new file mode 100644
index 0000000000..32f62bea76
--- /dev/null
+++ b/engines/tsage/ringworld_logic.cpp
@@ -0,0 +1,1162 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/ringworld_logic.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/ringworld_scenes1.h"
+#include "tsage/ringworld_scenes2.h"
+#include "tsage/ringworld_scenes3.h"
+#include "tsage/ringworld_scenes4.h"
+#include "tsage/ringworld_scenes5.h"
+#include "tsage/ringworld_scenes6.h"
+#include "tsage/ringworld_scenes8.h"
+#include "tsage/ringworld_scenes10.h"
+
+namespace tSage {
+
+Scene *SceneFactory::createScene(int sceneNumber) {
+ switch (sceneNumber) {
+ /* Scene group 1 */
+ // Kziniti Palace (Introduction)
+ case 10: return new Scene10();
+ // Outer Space (Introduction)
+ case 15: return new Scene15();
+ // Cut-scenes for Ch'mee house in distance
+ case 20: return new Scene20();
+ // Outside Ch'mee residence
+ case 30: return new Scene30();
+ // Chmeee Home
+ case 40: return new Scene40();
+ // By Flycycles
+ case 50: return new Scene50();
+ // Flycycle controls
+ case 60: return new Scene60();
+ // Shipyard Entrance
+ case 90: return new Scene90();
+ // Ship Close-up
+ case 95: return new Scene95();
+ // Sunflower navigation sequence
+ case 6100: return new Scene6100();
+
+ /* Scene group 2 */
+ // Title screen
+ case 1000: return new Scene1000();
+ // Fleeing planet cutscene
+ case 1001: return new Scene1001();
+ // Unused
+ case 1250: return new Scene1250();
+ // Ringworld Wall
+ case 1400: return new Scene1400();
+ // Ringworld Space-port
+ case 1500: return new Scene1500();
+
+ /* Scene group 3 - Part #1 */
+ // Cockpit cutscenes
+ case 2000: return new Scene2000();
+ // Starcraft - Cockpit
+ case 2100: return new Scene2100();
+ // Encyclopedia
+ case 2120: return new Scene2120();
+ // Starcraft - Level 2
+ case 2150: return new Scene2150();
+ // Starcraft - AutoDoc
+ case 2200: return new Scene2200();
+ // Stasis Field Map
+ case 2222: return new Scene2222();
+ // Starcraft - Quinn's Room
+ case 2230: return new Scene2230();
+
+ /* Scene group 3 - Part #2 */
+ // Starcraft - Storage Room
+ case 2280: return new Scene2280();
+ // Starcraft - Hanger Bay
+ case 2300: return new Scene2300();
+ // Starcraft - Copy Protection Screen
+ case 2310: return new Scene2310();
+ // Starcraft - Lander Bay
+ case 2320: return new Scene2320();
+ // Scene 2400 - Descending in Lander
+ case 2400: return new Scene2400();
+
+ /* Scene group 4 */
+ // Ringworld Scan
+ case 3500: return new Scene3500();
+ // Remote Viewer
+ case 3700: return new Scene3700();
+
+ /* Scene group 5 */
+ // Village
+ case 4000: return new Scene4000();
+ // Village - Outside Lander
+ case 4010: return new Scene4010();
+ // Village - Puzzle Board
+ case 4025: return new Scene4025();
+ // Village - Temple Antechamber
+ case 4045: return new Scene4045();
+ // Village - Temple
+ case 4050: return new Scene4050();
+ // Village - Hut
+ case 4100: return new Scene4100();
+ // Village - Bedroom
+ case 4150: return new Scene4150();
+ // Village - Near Slaver Ship
+ case 4250: return new Scene4250();
+ // Village - Slaver Ship
+ case 4300: return new Scene4300();
+ // Village - Slaver Ship Keypad
+ case 4301: return new Scene4301();
+
+ /* Scene group 6 */
+ // Caverns - Entrance
+ case 5000: return new Scene5000();
+ // Caverns
+ case 5100: return new Scene5100();
+ // Caverns - Throne-room
+ case 5200: return new Scene5200();
+ // Caverns - Pit
+ case 5300: return new Scene5300();
+
+ /* Scene group 8 */
+ // Scene 7000: Landing
+ case 7000: return new Scene7000();
+ // Scene 7100: swimming under water
+ case 7100: return new Scene7100();
+ // Scene 7200: Entering the underwater cave
+ case 7200: return new Scene7200();
+ // Scene 7300: Discussion with Lord Poria
+ case 7300: return new Scene7300();
+ case 7600: return new Scene7600();
+ case 7700: return new Scene7700();
+
+ /* Scene group 10 */
+ case 9100: return new Scene9100();
+ case 9150: return new Scene9150();
+ case 9200: return new Scene9200();
+ case 9300: return new Scene9300();
+ case 9350: return new Scene9350();
+ case 9360: return new Scene9360();
+ case 9400: return new Scene9400();
+ case 9450: return new Scene9450();
+ case 9500: return new Scene9500();
+ case 9700: return new Scene9700();
+ case 9750: return new Scene9750();
+ case 9850: return new Scene9850();
+ // Scene 9900: Ending
+ case 9900: return new Scene9900();
+ case 9999: return new Scene9999();
+
+ default:
+ error("Unknown scene number - %d", sceneNumber);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+DisplayHotspot::DisplayHotspot(int regionId, ...) {
+ _sceneRegionId = regionId;
+
+ // Load up the actions
+ va_list va;
+ va_start(va, regionId);
+
+ int param = va_arg(va, int);
+ while (param != LIST_END) {
+ _actions.push_back(param);
+ param = va_arg(va, int);
+ }
+
+ va_end(va);
+}
+
+bool DisplayHotspot::performAction(int action) {
+ for (uint i = 0; i < _actions.size(); i += 3) {
+ if (_actions[i] == action) {
+ display(_actions[i + 1], _actions[i + 2], SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+DisplayObject::DisplayObject(int firstAction, ...) {
+ // Load up the actions
+ va_list va;
+ va_start(va, firstAction);
+
+ int param = firstAction;
+ while (param != LIST_END) {
+ _actions.push_back(param);
+ param = va_arg(va, int);
+ }
+
+ va_end(va);
+}
+
+bool DisplayObject::performAction(int action) {
+ for (uint i = 0; i < _actions.size(); i += 3) {
+ if (_actions[i] == action) {
+ display(_actions[i + 1], _actions[i + 2], SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneArea::SceneArea() {
+ _savedArea = NULL;
+ _pt.x = _pt.y = 0;
+}
+
+SceneArea::~SceneArea() {
+ delete _savedArea;
+}
+
+void SceneArea::setup(int resNum, int rlbNum, int subNum, int actionId) {
+ _resNum = resNum;
+ _rlbNum = rlbNum;
+ _subNum = subNum;
+ _actionId = actionId;
+
+ _surface = surfaceFromRes(resNum, rlbNum, subNum);
+}
+
+void SceneArea::draw2() {
+ _surface.draw(Common::Point(_bounds.left, _bounds.top));
+}
+
+void SceneArea::display() {
+ _bounds.left = _pt.x - (_surface.getBounds().width() / 2);
+ _bounds.top = _pt.y + 1 - _surface.getBounds().height();
+ _bounds.setWidth(_surface.getBounds().width());
+ _bounds.setHeight(_surface.getBounds().height());
+
+ _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), _bounds);
+ draw2();
+}
+
+void SceneArea::restore() {
+ assert(_savedArea);
+ _savedArea->draw(Common::Point(_bounds.left, _bounds.top));
+ delete _savedArea;
+ _savedArea = NULL;
+}
+
+void SceneArea::draw(bool flag) {
+ _surface = surfaceFromRes(_resNum, _rlbNum, flag ? _subNum + 1 : _subNum);
+ _surface.draw(Common::Point(_bounds.left, _bounds.top));
+}
+
+void SceneArea::wait() {
+ // Wait until a mouse or keypress
+ Event event;
+ while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event)) {
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+
+ SynchronisedList<SceneItem *>::iterator ii;
+ for (ii = _globals->_sceneItems.begin(); ii != _globals->_sceneItems.end(); ++ii) {
+ SceneItem *sceneItem = *ii;
+ if (sceneItem->contains(event.mousePos)) {
+ sceneItem->doAction(_actionId);
+ break;
+ }
+ }
+
+ _globals->_events.setCursor(CURSOR_ARROW);
+}
+
+void SceneArea::synchronise(Serialiser &s) {
+ s.syncAsSint16LE(_pt.x);
+ s.syncAsSint16LE(_pt.y);
+ s.syncAsSint32LE(_resNum);
+ s.syncAsSint32LE(_rlbNum);
+ s.syncAsSint32LE(_subNum);
+ s.syncAsSint32LE(_actionId);
+ _bounds.synchronise(s);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerGText::SpeakerGText() {
+ _speakerName = "GTEXT";
+ _textWidth = 160;
+ _textPos = Common::Point(130, 10);
+ _colour1 = 42;
+ _hideObjects = false;
+}
+
+void SpeakerGText::setText(const Common::String &msg) {
+ // Set the animation properties
+ _sceneObject.postInit();
+ _sceneObject.setVisage(9405);
+ _sceneObject.setStrip2(3);
+ _sceneObject.setPriority2(255);
+ _sceneObject.changeZoom(100);
+ _sceneObject._frame = 1;
+ _sceneObject.setPosition(Common::Point(183, 71));
+ _sceneObject.animate(ANIM_MODE_7, 0, NULL);
+
+ // Set the text
+ Rect textRect;
+ _globals->gfxManager()._font.getStringBounds(msg.c_str(), textRect, _textWidth);
+ textRect.centre(_sceneObject._position.x, _sceneObject._position.y);
+ _textPos.x = textRect.left;
+ Speaker::setText(msg);
+}
+
+void SpeakerGText::removeText() {
+ _sceneObject.remove();
+ Speaker::removeText();
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerPOR::SpeakerPOR() {
+ _speakerName = "POR";
+ _newSceneNumber = 7221;
+ _textPos = Common::Point(10, 30);
+ _colour1 = 41;
+}
+
+void SpeakerPOR::SpeakerAction1::signal(){
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(60) + 60);
+ break;
+ case 1:
+ static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_5, this, NULL);
+ break;
+ case 2:
+ setDelay(_globals->_randomSource.getRandomNumber(10));
+ _actionIndex = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void SpeakerPOR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(7223);
+ _object1.setStrip2(2);
+ _object1.setPosition(Common::Point(191, 166), 0);
+ _object1.animate(ANIM_MODE_7, 0, 0);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(7223);
+ _object2.setPosition(Common::Point(159, 86), 0);
+ _object2.setAction(&_speakerAction, 0);
+
+ _object3.postInit(&_objectList);
+ _object3.setVisage(7223);
+ _object3.setStrip(3);
+ _object3.setPosition(Common::Point(119, 107), 0);
+ _object3.setPriority2(199);
+ _object3.setAction(&_action2);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerOR::SpeakerOR() {
+ _speakerName = "OR";
+ _newSceneNumber = 9430;
+ _textPos = Common::Point(8, 36);
+ _colour1 = 42;
+ _textWidth = 136;
+}
+
+void SpeakerOR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(9431);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(202, 147), 0);
+ _object1.animate(ANIM_MODE_7, 0, 0);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(9431);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.setZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(199, 85), 0);
+ _object2.setAction(&_speakerAction, 0);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerOText::SpeakerOText() : SpeakerGText() {
+ _speakerName = "OTEXT";
+ _textWidth = 240;
+ _textPos = Common::Point(130, 10);
+ _colour1 = 42;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerQText::SpeakerQText() : ScreenSpeaker() {
+ _speakerName = "QTEXT";
+ _textPos = Common::Point(160, 40);
+ _colour1 = 35;
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSText::SpeakerSText() : ScreenSpeaker() {
+ _speakerName = "STEXT";
+ _colour1 = 13;
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerPOText::SpeakerPOText() : ScreenSpeaker() {
+ _speakerName = "POTEXT";
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 41;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerMText::SpeakerMText() {
+ _speakerName = "MTEXT";
+ _colour1 = 11;
+ _textWidth = 160;
+ _textMode = ALIGN_CENTRE;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCText::SpeakerCText() {
+ _speakerName = "CTEXT";
+ _colour1 = 4;
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerEText::SpeakerEText() {
+ _speakerName = "ETEXT";
+ _textPos = Common::Point(20, 20);
+ _colour1 = 22;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerGR::SpeakerGR() {
+ _speakerName = "GR";
+ _newSceneNumber = 9220;
+ _textWidth = 136;
+ _textPos = Common::Point(168, 36);
+ _colour1 = 14;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerHText::SpeakerHText() {
+ _speakerName = "HTEXT";
+ _textPos = Common::Point(160, 40);
+ _colour1 = 52;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSKText::SpeakerSKText() : ScreenSpeaker() {
+ _speakerName = "SKTEXT";
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 5;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerPText::SpeakerPText() {
+ _speakerName = "PTEXT";
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 5;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCHFText::SpeakerCHFText() {
+ _speakerName = "CHFTEXT";
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 56;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCDRText::SpeakerCDRText() {
+ _speakerName = "CDRTEXT";
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 52;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerFLText::SpeakerFLText() {
+ _speakerName = "FLTEXT";
+ _textPos = Common::Point(10, 40);
+ _colour1 = 17;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerBatText::SpeakerBatText() {
+ _speakerName = "BATTEXT";
+ _textWidth = 240;
+ _textMode = ALIGN_CENTRE;
+ _colour1 = 3;
+ _hideObjects = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSKL::SpeakerSKL() : AnimatedSpeaker() {
+ _speakerName = "SKL";
+ _newSceneNumber = 7011;
+ _textPos = Common::Point(10, 30);
+ _colour1 = 10;
+}
+
+void SpeakerSKL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(7013);
+ _object1.setStrip2(2);
+ _object1._frame = 1;
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1.setPosition(Common::Point(203, 120));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(7013);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(197, 80));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerQL::SpeakerQL() : AnimatedSpeaker() {
+ _speakerName = "QL";
+ _newSceneNumber = 2610;
+ _textPos = Common::Point(160, 30);
+ _colour1 = 35;
+ _textMode = ALIGN_CENTRE;
+}
+
+void SpeakerQL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2612);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(128, 146));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2612);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(122, 84));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSR::SpeakerSR() {
+ _speakerName = "SR";
+ _newSceneNumber = 2811;
+ _textPos = Common::Point(10, 30);
+ _colour1 = 13;
+ _textMode = ALIGN_CENTRE;
+}
+
+void SpeakerSR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2813);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(224, 198));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2813);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(203, 96));
+ _object2.setAction(&_speakerAction, NULL);
+
+ _object3.postInit(&_objectList);
+ _object3.setVisage(2813);
+ _object3.setStrip(3);
+ _object3.setPosition(Common::Point(204, 91));
+ _object3.setPriority2(199);
+ _object3._numFrames = 3;
+ _object3.animate(ANIM_MODE_7, 0, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSL::SpeakerSL() {
+ _speakerName = "SL";
+ _newSceneNumber = 2810;
+ _textPos = Common::Point(140, 30);
+ _textWidth = 160;
+ _colour1 = 13;
+ _textMode = ALIGN_CENTRE;
+}
+
+void SpeakerSL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2812);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(95, 198));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2812);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(116, 96));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerQR::SpeakerQR() {
+ _speakerName = "QR";
+ _newSceneNumber = 2611;
+ _textPos = Common::Point(10, 30);
+ _colour1 = 13;
+ _textMode = ALIGN_CENTRE;
+}
+
+void SpeakerQR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2613);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(191, 146));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2613);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(197, 84));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerQU::SpeakerQU() {
+ _speakerName = "QU";
+ _newSceneNumber = 7020;
+ _textPos = Common::Point(160, 30);
+ _colour1 = 35;
+ _textMode = ALIGN_CENTRE;
+}
+
+void SpeakerQU::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(7021);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(116, 120), 0);
+ _object1.animate(ANIM_MODE_7, 0, 0);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(7021);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(111, 84), 0);
+ _object2.setAction(&_speakerAction, 0);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCR::SpeakerCR() {
+ _speakerName = "CR";
+ _newSceneNumber = 9010;
+ _textPos = Common::Point(20, 40);
+ _colour1 = 4;
+}
+
+void SpeakerCR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(9011);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.setPosition(Common::Point(219, 168));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(9011);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.setPosition(Common::Point(232, 81));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerMR::SpeakerMR() {
+ _speakerName = "MR";
+ _newSceneNumber = 2711;
+ _textPos = Common::Point(40, 10);
+ _colour1 = 22;
+}
+
+void SpeakerMR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2713);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(220, 143));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2713);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(215, 99));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerSAL::SpeakerSAL() {
+ _speakerName = "SAL";
+ _newSceneNumber = 2851;
+ _textPos = Common::Point(10, 30);
+ _colour1 = 13;
+ _textMode = ALIGN_CENTRE;
+}
+
+void SpeakerSAL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2853);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(185, 200));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2853);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(170, 92));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerML::SpeakerML() {
+ _speakerName = "ML";
+ _newSceneNumber = 2710;
+ _textPos = Common::Point(160, 40);
+ _colour1 = 22;
+}
+
+void SpeakerML::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(2712);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(99, 143));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(2712);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(105, 99));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCHFL::SpeakerCHFL() {
+ _speakerName = "CHFL";
+ _newSceneNumber = 4111;
+ _textPos = Common::Point(10, 40);
+ _colour1 = 56;
+}
+
+void SpeakerCHFL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(4113);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(205, 116));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(4113);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(202, 71));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCHFR::SpeakerCHFR() {
+ _speakerName = "CHFR";
+ _newSceneNumber = 4110;
+ _textPos = Common::Point(160, 40);
+ _colour1 = 56;
+}
+
+void SpeakerCHFR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(4112);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(103, 116));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(4112);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(106, 71));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerPL::SpeakerPL() {
+ _speakerName = "PL";
+ _newSceneNumber = 4060;
+ _textPos = Common::Point(160, 40);
+ _colour1 = 5;
+}
+
+void SpeakerPL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(4062);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(107, 117));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(4062);
+ _object2.setStrip2(1);
+ _object2.setPriority2(200);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(105, 62));
+ _object2.setAction(&_speakerAction, NULL);
+
+ _object3.postInit(&_objectList);
+ _object3.setVisage(4062);
+ _object3.setStrip2(3);
+ _object3.setPriority2(255);
+ _object3._frame = 1;
+ _object3.setPosition(Common::Point(105, 59));
+ _object3.setAction(&_speakerAction2, NULL);
+
+ Speaker::setText(msg);
+}
+
+void SpeakerPL::removeText() {
+ _object3.remove();
+ AnimatedSpeaker::removeText();
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerPR::SpeakerPR() {
+ _speakerName = "PR";
+ _newSceneNumber = 4061;
+ _textPos = Common::Point(10, 40);
+ _colour1 = 5;
+}
+
+void SpeakerPR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(4063);
+ _object1.setStrip2(1);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(212, 117));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(4063);
+ _object2.setStrip2(2);
+ _object2.setPriority2(200);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(214, 62));
+ _object2.setAction(&_speakerAction, NULL);
+
+ _object3.postInit(&_objectList);
+ _object3.setVisage(4063);
+ _object3.setStrip2(3);
+ _object3.setPriority2(255);
+ _object3.changeZoom(100);
+ _object3._frame = 1;
+ _object3.setPosition(Common::Point(214, 59));
+ _object3.setAction(&_speakerAction2, NULL);
+
+ Speaker::setText(msg);
+}
+
+void SpeakerPR::removeText() {
+ _object3.remove();
+ AnimatedSpeaker::removeText();
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCDR::SpeakerCDR() {
+ _speakerName = "CDR";
+ _newSceneNumber = 4161;
+ _textPos = Common::Point(10, 40);
+ _colour1 = 52;
+}
+
+void SpeakerCDR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(4163);
+ _object1.setStrip2(1);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(208, 97));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(4163);
+ _object2.setStrip2(2);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(200, 57));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerCDL::SpeakerCDL() {
+ _speakerName = "CDL";
+ _newSceneNumber = 4160;
+ _textPos = Common::Point(160, 40);
+ _colour1 = 52;
+}
+
+void SpeakerCDL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(4162);
+ _object1.setStrip2(1);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(112, 97));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(4162);
+ _object2.setStrip2(2);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(115, 57));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerFLL::SpeakerFLL() {
+ _speakerName = "FLL";
+ _newSceneNumber = 5221;
+ _textPos = Common::Point(10, 40);
+ _colour1 = 17;
+}
+
+void SpeakerFLL::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(5223);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(216, 129));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(5223);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(210, 67));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+/*--------------------------------------------------------------------------*/
+
+SpeakerBatR::SpeakerBatR() {
+ _speakerName = "BATR";
+ _newSceneNumber = 5360;
+ _textPos = Common::Point(140, 40);
+ _colour1 = 3;
+}
+
+void SpeakerBatR::setText(const Common::String &msg) {
+ _object1.postInit(&_objectList);
+ _object1.setVisage(5361);
+ _object1.setStrip2(2);
+ _object1.setPriority2(255);
+ _object1.changeZoom(100);
+ _object1._frame = 1;
+ _object1.setPosition(Common::Point(137, 122));
+ _object1.animate(ANIM_MODE_7, 0, NULL);
+
+ _object2.postInit(&_objectList);
+ _object2.setVisage(5361);
+ _object2.setStrip2(1);
+ _object2.setPriority2(255);
+ _object2.changeZoom(100);
+ _object2._frame = 1;
+ _object2.setPosition(Common::Point(137, 104));
+ _object2.setAction(&_speakerAction, NULL);
+
+ Speaker::setText(msg);
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_logic.h b/engines/tsage/ringworld_logic.h
new file mode 100644
index 0000000000..66c7bff912
--- /dev/null
+++ b/engines/tsage/ringworld_logic.h
@@ -0,0 +1,402 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_LOGIC_H
+#define TSAGE_RINGWORLD_LOGIC_H
+
+#include "common/scummsys.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+#define ADD_PLAYER_MOVER(X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
+ _globals->_player.addMover(mover, &pt, this); }
+#define ADD_PLAYER_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
+ OBJ.addMover(mover, &pt, NULL); }
+#define ADD_PLAYER_MOVER_THIS(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
+ OBJ.addMover(mover, &pt, this); }
+
+#define ADD_MOVER(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \
+ OBJ.addMover(mover, &pt, this); }
+#define ADD_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \
+ OBJ.addMover(mover, &pt, NULL); }
+
+
+class SceneFactory {
+public:
+ static Scene *createScene(int sceneNumber);
+};
+
+class DisplayHotspot : public SceneObject {
+private:
+ Common::Array<int> _actions;
+ bool performAction(int action);
+public:
+ DisplayHotspot(int regionId, ...);
+
+ virtual void doAction(int action) {
+ if (!performAction(action))
+ SceneHotspot::doAction(action);
+ }
+};
+
+class DisplayObject : public SceneObject {
+private:
+ Common::Array<int> _actions;
+ bool performAction(int action);
+public:
+ DisplayObject(int firstAction, ...);
+
+ virtual void doAction(int action) {
+ if (!performAction(action))
+ SceneHotspot::doAction(action);
+ }
+};
+
+class SceneArea : public SavedObject {
+public:
+ GfxSurface _surface;
+ GfxSurface *_savedArea;
+ Common::Point _pt;
+ int _resNum;
+ int _rlbNum;
+ int _subNum;
+ int _actionId;
+ Rect _bounds;
+public:
+ SceneArea();
+ ~SceneArea();
+
+ void setup(int resNum, int rlbNum, int subNum, int actionId);
+ void draw2();
+ void display();
+ void restore();
+
+ virtual void synchronise(Serialiser &s);
+ virtual void draw(bool flag);
+ virtual void wait();
+};
+
+/*--------------------------------------------------------------------------*/
+// Ringworld specific game speakers
+
+class SpeakerGText : public Speaker {
+public:
+ SceneObject _sceneObject;
+public:
+ SpeakerGText();
+
+ virtual Common::String getClassName() { return "SpeakerGText"; }
+ virtual void setText(const Common::String &msg);
+ virtual void removeText();
+};
+
+class SpeakerPOR : public AnimatedSpeaker {
+ class SpeakerAction1 : public SpeakerAction {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SceneObject _object3;
+ SpeakerAction1 _action2;
+public:
+ SpeakerPOR();
+ virtual Common::String getClassName() { return "SpeakerPOR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerOR : public AnimatedSpeaker {
+public:
+ SpeakerOR();
+ virtual Common::String getClassName() { return "SpeakerOR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerOText : public SpeakerGText {
+public:
+ SpeakerOText();
+
+ virtual Common::String getClassName() { return "SpeakerOText"; }
+};
+
+class SpeakerPOText : public ScreenSpeaker {
+public:
+ SpeakerPOText();
+
+ virtual Common::String getClassName() { return "SpeakerPOText"; }
+};
+
+class SpeakerSText : public ScreenSpeaker {
+public:
+ SpeakerSText();
+
+ virtual Common::String getClassName() { return "SpeakerSText"; }
+};
+
+class SpeakerQText : public ScreenSpeaker {
+public:
+ SpeakerQText();
+
+ virtual Common::String getClassName() { return "SpeakerQText"; }
+};
+
+class SpeakerMText : public ScreenSpeaker {
+public:
+ SpeakerMText();
+
+ virtual Common::String getClassName() { return "SpeakerMText"; }
+};
+
+class SpeakerCText : public ScreenSpeaker {
+public:
+ SpeakerCText();
+
+ virtual Common::String getClassName() { return "SpeakerCText"; }
+};
+
+class SpeakerEText : public ScreenSpeaker {
+public:
+ SpeakerEText();
+
+ virtual Common::String getClassName() { return "SpeakerEText"; }
+};
+
+class SpeakerGR : public AnimatedSpeaker {
+public:
+ SpeakerGR();
+
+ virtual Common::String getClassName() { return "SpeakerGR"; }
+};
+
+class SpeakerHText : public ScreenSpeaker {
+public:
+ SpeakerHText();
+
+ virtual Common::String getClassName() { return "SpeakerHText"; }
+};
+
+class SpeakerPText : public ScreenSpeaker {
+public:
+ SpeakerPText();
+
+ virtual Common::String getClassName() { return "SpeakerPText"; }
+};
+
+class SpeakerCHFText : public ScreenSpeaker {
+public:
+ SpeakerCHFText();
+
+ virtual Common::String getClassName() { return "SpeakerCHFText"; }
+};
+
+class SpeakerSKText : public ScreenSpeaker {
+public:
+ SpeakerSKText();
+
+ virtual Common::String getClassName() { return "SpeakerSKText"; }
+};
+
+class SpeakerCDRText : public ScreenSpeaker {
+public:
+ SpeakerCDRText();
+
+ virtual Common::String getClassName() { return "SpeakerCDRText"; }
+};
+
+class SpeakerFLText : public ScreenSpeaker {
+public:
+ SpeakerFLText();
+
+ virtual Common::String getClassName() { return "SpeakerFLText"; }
+};
+
+class SpeakerBatText : public ScreenSpeaker {
+public:
+ SpeakerBatText();
+
+ virtual Common::String getClassName() { return "SpeakerFLText"; }
+};
+
+class SpeakerQR : public AnimatedSpeaker {
+public:
+ SpeakerQR();
+
+ virtual Common::String getClassName() { return "SpeakerQR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerQU : public AnimatedSpeaker {
+public:
+ SpeakerQU();
+
+ virtual Common::String getClassName() { return "SpeakerQU"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerSKL : public AnimatedSpeaker {
+public:
+ SpeakerSKL();
+
+ virtual Common::String getClassName() { return "SpeakerQL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerQL : public AnimatedSpeaker {
+public:
+ SpeakerQL();
+
+ virtual Common::String getClassName() { return "SpeakerQL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerSR : public AnimatedSpeaker {
+public:
+ SceneObject _object3;
+public:
+ SpeakerSR();
+
+ virtual Common::String getClassName() { return "SpeakerSR"; }
+ void setText(const Common::String &msg);
+};
+
+class SpeakerSL : public AnimatedSpeaker {
+public:
+ SpeakerSL();
+
+ virtual Common::String getClassName() { return "SpeakerSL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerCR : public AnimatedSpeaker {
+public:
+ SpeakerCR();
+
+ virtual Common::String getClassName() { return "SpeakerCR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerMR : public AnimatedSpeaker {
+public:
+ SpeakerMR();
+
+ virtual Common::String getClassName() { return "SpeakerMR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerSAL : public AnimatedSpeaker {
+public:
+ SpeakerSAL();
+
+ virtual Common::String getClassName() { return "SpeakerSAL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerML : public AnimatedSpeaker {
+public:
+ SpeakerML();
+
+ virtual Common::String getClassName() { return "SpeakerML"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerCHFL : public AnimatedSpeaker {
+public:
+ SpeakerCHFL();
+
+ virtual Common::String getClassName() { return "SpeakerCHFL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerCHFR : public AnimatedSpeaker {
+public:
+ SpeakerCHFR();
+
+ virtual Common::String getClassName() { return "SpeakerCHFR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerPL : public AnimatedSpeaker {
+public:
+ SceneObject _object3;
+ SpeakerAction _speakerAction2;
+
+ SpeakerPL();
+
+ virtual Common::String getClassName() { return "SpeakerPL"; }
+ virtual void setText(const Common::String &msg);
+ virtual void removeText();
+};
+
+class SpeakerPR : public AnimatedSpeaker {
+public:
+ SceneObject _object3;
+ SpeakerAction _speakerAction2;
+
+ SpeakerPR();
+
+ virtual Common::String getClassName() { return "SpeakerPR"; }
+ virtual void setText(const Common::String &msg);
+ virtual void removeText();
+};
+
+class SpeakerCDR : public AnimatedSpeaker {
+public:
+ SpeakerCDR();
+
+ virtual Common::String getClassName() { return "SpeakerCDR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerCDL : public AnimatedSpeaker {
+public:
+ SpeakerCDL();
+
+ virtual Common::String getClassName() { return "SpeakerCDL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerFLL : public AnimatedSpeaker {
+public:
+ SpeakerFLL();
+
+ virtual Common::String getClassName() { return "SpeakerFLL"; }
+ virtual void setText(const Common::String &msg);
+};
+
+class SpeakerBatR : public AnimatedSpeaker {
+public:
+ SpeakerBatR();
+
+ virtual Common::String getClassName() { return "SpeakerBatR"; }
+ virtual void setText(const Common::String &msg);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes1.cpp b/engines/tsage/ringworld_scenes1.cpp
new file mode 100644
index 0000000000..4497d6af75
--- /dev/null
+++ b/engines/tsage/ringworld_scenes1.cpp
@@ -0,0 +1,3263 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/ringworld_scenes1.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 10 - Kziniti Palace (Introduction)
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene10::Action1::signal() {
+ Scene10 *scene = (Scene10 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(6);
+ break;
+ case 1:
+ _globals->_scenePalette.addRotation(240, 254, -1);
+ scene->_stripManager.start(10, this);
+ break;
+ case 2:
+ scene->_speakerSText.setTextPos(Common::Point(20, 20));
+ scene->_speakerSText._colour1 = 10;
+ scene->_speakerSText._textWidth = 160;
+ scene->_stripManager.start(11, this, scene);
+ break;
+ case 3:
+ scene->_object2.hide();
+ scene->_object3.hide();
+ scene->_object3.setAction(NULL);
+ scene->_object4.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ case 9:
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ scene->_object2.setStrip(3);
+ scene->_object2.setFrame(1);
+ scene->_object2.setPosition(Common::Point(240, 51));
+ scene->_object2.show();
+
+ scene->_object3.setStrip(6);
+ scene->_object3.setFrame(1);
+ scene->_object3.setPosition(Common::Point(200, 76));
+ scene->_object3._numFrames = 20;
+ scene->_object3.show();
+
+ scene->_stripManager.start(12, this, scene);
+ break;
+ case 6:
+ scene->_object2.hide();
+ scene->_object3.hide();
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ scene->_object3.show();
+ scene->_object3.setStrip2(5);
+ scene->_object3._numFrames = 10;
+ scene->_object3.setPosition(Common::Point(180, 87));
+ scene->_object3.setAction(&scene->_action2);
+
+ scene->_object2.setStrip(4);
+ scene->_object2.setFrame(1);
+ scene->_object2.setPosition(Common::Point(204, 59));
+ scene->_object2.show();
+
+ scene->_stripManager.start(13, this, scene);
+ break;
+ case 8:
+ scene->_object2.hide();
+ scene->_object3.hide();
+ scene->_object4.animate(ANIM_MODE_6, this);
+ break;
+ case 10:
+ _globals->_soundHandler.proc1(this);
+ break;
+ case 11:
+ _globals->_scenePalette.clearListeners();
+ _globals->_sceneManager.changeScene(15);
+ break;
+ }
+}
+
+void Scene10::Action2::signal() {
+ Scene10 *scene = (Scene10 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(179));
+ break;
+ case 1:
+ scene->_object3.setFrame(1);
+ scene->_object3.animate(ANIM_MODE_5, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene10::postInit(SceneObjectList *OwnerList) {
+ loadScene(10);
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _speakerSText._speakerName = "STEXT";
+ _speakerQText._speakerName = "QTEXT";
+ _speakerSText._hideObjects = false;
+ _speakerQText._hideObjects = false;
+ _speakerQText.setTextPos(Common::Point(140, 120));
+ _speakerQText._colour1 = 4;
+ _speakerQText._textWidth = 160;
+ _speakerSText.setTextPos(Common::Point(20, 20));
+ _speakerSText._colour1 = 7;
+ _speakerSText._textWidth = 320;
+
+ _stripManager.setCallback(this);
+
+ _object1.postInit();
+ _object1.setVisage(10);
+ _object1.setPosition(Common::Point(232, 90));
+ _object1.setPriority2(1);
+
+ _object2.postInit();
+ _object2.setVisage(10);
+ _object2.setStrip(4);
+ _object2.setFrame(1);
+ _object2.setPosition(Common::Point(204, 59));
+ _object2.setPriority2(198);
+
+ _object3.postInit();
+ _object3.setVisage(10);
+ _object3.setStrip2(5);
+ _object3.setPosition(Common::Point(180, 87));
+ _object3.setPriority2(196);
+ _object3.setAction(&_action2);
+
+ _object4.postInit();
+ _object4.setVisage(10);
+ _object4.setStrip(2);
+ _object4.setPosition(Common::Point(0, 209));
+ _object4.animate(ANIM_MODE_1, NULL);
+
+ _object5.postInit();
+ _object5.setVisage(11);
+ _object5.setPosition(Common::Point(107, 146));
+ _object5.animate(ANIM_MODE_2, NULL);
+ _object5._numFrames = 5;
+
+ _object6.postInit();
+ _object6.setVisage(11);
+ _object6.setStrip(2);
+ _object6.setPosition(Common::Point(287, 149));
+ _object6.animate(ANIM_MODE_2, NULL);
+ _object6._numFrames = 5;
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+
+ setAction(&_action1);
+ _globals->_soundHandler.startSound(5);
+}
+
+void Scene10::stripCallback(int v) {
+ switch (v) {
+ case 1:
+ _object2.animate(ANIM_MODE_7, -1, NULL);
+ break;
+ case 2:
+ _object2.animate(ANIM_MODE_NONE);
+ break;
+ case 3:
+ _object2.animate(ANIM_MODE_7, -1, NULL);
+ _object3.animate(ANIM_MODE_5, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 15 - Outer Space (Introduction)
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene15::Action1::signal() {
+ Scene15 *scene = (Scene15 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ SceneItem::display(15, 0, SET_Y, 20, SET_FONT, 2, SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 7,
+ SET_WIDTH, 320, SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(300);
+ break;
+ case 2: {
+ SceneItem::display(15, 1, SET_Y, 20, SET_FONT, 2, SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 7,
+ SET_WIDTH, 320, SET_KEEP_ONSCREEN, 1, LIST_END);
+ scene->_object1.postInit();
+ scene->_object1.setVisage(15);
+ scene->_object1.setPosition(Common::Point(160, -10));
+ scene->_object1.animate(ANIM_MODE_2, NULL);
+ Common::Point pt(160, 100);
+ NpcMover *mover = new NpcMover();
+ scene->_object1.addMover(mover, &pt, this);
+ scene->_soundHandler.startSound(7);
+ break;
+ }
+ case 3:
+ SceneItem::display(0, 0);
+ _globals->_sceneManager.changeScene(20);
+ break;
+ }
+}
+
+void Scene15::Action1::dispatch() {
+ Scene15 *scene = (Scene15 *)_globals->_sceneManager._scene;
+
+ if (scene->_object1._position.y < 100)
+ scene->_object1.changeZoom(100 - scene->_object1._position.y);
+ Action::dispatch();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene15::postInit(SceneObjectList *OwnerList) {
+ loadScene(15);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+ _globals->_soundHandler.startSound(6);
+ setAction(&_action1);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 20 - Cut-scenes where House Chmeee is in the distance
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene20::Action1::signal() {
+ Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(120);
+ break;
+ case 1:
+ scene->_stripManager.start(20, this);
+ break;
+ case 2:
+ _globals->_soundHandler.proc1(this);
+ break;
+ case 3:
+ _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
+ _globals->_sceneManager.changeScene(30); // First game scene
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene20::Action2::signal() {
+ Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene;
+ NpcMover *npcMover;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ SceneItem::display(20, 1, SET_WIDTH, 200, SET_Y, 20, SET_X, 160, SET_KEEP_ONSCREEN, true,
+ SET_EXT_BGCOLOUR, 4, LIST_END);
+ setDelay(120);
+ break;
+ case 2: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(455, 77);
+ _globals->_player.addMover(mover, &pt, this);
+ ObjectMover2 *mover2 = new ObjectMover2();
+ scene->_SceneObjectExt.addMover(mover2, 5, 10, &_globals->_player);
+ ObjectMover2 *mover3 = new ObjectMover2();
+ scene->_sceneObject3.addMover(mover3, 10, 15, &_globals->_player);
+ break;
+ }
+ case 3: {
+ npcMover = new NpcMover();
+ Common::Point pt(557, 100);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 4: {
+ npcMover = new NpcMover();
+ Common::Point pt(602, 90);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 5: {
+ npcMover = new NpcMover();
+ Common::Point pt(618, 90);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 6: {
+ npcMover = new NpcMover();
+ Common::Point pt(615, 81);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 7: {
+ npcMover = new NpcMover();
+ Common::Point pt(588, 79);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 8:
+ scene->_sound.proc4();
+ scene->_sound.proc1(this);
+ break;
+ case 9:
+ SceneItem::display(0, 0, LIST_END);
+ _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
+ _globals->_sceneManager.changeScene(40);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene20::Action3::signal() {
+ Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene;
+ NpcMover *npcMover;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(120);
+ break;
+ case 1: {
+ npcMover = new NpcMover();
+ Common::Point pt(615, 81);
+ _globals->_player.addMover(npcMover, &pt, this);
+ ObjectMover2 *mover1 = new ObjectMover2();
+ scene->_SceneObjectExt.addMover(mover1, 5, 10, &_globals->_player);
+ ObjectMover2 *mover2 = new ObjectMover2();
+ scene->_sceneObject3.addMover(mover2, 20, 25, &_globals->_player);
+ break;
+ }
+ case 2: {
+ npcMover = new NpcMover();
+ Common::Point pt(618, 90);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 3: {
+ _globals->_player._moveDiff = Common::Point(10, 10);
+ scene->_SceneObjectExt._moveDiff = Common::Point(10, 10);
+ scene->_sceneObject3._moveDiff = Common::Point(10, 10);
+ npcMover = new NpcMover();
+ Common::Point pt(445, 132);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 4: {
+ npcMover = new NpcMover();
+ Common::Point pt(151, 137);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 5: {
+ npcMover = new NpcMover();
+ Common::Point pt(-15, 137);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 6:
+ scene->_sound.startSound(60, this, 127);
+ _globals->_soundHandler.proc4();
+ break;
+ case 7:
+ _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
+ _globals->_sceneManager.changeScene(90);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene20::Action4::signal() {
+ Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene;
+ NpcMover *npcMover;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1: {
+ npcMover = new NpcMover();
+ Common::Point pt(486, 134);
+ _globals->_player.addMover(npcMover, &pt, this);
+ ObjectMover2 *mover1 = new ObjectMover2();
+ scene->_SceneObjectExt.addMover(mover1, 20, 35, &_globals->_player);
+ break;
+ }
+ case 2: {
+ _globals->_player._moveDiff = Common::Point(12, 12);
+ scene->_SceneObjectExt._moveDiff = Common::Point(12, 12);
+ NpcMover *mover1 = new NpcMover();
+ Common::Point pt(486, 134);
+ scene->_sceneObject3.addMover(mover1, &pt, this);
+ NpcMover *mover2 = new NpcMover();
+ pt = Common::Point(-15, 134);
+ _globals->_player.addMover(mover2, &pt, NULL);
+ NpcMover *mover3 = new NpcMover();
+ pt = Common::Point(-15, 134);
+ scene->_SceneObjectExt.addMover(mover3, &pt, NULL);
+ break;
+ }
+ case 3: {
+ scene->_sceneObject3._moveDiff = Common::Point(20, 20);
+ npcMover = new NpcMover();
+ Common::Point pt(320, 134);
+ scene->_sceneObject3.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 4: {
+ scene->_sound.startSound(28);
+ scene->_sceneObject4.postInit();
+ scene->_sceneObject4.setVisage(21);
+ scene->_sceneObject4.setStrip(3);
+ scene->_sceneObject4.setPosition(Common::Point(scene->_sceneObject3._position.x - 36,
+ scene->_sceneObject3._position.y - 1));
+ scene->_sceneObject4._moveDiff.x = 48;
+
+ ObjectMover3 *mover = new ObjectMover3();
+ scene->_sceneObject4.addMover(mover, &scene->_SceneObjectExt, 4, this);
+ break;
+ }
+ case 5: {
+ scene->_sound.startSound(42);
+ scene->_sceneObject4.remove();
+ scene->_SceneObjectExt.setVisage(21);
+ scene->_SceneObjectExt.setStrip(1);
+ scene->_SceneObjectExt.setFrame(1);
+ scene->_SceneObjectExt.animate(ANIM_MODE_5, NULL);
+
+ scene->_SceneObjectExt._moveDiff.x = 4;
+ NpcMover *mover1 = new NpcMover();
+ Common::Point pt(scene->_SceneObjectExt._position.x - 12, scene->_SceneObjectExt._position.y + 5);
+ scene->_SceneObjectExt.addMover(mover1, &pt, NULL);
+
+ scene->_sceneObject5.postInit();
+ scene->_sceneObject5.setVisage(21);
+ scene->_sceneObject5.setStrip(3);
+ scene->_sceneObject5.setPosition(Common::Point(scene->_sceneObject3._position.x - 36,
+ scene->_sceneObject3._position.y - 1));
+ scene->_sceneObject5._moveDiff.x = 48;
+
+ ObjectMover3 *mover = new ObjectMover3();
+ scene->_sceneObject5.addMover(mover, &_globals->_player, 4, this);
+ break;
+ }
+ case 6: {
+ scene->_sound.startSound(42);
+ scene->_SceneObjectExt.setStrip(2);
+ scene->_SceneObjectExt.animate(ANIM_MODE_2, NULL);
+
+ scene->_sceneObject5.remove();
+ _globals->_player.setVisage(21);
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ _globals->_player._moveDiff.x = 4;
+
+ npcMover = new NpcMover();
+ Common::Point pt(_globals->_player._position.x - 25, _globals->_player._position.y + 5);
+ _globals->_player.addMover(npcMover, &pt, this);
+ break;
+ }
+ case 7:
+ _globals->_player.setStrip(2);
+ _globals->_player.animate(ANIM_MODE_2, NULL);
+ scene->_sound.startSound(77, this, 127);
+ break;
+ case 8:
+ _globals->_game.endGame(20, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene20::Scene20() {
+}
+
+void Scene20::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerGameText);
+ _speakerQText._npc = &_globals->_player;
+
+ if (_globals->_sceneManager._previousScene == 30) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(20);
+ _globals->_player.setPosition(Common::Point(405, 69));
+ _globals->_player._moveDiff = Common::Point(10, 10);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ _SceneObjectExt.postInit();
+ _SceneObjectExt.setVisage(20);
+ _SceneObjectExt.setPosition(Common::Point(400, 69));
+ _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+
+ _sceneObject3.postInit();
+ _sceneObject3.setVisage(20);
+ _sceneObject3.setPosition(Common::Point(395, 69));
+ _sceneObject3.animate(ANIM_MODE_1, NULL);
+
+ _SceneObjectExt._moveDiff = Common::Point(10, 10);
+ _sceneObject3._moveDiff = Common::Point(10, 10);
+ _globals->_soundHandler.startSound(20);
+ _sound.startSound(21);
+ _sound.proc5(1);
+ setAction(&_action2);
+
+ _sceneBounds = Rect(320, 0, 640, 200);
+ } else if (_globals->_sceneManager._previousScene == 60) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2640);
+ _globals->_player.animate(ANIM_MODE_NONE, NULL);
+ _globals->_player.setStrip2(1);
+ _globals->_player.setFrame2(4);
+ _globals->_player.setPriority2(200);
+ _globals->_player.setPosition(Common::Point(425, 233));
+
+ setAction(&_action1);
+ _speakerQText.setTextPos(Common::Point(350, 20));
+ _speakerQText._textWidth = 260;
+ _speakerGameText.setTextPos(Common::Point(350, 20));
+ _speakerGameText._textWidth = 260;
+
+ _globals->_soundHandler.startSound(8);
+ _sceneBounds = Rect(320, 0, 640, 200);
+ } else {
+ _sound.startSound(30);
+ _globals->_player.postInit();
+ _globals->_player.setVisage(20);
+ _globals->_player.setPosition(Common::Point(588, 79));
+ _globals->_player._moveDiff = Common::Point(5, 5);
+ _globals->_player.setPriority2(50);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ _SceneObjectExt.postInit();
+ _SceneObjectExt.setVisage(20);
+ _SceneObjectExt.setPosition(Common::Point(583, 79));
+ _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+
+ _sceneObject3.postInit();
+ _sceneObject3.setVisage(20);
+ _sceneObject3.setStrip(2);
+ _SceneObjectExt.setPosition(Common::Point(595, 79));
+ _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+
+ if ((_globals->getFlag(120) && _globals->getFlag(116)) ||
+ (_globals->getFlag(117) && _globals->getFlag(119))) {
+ setAction(&_action3);
+ } else if (_globals->getFlag(104)) {
+ _sceneMode = 21;
+ setAction(&_sequenceManager, this, 21, &_globals->_player, &_SceneObjectExt, NULL);
+ } else {
+ _sceneObject3._moveDiff = Common::Point(8, 8);
+ setAction(&_action4);
+ }
+
+ _sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y);
+ }
+
+ _globals->_player.disableControl();
+ loadScene(20);
+}
+
+void Scene20::signal() {
+ if (_sceneMode == 21)
+ _globals->_sceneManager.changeScene(90);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 30 - First game scene (Outside Ch'mee house)
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene30::BeamAction::signal() {
+ Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ // Disable control and move player to the doorway beam
+ _globals->_player.disableControl();
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(114, 198);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+
+ case 1:
+ // Perform the animation of player raising hand
+ _globals->_player.setVisage(31);
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+
+ case 2:
+ // Hide the beam and lower the player's hand
+ scene->_sound.startSound(10, NULL, 127);
+ _globals->_player.animate(ANIM_MODE_6, this);
+ scene->_beam.remove();
+ break;
+
+ case 3: {
+ // Bring the Kzin to the doorway
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(7);
+ scene->_kzin.postInit();
+ scene->_kzin.setVisage(2801);
+ scene->_kzin.animate(ANIM_MODE_1, NULL);
+ scene->_kzin.setObjectWrapper(new SceneObjectWrapper());
+ scene->_kzin.setPosition(Common::Point(334, 1));
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(158, 170);
+ scene->_kzin.addMover(mover, &pt, this);
+ _globals->_sceneItems.push_front(&scene->_kzin);
+ break;
+ }
+
+ case 4:
+ // Open the door
+ scene->_sound.startSound(11, NULL, 127);
+ scene->_door.animate(ANIM_MODE_5, this);
+ break;
+
+ case 5:
+ // Run the Kzin's talk sequence
+ scene->_sound.startSound(13, NULL, 127);
+ _globals->_soundHandler.startSound(12, NULL, 127);
+ scene->_stripManager.start((scene->_sceneMode == 0) ? 30 : 37, this);
+ break;
+
+ case 6:
+ // Slight delay
+ setDelay(3);
+ break;
+
+ case 7:
+ // Re-activate player control
+ scene->_sceneMode = 31;
+ scene->_kzin.setAction(&scene->_kzinAction);
+ _globals->_player.enableControl();
+
+ // End this action
+ remove();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene30::KzinAction::signal() {
+ Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1200);
+ break;
+ case 1:
+ _globals->_soundHandler.proc2(0);
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager, _globals->_sceneManager._scene, 31, &scene->_kzin, &scene->_door, NULL);
+ break;
+ case 2:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene30::RingAction::signal() {
+ Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ scene->_kzin.setAction(NULL);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(114, 198);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+
+ case 1:
+ _globals->_player.checkAngle(&scene->_kzin);
+ scene->_stripManager.start(32, this);
+ break;
+
+ case 2: {
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(143, 177);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+
+ case 3:
+ scene->_sound.startSound(11, NULL, 127);
+ scene->_door.animate(ANIM_MODE_6, this);
+ break;
+
+ case 4: {
+ scene->_sound.startSound(13, NULL, 127);
+ NpcMover *kzinMover = new NpcMover();
+ Common::Point pt(354, 5);
+ scene->_kzin.addMover(kzinMover, &pt, this);
+ NpcMover *playerMover = new NpcMover();
+ pt = Common::Point(335, 36);
+ _globals->_player.addMover(playerMover, &pt, this);
+ break;
+ }
+
+ case 5:
+ break;
+
+ case 6:
+ _globals->_sceneManager.changeScene(20);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene30::TalkAction::signal() {
+ Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ scene->_kzin.setAction(NULL);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(114, 198);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_player.checkAngle(&scene->_kzin);
+ scene->_stripManager.start(34, this);
+ break;
+ case 2:
+ setDelay(5);
+ break;
+ case 3:
+ scene->_kzin.setAction(&scene->_kzinAction);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene30::KzinObject::doAction(int action) {
+ Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ display2(30, 12);
+ break;
+ case OBJECT_SCANNER:
+ display2(30, 11);
+ break;
+ case OBJECT_RING:
+ _globals->_inventory._ring._sceneNumber = 30;
+ scene->setAction(&scene->_ringAction);
+ break;
+ case CURSOR_LOOK:
+ display2(30, 6);
+ break;
+ case CURSOR_USE:
+ display2(30, 10);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_talkAction);
+ break;
+ default:
+ SceneObject::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene30::Scene30() :
+ _groundHotspot(9, OBJECT_SCANNER, 50, 17, CURSOR_LOOK, 30, 3, CURSOR_USE, 30, 8, LIST_END),
+ _wallsHotspot(8, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 30, 0, CURSOR_USE, 30, 7, LIST_END),
+ _courtyardHotspot(0, CURSOR_LOOK, 30, 4, LIST_END),
+ _treeHotspot(10, OBJECT_SCANNER, 40, 39, CURSOR_LOOK, 30, 5, CURSOR_USE, 30, 9, LIST_END) {
+}
+
+void Scene30::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ // Add the speaker classes to the strip manager
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerSR);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _speakerSText._npc = &_kzin;
+ _speakerQText._npc = &_globals->_player;
+
+
+ // Setup player
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setStrip(7);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(114, 198));
+ _globals->_player.changeZoom(75);
+ _globals->_player.enableControl();
+
+ // Set up beam object
+ _beam.postInit();
+ _beam.setVisage(31);
+ _beam.setStrip(2);
+ _beam.setPosition(Common::Point(124, 178));
+ _beam.setPriority2(188);
+
+ // Set up door object
+ _door.postInit();
+ _door.setVisage(30);
+ _door.setPosition(Common::Point(150, 183));
+
+ // Final processing and add of scene items
+ _courtyardHotspot.setBounds(Rect(0, 0, 320, 200));
+
+ // Add the objects and hotspots to the scene
+ _globals->_sceneItems.addItems(&_beam, &_wallsHotspot, &_door, &_treeHotspot, &_groundHotspot,
+ &_courtyardHotspot, NULL);
+
+ // Load the scene data
+ loadScene(30);
+ _sceneMode = 0;
+}
+
+void Scene30::signal() {
+ if (_sceneMode == 31) {
+ // Re-activate beam if the Kzin goes back inside
+ _beam.postInit();
+ _beam.setVisage(31);
+ _beam.setStrip(2);
+ _beam.setPosition(Common::Point(124, 178));
+ _beam.setPriority2(188);
+ _globals->_sceneItems.push_front(&_beam);
+ _globals->_player.enableControl();
+ } else if (_sceneMode == 32) {
+ _globals->_player.disableControl();
+ _sceneMode = 31;
+ setAction(&_sequenceManager, _globals->_sceneManager._scene, 31, &_kzin, &_door, NULL);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 40 - Chmeee Home
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene40::Action1::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(120);
+ break;
+ case 1:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(40, this);
+ break;
+ case 2:
+ scene->_doorway.postInit();
+ scene->_doorway.setVisage(46);
+ scene->_doorway.setPosition(Common::Point(305, 61));
+ scene->_doorway.animate(ANIM_MODE_5, this);
+ scene->_soundHandler.startSound(25);
+ break;
+ case 3:
+ scene->_doorway.hide();
+ scene->_dyingKzin.setPosition(Common::Point(296, 62));
+ _globals->_player.animate(ANIM_MODE_5, NULL);
+ scene->_object1.setVisage(43);
+ scene->_object1.setStrip(3);
+ scene->_object1.animate(ANIM_MODE_5, NULL);
+ scene->_object2.hide();
+ scene->_object3.hide();
+ scene->_stripManager.start(45, this);
+ break;
+ case 4:
+ scene->_object2.remove();
+ scene->_object3.remove();
+ scene->_assassin.setVisage(42);
+ scene->_assassin.setStrip(2);
+ scene->_assassin.setFrame(1);
+ scene->_assassin.setPosition(Common::Point(13, 171));
+ scene->_assassin.animate(ANIM_MODE_5, this);
+ scene->_soundHandler.startSound(25);
+ break;
+ case 5:
+ scene->_doorway.show();
+ scene->_doorway.setVisage(42);
+ scene->_doorway.setStrip(3);
+ scene->_doorway.setFrame(1);
+ scene->_doorway.setPosition(Common::Point(41, 144));
+ scene->_assassin.animate(ANIM_MODE_6, NULL);
+ setDelay(6);
+ break;
+ case 6:
+ scene->_doorway.setPosition(Common::Point(178, 101));
+ setDelay(6);
+ break;
+ case 7:
+ scene->_doorway.setPosition(Common::Point(271, 69));
+ setDelay(6);
+ break;
+ case 8:
+ scene->_doorway.remove();
+ scene->_dyingKzin.animate(ANIM_MODE_5, this);
+ break;
+ case 9: {
+ scene->_dyingKzin.setStrip(1);
+ scene->_dyingKzin.setFrame(1);
+ scene->_dyingKzin._moveDiff.y = 15;
+ scene->_dyingKzin.animate(ANIM_MODE_5, NULL);
+ Common::Point pt(223, 186);
+ NpcMover *mover = new NpcMover();
+ scene->_dyingKzin.addMover(mover, &pt, this);
+ break;
+ }
+ case 10: {
+ scene->_soundHandler.startSound(27);
+ Common::Point pt(223, 184);
+ NpcMover *mover = new NpcMover();
+ scene->_dyingKzin.addMover(mover, &pt, this);
+ break;
+ }
+ case 11: {
+ Common::Point pt(223, 186);
+ NpcMover *mover = new NpcMover();
+ scene->_dyingKzin.addMover(mover, &pt, this);
+ break;
+ }
+ case 12: {
+ _globals->_soundHandler.startSound(26);
+ _globals->_player._uiEnabled = true;
+ scene->_assassin.setVisage(42);
+ scene->_assassin.setPosition(Common::Point(4, 191));
+ scene->_assassin.setStrip(1);
+ scene->_assassin.animate(ANIM_MODE_1, NULL);
+ Common::Point pt(230, 187);
+ NpcMover *mover = new NpcMover();
+ scene->_assassin.addMover(mover, &pt, this);
+ break;
+ }
+ case 13:
+ setDelay(180);
+ break;
+ case 14:
+ scene->_assassin.setVisage(45);
+ scene->_assassin.setStrip(1);
+ scene->_assassin.setFrame(1);
+ scene->_assassin.animate(ANIM_MODE_5, this);
+ scene->_soundHandler.startSound(28);
+ break;
+ case 15:
+ _globals->_player.disableControl();
+ scene->_object1.setVisage(40);
+ scene->_object1.setStrip(4);
+ scene->_object1.setFrame(1);
+ scene->_object1.animate(ANIM_MODE_5, NULL);
+ _globals->_player.setVisage(40);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 16:
+ _globals->_soundHandler.startSound(77, this);
+ break;
+ case 17:
+ _globals->_game.endGame(40, 20);
+ remove();
+ break;
+ }
+}
+
+void Scene40::Action2::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ if (scene->_assassin._position.x < 229)
+ _actionIndex = 0;
+ setDelay(1);
+ break;
+ case 1:
+ scene->_assassin.animate(ANIM_MODE_NONE, NULL);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ scene->_soundHandler.startSound(28);
+ scene->_doorway.postInit();
+ scene->_doorway.setVisage(16);
+ scene->_doorway.setStrip2(6);
+ scene->_doorway.setPriority2(200);
+ scene->_doorway.setPosition(Common::Point(159, 191));
+ scene->_doorway._moveDiff = Common::Point(40, 40);
+ scene->_doorway._field7A = 60;
+ scene->_doorway.animate(ANIM_MODE_5, NULL);
+
+ Common::Point pt(271, 165);
+ NpcMover *mover = new NpcMover();
+ scene->_doorway.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ scene->_doorway.remove();
+ scene->_assassin.setVisage(44);
+ scene->_assassin._frame = 1;
+ scene->_assassin.animate(ANIM_MODE_5, this);
+ scene->_soundHandler.startSound(29);
+ _globals->_inventory._infoDisk._sceneNumber = 40;
+ break;
+ case 4:
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 5: {
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(1);
+ Common::Point pt(230, 195);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6: {
+ _globals->_player.setStrip(7);
+ scene->_object1.setVisage(2806);
+ scene->_object1.animate(ANIM_MODE_1, NULL);
+ SceneObjectWrapper *wrapper = new SceneObjectWrapper();
+ scene->_object1.setObjectWrapper(wrapper);
+ Common::Point pt(200, 190);
+ NpcMover *mover = new NpcMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 7:
+ scene->_stripManager.start(44, this);
+ break;
+ case 8: {
+ Common::Point pt(170, 260);
+ NpcMover *mover = new NpcMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 9:
+ scene->_dyingKzin.setAction(&scene->_action7);
+ scene->_object1.remove();
+ _globals->_stripNum = 88;
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.enableControl();
+ scene->_assassin.setAction(&scene->_action8);
+ break;
+ }
+}
+
+void Scene40::Action3::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.setAction(NULL);
+ _globals->_stripNum = 99;
+ _globals->_player.disableControl();
+ Common::Point pt(240, 195);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_player.setVisage(5010);
+ _globals->_player._strip = 2;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_4, 5, 1, this);
+ break;
+ case 2:
+ scene->_assassin.setStrip(2);
+ scene->_assassin.setFrame(1);
+ _globals->_inventory._infoDisk._sceneNumber = 1;
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(7);
+ _globals->_stripNum = 88;
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene40::Action4::signal() {
+ switch (_actionIndex++) {
+ case 0: {
+ Common::Point pt(178, 190);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_stripNum = 88;
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene40::Action5::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(120));
+ break;
+ case 1:
+ scene->_object2.animate(ANIM_MODE_8, 1, this);
+ _actionIndex = 0;
+ }
+}
+
+void Scene40::Action6::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_object1.postInit();
+ scene->_object1.setVisage(16);
+ scene->_object1.setStrip2(6);
+ scene->_object1.setPosition(Common::Point(313, 53));
+ scene->_object1._field7A = 60;
+
+ Common::Point pt(141, 194);
+ NpcMover *mover = new NpcMover();
+ scene->_object1.addMover(mover, &pt, this);
+ scene->_object1.animate(ANIM_MODE_5, NULL);
+
+ scene->_doorway.postInit();
+ scene->_doorway.setVisage(46);
+ scene->_doorway.setPosition(Common::Point(305, 61));
+ scene->_doorway.animate(ANIM_MODE_5, this);
+ scene->_soundHandler.startSound(25);
+ break;
+ }
+ case 1:
+ scene->_soundHandler.startSound(28);
+ scene->_doorway.setPosition(Common::Point(148, 74));
+ scene->_doorway.setFrame(1);
+ scene->_doorway.setStrip(2);
+ scene->_doorway.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ remove();
+ break;
+ }
+}
+
+void Scene40::Action7::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(500));
+ break;
+ case 1:
+ scene->_object7.postInit();
+ scene->_object7.setVisage(46);
+
+ if (_globals->_randomSource.getRandomNumber(32767) >= 16384) {
+ scene->_object7.setStrip(3);
+ scene->_object7.setPosition(Common::Point(15, 185));
+ } else {
+ scene->_object7.setPosition(Common::Point(305, 61));
+ scene->_object7.setFrame(15);
+ }
+ break;
+ case 2:
+ scene->_object7.remove();
+ _actionIndex = 0;
+ setDelay(60);
+ break;
+ }
+}
+
+void Scene40::Action8::signal() {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(300);
+ break;
+ case 1:
+ _globals->_player.disableControl();
+
+ if ((_globals->_player._position.y >= 197) || (_globals->_player._visage)) {
+ _actionIndex = 1;
+ setDelay(30);
+ } else {
+ scene->_doorway.postInit();
+ scene->_doorway.setVisage(16);
+ scene->_doorway.setStrip2(6);
+ scene->_doorway.setPriority2(200);
+ scene->_doorway._field7A = 60;
+
+ if (_globals->_player._position.x >= 145) {
+ scene->_doorway.setPriority2(-1);
+ scene->_doorway.setPosition(Common::Point(6, 157));
+ } else {
+ scene->_doorway.setPosition(Common::Point(313, 53));
+ }
+
+ scene->_doorway._moveDiff = Common::Point(40, 40);
+ Common::Point pt(_globals->_player._position.x, _globals->_player._position.y - 18);
+ NpcMover *mover = new NpcMover();
+ scene->_doorway.addMover(mover, &pt, this);
+ scene->_doorway.animate(ANIM_MODE_5, NULL);
+ }
+ break;
+ case 2:
+ scene->_doorway.remove();
+ _globals->_player.setVisage(40);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->_soundHandler.startSound(77, this);
+ break;
+ case 4:
+ _globals->_game.endGame(40, 45);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene40::DyingKzin::doAction(int action) {
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(40, 43);
+ break;
+ case CURSOR_CROSSHAIRS:
+ SceneItem::display2(40, 44);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(40, 12);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(40, 18);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene40::Assassin::doAction(int action) {
+ Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_CROSSHAIRS:
+ if (scene->_assassin._visage == 44)
+ SceneItem::display2(40, 21);
+ else {
+ _globals->_player.disableControl();
+ Common::Point pt(230, 187);
+ NpcMover *mover = new NpcMover();
+ addMover(mover, &pt, NULL);
+ }
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(40, (scene->_assassin._visage == 44) ? 22 : 23);
+ break;
+ case CURSOR_LOOK:
+ if (scene->_assassin._visage != 44)
+ SceneItem::display2(40, 13);
+ else
+ SceneItem::display2(40, (_globals->_inventory._infoDisk._sceneNumber == 1) ? 19 : 14);
+ break;
+ case CURSOR_USE:
+ if (scene->_assassin._visage != 44)
+ SceneItem::display2(40, 15);
+ else if (_globals->_inventory._infoDisk._sceneNumber == 1)
+ SceneItem::display2(40, 19);
+ else {
+ _globals->_player.disableControl();
+ setAction(&scene->_action3);
+ }
+ break;
+ case CURSOR_TALK:
+ SceneItem::display2(40, 38);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene40::Item2::doAction(int action) {
+ switch (action) {
+ case CURSOR_CROSSHAIRS:
+ SceneItem::display2(40, 35);
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(40, 34);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(40, 8);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(40, 36);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display2(40, 37);
+ break;
+ default:
+ SceneItem::doAction(action);
+ break;
+ }
+}
+
+void Scene40::Item6::doAction(int action) {
+ switch (action) {
+ case CURSOR_CROSSHAIRS:
+ SceneItem::display2(40, 25);
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(40, 42);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(40, 6);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(40, 36);
+ break;
+ default:
+ SceneItem::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene40::Scene40() :
+ _item1(2, OBJECT_SCANNER, 40, 24, CURSOR_CROSSHAIRS, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END),
+ _item3(5, OBJECT_SCANNER, 40, 26, CURSOR_CROSSHAIRS, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END),
+ _item4(6, OBJECT_SCANNER, 40, 31, CURSOR_CROSSHAIRS, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END),
+ _item5(0, CURSOR_LOOK, 40, 11, LIST_END),
+ _item7(4, OBJECT_SCANNER, 40, 26, CURSOR_CROSSHAIRS, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END),
+ _item8(8, OBJECT_SCANNER, 40, 39, CURSOR_CROSSHAIRS, 40, 40, CURSOR_LOOK, 40, 3, CURSOR_USE, 40, 41, LIST_END) {
+}
+
+void Scene40::postInit(SceneObjectList *OwnerList) {
+ loadScene(40);
+ Scene::postInit();
+
+ setZoomPercents(0, 100, 200, 100);
+ _globals->_stripNum = 99;
+
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerGameText);
+
+ _speakerGameText._colour1 = 9;
+ _speakerGameText.setTextPos(Common::Point(160, 30));
+ _speakerQText._npc = &_globals->_player;
+ _speakerSText._npc = &_object1;
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(130, 220));
+ _globals->_player.disableControl();
+
+ if (_globals->_sceneManager._previousScene == 20) {
+ _globals->_soundHandler.startSound(24);
+ _globals->_player.setVisage(43);
+
+ _object1.postInit();
+ _object1.setVisage(41);
+ _object1.setPosition(Common::Point(105, 220));
+ _object2.postInit();
+ _object2.setVisage(41);
+ _object2.setStrip(6);
+ _object2.setPriority2(200);
+ _object2.setPosition(Common::Point(94, 189));
+ _object2.setAction(&_action5);
+
+ _object3.postInit();
+ _object3.setVisage(41);
+ _object3.setStrip(5);
+ _object3.setPriority2(205);
+ _object3.setPosition(Common::Point(110, 186));
+ _object3._numFrames = 2;
+ _object3.animate(ANIM_MODE_8, NULL, NULL);
+
+ _assassin.postInit();
+ _assassin.setPosition(Common::Point(-40, 191));
+ _globals->_sceneItems.push_back(&_assassin);
+
+ _dyingKzin.postInit();
+ _dyingKzin.setVisage(40);
+ _dyingKzin.setStrip(6);
+ _dyingKzin.setPosition(Common::Point(-90, 65));
+ _dyingKzin.setPriority2(170);
+
+ setAction(&_action1);
+ } else {
+ _doorway.postInit();
+ _doorway.setVisage(46);
+ _doorway.setPosition(Common::Point(148, 74));
+ _doorway.setStrip(2);
+ _doorway.setFrame(_doorway.getFrameCount());
+
+ _dyingKzin.postInit();
+ _dyingKzin.setVisage(40);
+ _dyingKzin.setPosition(Common::Point(205, 183));
+ _dyingKzin.setPriority2(170);
+ _dyingKzin._frame = 9;
+ _dyingKzin.setAction(&_action7);
+
+ _assassin.postInit();
+ _assassin.setVisage(44);
+ _assassin.setPosition(Common::Point(230, 187));
+ _assassin.setAction(&_action8);
+
+ if (_globals->_inventory._infoDisk._sceneNumber == 40) {
+ _assassin.setStrip(1);
+ _assassin.setFrame(_assassin.getFrameCount());
+ } else {
+ _assassin.setStrip(2);
+ }
+
+ _globals->_sceneItems.push_back(&_assassin);
+ _globals->_player.setPosition(Common::Point(170, 220));
+
+ setAction(&_action4);
+ }
+
+ _item5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _item6._sceneRegionId = 3;
+ _item2._sceneRegionId = 7;
+
+ _globals->_sceneItems.addItems(&_dyingKzin, &_item8, &_item1, &_item2, &_item3, &_item4,
+ &_item6, &_item7, &_item5, NULL);
+}
+
+void Scene40::signal() {
+ if (_sceneMode == 41)
+ _globals->_sceneManager.changeScene(50);
+}
+
+void Scene40::dispatch() {
+ if ((_globals->_stripNum == 88) && (_globals->_player._position.y >= 197)) {
+ _globals->_player.disableControl();
+ _globals->_stripNum = 0;
+ _globals->_player.setAction(NULL);
+ _sceneMode = 41;
+ setAction(&_sequenceManager, this, 41, &_globals->_player, NULL);
+
+ if (_globals->_sceneManager._previousScene == 20) {
+ _dyingKzin.setAction(&_action6);
+ }
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 50 - By Flycycles
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene50::Action1::signal() {
+ Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setAction(&scene->_sequenceManager, this, 54, &_globals->_player, NULL);
+ break;
+ case 1:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(63, this);
+ break;
+ case 2:
+ if (scene->_stripManager._field2E8 != 107) {
+ _globals->_player.enableControl();
+ remove();
+ } else {
+ Common::Point pt(282, 139);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ }
+ break;
+ case 3:
+ _globals->_stripNum = -1;
+ _globals->_sceneManager.changeScene(60);
+ break;
+ }
+}
+
+void Scene50::Action2::signal() {
+ Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ scene->_stripManager.start(66, this);
+ break;
+ case 1: {
+ Common::Point pt(141, 142);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_sceneManager.changeScene(40);
+ remove();
+ break;
+ }
+}
+
+void Scene50::Action3::signal() {
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ Common::Point pt(136, 185);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_sceneManager.changeScene(60);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene50::Object1::doAction(int action) {
+ Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(50, 20);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(50, 19);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(50, 4);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(50, 21);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 52;
+ scene->setAction(&scene->_sequenceManager, scene, 52, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene50::Object2::doAction(int action) {
+ Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(50, 11);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(50, 10);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(50, 1);
+ break;
+ case OBJECT_INFODISK:
+ case CURSOR_USE:
+ _globals->_stripNum = 50;
+ scene->setAction(&scene->_action3);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene50::Object3::doAction(int action) {
+ Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(50, 11);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(50, 10);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(50, 1);
+ break;
+ case OBJECT_INFODISK:
+ case CURSOR_USE:
+ SceneItem::display2(50, 8);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 52;
+ scene->setAction(&scene->_sequenceManager, scene, 52, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene50::Object4::doAction(int action) {
+ Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(50, 11);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(50, 10);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(50, 1);
+ break;
+ case OBJECT_INFODISK:
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ _globals->_stripNum = 0;
+ scene->_sceneMode = 51;
+ scene->setAction(&scene->_sequenceManager, scene, 51, &_globals->_player, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene50::Scene50() :
+ _item0(0, CURSOR_LOOK, 50, 3, LIST_END),
+ _item1(0, OBJECT_SCANNER, 50, 15, CURSOR_USE, 50, 16, CURSOR_LOOK, 50, 3, LIST_END),
+ _item2(0, CURSOR_LOOK, 50, 7, LIST_END),
+ _item3(8, OBJECT_STUNNER, 50, 14, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 50, 3, LIST_END),
+ _item4(9, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_USE, 40, 41, CURSOR_LOOK, 50, 5, LIST_END),
+ _item5(10, OBJECT_SCANNER, 50, 17, OBJECT_STUNNER, 50, 18, CURSOR_LOOK, 50, 6, CURSOR_USE, 30, 8, LIST_END) {
+}
+
+void Scene50::postInit(SceneObjectList *OwnerList) {
+ loadScene(50);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player._canWalk = false;
+ _globals->_player.changeZoom(75);
+ _globals->_player._moveDiff.y = 3;
+
+ if (_globals->_sceneManager._previousScene == 40) {
+ _globals->_player.setPosition(Common::Point(128, 123));
+ } else if (_globals->_stripNum == 50) {
+ _globals->_player.setPosition(Common::Point(136, 185));
+ } else {
+ _globals->_player.setPosition(Common::Point(270, 143));
+ }
+
+ _object2.postInit();
+ _object2.setVisage(2331);
+ _object2.setStrip(6);
+ _object2.setPosition(Common::Point(136, 192));
+ _object2.setPriority2(200);
+
+ _object3.postInit();
+ _object3.setVisage(2337);
+ _object3.setStrip(6);
+ _object3.setPosition(Common::Point(260, 180));
+ _object3.setPriority2(200);
+
+ _object4.postInit();
+ _object4.setVisage(2331);
+ _object4.setStrip(6);
+ _object4.setPosition(Common::Point(295, 144));
+ _object4.setPriority2(178);
+
+ _globals->_sceneItems.addItems(&_object2, &_object3, &_object4, NULL);
+
+ if (!_globals->getFlag(101)) {
+ _globals->_player.disableControl();
+ _globals->setFlag(101);
+ setAction(&_action1);
+ } else {
+ _globals->_player.enableControl();
+
+ if (_globals->_sceneManager._previousScene == 40) {
+ _globals->_player.disableControl();
+ _sceneMode = 54;
+ setAction(&_sequenceManager, this, 54, &_globals->_player, NULL);
+ }
+ }
+
+ _item0.setBounds(Rect(200, 0, 320, 200));
+ _globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item0, NULL);
+ _doorwayRect = Rect(80, 108, 160, 112);
+}
+
+void Scene50::signal() {
+ switch (_sceneMode) {
+ case 51:
+ _globals->_sceneManager.changeScene(60);
+ break;
+ case 55:
+ _globals->_sceneManager.changeScene(40);
+ break;
+ case 52:
+ case 54:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene50::dispatch() {
+ if ((_sceneMode != 55) && _doorwayRect.contains(_globals->_player._position)) {
+ // Player in house doorway, start player moving to within
+ _globals->_player.disableControl();
+ _sceneMode = 55;
+ Common::Point pt(89, 111);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 60 - Flycycle controls
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene60::Action1::signal() {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_object9.postInit();
+ scene->_object9.setVisage(60);
+ scene->_object9.setStrip(7);
+ scene->_object9.setPosition(Common::Point(136, 65));
+ scene->_object9.animate(ANIM_MODE_5, this);
+
+ scene->_soundHandler1.startSound(35);
+ break;
+ case 2:
+ scene->_object10.postInit();
+ scene->_object10.setVisage(60);
+ scene->_object10.setPosition(Common::Point(199, 186));
+ scene->_object10.animate(ANIM_MODE_8, 0, NULL);
+ scene->_object10._numFrames = 5;
+
+ scene->_object6.animate(ANIM_MODE_2, NULL);
+
+ if (!_globals->getFlag(83)) {
+ scene->_object5.postInit();
+ scene->_object5.setVisage(60);
+ scene->_object5.setStrip2(3);
+ scene->_object5.setFrame(2);
+ scene->_object5.setPosition(Common::Point(148, 85));
+ scene->_object5.animate(ANIM_MODE_2, NULL);
+ scene->_object5._numFrames = 5;
+
+ _globals->_sceneItems.push_front(&scene->_object5);
+ scene->_soundHandler2.startSound(38);
+ }
+
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 3:
+ scene->_soundHandler2.startSound(37);
+ scene->loadScene(65);
+ scene->_object5.remove();
+
+ if (_globals->_sceneObjects->contains(&scene->_object10))
+ scene->_object10.remove();
+
+ scene->_object6.remove();
+ scene->_slaveButton.remove();
+ scene->_object8.remove();
+ scene->_item1.remove();
+ scene->_item2.remove();
+
+ scene->_object3.postInit();
+ scene->_object3.setVisage(65);
+ scene->_object3.setPosition(Common::Point(118, 197));
+
+ scene->_object2.postInit();
+ scene->_object2.setVisage(65);
+ scene->_object2.setStrip(2);
+ scene->_object2.setPosition(Common::Point(160, 197));
+
+ scene->_object4.postInit();
+ scene->_object4.setVisage(65);
+ scene->_object4.setStrip(3);
+ scene->_object4.setPosition(Common::Point(202, 197));
+
+ scene->_object1.postInit();
+ scene->_object1.setVisage(65);
+ scene->_object1.setStrip(4);
+ scene->_object1.setFrame(1);
+ scene->_object1.setPosition(Common::Point(145, 165));
+
+ _globals->_sceneItems.push_front(&scene->_object3);
+ _globals->_sceneItems.push_front(&scene->_object2);
+ _globals->_sceneItems.push_front(&scene->_object4);
+ setDelay(10);
+
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 4:
+ _globals->setFlag(90);
+ // Deliberate fall-through
+ case 5:
+ case 6:
+ case 7:
+ SceneItem::display(60, _actionIndex - 4, SET_Y, 40, SET_X, 25, SET_FONT, 75,
+ SET_EXT_BGCOLOUR, -1, SET_FG_COLOUR, 34, SET_POS_MODE, 0,
+ SET_WIDTH, 280, SET_KEEP_ONSCREEN, 1, LIST_END);
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 9:
+ _globals->_player._uiEnabled = false;
+ _globals->_inventory._infoDisk._sceneNumber = 1;
+
+ if (_globals->_sceneObjects->contains(&scene->_object5))
+ scene->_object5.remove();
+
+ scene->_object6.animate(ANIM_MODE_NONE);
+ scene->_object6.setFrame(1);
+ scene->_object10.remove();
+
+ scene->_object9.postInit();
+ scene->_object9.setVisage(60);
+ scene->_object9.setStrip(7);
+ scene->_object9.setPosition(Common::Point(136, 65));
+ scene->_object9.setFrame(scene->_object9.getFrameCount());
+ scene->_object9.animate(ANIM_MODE_6, this);
+
+ scene->_soundHandler1.startSound(35);
+ scene->_soundHandler3.proc3();
+
+ scene->_object8.setFrame(1);
+ scene->_object8._state = 0;
+
+ _globals->clearFlag(103);
+ _globals->clearFlag(!_globals->_stripNum ? 116 : 119);
+ break;
+ case 10:
+ setDelay(60);
+ break;
+ case 11:
+ _globals->_player._uiEnabled = true;
+ scene->_object9.remove();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene60::Action2::signal() {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ case 2:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_stripManager.start(66, this);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(50);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene60::Object2::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 16);
+ } else if (action == CURSOR_USE) {
+ animate(ANIM_MODE_8, 1, NULL);
+
+ if (scene->_action1.getActionIndex() > 5) {
+ scene->_soundHandler3.startSound(36);
+ scene->_action1.setActionIndex(scene->_action1.getActionIndex() - 2);
+ scene->_action1.setDelay(1);
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::Object3::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 17);
+ } else if (action == CURSOR_USE) {
+ animate(ANIM_MODE_8, 1, NULL);
+
+ if (scene->_action1.getActionIndex() < 8) {
+ scene->_soundHandler3.startSound(36);
+ scene->_action1.setDelay(1);
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::Object4::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 18);
+ } else if (action == CURSOR_USE) {
+ scene->_soundHandler3.startSound(36);
+ animate(ANIM_MODE_8, 1, NULL);
+ scene->_object3.remove();
+ scene->_object2.remove();
+ scene->_object4.remove();
+ scene->_object1.remove();
+
+ SceneItem::display(0, 0);
+ scene->loadScene(60);
+
+ scene->_object6.setVisage(60);
+ scene->_object6.setPosition(Common::Point(233, 143));
+ scene->_object6.animate(ANIM_MODE_2, NULL);
+
+ scene->_slaveButton.postInit();
+ scene->_slaveButton.setVisage(60);
+ scene->_slaveButton.setStrip(8);
+ scene->_slaveButton.setPosition(Common::Point(143, 125));
+
+ scene->_object8.postInit();
+ scene->_object8.setVisage(60);
+ scene->_object8.setStrip(8);
+ scene->_object8.setPosition(Common::Point(143, 105));
+
+ _globals->_sceneItems.push_front(&scene->_object8);
+ _globals->_sceneItems.push_front(&scene->_slaveButton);
+
+ scene->_object10.postInit();
+ scene->_object10.setVisage(60);
+ scene->_object10.setPosition(Common::Point(199, 186));
+ scene->_object10.animate(ANIM_MODE_8, 0, NULL);
+ scene->_object10._numFrames = 5;
+ scene->_object10.setAction(&scene->_sequenceManager, scene, 61, NULL);
+
+ if (scene->_slaveButton._state)
+ scene->_slaveButton.setFrame(2);
+ if (scene->_object8._state)
+ scene->_object8.setFrame(2);
+
+ _globals->_sceneItems.push_front(&scene->_item1);
+ _globals->_sceneItems.push_front(&scene->_object6);
+ _globals->_sceneItems.push_front(&scene->_slaveButton);
+ _globals->_sceneItems.push_front(&scene->_object8);
+ _globals->_sceneItems.push_back(&scene->_item2);
+
+ _globals->gfxManager()._font.setFontNumber(2);
+ _globals->_sceneText._fontNumber = 2;
+
+ scene->_action1.setActionIndex(2);
+ scene->_action1.setDelay(1);
+ scene->_sceneMode = 9999;
+ scene->signal();
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::Object5::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 9);
+ } else if (action == CURSOR_USE) {
+ scene->_action1.setDelay(1);
+ _globals->setFlag(83);
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::Object6::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 11);
+ } else if (action == CURSOR_USE) {
+ if (_animateMode == ANIM_MODE_NONE)
+ SceneItem::display2(60, 14);
+ else if (!scene->_slaveButton._state) {
+ _globals->_soundHandler.startSound(40);
+ _globals->_soundHandler.proc5(1);
+ _globals->_sceneManager.changeScene(20);
+ } else {
+ scene->_sceneMode = 15;
+ setAction(&scene->_sequenceManager, scene, 62, NULL);
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::SlaveObject::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 8);
+ } else if (action == CURSOR_USE) {
+ if (scene->_object8._state)
+ scene->_sceneMode = 19;
+ else if (_state) {
+ scene->_soundHandler3.proc3();
+ animate(ANIM_MODE_6, NULL);
+ _globals->clearFlag(102);
+ _globals->clearFlag(!_globals->_stripNum ? 117 : 120);
+ _state = 0;
+ scene->_sceneMode = 9998;
+ } else {
+ scene->_soundHandler3.startSound(39);
+ _globals->setFlag(102);
+ _globals->setFlag(!_globals->_stripNum ? 117 : 120);
+ animate(ANIM_MODE_5, NULL);
+ _state = 1;
+ scene->_sceneMode = 9998;
+ }
+
+ setAction(&scene->_sequenceManager, scene, 62, NULL);
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::Object8::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 7);
+ } else if (action == CURSOR_USE) {
+ if (!scene->_object8._state)
+ scene->_sceneMode = 14;
+ else if (_state) {
+ scene->_soundHandler3.proc3();
+ animate(ANIM_MODE_6, NULL);
+ _globals->clearFlag(103);
+ _globals->clearFlag(!_globals->_stripNum ? 116 : 119);
+ _state = 0;
+ scene->_sceneMode = 9998;
+ } else {
+ scene->_soundHandler3.startSound(39);
+ animate(ANIM_MODE_5, NULL);
+ _state = 1;
+ _globals->setFlag(103);
+ _globals->setFlag(!_globals->_stripNum ? 116 : 119);
+ scene->_sceneMode = 9998;
+ }
+
+ setAction(&scene->_sequenceManager, scene, 62, NULL);
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene60::Object9::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display2(60, 13);
+ } else if (action == CURSOR_USE) {
+ _globals->setFlag(!_globals->_stripNum ? 118 : 121);
+ scene->setAction(&scene->_action1);
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene60::Item1::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_INFODISK:
+ _globals->_inventory._infoDisk._sceneNumber = 60;
+ _globals->setFlag(!_globals->_stripNum ? 118 : 121);
+ scene->_sceneMode = 0;
+ scene->setAction(&scene->_action1);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(60, 10);
+ break;
+ case CURSOR_USE:
+ if (_globals->_inventory._infoDisk._sceneNumber == 60) {
+ if (_globals->getFlag(118) && !_globals->_stripNum) {
+ _globals->clearFlag(118);
+ scene->setAction(&scene->_action1);
+ scene->_action1.setActionIndex(9);
+ scene->_action1.setDelay(1);
+ }
+ if (_globals->getFlag(121) && !_globals->_stripNum) {
+ _globals->clearFlag(121);
+ scene->setAction(&scene->_action1);
+ scene->_action1.setActionIndex(9);
+ scene->_action1.setDelay(1);
+ }
+ } else if (_globals->_inventory._infoDisk._sceneNumber == 1) {
+ scene->_sceneMode = 0;
+ setAction(&scene->_sequenceManager, scene, 62, NULL);
+ } else {
+ scene->setAction(&scene->_action2);
+ }
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene60::Item::doAction(int action) {
+ Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(60, _messageNum);
+ break;
+ case CURSOR_USE:
+ scene->_sceneMode = _sceneMode;
+ setAction(&scene->_sequenceManager, this, 62, NULL);
+ break;
+ default:
+ SceneItem::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene60::Scene60() :
+ _item2(0, 12, 12),
+ _item3(8, 22, 23),
+ _item4(9, 24, 25),
+ _item5(10, 26, 27),
+ _item6(11, 28, 29) {
+}
+
+void Scene60::postInit(SceneObjectList *OwnerList) {
+ loadScene(60);
+ Scene::postInit();
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_USE);
+
+ _slaveButton.postInit();
+ _slaveButton.setVisage(60);
+ _slaveButton.setStrip(8);
+ _slaveButton.setPosition(Common::Point(143, 125));
+ _slaveButton._state = 0;
+
+ _object8.postInit();
+ _object8.setVisage(60);
+ _object8.setStrip(8);
+ _object8.setPosition(Common::Point(143, 105));
+ _object8._state = 0;
+
+ _globals->_sceneItems.push_back(&_object8);
+ _globals->_sceneItems.push_back(&_slaveButton);
+
+ _object6.postInit();
+ _object6.setVisage(60);
+ _object6.setStrip(5);
+ _object6.setPosition(Common::Point(233, 143));
+ _globals->_sceneItems.push_back(&_object6);
+
+ if (_globals->_stripNum == -1) {
+ _globals->_stripNum = 0;
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 9999;
+ setAction(&_sequenceManager, this, 61, NULL);
+ }
+
+ _item1.setBounds(Rect(130, 55, 174, 70));
+ _item2.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ if (_globals->_stripNum == 0) {
+ if (_globals->getFlag(117)) {
+ _slaveButton._state = 1;
+ _slaveButton.setFrame(2);
+ }
+
+ if (_globals->getFlag(116)) {
+ _object8._state = 1;
+ _object8.setFrame(2);
+ }
+
+ if (_globals->getFlag(118)) {
+ _object6.animate(ANIM_MODE_2, NULL);
+
+ _object10.postInit();
+ _object10.setVisage(60);
+ _object10.setPosition(Common::Point(199, 186));
+ _object10.animate(ANIM_MODE_8, 0, NULL);
+
+ _soundHandler1.startSound(35);
+
+ if (!_globals->getFlag(83)) {
+ _object5.postInit();
+ _object5.setVisage(60);
+ _object5.setStrip2(3);
+ _object5.setFrame(2);
+ _object5.setPosition(Common::Point(148, 85));
+ _object5.animate(ANIM_MODE_2, NULL);
+ _object5._numFrames = 5;
+ _globals->_sceneItems.push_front(&_object5);
+
+ _soundHandler2.startSound(38);
+ }
+ }
+ } else {
+ if (_globals->getFlag(120)) {
+ _slaveButton._state = 1;
+ _slaveButton.setFrame(2);
+ }
+
+ if (_globals->getFlag(119)) {
+ _object8._state = 1;
+ _object8.setFrame(2);
+ }
+
+ if (_globals->getFlag(121)) {
+ _object6.animate(ANIM_MODE_2, NULL);
+
+ _object10.postInit();
+ _object10.setVisage(60);
+ _object10.setPosition(Common::Point(199, 186));
+ _object10.animate(ANIM_MODE_8, 0, NULL);
+ _object10._numFrames = 5;
+
+ _soundHandler1.startSound(35);
+
+ if (!_globals->getFlag(83)) {
+ _object5.postInit();
+ _object5.setVisage(60);
+ _object5.setStrip2(3);
+ _object5.setFrame(2);
+ _object5.setPosition(Common::Point(148, 85));
+ _object5.animate(ANIM_MODE_2, NULL);
+ _object5._numFrames = 5;
+ _globals->_sceneItems.push_front(&_object5);
+
+ _soundHandler2.startSound(38);
+ }
+ }
+ }
+
+ _globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item6,
+ &_item1, &_item2, NULL);
+}
+
+void Scene60::signal() {
+ if (_sceneMode != 0) {
+ if (_sceneMode == 9998) {
+ _globals->_events.setCursor(CURSOR_USE);
+ } else if (_sceneMode == 9999) {
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_USE);
+
+ _gfxButton.setText(EXIT_MSG);
+ _gfxButton._bounds.centre(160, 193);
+ _gfxButton.draw();
+ _gfxButton._bounds.expandPanes();
+ } else {
+ SceneItem::display2(60, _sceneMode);
+ _globals->_events.setCursor(CURSOR_USE);
+ }
+ }
+}
+
+void Scene60::process(Event &event) {
+ Scene::process(event);
+
+ if (_sceneNumber == 60) {
+ if (_gfxButton.process(event))
+ _globals->_sceneManager.changeScene(50);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 90 - Shipyard Entrance
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene90::Action1::signal() {
+ Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ _globals->_scenePalette.addRotation(64, 72, -1);
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(90, this);
+ break;
+ case 2:
+ setDelay(2);
+ break;
+ case 3: {
+ Common::Point pt(278, 191);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 4:
+ scene->_object2.setStrip(3);
+ setDelay(2);
+ break;
+ case 5:
+ scene->_soundHandler2.startSound(58);
+
+ if (scene->_stripManager._field2E8 == 220)
+ scene->_stripManager.start(91, this, scene);
+ else {
+ scene->_stripManager.start(_globals->getFlag(104) ? 93 : 92, this, scene);
+ _actionIndex = 7;
+ }
+ break;
+ case 6:
+ scene->_object2.animate(ANIM_MODE_NONE);
+ _globals->_player._uiEnabled = true;
+ break;
+ case 7:
+ scene->_object2.animate(ANIM_MODE_NONE);
+ _globals->_soundHandler.startSound(56);
+ scene->_object3.animate(ANIM_MODE_5, this);
+ break;
+ case 8: {
+ Common::Point pt(215, 127);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object5.addMover(mover, &pt, this);
+ break;
+ }
+ case 9: {
+ Common::Point pt1(215, 127);
+ PlayerMover *mover1 = new PlayerMover();
+ scene->_object1.addMover(mover1, &pt1, this);
+ Common::Point pt2(86, 62);
+ PlayerMover *mover2 = new PlayerMover();
+ scene->_object5.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 10: {
+ PlayerMover2 *mover = new PlayerMover2();
+ scene->_object1.addMover(mover, 10, 15, &scene->_object5);
+
+ if (!_globals->getFlag(104)) {
+ mover = new PlayerMover2();
+ scene->_object4.addMover(mover, 10, 15, &scene->_object1);
+ }
+ setDelay(60);
+ break;
+ }
+ case 11:
+ _globals->_soundHandler.startSound(57);
+ _globals->_soundHandler.startSound(68);
+ scene->_object3.animate(ANIM_MODE_6, NULL);
+
+ SceneItem::display(90, _globals->getFlag(104) ? 15 : 14,
+ SET_EXT_BGCOLOUR, 13, SET_KEEP_ONSCREEN, -1, SET_X, 120, SET_Y, 20, LIST_END);
+ break;
+ case 12:
+ SceneItem::display(0, 0);
+ _globals->_scenePalette.clearListeners();
+ _globals->_sceneManager.changeScene(95);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene90::Object1::doAction(int action) {
+ Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(90, 7);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 97;
+ setAction(&scene->_sequenceManager, scene, 97, this, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene90::Object2::doAction(int action) {
+ Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_object6.postInit();
+ scene->_object6.setVisage(90);
+ scene->_object6.setStrip(6);
+ scene->_object6.setPosition(Common::Point(184, 210));
+ scene->_object6.hide();
+
+ scene->_sceneMode = 91;
+ scene->_soundHandler1.startSound(59);
+ scene->_soundHandler1.proc5(1);
+ scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_object6, NULL);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(90, 8);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager, scene, 96, this, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene90::Scene90() :
+ _item1(0, CURSOR_LOOK, 90, 9, LIST_END),
+ _item2(0, CURSOR_LOOK, 90, 10, LIST_END),
+ _item3(0, CURSOR_LOOK, 90, 11, LIST_END),
+ _object3(OBJECT_STUNNER, 90, 13, CURSOR_LOOK, 90, 12, CURSOR_USE, 90, 16, LIST_END),
+ _object4(CURSOR_LOOK, 90, 17, LIST_END),
+ _object5(CURSOR_LOOK, 90, 18, CURSOR_USE, 90, 19, LIST_END) {
+}
+
+void Scene90::stripCallback(int v) {
+ Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene;
+
+ if (v == 1)
+ scene->_object2.animate(ANIM_MODE_7, NULL);
+ else if (v == 2)
+ scene->_object2.animate(ANIM_MODE_NONE);
+}
+
+void Scene90::postInit(SceneObjectList *OwnerList) {
+ loadScene(90);
+ Scene::postInit();
+
+ setZoomPercents(70, 10, 180, 100);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerSR);
+
+ _speakerMText._npc = &_object2;
+ _speakerQText._textWidth = 160;
+ _speakerQText._npc = &_object5;
+ _speakerSText._npc = &_object1;
+
+ _object5.postInit();
+ _object5.setVisage(2333);
+ _object5.setObjectWrapper(new SceneObjectWrapper());
+ _object5._strip = 7;
+ _object5._moveDiff = Common::Point(22, 22);
+ _object5.setPosition(Common::Point(151, 177));
+ _object5.changeZoom(-1);
+ _globals->_sceneItems.push_back(&_object5);
+
+ _object1.postInit();
+ _object1.setVisage(2337);
+ _object1.setObjectWrapper(new SceneObjectWrapper());
+ _object1._strip = 4;
+ _object1._moveDiff = Common::Point(20, 20);
+ _object1.setPosition(Common::Point(212, 183));
+ _object1.changeZoom(-1);
+ _globals->_sceneItems.push_back(&_object1);
+
+ if (!_globals->getFlag(104)) {
+ _object4.postInit();
+ _object4.setVisage(2331);
+ _object4.setObjectWrapper(new SceneObjectWrapper());
+ _object4._strip = 4;
+ _object4._moveDiff = Common::Point(20, 20);
+ _object4.setPosition(Common::Point(251, 207));
+ _object4.changeZoom(-1);
+ _globals->_sceneItems.push_back(&_object4);
+ }
+
+ _object2.postInit();
+ _object2.setVisage(90);
+ _object2.animate(ANIM_MODE_1, NULL);
+ _object2.setPosition(Common::Point(315, 185));
+ _object2._strip = 2;
+ _globals->_sceneItems.push_back(&_object2);
+
+ _object3.postInit();
+ _object3.setVisage(90);
+ _object3.animate(ANIM_MODE_1, NULL);
+ _object3.setPosition(Common::Point(196, 181));
+ _object3.setPriority2(175);
+ _globals->_sceneItems.push_back(&_object3);
+
+ _globals->_player.disableControl();
+ _globals->_soundHandler.startSound(55);
+ _soundHandler1.startSound(52);
+ _soundHandler1.proc5(1);
+
+ setAction(&_action1);
+
+ _item3.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _item1.setBounds(Rect(271, 65, 271, 186));
+ _item2.setBounds(Rect(0, 17, 124, 77));
+
+ _globals->_sceneItems.addItems(&_item1, &_item2, &_item3, NULL);
+}
+
+void Scene90::signal() {
+ switch (_sceneMode) {
+ case 91:
+ _sceneMode = 92;
+ _globals->_soundHandler.startSound(77, this);
+ break;
+ case 92:
+ _globals->_scenePalette.clearListeners();
+ _globals->_game.endGame(90, 6);
+ break;
+ case 96:
+ _globals->_player.enableControl();
+ break;
+ case 97:
+ _stripManager._field2E8 = 0;
+ _action1.setActionIndex(5);
+ _action1.setDelay(1);
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 95 - Ship Close-up
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene95::Action1::signal() {
+ Scene95 *scene = (Scene95 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _state = 6;
+ setDelay(60);
+ break;
+ case 1:
+ if (_state) {
+ SceneItem::display(95, _state % 2, SET_FONT, 2,
+ SET_EXT_BGCOLOUR, -1, SET_EXT_BGCOLOUR, 20,
+ SET_WIDTH, 200, SET_KEEP_ONSCREEN, 1, SET_TEXT_MODE, 1, LIST_END);
+ --_state;
+ _actionIndex = 1;
+ }
+ setDelay(60);
+ break;
+ case 2: {
+ scene->_soundHandler.startSound(66);
+ scene->_object3._numFrames = 5;
+ scene->_object3.animate(ANIM_MODE_5, NULL);
+ SceneItem::display(0, 0);
+
+ Common::Point pt1(5, 198);
+ NpcMover *mover1 = new NpcMover();
+ _globals->_player.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(9, 190);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object1.addMover(mover2, &pt2, NULL);
+ break;
+ }
+ case 3: {
+ scene->_soundHandler.startSound(21);
+
+ Common::Point pt1(235, 72);
+ PlayerMover *mover1 = new PlayerMover();
+ _globals->_player.addMover(mover1, &pt1, NULL);
+
+ Common::Point pt2(235, 72);
+ PlayerMover *mover2 = new PlayerMover();
+ scene->_object1.addMover(mover2, &pt2, NULL);
+
+ SceneItem::display(95, 2, SET_Y, 45, SET_FONT, 2,
+ SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 13, SET_WIDTH, 200,
+ SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(240);
+ break;
+ }
+ case 4:
+ scene->_object3.remove();
+
+ SceneItem::display(95, 3, SET_Y, 45, SET_FONT, 2,
+ SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 35, SET_WIDTH, 200,
+ SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(240);
+ break;
+ case 5:
+ SceneItem::display(95, 4, SET_Y, 45, SET_FONT, 2,
+ SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 35, SET_WIDTH, 200,
+ SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(240);
+ break;
+ case 6:
+ setDelay(20);
+ break;
+ case 7: {
+ SceneItem::display(0, 0);
+ _globals->_player.setVisage(92);
+ _globals->_player.setPosition(Common::Point(-25, 200));
+ scene->_object1.setVisage(91);
+ scene->_object1.setPosition(Common::Point(-22, 220));
+
+ scene->_soundHandler.startSound(21);
+
+ Common::Point pt1(5, 198);
+ NpcMover *mover1 = new NpcMover();
+ _globals->_player.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(9, 190);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object1.addMover(mover2, &pt2, NULL);
+ break;
+ }
+ case 8: {
+ Common::Point pt1(108, 112);
+ PlayerMover *mover1 = new PlayerMover();
+ _globals->_player.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(108, 112);
+ PlayerMover *mover2 = new PlayerMover();
+ scene->_object1.addMover(mover2, &pt2, NULL);
+ break;
+ }
+ case 9:
+ _globals->_sceneManager.changeScene(2300);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene95::Scene95() {
+}
+
+void Scene95::postInit(SceneObjectList *OwnerList) {
+ loadScene(95);
+ Scene::postInit();
+ setZoomPercents(100, 10, 200, 100);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2337);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player._strip = 4;
+ _globals->_player._moveDiff = Common::Point(30, 30);
+ _globals->_player.setPosition(Common::Point(-35, 200));
+ _globals->_player.changeZoom(-1);
+ _globals->_player.disableControl();
+
+ _object1.postInit();
+ _object1.setVisage(2333);
+ _object1.setPosition(Common::Point(-22, 220));
+ _object1.animate(ANIM_MODE_1, NULL);
+ _object1.setObjectWrapper(new SceneObjectWrapper());
+ _object1._moveDiff = Common::Point(30, 30);
+ _object1.changeZoom(-1);
+
+ _object3.postInit();
+ _object3.setVisage(96);
+ _object3.setPosition(Common::Point(29, 198));
+
+ _soundHandler.startSound(67);
+ setAction(&_action1);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 6100 - Sunflower navigation sequence
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene6100::Action1::signal() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->showMessage(SCENE6100_CAREFUL, 13, this);
+ break;
+ case 1:
+ scene->showMessage(SCENE6100_TOUGHER, 35, this);
+ break;
+ case 2:
+ scene->showMessage(NULL, 0, NULL);
+ remove();
+ break;
+ }
+}
+
+void Scene6100::Action2::signal() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->showMessage(SCENE6100_ONE_MORE_HIT, 13, this);
+ break;
+ case 1:
+ scene->showMessage(SCENE6100_DOING_BEST, 35, this);
+ break;
+ case 2:
+ scene->showMessage(NULL, 0, NULL);
+ remove();
+ break;
+ }
+}
+
+void Scene6100::Action3::signal() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_speed = 0;
+ setDelay(60);
+ break;
+ case 1:
+ _globals->_scenePalette.clearListeners();
+ scene->_fadePercent = 0;
+ _globals->_scenePalette.refresh();
+ scene->loadScene(9997);
+ scene->_object1.hide();
+ scene->_object2.hide();
+ scene->_object3.hide();
+ scene->_sunflower1.hide();
+ scene->_sunflower2.hide();
+ scene->_sunflower3.hide();
+ scene->_rocks.hide();
+ scene->_sceneText.hide();
+
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(8120, this);
+ break;
+ case 2:
+ scene->showMessage(SCENE6100_REPAIR, 7, this);
+ break;
+ case 3:
+ scene->showMessage(NULL, 0, NULL);
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(8130, this);
+ break;
+ case 4:
+ _globals->setFlag(76);
+ _globals->_sceneManager.changeScene(
+ (scene->_stripManager._field2E8 == 135) ? 6100 : 2320);
+ remove();
+ break;
+ }
+}
+
+void Scene6100::Action4::signal() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->showMessage(SCENE6100_ROCKY_AREA, 13, this);
+ break;
+ case 1:
+ scene->showMessage(SCENE6100_REPLY, 35, this);
+ break;
+ case 2:
+ scene->showMessage(NULL, 0, NULL);
+ remove();
+ break;
+ }
+}
+
+void Scene6100::Action5::dispatch() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+ FloatSet zeroSet;
+ const double MULTIPLY_FACTOR = 0.01744; // 2 * pi / 360
+
+ if (scene->_turnAmount) {
+ scene->_angle = (scene->_turnAmount + scene->_angle) % 360;
+
+ for (int objIndex = 1; objIndex <= 3; ++objIndex) {
+ SceneObject *obj = &scene->_object1;
+ if (objIndex == 2) obj = &scene->_object2;
+ if (objIndex == 3) obj = &scene->_object3;
+
+ obj->_position.x += scene->_turnAmount * 2;
+ if (obj->_position.x >= 320)
+ obj->_position.x -= 480;
+ if (obj->_position.x < -160)
+ obj->_position.x += 480;
+ }
+ }
+
+ scene->_object1._flags |= OBJFLAG_PANES;
+ scene->_object2._flags |= OBJFLAG_PANES;
+ scene->_object3._flags |= OBJFLAG_PANES;
+
+ double distance = scene->_speed;
+ double angle = (double)scene->_angle * MULTIPLY_FACTOR;
+ scene->_probe._floats._float1 += sin(angle) * distance;
+ scene->_probe._floats._float2 += cos(angle) * distance;
+
+ for (int idx = 0; idx < 4; ++idx) {
+ FloatSet tempSet = scene->_objList[idx]->_floats;
+ tempSet.add(-scene->_probe._floats._float1, -scene->_probe._floats._float2,
+ -scene->_probe._floats._float3);
+
+ tempSet.proc1(scene->_angle * MULTIPLY_FACTOR);
+
+ double sqrtVal = tempSet.sqrt(zeroSet);
+ if (sqrtVal != 0.0) {
+ scene->_objList[idx]->_position.y = static_cast<int>(13800.0 / sqrtVal + 62.0);
+ }
+
+ scene->_objList[idx]->_position.x = static_cast<int>(
+ 160.0 - (330.0 / (tempSet._float2 + 330.0) * tempSet._float1));
+ scene->_objList[idx]->dispatch();
+
+ if (tempSet._float2 < 0) {
+ scene->_objList[idx]->_position.y = 300;
+
+ if (idx != 3) {
+ scene->_objList[idx]->_floats._float1 =
+ _globals->_randomSource.getRandomNumber(199);
+ scene->_objList[idx]->_floats._float2 =
+ _globals->_randomSource.getRandomNumber(999) + 750.0;
+
+ scene->_objList[idx]->_floats.proc1(
+ -(scene->_turnAmount * 10 + scene->_angle) * MULTIPLY_FACTOR);
+ scene->_objList[idx]->_floats.add(scene->_probe._floats._float1,
+ scene->_probe._floats._float2, scene->_probe._floats._float3);
+ }
+ }
+
+ if (idx == 3) {
+ scene->_rocksCheck = (ABS((int)tempSet._float1) < 100) && (tempSet._float2 > 0);
+ }
+
+ scene->_objList[idx]->_flags |= OBJFLAG_PANES;
+/*
+ if ((idx != 3) && (scene->_fadePercent == 100) &&
+ (tempSet.sqrt(floatSet) < 150.0)) {
+ switch (scene->_hitCount++) {
+ case 1:
+ scene->_soundHandler.startSound(233);
+ scene->showMessage(0, NULL, 0);
+
+ if (!_globals->getFlag(76))
+ scene->_object5.setAction(&scene->_action2);
+
+ case 2:
+ scene->_soundHandler.startSound(234);
+ scene->showMessage(0, NULL, 0);
+
+ if (!_globals->getFlag(76))
+ scene->_object5.setAction(NULL);
+ scene->setAction(&scene->_action3);
+ break;
+
+ default:
+ scene->_soundHandler.startSound(233);
+ scene->showMessage(0, NULL, 0);
+
+ if (!_globals->getFlag(76))
+ scene->_object5.setAction(&scene->_action1);
+ break;
+ }
+
+ _globals->_scenePalette.clearListeners();
+ scene->_fadePercent = 0;
+ }
+ */
+ }
+}
+
+void Scene6100::GetBoxAction::signal() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_turnAmount = 0;
+ Common::Point pt(scene->_rocks._position.x, scene->_rocks._position.y + 10);
+ ProbeMover *mover = new ProbeMover();
+ scene->_probe.addMover(mover, &pt, NULL);
+ scene->_probe.show();
+ break;
+ }
+ case 1: {
+ scene->showMessage(SCENE6100_TAKE_CONTROLS, 35, this);
+ _globals->_scenePalette.clearListeners();
+
+ Common::Point pt(scene->_rocks._position.x, scene->_rocks._position.y - 10);
+ NpcMover *mover = new NpcMover();
+ scene->_probe.addMover(mover, &pt, NULL);
+ break;
+ }
+ case 2:
+ scene->_probe._percent = 4;
+ scene->showMessage(SCENE6100_SURPRISE, 13, this);
+ break;
+ case 3:
+ scene->showMessage(SCENE6100_SWEAT, 35, this);
+ break;
+ case 4:
+ scene->showMessage(SCENE6100_VERY_WELL, 13, this);
+ break;
+ case 5:
+ scene->showMessage(NULL, 0, NULL);
+ _globals->_sceneManager.changeScene(2320);
+ remove();
+ }
+}
+
+void Scene6100::GetBoxAction::dispatch() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ if (!scene->_probe._mover && (scene->_getBoxAction._actionIndex >= 1)) {
+ if (scene->_getBoxAction._actionIndex == 1) {
+ scene->_speed = 0;
+ scene->_getBoxAction.signal();
+ }
+
+ if (scene->_probe._percent > 4)
+ // Handle the probe disappearing into the rocks
+ scene->_probe._percent = scene->_probe._percent * 7 / 8;
+ scene->_probe._flags |= OBJFLAG_PANES;
+ }
+
+ Action::dispatch();
+}
+
+void Scene6100::Action7::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ setDelay(90);
+ break;
+ case 2:
+ _globals->_sceneManager.changeScene(2100);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene6100::ProbeMover::dispatch() {
+ Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene;
+
+ if (!dontMove()) {
+ if (scene->_speed > 0) {
+ scene->_action5.dispatch();
+ scene->_speed = (scene->_speed * 4) / 5;
+ }
+ }
+
+ NpcMover::dispatch();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene6100::Item1::doAction(int action) {
+ SceneItem::display2(4000, 0);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene6100::postInit(SceneObjectList *OwnerList) {
+ loadScene(6100);
+ Scene::postInit();
+ setZoomPercents(62, 2, 200, 425);
+
+ _globals->_player.disableControl();
+ _globals->_events.setCursor(CURSOR_WALK);
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerSL);
+
+ _object1.postInit();
+ _object1.setVisage(6100);
+ _object1._frame = 1;
+ _object1._strip = 4;
+ _object1.setPosition(Common::Point(0, 60));
+ _object1.setPriority2(1);
+
+ _object2.postInit();
+ _object2.setVisage(6100);
+ _object2._frame = 1;
+ _object2._strip = 4;
+ _object2.setPosition(Common::Point(160, 60));
+ _object2.setPriority2(1);
+
+ _object3.postInit();
+ _object3.setVisage(6100);
+ _object3._frame = 1;
+ _object3._strip = 4;
+ _object3.setPosition(Common::Point(320, 60));
+ _object3.setPriority2(1);
+
+ _rocks.postInit();
+ _rocks.setVisage(6100);
+ _rocks._frame = 1;
+ _rocks._strip = 3;
+ _rocks.setPosition(Common::Point(320, 0));
+ _rocks.setPriority2(2);
+ _rocks.changeZoom(-1);
+ _rocks._floats._float1 = 320.0;
+ _rocks._floats._float2 = 25000.0;
+ _rocks._floats._float3 = 0.0;
+
+ _probe.postInit();
+ _probe._moveDiff = Common::Point(15, 15);
+ _probe.setVisage(6100);
+ _probe._frame = 1;
+ _probe._strip = 5;
+ _probe.setPosition(Common::Point(160, 260));
+ _probe.setPriority2(3);
+ _probe._floats._float1 = 320.0;
+ _probe._floats._float2 = 0.0;
+ _probe._floats._float3 = 0.0;
+ _probe.hide();
+
+ _objList[0] = &_sunflower1;
+ _objList[1] = &_sunflower2;
+ _objList[2] = &_sunflower3;
+ _objList[3] = &_rocks;
+
+ int baseVal = 2000;
+ for (int idx = 0; idx < 3; ++idx) {
+ _objList[idx]->_floats._float1 = _globals->_randomSource.getRandomNumber(999);
+ _objList[idx]->_floats._float2 = baseVal;
+ _objList[idx]->_floats._float3 = 0.0;
+ baseVal += _globals->_randomSource.getRandomNumber(499);
+
+ _objList[idx]->postInit();
+ _objList[idx]->setVisage(6100);
+ _objList[idx]->_frame = 1;
+ _objList[idx]->_strip = 2;
+
+ _objList[idx]->setPosition(Common::Point(
+ _globals->_randomSource.getRandomNumber(319), 60));
+ _objList[idx]->setPriority2(1);
+ _objList[idx]->changeZoom(-1);
+ }
+
+ _speed = 30;
+ _fadePercent = 100;
+ _rocksCheck = false;
+ _hitCount = 0;
+ _turnAmount = 0;
+ _angle = 0;
+ _msgActive = false;
+
+ setAction(&_action5);
+ _globals->_scenePalette.addRotation(96, 143, -1);
+
+ if (!_globals->getFlag(76))
+ _probe.setAction(&_action4);
+
+ _globals->_soundHandler.startSound(231);
+}
+
+void Scene6100::remove() {
+ _globals->_player.disableControl();
+ _globals->_scenePalette.clearListeners();
+ Scene::remove();
+}
+
+void Scene6100::process(Event &event) {
+ Scene::process(event);
+
+ if (event.eventType == EVENT_KEYPRESS) {
+ // Handle incremental turning speeds with arrow keys
+ if ((event.kbd.keycode == Common::KEYCODE_LEFT) || (event.kbd.keycode == Common::KEYCODE_KP4)) {
+ _turnAmount = MAX(_turnAmount - 1, -8);
+ } else if ((event.kbd.keycode == Common::KEYCODE_RIGHT) || (event.kbd.keycode == Common::KEYCODE_KP6)) {
+ _turnAmount = MIN(_turnAmount + 1, -8);
+ }
+ }
+
+ if (_probe._action)
+ _probe._action->process(event);
+}
+
+void Scene6100::dispatch() {
+ Scene::dispatch();
+
+ if (_probe._action)
+ _probe._action->dispatch();
+
+ // Handle mouse controlling the turning
+ int changeAmount = (_globals->_events._mousePos.x - 160) / -20;
+ _turnAmount += (changeAmount - _turnAmount) / 2;
+
+ if (_fadePercent < 100) {
+ _fadePercent += 10;
+ if (_fadePercent >= 100) {
+ _globals->_scenePalette.addRotation(96, 143, -1);
+ _fadePercent = 100;
+ }
+
+ byte adjustData[] = {0xff, 0xff, 0xff, 0};
+ _globals->_scenePalette.fade(adjustData, false, _fadePercent);
+ }
+
+ if (_action != &_action3) {
+ // Display the distance remaining to the target
+ int distance = (int)_probe._floats.sqrt(_rocks._floats);
+ Common::String s = Common::String::format("%06d", distance);
+
+ _sceneText.setPosition(Common::Point(24, 160));
+ _sceneText._fontNumber = 0;
+ _sceneText._colour1 = 35;
+ _sceneText.setup(s);
+ }
+
+ if (_rocksCheck && (_action == &_action5)) {
+ // Check whether the probe is close enough to the rocks
+ double distance = _probe._floats.sqrt(_rocks._floats);
+
+ if ((distance >= 300.0) && (distance <= 500.0))
+ setAction(&_getBoxAction);
+ }
+}
+
+void Scene6100::showMessage(const Common::String &msg, int colour, Action *action) {
+ if (_msgActive) {
+ _msgActive = false;
+ _speaker1.removeText();
+ }
+
+ if (!msg.empty()) {
+ _msgActive = true;
+ _speaker1._textPos.x = 20;
+ _speaker1._textWidth = 280;
+ _speaker1._colour1 = colour;
+ _speaker1._action = action;
+ _speaker1.setText(msg);
+ }
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes1.h b/engines/tsage/ringworld_scenes1.h
new file mode 100644
index 0000000000..b567aeea2d
--- /dev/null
+++ b/engines/tsage/ringworld_scenes1.h
@@ -0,0 +1,557 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES1_H
+#define TSAGE_RINGWORLD_SCENES1_H
+
+#include "common/scummsys.h"
+#include "tsage/ringworld_logic.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+class Scene10 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ Speaker _speakerSText;
+ Speaker _speakerQText;
+ Action1 _action1;
+ Action2 _action2;
+ SceneObject _object1, _object2, _object3;
+ SceneObject _object4, _object5, _object6;
+
+ virtual void stripCallback(int v);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene15 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ virtual void dispatch();
+ };
+public:
+ Action1 _action1;
+ SceneObject _object1;
+ SoundHandler _soundHandler;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene20 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ SequenceManager _sequenceManager;
+ SpeakerQText _speakerQText;
+ SpeakerGameText _speakerGameText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ SceneObject _sceneObject1, _SceneObjectExt, _sceneObject3, _sceneObject4, _sceneObject5;
+ SoundHandler _sound;
+public:
+ Scene20();
+ virtual ~Scene20() {}
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene30 : public Scene {
+ /* Scene objects */
+ // Doorway beam sensor
+ class BeamObject : public SceneObject {
+ public:
+ virtual void doAction(int action) {
+ if (action == OBJECT_SCANNER)
+ display(30, 14, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else if (action == CURSOR_LOOK)
+ display(30, 2, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else if (action == CURSOR_USE) {
+ Scene30 *parent = (Scene30 *)_globals->_sceneManager._scene;
+ parent->setAction(&parent->_beamAction);
+ } else
+ SceneObject::doAction(action);
+ }
+ };
+
+ // Doorway object
+ class DoorObject : public SceneObject {
+ public:
+ virtual void doAction(int action) {
+ if (action == OBJECT_SCANNER)
+ display(30, 13, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else if (action == CURSOR_LOOK)
+ display(30, 1, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else if (action == CURSOR_USE)
+ display(30, 7, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneObject::doAction(action);
+ }
+ };
+
+ // Kzin object
+ class KzinObject : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+ /* Actions */
+ class BeamAction : public Action {
+ public:
+ virtual void signal();
+ };
+ class KzinAction : public Action {
+ public:
+ virtual void signal();
+ };
+ class RingAction : public Action {
+ public:
+ virtual void signal();
+ };
+ class TalkAction : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SoundHandler _sound;
+ DisplayHotspot _groundHotspot, _wallsHotspot, _courtyardHotspot, _treeHotspot;
+ BeamObject _beam;
+ DoorObject _door;
+ KzinObject _kzin;
+
+ BeamAction _beamAction;
+ KzinAction _kzinAction;
+ RingAction _ringAction;
+ TalkAction _talkAction;
+ SequenceManager _sequenceManager;
+
+ SpeakerSR _speakerSR;
+ SpeakerQL _speakerQL;
+ SpeakerSText _speakerSText;
+ SpeakerQText _speakerQText;
+public:
+ Scene30();
+ virtual ~Scene30() {}
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene40 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Objects */
+ class DyingKzin : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Assassin : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+ /* Items */
+ class Item2 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+ class Item6 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+ class Item8 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SpeakerSL _speakerSL;
+ SpeakerQR _speakerQR;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ SpeakerGameText _speakerGameText;
+ SoundHandler _soundHandler;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ SceneObject _object1, _object2, _object3;
+ DyingKzin _dyingKzin;
+ Assassin _assassin;
+ SceneObject _doorway, _object7, _object8;
+ DisplayHotspot _item1;
+ Item2 _item2;
+ DisplayHotspot _item3, _item4, _item5;
+ Item6 _item6;
+ DisplayHotspot _item7, _item8;
+
+ Scene40();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene50 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Objects */
+ class Object1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SequenceManager _sequenceManager;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Object1 _object1;
+ Object2 _object2;
+ Object3 _object3;
+ Object4 _object4;
+ Rect _doorwayRect;
+ SpeakerSText _speakerSText;
+ SpeakerQText _speakerQText;
+ DisplayHotspot _item0, _item1, _item2;
+ DisplayHotspot _item3, _item4, _item5;
+
+ Scene50();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene60 : public Scene {
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Object2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class SlaveObject : public SceneObjectExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object8 : public SceneObjectExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object9 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Item1 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class Item : public SceneHotspot {
+ public:
+ int _messageNum, _sceneMode;
+
+ Item(int sceneRegionId, int messageNum, int sceneMode) {
+ _sceneRegionId = sceneRegionId;
+ _messageNum = messageNum;
+ _sceneMode = sceneMode;
+ }
+ virtual void doAction(int action);
+ };
+
+public:
+ GfxButton _gfxButton;
+ SequenceManager _sequenceManager;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ Action1 _action1;
+ Action2 _action2;
+ SceneObject _object1;
+ Object2 _object2;
+ Object3 _object3;
+ Object4 _object4;
+ Object5 _object5;
+ Object6 _object6;
+ SlaveObject _slaveButton;
+ Object8 _object8;
+ Object9 _object9;
+ SceneObject _object10;
+ Item1 _item1;
+ Item _item2, _item3, _item4, _item5, _item6;
+ SoundHandler _soundHandler1;
+ SoundHandler _soundHandler2;
+ SoundHandler _soundHandler3;
+
+ Scene60();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene90 : public Scene {
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Object1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SpeakerSText _speakerSText;
+ SpeakerQText _speakerQText;
+ SpeakerQL _speakerQL;
+ SpeakerSR _speakerSR;
+ SpeakerMText _speakerMText;
+ Action1 _action1;
+ Object1 _object1;
+ Object2 _object2;
+ DisplayObject _object3, _object4, _object5;
+ SceneObject _object6;
+ DisplayHotspot _item1, _item2, _item3;
+ SoundHandler _soundHandler1, _soundHandler2;
+
+ Scene90();
+
+ virtual void stripCallback(int v);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene95 : public Scene {
+ class Action1 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+
+public:
+ Action1 _action1;
+ int _field326;
+ SceneObject _object1, _object2, _object3;
+ SoundHandler _soundHandler;
+
+ Scene95();
+ virtual void postInit(SceneObjectList *OwnerList);
+};
+
+class Scene6100 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void dispatch();
+ };
+ class GetBoxAction : public Action {
+ public:
+ virtual void signal();
+ virtual void dispatch();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Objects */
+ class Object : public SceneObject {
+ public:
+ FloatSet _floats;
+ };
+ class ProbeMover : public NpcMover {
+ public:
+ virtual void dispatch();
+ };
+
+ /* Items */
+ class Item1 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ GetBoxAction _getBoxAction;
+ Action7 _action7;
+ SoundHandler _soundHandler;
+ Speaker _speaker1;
+ SpeakerQR _speakerQR;
+ SpeakerSL _speakerSL;
+ SceneObject _object1, _object2, _object3;
+ Object _rocks, _probe;
+ Object _sunflower1, _sunflower2, _sunflower3;
+ SceneText _sceneText;
+ SceneItem _item1;
+
+ int _turnAmount, _angle, _speed, _fadePercent;
+ int _hitCount;
+ bool _rocksCheck;
+ Object *_objList[4];
+ bool _msgActive;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void process(Event &event);
+ virtual void dispatch();
+ void showMessage(const Common::String &msg, int colour, Action *action);
+
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes10.cpp b/engines/tsage/ringworld_scenes10.cpp
new file mode 100644
index 0000000000..30a0ffd34e
--- /dev/null
+++ b/engines/tsage/ringworld_scenes10.cpp
@@ -0,0 +1,2064 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "graphics/cursorman.h"
+#include "tsage/ringworld_scenes10.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+Scene2::Scene2() : Scene() {
+ _sceneState = 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Object9350::postInit(SceneObjectList *OwnerList) {
+ _globals->_sceneManager.postInit(&_globals->_sceneManager._altSceneObjects);
+}
+
+void Object9350::draw() {
+ reposition();
+ Rect destRect = _bounds;
+ destRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y);
+ Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(_globals->_sceneManager._scene->_stripManager._stripNum);
+ GfxSurface frame = getFrame();
+ _globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9100
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9100::SceneHotspot1::doAction(int action) {
+ Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_TALK) {
+ if (_globals->getFlag(23)) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9104;
+ } else {
+ _globals->setFlag(23);
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9105;
+ }
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &_globals->_player, &scene->_object5, &scene->_object6, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9100::dispatch() {
+ Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene;
+
+ if (!_action) {
+ if (_globals->_player._position.x < 25) {
+ if (!_globals->getFlag(11)) {
+ scene->_sceneMode = 9106;
+ } else {
+ scene->_sceneMode = 9108;
+ _globals->setFlag(11);
+ }
+ } else {
+ scene->_sceneMode = 9106;
+ }
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &_globals->_player, 0);
+ } else {
+ Scene::dispatch();
+ }
+}
+
+void Scene9100::signal() {
+ Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene;
+
+ switch (scene->_sceneMode) {
+ case 9102:
+ case 9106:
+ case 9108:
+ _globals->_sceneManager.changeScene(9150);
+ break;
+ case 9105:
+ _sceneHotspot1.remove();
+ // No break on purpose
+ case 9103:
+ case 9104:
+ case 9107:
+ case 9109:
+ default:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene9100::postInit(SceneObjectList *OwnerList) {
+ Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene;
+
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+ _object1.postInit();
+ _object1.setVisage(9100);
+ _object1._strip = 1;
+ _object1._numFrames = 6;
+ _object1.setPosition(Common::Point(297, 132), 0);
+ _object1.animate(ANIM_MODE_2, 0);
+ _object1.setPriority2(10);
+
+ _globals->_player.postInit();
+
+ _object2.postInit();
+ _object2.hide();
+
+ _object3.postInit();
+ _object3.hide();
+
+ _object4.postInit();
+ _object4.hide();
+
+ _object5.postInit();
+ _object5.hide();
+
+ if (!_globals->getFlag(23)) {
+ _object6.postInit();
+ _object6.setVisage(9111);
+ _object6.setStrip(6);
+ _object6.setFrame(1);
+ _object6.setPosition(Common::Point(138, 166), 0);
+ _sceneHotspot3.setup(145, 125, 166, 156, 9100, 40, 43);
+ }
+ _sceneHotspot1.setup(140, 176, 185, 215, 9100, 36, 37);
+ _sceneHotspot2.setup(161, 138, 182, 175, 9100, 38, 39);
+ _sceneHotspot4.setup(37, 196, 47, 320, 9100, 44, -1);
+ _sceneHotspot5.setup(69, 36, 121, 272, 9100, 45, 46);
+ _sceneHotspot6.setup(127, 0, 200, 52, 9100, 47, 48);
+
+ _globals->_soundHandler.startSound(251, 0, 127);
+ if (_globals->_sceneManager._previousScene == 9150) {
+ if (_globals->getFlag(20)) {
+ _globals->_player.disableControl();
+ if (_globals->getFlag(11))
+ _sceneMode = 9107;
+ else
+ _sceneMode = 9109;
+ setAction(&scene->_sequenceManager, scene, _sceneMode, &_globals->_player, &_object5, 0);
+ } else {
+ _sceneMode = 9103;
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager, scene, _sceneMode, &_globals->_player, &_object2, &_object3, &_object4, &_object5, 0);
+ _globals->setFlag(20);
+ }
+ } else {
+ _sceneMode = 9102;
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager, scene, _sceneMode, &_globals->_player, &_object2, &_object3, &_object4, &_object5, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9150
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9150::Object3::signal() {
+ switch (_signalFlag++) {
+ case 0:
+ _timer = 10 + _globals->_randomSource.getRandomNumber(90);
+ break;
+ default:
+ animate(ANIM_MODE_5, this);
+ _signalFlag = 0;
+ break;
+ }
+}
+
+void Scene9150::Object3::dispatch() {
+ SceneObject::dispatch();
+ if ((_timer != 0) && (--_timer == 0))
+ signal();
+}
+
+void Scene9150::signal() {
+ switch (_sceneMode) {
+ case 9151:
+ case 9157:
+ _globals->_sceneManager.changeScene(9100);
+ break;
+ case 9153:
+ _globals->_sceneManager.changeScene(9300);
+ break;
+ case 9152:
+ case 9155:
+ case 9156:
+ _globals->_player.enableControl();
+ break;
+ case 9154:
+ default:
+ break;
+ }
+}
+
+void Scene9150::dispatch() {
+
+ if ((_sceneState != 0) && (_sceneBounds.left == 0)) {
+ _object3._timer = 0;
+ _sceneState = 0;
+ _sceneHotspot3.setAction(&_sequenceManager2, 0, 9154, &_object3, 0);
+ _sceneHotspot10.remove();
+ }
+
+ if (_action) {
+ _action->dispatch();
+ } else {
+ if (_globals->_player._position.x >= 160) {
+ if (_globals->_player._position.x > 630) {
+ _globals->_player.disableControl();
+ _sceneMode = 9157;
+ setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, 0);
+ }
+ } else {
+ _globals->_player.disableControl();
+ if (_globals->getFlag(11)) {
+ _globals->_soundHandler.startSound(286, 0, 127);
+ _sceneMode = 9153;
+ } else {
+ _sceneMode = 9156;
+ }
+ setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, 0);
+ }
+ }
+}
+
+void Scene9150::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+ _globals->_player.postInit();
+
+ _object3.postInit();
+ _sceneState = 1;
+ _object3.setVisage(9151);
+ _object3._strip = 1;
+ _object3._frame = 1;
+ _object3.setPosition(Common::Point(312, 95), 0);
+ _object3.signal();
+
+ _sceneHotspot1.setup(0, 0, 200, 94, 9150, 46, -1);
+ _sceneHotspot2.setup(51, 90, 118, 230, 9150, 47, -1);
+ _sceneHotspot3.setup(182, 104, 200, 320, 9150, 48, 49);
+ _sceneHotspot4.setup(103, 292, 152, 314, 9150, 50, 51);
+ _sceneHotspot5.setup(115, 350, 160, 374, 9150, 52, 53);
+ _sceneHotspot6.setup(0, 471, 200, 531, 9150, 54, 55);
+ _sceneHotspot7.setup(170, 320, 185, 640, 9150, 56, -1);
+ _sceneHotspot9.setup(157, 107, 186, 320, 9150, 56, -1);
+ _sceneHotspot8.setup(133, 584, 142, 640, 9150, 57, -1);
+ _sceneHotspot10.setup(83, 304, 103, 323, 9150, 58, 59);
+
+ _globals->_soundHandler.startSound(285, 0, 127);
+ _globals->_player.disableControl();
+
+ if (_globals->getFlag(20)) {
+ // Walking alone
+ _globals->_scrollFollower = &_globals->_player;
+ if (_globals->getFlag(11))
+ // Hero wearing peasan suit
+ _sceneMode = 9155;
+ else
+ // Hero wearing Purple suit
+ _sceneMode = 9152;
+ setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, 0);
+ } else {
+ // Walking with the tiger
+ _sceneMode = 9151;
+ _object2.postInit();
+ _object2.hide();
+ _object1.postInit();
+ setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, &_object1, &_object2, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9200
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9200::SceneHotspot1::doAction(int action) {
+ Scene9200 *scene = (Scene9200 *)_globals->_sceneManager._scene;
+
+ if (action == OBJECT_TUNIC) {
+ _globals->_player.disableControl();
+ if (_globals->getFlag(93)) {
+ scene->_sceneState = 9214;
+ setAction(&scene->_sequenceManager, scene, 9214, &_globals->_player, &scene->_object2, 0);
+ } else {
+ _globals->setFlag(93);
+ scene->_sceneState = 9213;
+ setAction(&scene->_sequenceManager, scene, 9213, &_globals->_player, &scene->_object2, 0);
+ }
+ } else if (action <= 100) {
+ _globals->_player.disableControl();
+ scene->_sceneState = 9214;
+ setAction(&scene->_sequenceManager, scene, 9214, &_globals->_player, &scene->_object2, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9200::signal() {
+ switch (_sceneState++) {
+ case 9207:
+ _globals->_sceneManager.changeScene(9700);
+ break;
+ case 9208:
+ case 9211:
+ case 9212:
+ _globals->_sceneManager.changeScene(9500);
+ break;
+ case 9209:
+ _globals->_sceneManager.changeScene(9360);
+ break;
+ case 9210:
+ _hotspot1.remove();
+ // No break on purpose
+ case 9201:
+ case 9202:
+ case 9203:
+ case 9204:
+ case 9205:
+ case 9206:
+ default:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene9200::process(Event &event) {
+ Scene::process(event);
+}
+
+void Scene9200::dispatch() {
+// Rect rect9200 = Rect(320, 175, 250, 154);
+ Rect rect9200 = Rect(250, 154, 320, 175);
+
+ if (_action) {
+ _action->dispatch();
+ } else {
+ if ( (_globals->_player._position.x <= 0) || ((_globals->_player._position.x < 100) && (_globals->_player._position.y > 199))) {
+ _globals->_player.disableControl();
+ _sceneState = 9209;
+ setAction(&_sequenceManager, this, 9209, &_globals->_player, &_object2, &_object3, 0);
+ } else {
+ if (rect9200.contains(_globals->_player._position)) {
+ if (_globals->getFlag(93)) {
+ if (_globals->getFlag(86)) {
+ _sceneState = 9215;
+ setAction(&_sequenceManager, this, 9215, &_globals->_player, &_object2, &_object3, 0);
+ } else {
+ _sceneState = 9208;
+ setAction(&_sequenceManager, this, 9208, &_globals->_player, &_object2, &_object3, 0);
+ }
+ } else {
+ _globals->_player.disableControl();
+ _sceneState = 9204;
+ setAction(&_sequenceManager, this, 9204, &_globals->_player, &_object2, &_object3, 0);
+ }
+ } else {
+ if (_globals->_player._position.y < 140) {
+ _globals->_player.disableControl();
+ _sceneState = 9207;
+ setAction(&_sequenceManager, this, 9207, &_globals->_player, &_object2, &_object3, 0);
+ }
+ }
+ }
+ }
+}
+
+void Scene9200::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(130, 50, 200, 150);
+
+ _globals->_player.postInit();
+ _object3.postInit();
+ _object3.hide();
+ _object1.postInit();
+ // Water animation
+ _object1.setVisage(9200);
+ _object1._strip = 3;
+ _object1.animate(ANIM_MODE_2, 0);
+ _object1.setPosition(Common::Point(132, 114), 0);
+ _object1.setPriority2(140);
+ _soundHandler.startSound(297, 0, 127);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerGR);
+ _stripManager.addSpeaker(&_speakerGText);
+
+ if (!_globals->getFlag(86)) {
+ _object2.postInit();
+ _hotspot1.setup(96, 194, 160, 234, 9200, 29, 31);
+ }
+ _hotspot2.setup(164, 0, 200, 282, 9200, 0, 1);
+ _hotspot3.setup(140, 39, 165, 153, 9200, 2, 3);
+ _hotspot4.setup(92, 122, 139, 152, 9200, 4, 5);
+ _hotspot5.setup(33, 20, 142, 115, 9200, 6, 7);
+ _hotspot6.setup(104, 235, 153, 265, 9200, 8, 9);
+ _hotspot7.setup(107, 262, 153, 286, 9200, 10, 11);
+ _hotspot8.setup(69, 276, 164, 320, 9200, 12, 13);
+
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.disableControl();
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 9500:
+ if (_globals->getFlag(85)) {
+ if (_globals->_inventory._helmet._sceneNumber == 1) {
+ _globals->setFlag(86);
+ _sceneState = 9210;
+ setAction(&_sequenceManager, this, 9210, &_globals->_player, &_object2, &_object3, 0);
+ } else {
+ _sceneState = 9212;
+ setAction(&_sequenceManager, this, 9212, &_globals->_player, &_object2, &_object3, 0);
+ }
+ } else {
+ if (_globals->_inventory._helmet._sceneNumber == 1) {
+ _sceneState = 9211;
+ setAction(&_sequenceManager, this, 9211, &_globals->_player, &_object2, &_object3, 0);
+ } else {
+ _sceneState = 9202;
+ setAction(&_sequenceManager, this, 9202, &_globals->_player, &_object2, &_object3, 0);
+ }
+ }
+ break;
+ case 9700:
+ if (_globals->getFlag(86)) {
+ _sceneState = 9206;
+ setAction(&_sequenceManager, this, 9206, &_globals->_player, &_object2, &_object3, 0);
+ } else {
+ _sceneState = 9203;
+ setAction(&_sequenceManager, this, 9203, &_globals->_player, &_object2, &_object3, 0);
+ }
+ break;
+ case 9360:
+ default:
+ if (_globals->getFlag(86)) {
+ _sceneState = 9205;
+ setAction(&_sequenceManager, this, 9205, &_globals->_player, &_object2, &_object3, 0);
+ } else {
+ _sceneState = 9201;
+ setAction(&_sequenceManager, this, 9201, &_globals->_player, &_object2, &_object3, 0);
+ }
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9300
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9300::signal() {
+ switch (_sceneMode++) {
+ case 9301:
+ _globals->setFlag(84);
+ // No break on purpose
+ case 9303:
+ _globals->_soundHandler.startSound(295, 0, 127);
+ _globals->_sceneManager.changeScene(9350);
+ break;
+ case 9302:
+ _globals->_player.enableControl();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene9300::dispatch() {
+ if (_action) {
+ _action->dispatch();
+ } else if (_globals->_player._position.y < 145) {
+ _globals->_player.disableControl();
+ _sceneMode = 9303;
+ setAction(&_sequenceManager, this, 9303, &_globals->_player, &_object1, &_object2, 0);
+ }
+}
+
+void Scene9300::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(130, 75, 230, 150);
+
+ _sceneMode = 0;
+ _globals->_player.postInit();
+ _globals->_player.changeZoom(-1);
+ _object1.postInit();
+ _object2.postInit();
+ _globals->_soundHandler.startSound(289, 0, 127);
+
+ _hotspot1.setup(35, 142, 76, 212, 9300, 0, 1);
+ _hotspot2.setup(28, 90, 81, 143, 9300, 2, 3);
+ _hotspot3.setup(78, 142, 146, 216, 9300, 4, 5);
+ _hotspot4.setup(3, 43, 91, 74, 9300, 6, 7);
+ _hotspot5.setup(82, 19, 157, 65, 9300, 8, 9);
+ _hotspot6.setup(5, 218, 84, 274, 9300, 10, 11);
+ _hotspot7.setup(86, 233, 168, 293, 9300, 12, 13);
+ _hotspot8.setup(157, 0, 200, 230, 9300, 14, 15);
+ _hotspot9.setup(169, 227, 200, 320, 9300, 16, 17);
+ _hotspot10.setup(145, 97, 166, 225, 9300, 18, 19);
+ _hotspot11.setup(81, 75, 145, 145, 9300, 20, 21);
+ _hotspot12.setup(0, 0, 94, 35, 9300, 22, 23);
+ _hotspot13.setup(12, 268, 149, 320, 9300, 24, 25);
+
+ if (_globals->_sceneManager._previousScene == 9350) {
+ _globals->_player.disableControl();
+ _sceneMode = 9302;
+ setAction(&_sequenceManager, this, 9302, &_globals->_player, &_object1, &_object2, 0);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 9301;
+ setAction(&_sequenceManager, this, 9301, &_globals->_player, &_object1, &_object2, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9350
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene9350::signal() {
+ switch (_sceneState ++) {
+ case 0:
+ case 9352:
+ case 9353:
+ case 9354:
+ _globals->_player.enableControl();
+ break;
+ case 9355:
+ _globals->_sceneManager.changeScene(9300);
+ break;
+ case 9356:
+ _globals->_sceneManager.changeScene(9360);
+ break;
+ case 9357:
+ case 9359:
+ _globals->_sceneManager.changeScene(9400);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene9350::dispatch() {
+ if (_action == 0) {
+ if ((_globals->_player._position.x > 300) && (_globals->_player._position.y < 160)) {
+ _globals->_player.disableControl();
+ _sceneState = 9356;
+ setAction(&_sequenceManager, this, 9356, &_globals->_player, &_object2, 0);
+ } else if ((_globals->_player._position.x > 110) && (_globals->_player._position.y >= 195)) {
+ _globals->_player.disableControl();
+ _sceneState = 9357;
+ setAction(&_sequenceManager, this, 9357, &_globals->_player, &_object2, 0);
+ } else if ((_globals->_player._position.x < 10) || ((_globals->_player._position.x <= 110) && (_globals->_player._position.y >= 195))) {
+ _globals->_player.disableControl();
+ _sceneState = 9355;
+ setAction(&_sequenceManager, this, 9355, &_globals->_player, &_object2, 0);
+ }
+ } else {
+ Scene::dispatch();
+ }
+}
+
+void Scene9350::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(95, 80, 200, 100);
+ _globals->_player.postInit();
+
+ _object1.setup(9350, 1, 3, 139, 97, 0);
+ _sceneHotspot1.setup(42, 0, 97, 60, 9350, 0, -1);
+ _sceneHotspot2.setup(37, 205, 82, 256, 9350, 0, -1);
+ _sceneHotspot3.setup(29, 93, 92, 174, 9350, 1, -1);
+ _sceneHotspot4.setup(0, 308, 109, 320, 9350, 2, -1);
+ _sceneHotspot5.setup(0, 0, 200, 320, 9350, 3, -1);
+
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.disableControl();
+
+ if (_globals->_sceneManager._previousScene == 9360) {
+ _globals->_player.disableControl();
+ _sceneState = 9352;
+ setAction(&_sequenceManager, this, 9352, &_globals->_player, &_object2, 0);
+ } else if (_globals->_sceneManager._previousScene == 9400) {
+ _globals->_player.disableControl();
+ _sceneState = 9353;
+ setAction(&_sequenceManager, this, 9353, &_globals->_player, &_object2, 0);
+ } else {
+ if (!_globals->getFlag(84)) {
+ _globals->clearFlag(84);
+ _object2.postInit();
+ _globals->_player.disableControl();
+ _sceneState = 9359;
+ setAction(&_sequenceManager, this, 9359, &_globals->_player, &_object2, 0);
+ } else {
+ _globals->_player.disableControl();
+ _sceneState = 9354;
+ setAction(&_sequenceManager, this, 9354, &_globals->_player, &_object2, 0);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9360
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene9360::signal() {
+ switch (_sceneState ++) {
+ case 0:
+ case 9362:
+ case 9363:
+ case 9364:
+ _globals->_player.enableControl();
+ break;
+ case 9365:
+ _globals->_sceneManager.changeScene(9350);
+ break;
+ case 9366:
+ _globals->_sceneManager.changeScene(9200);
+ break;
+ case 9367:
+ _globals->_sceneManager.changeScene(9450);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene9360::dispatch() {
+ if (_action == 0) {
+ if ((_globals->_player._position.x > 300) && (_globals->_player._position.y < 160)) {
+ _globals->_player.disableControl();
+ _sceneState = 9366;
+ setAction(&_sequenceManager, this, 9366, &_globals->_player, 0);
+ } else if ((_globals->_player._position.x > 110) && (_globals->_player._position.y >= 195)) {
+ _globals->_player.disableControl();
+ _sceneState = 9367;
+ setAction(&_sequenceManager, this, 9367, &_globals->_player, 0);
+ } else if ((_globals->_player._position.x < 10) || ((_globals->_player._position.x <= 110) && (_globals->_player._position.y >= 195))) {
+ _globals->_player.disableControl();
+ _sceneState = 9365;
+ setAction(&_sequenceManager, this, 9365, &_globals->_player, 0);
+ }
+ } else {
+ Scene::dispatch();
+ }
+}
+
+void Scene9360::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(95, 80, 200, 100);
+ _globals->_player.postInit();
+
+ _hotspot1.setup(37, 92, 93, 173, 9360, 0, 1);
+ _hotspot2.setup(42, 0, 100, 63, 9360, 2, -1);
+ _hotspot3.setup(36, 205, 82, 260, 9360, 3, -1);
+ _hotspot4.setup(103, 2, 200, 320, 9360, 4, -1);
+ _hotspot5.setup(0, 0, 37, 320, 9360, 4, -1);
+ _hotspot6.setup(35, 61, 103, 92, 9360, 4, -1);
+ _hotspot7.setup(33, 174, 93, 207, 9360, 4, -1);
+ _hotspot8.setup(28, 257, 149, 320, 9360, 4, -1);
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.disableControl();
+ if (_globals->_sceneManager._previousScene == 9350) {
+ _globals->_player.disableControl();
+ _sceneState = 9364;
+ setAction(&_sequenceManager, this, 9364, &_globals->_player, 0);
+ } else if (_globals->_sceneManager._previousScene == 9450) {
+ _globals->_player.disableControl();
+ _sceneState = 9363;
+ setAction(&_sequenceManager, this, 9363, &_globals->_player, 0);
+ } else {
+ _globals->_player.disableControl();
+ _sceneState = 9362;
+ setAction(&_sequenceManager, this, 9362, &_globals->_player, 0);
+ }
+ _object1.setup(9351, 1, 1, 131, 90, 0);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9400
+ *
+ *--------------------------------------------------------------------------*/
+Scene9400::Scene9400() {
+ _field1032 = 0;
+}
+
+void Scene9400::SceneHotspot7::doAction(int action) {
+ Scene9400 *scene = (Scene9400 *)_globals->_sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (_globals->_inventory._straw._sceneNumber != 1)) {
+ scene->_sceneState = 1;
+ scene->setAction(&scene->_sequenceManager, scene, 9408, &_globals->_player, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9400::SceneHotspot8::doAction(int action) {
+ Scene9400 *scene = (Scene9400 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_TALK) {
+ _globals->_player.disableControl();
+ scene->_sceneState = 2;
+ scene->signal();
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9400::signal() {
+ switch (_sceneState ++) {
+ case 0:
+ _object1._numFrames = 6;
+ _stripManager.start(9400, this);
+ break;
+ case 1:
+ _object1._numFrames = 6;
+ _object1.animate(ANIM_MODE_2, 0);
+ _globals->_player.enableControl();
+ break;
+ case 2:
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _stripManager.start(9405, this);
+ break;
+ case 4:
+ _object1.animate(ANIM_MODE_2, this);
+ _globals->_player.enableControl();
+ break;
+ case 9350:
+ _globals->_sceneManager.changeScene(9350);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene9400::dispatch() {
+ if ((_object1._animateMode == 2) && (_object1._strip == 1) && (_object1._frame == 4)){
+ if (_field1032 == 0) {
+ _soundHandler.startSound(296, 0, 127);
+ _field1032 = 1;
+ }
+ } else {
+ _field1032 = 0;
+ }
+ if (_action == 0) {
+ if (_globals->_player._position.y < 120) {
+ _sceneState = 9350;
+ _globals->_player.disableControl();
+ setAction(&_action1);
+ Common::Point pt(-45, 88);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ }
+ } else {
+ Scene::dispatch();
+ }
+}
+
+void Scene9400::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ _sceneNumber = 9400;
+ setZoomPercents(0, 100, 200, 100);
+ _globals->_player.postInit();
+ _object1.postInit(0);
+ _object3.postInit(0);
+ _speakerQText._textPos.x = 20;
+
+ _hotspot7.setup(157, 66, 180, 110, 9400, 21, 23);
+ _hotspot5.setup(130, 133, 152, 198, 9400, 22, -1);
+ _hotspot1.setup(33, 280, 69, 297, 9400, 1, 2);
+ _hotspot2.setup(73, 96, 87, 159, 9400, 3, 4);
+ _hotspot3.setup(89, 253, 111, 305, 9400, 5, 6);
+ _hotspot4.setup(46, 0, 116, 35, 9400, 7, 8);
+ _hotspot8.setup(58, 169, 122, 200, 9400, 9, 10);
+ _hotspot6.setup(0, 0, 199, 319, 9400, 16, 0);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerOR);
+ _stripManager.addSpeaker(&_speakerOText);
+
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.disableControl();
+
+ // Useless check (skipped) : if (_globals->_sceneManager._previousScene == 9350)
+ _sceneState = 2;
+ if (!_globals->getFlag(89)) {
+ _globals->setFlag(89);
+ _sceneState = 0;
+ }
+
+ setAction(&_sequenceManager, this, 9400, &_globals->_player, &_object1, &_object3, 0);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9450
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9450::Object2::signal() {
+ Scene9450 *scene = (Scene9450 *)_globals->_sceneManager._scene;
+
+ this->setAction(&scene->_sequenceManager3, this, 9458, &scene->_object1, 0);
+}
+
+void Scene9450::Object3::dispatch() {
+ SceneObject::dispatch();
+ _percent = (_percent * 20) / 30;
+}
+
+void Scene9450::Hotspot1::doAction(int action) {
+ Scene9450 *scene = (Scene9450 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ if (scene->_object2._action)
+ scene->_object2._action->remove();
+ scene->_sceneMode = 9459;
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager1, scene, 9459, &scene->_object2, &scene->_object1, &scene->_object3, &_globals->_player, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9450::Hotspot3::doAction(int action) {
+ Scene9450 *scene = (Scene9450 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_CLOAK:
+ case OBJECT_JACKET:
+ case OBJECT_TUNIC2:
+ scene->_sceneMode = 9460;
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager1, scene, 9460, &_globals->_player, &scene->_object2, &scene->_object1, 0);
+ break;
+ case OBJECT_TUNIC:
+ SceneItem::display(9450, 49, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_WALK:
+ // nothing
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display(9450, 41, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ case CURSOR_TALK:
+ if (_globals->_inventory._tunic._sceneNumber == 9450) {
+ if (scene->_object2._action)
+ scene->_object2._action->remove();
+ scene->_sceneMode = 9459;
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager1, scene, 9459, &scene->_object2, &scene->_object1, &scene->_object3, &_globals->_player, 0);
+ } else if ((_globals->_inventory._cloak._sceneNumber != 1) && (_globals->_inventory._jacket._sceneNumber != 1) && (_globals->_inventory._tunic2._sceneNumber != 1)) {
+ SceneItem::display(9450, 38, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ scene->_sceneMode = 9460;
+ _globals->_player.disableControl();
+ setAction(&scene->_sequenceManager1, scene, 9460, &_globals->_player, &scene->_object2, &scene->_object1, 0);
+ }
+ break;
+ default:
+ SceneItem::display(9450, 45, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ }
+}
+
+void Scene9450::signal() {
+ switch (_sceneMode++) {
+ case 1002:
+ case 1004:
+ // Drink
+ setAction(&_sequenceManager1, this, 9456, &_object2, &_object1, &_object3, 0);
+ break;
+ case 1005:
+ // Bring me more wine
+ setAction(&_sequenceManager1, this, 9457, &_object2, &_object1, &_object3, 0);
+ break;
+ case 9451:
+ if (_globals->getFlag(87)) {
+ _globals->_player.enableControl();
+ } else {
+ _sceneMode = 1001;
+ if (_object2._action)
+ _object2._action->remove();
+ }
+ // No break on purpose
+ case 1001:
+ case 1003:
+ // Eat
+ setAction(&_sequenceManager1, this, 9455, &_object2, &_object1, &_object3, 0);
+ break;
+ case 9453:
+ _globals->_sceneManager.changeScene(9360);
+ break;
+ case 9459:
+ _object2.signal();
+ _globals->_events.setCursor(CURSOR_WALK);
+ _hotspot1.remove();
+ break;
+ case 1006:
+ _globals->setFlag(87);
+ // No break on purpose
+ default:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene9450::dispatch() {
+ if (_action) {
+ _action->dispatch();
+ } else {
+ if ((_globals->_player._position.y < 98) && (_globals->_player._position.x > 241) && (_globals->_player._position.x < 282)) {
+ _globals->_player.disableControl();
+ _sceneMode = 9452;
+ setAction(&_sequenceManager1, this, 9452, &_globals->_player, 0);
+ } else if ((_globals->_player._position.y < 99) && (_globals->_player._position.x > 68) && (_globals->_player._position.x < 103)) {
+ _globals->_player.disableControl();
+ _sceneMode = 9453;
+ setAction(&_sequenceManager1, this, 9453, &_globals->_player, 0);
+ }
+ }
+}
+
+void Scene9450::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(84, 75, 167, 150);
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.postInit();
+
+ _object2.postInit();
+ _object1.postInit();
+ _object1.hide();
+
+ _globals->_player.disableControl();
+ _sceneMode = 9451;
+ setAction(&_sequenceManager1, this, 9451, &_globals->_player, 0);
+
+ if (_globals->getFlag(87)) {
+ if (_globals->_inventory._tunic._sceneNumber == 1) {
+ _object2.signal();
+ } else {
+ _object2.setPosition(Common::Point(184, 144), 0);
+ _object2.setVisage(9451);
+ _object2.setPriority2(250);
+ _object2._strip = 5;
+ _object2._frame = 10;
+ }
+ } else {
+ _object3.postInit();
+ _object3.hide();
+ _object3.setAction(&_sequenceManager2, 0, 9455, &_object2, &_object1, 0);
+ }
+
+ if (_globals->_inventory._tunic._sceneNumber != 1)
+ _hotspot1.setup(123, 139, 138, 170, 9450, 37, -1);
+
+ _hotspot2.setup(153, 102, 176, 141, 9450, 39, 40);
+ _hotspot3.setup(97, 198, 130, 229, 9450, 41, 42);
+ _hotspot15.setup(131, 190, 145, 212, 9450, 43, 44);
+ _hotspot4.setup(33, 144, 105, 192, 9450, 0, 1);
+ _hotspot5.setup(20, 236, 106, 287, 9450, 2, 3);
+ _hotspot6.setup(137, 119, 195, 320, 9450, 4, 5);
+ _hotspot7.setup(20, 59, 99, 111, 9450, 6, -1);
+ _hotspot8.setup(110, 0, 199, 117, 9450, 7, 8);
+ _hotspot9.setup(101, 104, 130, 174, 9450, 9, 10);
+ _hotspot10.setup(110, 246, 149, 319, 9450, 11, 12);
+ _hotspot11.setup(16, 34, 74, 62, 6450, 13, 14);
+ _hotspot12.setup(19, 108, 72, 134, 9450, 15, 16);
+ _hotspot13.setup(18, 215, 71, 237, 9450, 17, 18);
+ _hotspot14.setup(15, 288, 76, 314, 9450, 19, 20);
+ _hotspot16.setup(0, 0, 200, 320, 9450, 46, -1);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9500
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9500::Hotspot1::doAction(int action) {
+ Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene;
+
+ if (action == OBJECT_SWORD) {
+ scene->_sceneMode = 9510;
+ _globals->setFlag(92);
+ _globals->_inventory._sword._sceneNumber = 9500;
+ _globals->_player.disableControl();
+ _globals->_sceneItems.remove(this);
+ scene->_hotspot2.setup(87, 294, 104, 314, 9400, 17, -1);
+ scene->setAction(&scene->_sequenceManager, scene, 9510, &_globals->_player, &scene->_object2, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9500::Hotspot2::doAction(int action) {
+ Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ scene->_sceneMode = 9511;
+ _globals->_player.disableControl();
+ _globals->_sceneItems.remove(this);
+ scene->setAction(&scene->_sequenceManager, scene, 9511, &_globals->_player, &scene->_object2, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9500::Hotspot3::doAction(int action) {
+ Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene;
+
+ if ((action == CURSOR_USE) && (_globals->_inventory._candle._sceneNumber != 1)){
+ scene->_sceneMode = 9505;
+ _globals->_player.disableControl();
+ _globals->_sceneItems.remove(this);
+ scene->setAction(&scene->_sequenceManager, scene, 9505, &_globals->_player, &scene->_candle, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9500::Hotspot4::doAction(int action) {
+ Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene;
+
+ if (action == OBJECT_CANDLE) {
+ _globals->_player.disableControl();
+ if (_globals->_inventory._straw._sceneNumber == 9500) {
+ scene->_sceneMode = 9506;
+ _globals->_sceneItems.remove(&scene->_hotspot5);
+ _globals->_sceneItems.remove(this);
+ scene->setAction(&scene->_sequenceManager, scene, 9506, &_globals->_player, &scene->_object3, 0);
+ _globals->_inventory._candle._sceneNumber = 9850;
+ } else {
+ scene->_sceneMode = 9507;
+ scene->setAction(&scene->_sequenceManager, scene, 9507, &_globals->_player, &scene->_object3, 0);
+ }
+ } else if (action == OBJECT_STRAW) {
+ scene->_sceneMode = 9512;
+ _globals->_player.disableControl();
+ _globals->_inventory._straw._sceneNumber = 9500;
+ scene->setAction(&scene->_sequenceManager, scene, 9512, &_globals->_player, &scene->_object3, 0);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9500::signal() {
+ switch (_sceneMode) {
+ case 9503:
+ _globals->_sceneManager.changeScene(9200);
+ _globals->_soundHandler.startSound(295, 0, 127);
+ break;
+ case 9504:
+ _globals->_sceneManager.changeScene(9850);
+ break;
+ case 9505:
+ _candle.setStrip(2);
+ _globals->_player.enableControl();
+ break;
+ case 9506:
+ _globals->setFlag(85);
+ _globals->_player.enableControl();
+ break;
+ case 9511:
+ _globals->_player.enableControl();
+ if (!_globals->getFlag(51)) {
+ _globals->setFlag(51);
+ _globals->_player.disableControl();
+ _sceneMode = 9514;
+ setAction(&_sequenceManager, this, 9514, &_globals->_player, 0, 0, 0, 0);
+ }
+ break;
+ case 0:
+ case 9514:
+ default:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene9500::dispatch() {
+ if (_action) {
+ _action->dispatch();
+ } else {
+ if (_globals->_player._position.y >= 199) {
+ _globals->_player.disableControl();
+ _sceneMode = 9503;
+ setAction(&_sequenceManager, this, 9503, &_globals->_player, 0, 0, 0, 0);
+ } else if (_globals->_player._position.y < 127) {
+ _globals->_player.disableControl();
+ _sceneMode = 9504;
+ setAction(&_sequenceManager, this, 9504, &_globals->_player, 0, 0, 0, 0);
+ }
+ }
+
+}
+
+void Scene9500::process(Event &event) {
+ Scene::process(event);
+}
+
+void Scene9500::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(110, 75, 200, 150);
+
+ _globals->_player.postInit();
+ _globals->_soundHandler.startSound(305, 0, 127);
+
+ _candle.postInit(0);
+ _candle.setVisage(9500);
+ _candle.setStrip(1);
+ _candle.animate(ANIM_MODE_2);
+ _candle.setPosition(Common::Point(30, 105), 0);
+ if (_globals->_inventory._candle._sceneNumber != 9500)
+ _candle.setStrip(2);
+
+ _object3.postInit(0);
+ _object3.hide();
+ _object3.setPriority2(150);
+ _object3.setPosition(Common::Point(166, 133));
+ if (_globals->_inventory._straw._sceneNumber == 9500) {
+ _object3.show();
+ _object3.setVisage(5);
+ _object3._strip = 2;
+ _object3._frame = 9;
+ _object3.setPosition(Common::Point(168, 128));
+ if (_globals->getFlag(85)) {
+ _object3.setVisage(9500);
+ _object3.setStrip(4);
+ _object3.animate(ANIM_MODE_8, 0, 0);
+ _object3.setPosition(Common::Point(166, 133));
+ }
+ }
+
+ _object2.postInit(0);
+ _object2.hide();
+ if (_globals->getFlag(92)) {
+ _object2.show();
+ _object2.setVisage(9501);
+ _object2.setStrip(1);
+ _object2.setFrame(_object2.getFrameCount());
+ _object2.setPosition(Common::Point(303, 130));
+ _object2.setPriority2(132);
+ if (_globals->_inventory._helmet._sceneNumber == 1) {
+ _hotspot2.setup(87, 294, 104, 314, 9400, 17, -1);
+ } else {
+ _object2.setStrip(2);
+ _object2.setFrame(1);
+ }
+ } else {
+ _hotspot1.setup(105, 295, 134, 313, 9500, 9, 10);
+ }
+
+ _hotspot17.setup(101, 293, 135, 315, 9500, 9, 10);
+ _hotspot3.setup(84, 12, 107, 47, 9500, 15, 15);
+ _hotspot6.setup(93, 11, 167, 46, 9500, 0, 1);
+ _hotspot7.setup(100, 70, 125, 139, 9500, 2, 3);
+
+ if (!_globals->getFlag(85)) {
+ _hotspot5.setup(111, 68, 155, 244, 9500, 17, -1);
+ _hotspot4.setup(57, 71, 120, 126, 9500, 16, -1);
+ }
+
+ _hotspot8.setup(60, 24, 90, 53, 9500, 4, 5);
+ _hotspot9.setup(72, 143, 93, 163, 9500, 4, 5);
+ _hotspot10.setup(70, 205, 92, 228, 9500, 4, 5);
+ _hotspot11.setup(66, 291, 90, 317, 9500, 4, 5);
+ _hotspot12.setup(22, 58, 101, 145, 9500, 6, 7);
+ _hotspot13.setup(121, 57, 163, 249, 9500, 6, 7);
+ _hotspot14.setup(115, 133, 135, 252, 9500, 6, 7);
+ _hotspot15.setup(55, 240, 125, 254, 9500, 6, 7);
+ _hotspot16.setup(53, 251, 132, 288, 9500, 8, -1);
+ _hotspot19.setup(101, 207, 120, 225, 9500, 9, 10);
+ _hotspot18.setup(98, 144, 117, 162, 9500, 9, 10);
+ _hotspot20.setup(102, 27, 132, 50, 9500, 9, 10);
+
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.disableControl();
+
+ if ((_globals->_sceneManager._previousScene == 9200) || (_globals->_sceneManager._previousScene != 9850)) {
+ _sceneMode = 0;
+ if (_globals->_inventory._helmet._sceneNumber != 1) {
+ setAction(&_sequenceManager, this, 9501, &_globals->_player, &_candle, 0);
+ } else {
+ _globals->_inventory._helmet._sceneNumber = 9500;
+ _hotspot2.setup(87, 294, 104, 314, 9400, 17, -1);
+ setAction(&_sequenceManager, this, 9513, &_globals->_player, &_object2, 0);
+ }
+ } else {
+ _sceneMode = 0;
+ setAction(&_sequenceManager, this, 9502, &_globals->_player, &_candle, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9700
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9700::signal() {
+ switch (_sceneMode ++) {
+ case 9703:
+ _globals->setFlag(88);
+ // No break on purpose
+ case 9701:
+ case 9702:
+ _gfxButton1.setText(EXIT_MSG);
+ _gfxButton1._bounds.centre(50, 190);
+ _gfxButton1.draw();
+ _gfxButton1._bounds.expandPanes();
+ _globals->_player.enableControl();
+ _globals->_player._canWalk = 0;
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 9704:
+ _globals->_soundHandler.startSound(323, 0, 127);
+ _globals->_sceneManager.changeScene(9750);
+ break;
+ }
+}
+
+void Scene9700::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (event.kbd.keycode == 0)) {
+ if (_gfxButton1.process(event)) {
+ _globals->_sceneManager.changeScene(9200);
+ } else if (_globals->_events._currentCursor == OBJECT_SCANNER) {
+ event.handled = true;
+ if (_globals->_inventory._helmet._sceneNumber == 1) {
+ _globals->_player.disableControl();
+ _sceneMode = 9704;
+ setAction(&_sequenceManager, this, 9704, &_globals->_player, &_object1, 0);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 9703;
+ setAction(&_sequenceManager, this, 9703, &_globals->_player, &_object1, 0);
+ }
+ }
+ }
+}
+
+void Scene9700::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _sceneHotspot1.setup(84, 218, 151, 278, 9700, 14, -1);
+ _sceneHotspot2.setup(89, 11, 151, 121, 9700, 14, -1);
+ _sceneHotspot3.setup(69, 119, 138, 218, 9700, 15, 16);
+ _sceneHotspot4.setup(34, 13, 88, 116, 9700, 17, -1);
+ _sceneHotspot5.setup(52, 119, 68, 204, 9700, 17, -1);
+ _sceneHotspot6.setup(0, 22, 56, 275, 9700, 18, -1);
+
+ _object1.postInit();
+ _object1.hide();
+ _globals->_player.postInit();
+ if (_globals->getFlag(97)) {
+ _globals->_player.disableControl();
+ _sceneMode = 9701;
+ setAction(&_sequenceManager, this, 9701, &_globals->_player, &_object1, 0);
+ _globals->setFlag(97);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 9702;
+ setAction(&_sequenceManager, this, 9702, &_globals->_player, &_object1, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9750
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9750::signal() {
+ switch (_sceneMode ++) {
+ case 9751:
+ _globals->_soundHandler.proc1(this);
+ break;
+ case 9752:
+ _globals->_sceneManager.changeScene(2100);
+ default:
+ break;
+ }
+}
+
+void Scene9750::dispatch() {
+ Scene::dispatch();
+}
+
+void Scene9750::postInit(SceneObjectList *OwnerList) {
+ loadScene(9750);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _globals->_player.postInit();
+ _object1.postInit();
+ _object1.hide();
+ _object2.postInit();
+ _object2.hide();
+ _globals->_player.disableControl();
+ _sceneMode = 9751;
+ setAction(&_sequenceManager, this, 9751, &_globals->_player, &_object1, &_object2, 0);
+}
+
+
+/*--------------------------------------------------------------------------
+ * Scene 9850
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9850::Object6::doAction(int action) {
+ if ((_flags & OBJFLAG_HIDE) == 0) {
+ if (action == CURSOR_LOOK) {
+ SceneItem::display(9850, 27, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else if (action == CURSOR_USE) {
+ _globals->_inventory._scimitar._sceneNumber = 1;
+ hide();
+ } else {
+ SceneHotspot::doAction(action);
+ }
+ }
+}
+void Scene9850::Object7::doAction(int action) {
+ if ((_flags & OBJFLAG_HIDE) == 0) {
+ if (action == CURSOR_LOOK) {
+ SceneItem::display(9850, 28, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else if (action == CURSOR_USE) {
+ _globals->_inventory._sword._sceneNumber = 1;
+ hide();
+ } else {
+ SceneHotspot::doAction(action);
+ }
+ }
+}
+
+// Hair covered tunic
+void Scene9850::Hotspot12::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ if (_globals->_inventory._tunic2._sceneNumber != 1) {
+ _globals->_inventory._tunic2._sceneNumber = 1;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9858;
+ setAction(&scene->_sequenceManager, scene, 9858, &_globals->_player, &scene->_objTunic2, 0);
+ } else {
+ _globals->_inventory._tunic2._sceneNumber = 9850;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9861;
+ setAction(&scene->_sequenceManager, scene, 9861, &_globals->_player, &scene->_objTunic2, 0);
+ }
+ } else if ((action != CURSOR_LOOK) || (_globals->_inventory._tunic2._sceneNumber != 1)) {
+ NamedHotspot::doAction(action);
+ } else {
+ SceneItem::display(9850, 30, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+}
+
+void Scene9850::Hotspot14::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ if (_globals->_inventory._jacket._sceneNumber != 1) {
+ _globals->_inventory._jacket._sceneNumber = 1;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9857;
+ setAction(&scene->_sequenceManager, scene, 9857, &_globals->_player, &scene->_objJacket, 0);
+ } else {
+ _globals->_inventory._jacket._sceneNumber = 9850;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9860;
+ setAction(&scene->_sequenceManager, scene, 9860, &_globals->_player, &scene->_objJacket, 0);
+ }
+ } else if ((action != CURSOR_LOOK) || (_globals->_inventory._jacket._sceneNumber != 1)) {
+ NamedHotspot::doAction(action);
+ } else {
+ SceneItem::display(9850, 30, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+}
+
+void Scene9850::Hotspot16::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ if (_globals->_inventory._cloak._sceneNumber != 1) {
+ _globals->_inventory._cloak._sceneNumber = 1;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9862;
+ setAction(&scene->_sequenceManager, scene, 9862, &_globals->_player, &scene->_objCloak, 0);
+ } else {
+ _globals->_inventory._cloak._sceneNumber = 9850;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 9859;
+ setAction(&scene->_sequenceManager, scene, 9859, &_globals->_player, &scene->_objCloak, 0);
+ }
+ } else if ((action != CURSOR_LOOK) || (_globals->_inventory._cloak._sceneNumber != 1)) {
+ NamedHotspot::doAction(action);
+ } else {
+ SceneItem::display(9850, 30, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+}
+
+void Scene9850::Hotspot17::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == OBJECT_SCANNER) {
+ SceneItem::display(9850, 32, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ if (action == CURSOR_USE)
+ scene->_soundHandler.startSound(306, 0, 127);
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9850::Hotspot18::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == OBJECT_SCANNER) {
+ SceneItem::display(9850, 32, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ if (action == CURSOR_USE)
+ scene->_soundHandler.startSound(306, 0, 127);
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9850::Hotspot19::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == OBJECT_SCANNER) {
+ SceneItem::display(9850, 31, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ if (action == CURSOR_USE)
+ scene->_soundHandler.startSound(313, 0, 127);
+ NamedHotspot::doAction(action);
+ }
+}
+
+// Arrow on Statue
+void Scene9850::Hotspot20::doAction(int action) {
+ Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ _globals->_player.disableControl();
+ if (scene->_objSword._state == 0) {
+ if (_globals->_inventory._scimitar._sceneNumber == 9850)
+ scene->_objScimitar.show();
+ if (_globals->_inventory._sword._sceneNumber == 9850)
+ scene->_objSword.show();
+ scene->_sceneMode = 11;
+ setAction(&scene->_sequenceManager, scene, 9853, &_globals->_player, &scene->_objDoor, &scene->_objLever, 0);
+ } else {
+ scene->_sceneMode = 10;
+ setAction(&scene->_sequenceManager, scene, 9854, &_globals->_player, &scene->_objDoor, &scene->_objLever, 0);
+ }
+ scene->_objSword._state ^= 1;
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene9850::signal() {
+ switch (_sceneMode ++) {
+ case 10:
+ // Hidden closet closed
+ if (_globals->_inventory._scimitar._sceneNumber == 9850)
+ _objScimitar.hide();
+ if (_globals->_inventory._sword._sceneNumber == 9850)
+ _objSword.hide();
+ _globals->_sceneItems.remove(&_objScimitar);
+ _globals->_sceneItems.remove(&_objSword);
+ _globals->_sceneItems.addItems(&_hotspot19, NULL);
+ _globals->_player.enableControl();
+ break;
+ case 11:
+ // Hidden closet opened
+ if (_globals->_inventory._scimitar._sceneNumber == 9850)
+ _globals->_sceneItems.addItems(&_objScimitar, NULL);
+ if (_globals->_inventory._sword._sceneNumber == 9850)
+ _globals->_sceneItems.addItems(&_objSword, NULL);
+ _globals->_sceneItems.remove(&_hotspot19);
+ _globals->_player.enableControl();
+ break;
+ case 9500:
+ _globals->_sceneManager.changeScene(9500);
+ break;
+ case 0:
+ default:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene9850::process(Event &event) {
+ Scene::process(event);
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_4)) {
+ event.handled = true;
+ _globals->_player.disableControl();
+ if (_objSword._state == 0) {
+ _sceneMode = 0;
+ setAction(&_sequenceManager, this, 9853, &_objLever, &_objDoor, &_objScimitar, &_objSword, 0);
+ } else {
+ _sceneMode = 10;
+ setAction(&_sequenceManager, this, 9854, &_objLever, &_objDoor, &_objScimitar, &_objSword, 0);
+ }
+ _objSword._state ^= 1;
+ }
+}
+
+void Scene9850::dispatch() {
+ if (_action) {
+ _action->dispatch();
+ } else if (_globals->_player._position.y >= 198) {
+ _globals->_player.disableControl();
+ _sceneMode = 9500;
+ setAction(&_sequenceManager, this, 9852, &_globals->_player, 0);
+ }
+}
+
+void Scene9850::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ _objSword._state = 0;
+
+ _objDoor.postInit();
+ _objDoor.setVisage(9850);
+ _objDoor.setStrip(1);
+ _objDoor.setFrame(1);
+ _objDoor.setPosition(Common::Point(28, 118), 0);
+ _objDoor.setPriority2(90);
+
+ _objLever.postInit();
+ _objLever.setVisage(9850);
+ _objLever.setStrip(4);
+ _objLever.setFrame(1);
+ _objLever.setPosition(Common::Point(256, 35), 0);
+
+ _objCloak.postInit();
+ _objCloak.setVisage(9850);
+ _objCloak.setStrip(5);
+ _objCloak.setFrame(1);
+ _objCloak.setPriority2(90);
+ _objCloak.setPosition(Common::Point(157, 81), 0);
+ if (_globals->_inventory._cloak._sceneNumber != 9850)
+ _objCloak.hide();
+
+ _objJacket.postInit();
+ _objJacket.setVisage(9850);
+ _objJacket.setStrip(5);
+ _objJacket.setFrame(2);
+ _objJacket.setPriority2(90);
+ _objJacket.setPosition(Common::Point(201, 84));
+ if (_globals->_inventory._jacket._sceneNumber != 9850)
+ _objJacket.hide();
+
+ _objTunic2.postInit();
+ _objTunic2.setVisage(9850);
+ _objTunic2.setStrip(5);
+ _objTunic2.setFrame(3);
+ _objTunic2.setPriority2(90);
+ _objTunic2.setPosition(Common::Point(295, 90));
+ if (_globals->_inventory._tunic2._sceneNumber != 9850)
+ _objTunic2.hide();
+
+ if (_globals->_inventory._scimitar._sceneNumber == 9850) {
+ _objScimitar.postInit();
+ _objScimitar.setVisage(9850);
+ _objScimitar.setStrip(2);
+ _objScimitar.setFrame(1);
+ _objScimitar.setPosition(Common::Point(55, 83), 0);
+ _objScimitar.setPriority2(80);
+ _objScimitar.hide();
+ }
+
+ if (_globals->_inventory._sword._sceneNumber == 9850) {
+ _objSword.postInit();
+ _objSword.setVisage(9850);
+ _objSword.setStrip(3);
+ _objSword.setFrame(1);
+ _objSword.setPosition(Common::Point(56, 101), 0);
+ _objSword.setPriority2(80);
+ _objSword.hide();
+ }
+
+ _spotLever.setup(30, 251, 45, 270, 9850, 26, -1);
+ _hotspot1.setup(123, 0, 200, 320, 9850, 0, 1);
+ _hotspot2.setup(107, 87, 133, 308, 9850, 0, 1);
+ _hotspot3.setup(2, 28, 53, 80, 9850, 2, 3);
+ _hotspot4.setup(13, 0, 55, 27, 9850, 2, 3);
+ _hotspot5.setup(8, 74, 27, 91, 9850, 4, 5);
+ _hotspot17.setup(61, 0, 125, 28, 9850, 6, 7);
+ _hotspot18.setup(51, 95, 105, 145, 9850, 6, 7);
+ _hotspot19.setup(56, 28, 115, 97, 9850, 6, 8);
+ _hotspot6.setup(0, 223, 115, 257, 9850, 9, 10);
+ _hotspot7.setup(15, 254, 33, 268, 9850, 9, -1);
+ _hotspot8.setup(17, 218, 37, 233, 9850, 9, 10);
+ _hotspot9.setup(8, 113, 26, 221, 9850, 11, 12);
+ _hotspot10.setup(14, 94, 53, 112, 9850, 13, 14);
+ _hotspot11.setup(5, 269, 29, 303, 9850, 15, 16);
+ _hotspot12.setup(43, 278, 91, 317, 9850, 17, 18);
+ _hotspot13.setup(47, 263, 112, 282, 9850, 19, 20);
+ _hotspot14.setup(43, 188, 86, 224, 9850, 21, 22);
+ _hotspot15.setup(43, 162, 92, 191, 9850, 23, 24);
+ _hotspot16.setup(40, 146, 90, 169, 9850, 25, -1);
+
+ _globals->_player.postInit();
+ _globals->_player.disableControl();
+ _sceneMode = 0;
+ setAction(&_sequenceManager, this, 9851, &_globals->_player, 0);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9900
+ *
+ *--------------------------------------------------------------------------*/
+void Scene9900::strAction1::signal() {
+ RGB8 mask1, mask2;
+ mask1.r = mask1.g = mask1.b = 0xff;
+ mask2.r = mask2.g = mask2.b = 0;
+
+ Scene9900 *scene = (Scene9900 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_soundHandler.startSound(351, 0, 127);
+ _object9.postInit();
+ _object9.setVisage(18);
+ _object9._frame = 1;
+ _object9._strip = 6;
+ _object9.setPosition(Common::Point(171, 59));
+ _object9.animate(ANIM_MODE_5, 0);
+ _globals->_scenePalette.addRotation(67, 111, 1, 1, this);
+ scene->_object2.hide();
+ break;
+ case 1:
+ _palette1.getPalette();
+ _globals->_scenePalette.addUnkPal(&mask1, 1, true /*10*/, this);
+ break;
+ case 2:
+ _object9.remove();
+ _globals->_scenePalette.addUnkPal(&mask2, 1, true /*5*/, this);
+ break;
+ case 3:
+ _globals->_soundHandler.startSound(377, 0, 127);
+ setDelay(120);
+ break;
+ case 4:
+ _globals->_scenePalette.addUnkPal(_palette1._palette, 256, 1, this);
+ break;
+ case 5:
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene9900::strAction2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ var1 = 0;
+ _txtArray1Index = 0;
+ _txtArray1[0]._position.y = 200;
+ _txtArray1[0]._position.y = 300;
+ _txtArray2[0]._position.y = 400;
+ _txtArray2[0]._position.y = 500;
+ var3 = 0;
+ // No break on purpose
+ case 1: {
+ Common::String msg = _vm->_dataManager->getMessage(8030, var1++);
+ if (!msg.compareTo("LASTCREDIT")) {
+ if (var3 == 0) {
+ // Not used?
+ // int x = _txtArray1[_txtArray1Index].getFrame().getBounds().height();
+ _txtArray1[_txtArray1Index]._moveDiff.y = 10;
+
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(_txtArray1[_txtArray1Index]._moveDiff.x, -100);
+ _txtArray1[_txtArray1Index].addMover(mover, &pt, 0);
+
+ // Not used?
+ // int x = _txtArray2[_txtArray1Index].getFrame().getBounds().height();
+ _txtArray2[_txtArray1Index]._moveDiff.y = 10;
+ _txtArray1Index = (_txtArray1Index + 1) % 2;
+ }
+ var3 = 1;
+ _txtArray1[_txtArray1Index]._textMode = ALIGN_CENTRE;
+ _txtArray1[_txtArray1Index]._width = 240;
+ _txtArray1[_txtArray1Index]._fontNumber = 2;
+ _txtArray1[_txtArray1Index]._colour1 = 7;
+ _txtArray1[_txtArray1Index].setup(msg);
+ _txtArray1[_txtArray1Index]._field7A = 20;
+ _txtArray1[_txtArray1Index]._moveDiff.y = 2;
+ _txtArray1[_txtArray1Index].setPriority2(255);
+ int frameWidth = _txtArray1[_txtArray1Index].getFrame().getBounds().width();
+ int frameHeight = _txtArray1[_txtArray1Index].getFrame().getBounds().height();
+ _txtArray1[_txtArray1Index].setPosition(Common::Point((320 - frameWidth) / 2, 200));
+ NpcMover *mover2 = new NpcMover();
+ Common::Point pt2(_txtArray1[_txtArray1Index]._position.x, 100);
+ _txtArray1[_txtArray1Index].addMover(mover2, &pt2, 0);
+
+ _txtArray2[_txtArray1Index]._textMode = ALIGN_CENTRE;
+ _txtArray2[_txtArray1Index]._width = 240;
+ _txtArray2[_txtArray1Index]._fontNumber = 2;
+ _txtArray2[_txtArray1Index]._colour1 = 23;
+
+ msg = _vm->_dataManager->getMessage(8030, var1++);
+ _txtArray2[_txtArray1Index].setup(msg);
+ _txtArray2[_txtArray1Index]._field7A = 20;
+ _txtArray2[_txtArray1Index]._moveDiff.y = 2;
+ _txtArray2[_txtArray1Index].setPriority2(255);
+ frameWidth = _txtArray2[_txtArray1Index].getFrame().getBounds().width();
+ _txtArray2[_txtArray1Index].setPosition(Common::Point((320 - frameWidth) / 2, 200 + frameHeight));
+ } else {
+ _globals->_player.enableControl();
+ _actionIndex = 3;
+ signal();
+ }
+ break;
+ }
+ case 2:
+ setDelay(60);
+ _actionIndex = 1;
+ break;
+ case 3:
+ setDelay(7200);
+ break;
+ case 4:
+ _txtArray1[0].remove();
+ _txtArray1[1].remove();
+ _txtArray2[0].remove();
+ _txtArray2[1].remove();
+ remove();
+ break;
+ default:
+ break;
+ }
+}
+void Scene9900::strAction2::dispatch() {
+// if (this->_txtArray1[0]._textSurface != 0) {
+ int frameHeight = _txtArray1[0].getFrame().getBounds().height();
+ _txtArray2[0]._position.y = frameHeight + _txtArray1[0]._position.y;
+ _txtArray2[0]._flags |= OBJFLAG_PANES;
+// }
+// if (this->_txtArray1[1]._textSurface != 0) {
+ frameHeight = _txtArray1[1].getFrame().getBounds().height();
+ _txtArray2[1]._position.y = frameHeight + _txtArray1[1]._position.y;
+ _txtArray2[1]._flags |= OBJFLAG_PANES;
+// }
+ Action::dispatch();
+}
+
+void Scene9900::strAction3::signal() {
+ RGB8 mask3, mask4;
+ mask3.r = 0xff; mask3.g = mask3.b = 0;
+ mask4.r = mask4.g = mask4.b = 0;
+
+ switch (_actionIndex++) {
+ case 0:
+ _palette2.getPalette();
+ _palette3.loadPalette(2003);
+ _globals->_scenePalette.addUnkPal(_palette3._palette, 256, true /*5*/, this);
+ break;
+ case 1:
+ _globals->_scenePalette.addUnkPal(&mask3, 1, true /*10*/, this);
+ break;
+ case 2:
+ _globals->_scenePalette.addUnkPal(&mask4, 1, true /*1*/, this);
+ break;
+ case 3:
+ _palette2.loadPalette(17);
+ _globals->_sceneManager._scene->loadScene(17);
+ _globals->_scenePalette.addUnkPal(_palette2._palette, 256, true /*5*/, this);
+ break;
+ case 4:
+ _globals->_game.endGame(9900, 61);
+ remove();
+ default:
+ break;
+ }
+}
+
+void Scene9900::signal() {
+ if ((_sceneMode != 9913) && (_sceneMode != 9905) && (_sceneMode != 9904) && (_sceneMode != 9912)) {
+ _object1.hide();
+ _object2.hide();
+ _object3.hide();
+ _object4.hide();
+ _object5.hide();
+ _object6.hide();
+ }
+
+ _object1.animate(ANIM_MODE_NONE, 0);
+ _object2.animate(ANIM_MODE_NONE, 0);
+ _object3.animate(ANIM_MODE_NONE, 0);
+ _object4.animate(ANIM_MODE_NONE, 0);
+ _object5.animate(ANIM_MODE_NONE, 0);
+ _object6.animate(ANIM_MODE_NONE, 0);
+
+ _object1.setObjectWrapper(0);
+ _object2.setObjectWrapper(0);
+ _object3.setObjectWrapper(0);
+ _object4.setObjectWrapper(0);
+ _object5.setObjectWrapper(0);
+ _object6.setObjectWrapper(0);
+
+ _object1.addMover(0);
+ _object2.addMover(0);
+ _object3.addMover(0);
+ _object4.addMover(0);
+ _object5.addMover(0);
+ _object6.addMover(0);
+
+ switch (_sceneMode){
+ case 150:
+ _globals->_soundHandler.startSound(380, 0, 127);
+ _object8.postInit(0);
+ _object8.setVisage(2002);
+ _object8.setStrip(1);
+ _object8.setFrame(1);
+ _object8.setPriority2(200);
+ _object8.setPosition(Common::Point(64, 199));
+ _globals->_player.disableControl();
+ _sceneMode = 9908;
+ setAction(&_sequenceManager, this, 9908, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 162:
+ warning("TBC: shutdown();");
+ _globals->_game.quitGame();
+ break;
+ case 9901:
+ _globals->_player.disableControl();
+ _sceneMode = 9906;
+ setAction(&_sequenceManager, this, 9906, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 9902:
+ _globals->_player.disableControl();
+ _sceneMode = 9901;
+ setAction(&_sequenceManager, this, 9901, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9903:
+ _globals->_player.disableControl();
+ _sceneMode = 9902;
+ setAction(&_sequenceManager, this, 9902, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9904:
+ _globals->_soundHandler.startSound(390, 0, 127);
+ _sceneMode = 9912;
+ setAction(&_strAction2, this);
+ break;
+ case 9905:
+ _sceneMode = 150;
+ setAction(&_strAction1, this);
+ break;
+ case 9906:
+ if (_object8._state == 0) {
+ _globals->_player.disableControl();
+ _sceneMode = 9913;
+ setAction(&_sequenceManager, this, 9913, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 9905;
+ setAction(&_sequenceManager, this, 9905, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ }
+ break;
+ case 9907:
+ _globals->_player.disableControl();
+ _sceneMode = 9903;
+ setAction(&_sequenceManager, this, 9903, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9908:
+ _object8.remove();
+ _globals->_player.disableControl();
+ _sceneMode = 9904;
+ setAction(&_sequenceManager, this, 9904, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9909:
+ _globals->_soundHandler.startSound(375, 0, 127);
+ _globals->_player.disableControl();
+ _sceneMode = 9907;
+ setAction(&_sequenceManager, this, 9907, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9910:
+ _globals->_player.disableControl();
+ _sceneMode = 9911;
+ setAction(&_sequenceManager, this, 9911, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9911:
+ _globals->_soundHandler.startSound(367, 0, 127);
+ _globals->_player.disableControl();
+ _sceneMode = 9909;
+ setAction(&_sequenceManager, this, 9909, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ break;
+ case 9912:
+ _globals->_player.disableControl();
+ _sceneMode = 9912;
+ setAction(&_sequenceManager, this, 9912, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+ _sceneMode = 162;
+ _globals->_player.enableControl();
+ _globals->_player._canWalk = false;
+ break;
+ case 9913:
+ _sceneMode = 200;
+ setAction(&_strAction3, this);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene9900::process(Event &event) {
+ if (event.handled)
+ return;
+ Scene::process(event);
+ if (_sceneMode != 9906) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (_globals->_events.getCursor() == OBJECT_ITEMS)) {
+ _object8._state = 1;
+ _globals->_inventory._items._sceneNumber = 9900;
+ _globals->_events.setCursor(CURSOR_USE);
+ }
+ }
+}
+
+void Scene9900::dispatch() {
+ if (_action)
+ _action->dispatch();
+}
+
+void Scene9900::postInit(SceneObjectList *OwnerList) {
+ _object1.postInit(0);
+ _object1.hide();
+ _object2.postInit(0);
+ _object2.hide();
+ _object3.postInit(0);
+ _object3.hide();
+ _object4.postInit(0);
+ _object4.hide();
+ _object5.postInit(0);
+ _object5.hide();
+ _object6.postInit(0);
+ _object6.hide();
+
+ _object8._state = 0;
+
+ _globals->_inventory._concentrator._sceneNumber = 9900;
+ _globals->_inventory._items._rlbNum = 3;
+ _globals->_inventory._items._cursorNum = 6;
+ _globals->_inventory._items._description = Common::String("One of the items from the stasis ship. The other is on the Lance's bridge.");
+
+ _stripManager.addSpeaker(&_speakerMR);
+ _globals->_player.disableControl();
+ _sceneMode = 9910;
+ setAction(&_sequenceManager, this, 9910, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 9999
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene9999::Action1::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(600);
+ break;
+ case 1:
+ _globals->_sceneManager.changeScene(3500);
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene9999::Action2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ SceneItem::display(9999, 0, SET_Y, 10, SET_X, 30, SET_FONT, 2, SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 23, SET_WIDTH, 260, SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(300);
+ break;
+ case 2:
+ _globals->_stripNum = 3600;
+ _globals->_sceneManager.changeScene(3600);
+ default:
+ break;
+ }
+}
+
+void Scene9999::postInit(SceneObjectList *OwnerList) {
+ loadScene(9998);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _object1.postInit();
+ _object1.setVisage(1303);
+ _object1.setStrip2(3);
+ _object1.setPosition(Common::Point(160, 152), 0);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(1303);
+ _globals->_player.setStrip2(1);
+ _globals->_player.setPriority2(250);
+ _globals->_player.animate(ANIM_MODE_2, 0);
+ _globals->_player.setPosition(Common::Point(194, 98), 0);
+ _globals->_player._numFrames = 20;
+ _globals->_player.disableControl();
+
+ _object2.postInit();
+ _object2.setVisage(1303);
+ _object2.setStrip2(2);
+ _object2.setPriority2(2);
+ _object2.setPosition(Common::Point(164, 149), 0);
+
+ _object3.postInit();
+ _object3.setVisage(1303);
+ _object3.setStrip2(2);
+ _object3.setPriority2(2);
+ _object3.setFrame(2);
+ _object3.setPosition(Common::Point(292, 149), 0);
+ _object3.setAction(&_action3);
+
+ if (_globals->_sceneManager._previousScene == 3500)
+ setAction(&_action2);
+ else
+ setAction(&_action1);
+
+ _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+
+ if (_globals->_sceneManager._previousScene == 3500)
+ _globals->_stripNum = 2222;
+ else
+ _globals->_stripNum = 2121;
+
+ _globals->_soundHandler.startSound(118, 0, 127);
+
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes10.h b/engines/tsage/ringworld_scenes10.h
new file mode 100644
index 0000000000..a89456e39d
--- /dev/null
+++ b/engines/tsage/ringworld_scenes10.h
@@ -0,0 +1,544 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES10_H
+#define TSAGE_RINGWORLD_SCENES10_H
+
+#include "common/scummsys.h"
+#include "tsage/ringworld_logic.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+class SceneObject9150 : public SceneObject {
+public:
+ int _timer, _signalFlag;
+
+ virtual void synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ s.syncAsSint16LE(_timer);
+ s.syncAsSint16LE(_signalFlag);
+ }
+ virtual Common::String getClassName() { return "SceneObject9150"; }
+};
+
+class Scene2 : public Scene {
+public :
+ int _sceneState;
+
+ Scene2();
+ virtual void synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ s.syncAsSint16LE(_sceneState);
+ }
+};
+
+class Object9350 : public SceneObject {
+public:
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void draw();
+};
+
+class Scene9100 : public Scene {
+ /* Items */
+ class SceneHotspot1 : public NamedHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SceneHotspot1 _sceneHotspot1;
+ NamedHotspot _sceneHotspot2;
+ NamedHotspot _sceneHotspot3;
+ NamedHotspot _sceneHotspot4;
+ NamedHotspot _sceneHotspot5;
+ NamedHotspot _sceneHotspot6;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9150 : public Scene2 {
+ class Object3 : public SceneObject9150 {
+ public:
+ virtual void signal();
+ virtual void dispatch();
+ };
+public:
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+ SceneObject _object1;
+ SceneObject _object2;
+ Object3 _object3;
+ NamedHotspot _sceneHotspot1;
+ NamedHotspot _sceneHotspot2;
+ NamedHotspot _sceneHotspot3;
+ NamedHotspot _sceneHotspot4;
+ NamedHotspot _sceneHotspot5;
+ NamedHotspot _sceneHotspot6;
+ NamedHotspot _sceneHotspot7;
+ NamedHotspot _sceneHotspot8;
+ NamedHotspot _sceneHotspot9;
+ NamedHotspot _sceneHotspot10;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9200 : public Scene2 {
+ class SceneHotspot1 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ Action _action1;
+ SpeakerGText _speakerGText;
+ SpeakerGR _speakerGR;
+ SpeakerQText _speakerQText;
+ SoundHandler _soundHandler;
+ SceneHotspot1 _hotspot1;
+ NamedHotspot _hotspot2;
+ NamedHotspot _hotspot3;
+ NamedHotspot _hotspot4;
+ NamedHotspot _hotspot5;
+ NamedHotspot _hotspot6;
+ NamedHotspot _hotspot7;
+ NamedHotspot _hotspot8;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+ virtual void process(Event &event);
+};
+
+class Scene9300 : public Scene {
+public:
+ SequenceManager _sequenceManager;
+ SceneObject _object1;
+ SceneObject _object2;
+ NamedHotspot _hotspot1;
+ NamedHotspot _hotspot2;
+ NamedHotspot _hotspot3;
+ NamedHotspot _hotspot4;
+ NamedHotspot _hotspot5;
+ NamedHotspot _hotspot6;
+ NamedHotspot _hotspot7;
+ NamedHotspot _hotspot8;
+ NamedHotspot _hotspot9;
+ NamedHotspot _hotspot10;
+ NamedHotspot _hotspot11;
+ NamedHotspot _hotspot12;
+ NamedHotspot _hotspot13;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9350 : public Scene2 {
+public:
+ SequenceManager _sequenceManager;
+ Object9350 _object1;
+ SceneObject _object2;
+ NamedHotspot _sceneHotspot1;
+ NamedHotspot _sceneHotspot2;
+ NamedHotspot _sceneHotspot3;
+ NamedHotspot _sceneHotspot4;
+ NamedHotspot _sceneHotspot5;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9360 : public Scene2 {
+public:
+ SequenceManager _sequenceManager;
+ Action _action1;
+ Object9350 _object1;
+ NamedHotspot _hotspot1;
+ NamedHotspot _hotspot2;
+ NamedHotspot _hotspot3;
+ NamedHotspot _hotspot4;
+ NamedHotspot _hotspot5;
+ NamedHotspot _hotspot6;
+ NamedHotspot _hotspot7;
+ NamedHotspot _hotspot8;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9400 : public Scene2 {
+ class SceneHotspot7 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class SceneHotspot8 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ Scene9400();
+ SequenceManager _sequenceManager;
+ Action _action1;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SpeakerOText _speakerOText;
+ SpeakerOR _speakerOR;
+ SpeakerQText _speakerQText;
+ NamedHotspot _hotspot1;
+ NamedHotspot _hotspot2;
+ NamedHotspot _hotspot3;
+ NamedHotspot _hotspot4;
+ NamedHotspot _hotspot5;
+ NamedHotspot _hotspot6;
+ SoundHandler _soundHandler;
+ int _field1032;
+ SceneHotspot7 _hotspot7;
+ SceneHotspot8 _hotspot8;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9450 : public Scene2 {
+ class Object2 : public SceneObject {
+ public:
+ virtual void signal();
+ };
+
+ class Object3 : public SceneObject9150 {
+ public:
+ virtual void dispatch();
+ };
+
+ class Hotspot1 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot3 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SceneObject _object1;
+ SequenceManager _sequenceManager1;
+ SequenceManager _sequenceManager2;
+ Object2 _object2;
+ SequenceManager _sequenceManager3;
+ Object3 _object3;
+ Hotspot1 _hotspot1;
+ NamedHotspot _hotspot2;
+ Hotspot3 _hotspot3;
+ NamedHotspot _hotspot4;
+ NamedHotspot _hotspot5;
+ NamedHotspot _hotspot6;
+ NamedHotspot _hotspot7;
+ NamedHotspot _hotspot8;
+ NamedHotspot _hotspot9;
+ NamedHotspot _hotspot10;
+ NamedHotspot _hotspot11;
+ NamedHotspot _hotspot12;
+ NamedHotspot _hotspot13;
+ NamedHotspot _hotspot14;
+ NamedHotspot _hotspot15;
+ NamedHotspot _hotspot16;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9500 : public Scene2 {
+ class Hotspot1 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot2 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot3 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot4 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SequenceManager _sequenceManager;
+ SceneObject _candle;
+ SceneObject _object2;
+ SceneObject _object3;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ Hotspot3 _hotspot3;
+ Hotspot4 _hotspot4;
+ Hotspot4 _hotspot5;
+ NamedHotspot _hotspot6;
+ NamedHotspot _hotspot7;
+ NamedHotspot _hotspot8;
+ NamedHotspot _hotspot9;
+ NamedHotspot _hotspot10;
+ NamedHotspot _hotspot11;
+ NamedHotspot _hotspot12;
+ NamedHotspot _hotspot13;
+ NamedHotspot _hotspot14;
+ NamedHotspot _hotspot15;
+ NamedHotspot _hotspot16;
+ NamedHotspot _hotspot17;
+ NamedHotspot _hotspot18;
+ NamedHotspot _hotspot19;
+ NamedHotspot _hotspot20;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+ virtual void process(Event &event);
+};
+
+class Scene9700 : public Scene2 {
+ SequenceManager _sequenceManager;
+ SceneObject _object1;
+ NamedHotspot _sceneHotspot1;
+ NamedHotspot _sceneHotspot2;
+ NamedHotspot _sceneHotspot3;
+ NamedHotspot _sceneHotspot4;
+ NamedHotspot _sceneHotspot5;
+ NamedHotspot _sceneHotspot6;
+ GfxButton _gfxButton1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+};
+
+class Scene9750 : public Scene {
+public:
+ SequenceManager _sequenceManager;
+ SceneObject _object1;
+ SceneObject _object2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene9850 : public Scene {
+ class Object6 : public SceneObject{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Object7 : public SceneObjectExt{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot12 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot14 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot16 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot17 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot18 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot19 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot20 : public NamedHotspot{
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SceneObject _objDoor;
+ SceneObject _objCloak;
+ SceneObject _objJacket;
+ SceneObject _objTunic2;
+ SceneObject _objLever;
+ Object6 _objScimitar;
+ Object7 _objSword;
+ SoundHandler _soundHandler;
+ NamedHotspot _hotspot1;
+ NamedHotspot _hotspot2;
+ NamedHotspot _hotspot3;
+ NamedHotspot _hotspot4;
+ NamedHotspot _hotspot5;
+ NamedHotspot _hotspot6;
+ NamedHotspot _hotspot7;
+ NamedHotspot _hotspot8;
+ NamedHotspot _hotspot9;
+ NamedHotspot _hotspot10;
+ NamedHotspot _hotspot11;
+ Hotspot12 _hotspot12;
+ NamedHotspot _hotspot13;
+ Hotspot14 _hotspot14;
+ NamedHotspot _hotspot15;
+ Hotspot16 _hotspot16;
+ Hotspot17 _hotspot17;
+ Hotspot18 _hotspot18;
+ Hotspot19 _hotspot19;
+ Hotspot20 _spotLever;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene9900 : public Scene {
+ class strAction1 : public Action {
+ public:
+ SceneObject _object9;
+ ScenePalette _palette1;
+
+ virtual void signal();
+ };
+
+ class strAction2 : public Action {
+ public:
+ SceneText _txtArray1[2];
+ SceneText _txtArray2[2];
+ int var1, _txtArray1Index, var3;
+
+ virtual void signal();
+ virtual void dispatch();
+ };
+
+ class strAction3 : public Action {
+ public:
+ SceneObject _object10;
+ ScenePalette _palette2;
+ ScenePalette _palette3;
+
+ virtual void signal();
+ };
+
+ class SceneTextArr1 {
+ public:
+ SceneText _sceneText[2];
+ };
+
+ class SceneTextArr2 {
+ public:
+ SceneText _sceneText[2];
+ int _var1, var2, var3;
+ };
+
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SceneObject _object7;
+ SceneObjectExt _object8;
+ strAction1 _strAction1;
+ strAction2 _strAction2;
+ strAction3 _strAction3;
+ SpeakerMR _speakerMR;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+ virtual void process(Event &event);
+};
+
+class Scene9999 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+
+ Action1 _action1;
+ Action2 _action2;
+ Action _action3;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes2.cpp b/engines/tsage/ringworld_scenes2.cpp
new file mode 100644
index 0000000000..8d95460615
--- /dev/null
+++ b/engines/tsage/ringworld_scenes2.cpp
@@ -0,0 +1,929 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/ringworld_scenes2.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 1000 - Title Screen
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene1000::Action1::signal() {
+ Scene1000 *scene = (Scene1000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(10);
+ break;
+ case 1:
+ scene->_object4.postInit();
+ scene->_object4.setVisage(1001);
+ scene->_object4._frame = 1;
+ scene->_object4.setStrip2(5);
+ scene->_object4.changeZoom(100);
+ scene->_object4.animate(ANIM_MODE_2, NULL);
+ scene->_object4.setPosition(Common::Point(403, 163));
+ setDelay(90);
+ break;
+ case 2: {
+ SceneItem::display(0, 0);
+ scene->_object4.remove();
+ scene->_object1.changeZoom(-1);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(180, 100);
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _globals->_sceneManager.changeScene(1400);
+ break;
+ }
+
+}
+
+void Scene1000::Action2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(10);
+ break;
+ case 1:
+ SceneItem::display(1000, 0, SET_Y, 20, SET_FONT, 2, SET_BG_COLOUR, -1,
+ SET_EXT_BGCOLOUR, 35, SET_WIDTH, 200, SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(180);
+ break;
+ case 2:
+ SceneItem::display(0, 0);
+ _globals->_sceneManager.changeScene(2000);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1000::Action3::signal() {
+ Scene1000 *scene = (Scene1000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_sceneManager._scene->loadBackground(0, 0);
+ setDelay(60);
+ break;
+ case 1: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(158, 31);
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ case 3:
+ setDelay(60);
+ break;
+ case 4:
+ _globals->_player.show();
+ setDelay(240);
+ break;
+ case 5: {
+ // Intro.txt file presence is used to allow user option to skip the introduction
+ _globals->_player.enableControl();
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading("Intro.txt");
+ if (!in) {
+ // File not present, so create it
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving("Intro.txt");
+ out->finalize();
+ delete out;
+ setDelay(1);
+ } else {
+ delete in;
+
+ // Prompt user for whether to start play or watch introduction
+ if (MessageDialog::show2(WATCH_INTRO_MSG, START_PLAY_BTN_STRING, INTRODUCTION_BTN_STRING) == 0) {
+ _actionIndex = 20;
+ _globals->_soundHandler.proc1(this);
+ } else {
+ setDelay(1);
+ }
+
+ _globals->_player.disableControl();
+ }
+ break;
+ }
+ case 6: {
+ scene->_object3.remove();
+ _globals->_player.setStrip2(2);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(480, 100);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 7:
+ _globals->_scenePalette.loadPalette(1002);
+ _globals->_scenePalette.refresh();
+ _globals->_scenePalette.addRotation(80, 95, -1);
+ scene->_object3.postInit();
+ scene->_object3.setVisage(1002);
+ scene->_object3.setStrip(1);
+ scene->_object3.setPosition(Common::Point(284, 122));
+ scene->_object3.changeZoom(1);
+
+ zoom(true);
+ setDelay(200);
+ break;
+ case 8:
+ zoom(false);
+ setDelay(10);
+ break;
+ case 9:
+ scene->_object3.setStrip(2);
+ scene->_object3.setPosition(Common::Point(285, 155));
+
+ zoom(true);
+ setDelay(400);
+ break;
+ case 10:
+ zoom(false);
+ setDelay(10);
+ break;
+ case 11:
+ scene->_object3.setStrip(3);
+ scene->_object3.setPosition(Common::Point(279, 172));
+
+ zoom(true);
+ setDelay(240);
+ break;
+ case 12:
+ zoom(false);
+ setDelay(10);
+ break;
+ case 13:
+ scene->_object3.setStrip(4);
+ scene->_object3.setPosition(Common::Point(270, 128));
+
+ zoom(true);
+ setDelay(300);
+ break;
+ case 14:
+ zoom(false);
+ setDelay(10);
+ break;
+ case 15:
+ scene->_object3.setStrip(1);
+ scene->_object3.setFrame(2);
+ scene->_object3.setPosition(Common::Point(283, 137));
+
+ zoom(true);
+ setDelay(300);
+ break;
+ case 16:
+ zoom(false);
+ setDelay(10);
+ break;
+ case 17:
+ scene->_object3.setStrip(5);
+ scene->_object3.setFrame(1);
+ scene->_object3.setPosition(Common::Point(292, 192));
+
+ zoom(true);
+ setDelay(300);
+ break;
+ case 18:
+ zoom(false);
+ _globals->_scenePalette.clearListeners();
+ _globals->_soundHandler.proc1(this);
+ break;
+ case 19:
+ _globals->_sceneManager.changeScene(10);
+ break;
+ case 20:
+ _globals->_sceneManager.changeScene(30);
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene1000::Action3::zoom(bool up) {
+ Scene1000 *scene = (Scene1000 *)_globals->_sceneManager._scene;
+
+ if (up) {
+ while ((scene->_object3._percent < 100) && !_vm->shouldQuit()) {
+ scene->_object3.changeZoom(MIN(scene->_object3._percent + 5, 100));
+ _globals->_sceneObjects->draw();
+ _globals->_events.delay(1);
+ }
+ } else {
+ while ((scene->_object3._percent > 0) && !_vm->shouldQuit()) {
+ scene->_object3.changeZoom(MAX(scene->_object3._percent - 5, 0));
+ _globals->_sceneObjects->draw();
+ _globals->_events.delay(1);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene1000::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+ loadScene(1000);
+
+ if (_globals->_sceneManager._previousScene == 2000) {
+ setZoomPercents(150, 10, 180, 100);
+ _object1.postInit();
+ _object1.setVisage(1001);
+ _object1._strip = 7;
+ _object1.animate(ANIM_MODE_2, 0);
+ _object1._moveDiff = Common::Point(1, 1);
+ _object1.setPosition(Common::Point(120, 180));
+
+ setAction(&_action2);
+
+ _globals->_sceneManager._scene->_sceneBounds.centre(_object1._position.x, _object1._position.y);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+ _globals->_soundHandler.startSound(114);
+ } else if (_globals->_sceneManager._previousScene == 2222) {
+ setZoomPercents(150, 10, 180, 100);
+ _object1.postInit();
+ _object1.setVisage(1001);
+ _object1._strip = 7;
+ _object1.animate(ANIM_MODE_2, 0);
+ _object1._moveDiff = Common::Point(2, 2);
+ _object1.setPosition(Common::Point(120, 180));
+
+ _globals->_sceneManager._scene->_sceneBounds.centre(_object1._position.x, _object1._position.y);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+
+ setAction(&_action1);
+ } else {
+ _globals->_soundHandler.startSound(4);
+ setZoomPercents(0, 10, 30, 100);
+ _object3.postInit();
+ _object3.setVisage(1050);
+ _object3.changeZoom(-1);
+ _object3.setPosition(Common::Point(158, 0));
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(1050);
+ _globals->_player.setStrip(3);
+ _globals->_player.setPosition(Common::Point(160, 191));
+ _globals->_player._moveDiff.x = 12;
+ _globals->_player.hide();
+ _globals->_player.disableControl();
+
+ _globals->_sceneManager._scene->_sceneBounds.centre(_object3._position.x, _object3._position.y);
+
+ setAction(&_action3);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1001 - Fleeing planet cutscene
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene1001::Action1::signal() {
+ Scene1001 *scene = (Scene1001 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_object3.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ Common::Point pt(108, 171);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ Common::Point pt(170, 159);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ scene->_object2.postInit();
+ scene->_object2.setVisage(16);
+ scene->_object2.setStrip2(4);
+ scene->_object2.setPosition(Common::Point(61, 177));
+ scene->_object2.animate(ANIM_MODE_5, this);
+
+ Common::Point pt(320, 100);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ Common::Point pt(82, 166);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 6: {
+ Common::Point pt(64, 149);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 7: {
+ Common::Point pt(15, 136);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 8: {
+ Common::Point pt(-5, 120);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 9: {
+ scene->_object1.postInit();
+ scene->_object1.setVisage(16);
+ scene->_object1.setStrip2(1);
+ scene->_object1.setFrame(1);
+ scene->_object1.setPosition(Common::Point(-75, 87));
+ scene->_object1.animate(ANIM_MODE_2, NULL);
+
+ Common::Point pt(0, 100);
+ NpcMover *mover = new NpcMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 10: {
+ Common::Point pt1(107, 115);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object1.addMover(mover1, &pt1, NULL);
+
+ scene->_object3.setVisage(16);
+ scene->_object3.setStrip2(5);
+ scene->_object3.setFrame2(2);
+ scene->_object3.setPosition(Common::Point(220, 200));
+
+ Common::Point pt2(187, 181);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object3.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 11: {
+ scene->_object2.setVisage(16);
+ scene->_object2.setStrip2(5);
+ scene->_object2.setFrame2(1);
+ scene->_object2.setPosition(Common::Point(211, 0));
+
+ Common::Point pt(189, 30);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 12:
+ scene->_stripManager.start(100, this);
+ break;
+ case 13: {
+ scene->_object4.postInit();
+ scene->_object4.setVisage(16);
+ scene->_object4.setStrip2(2);
+ scene->_object4.setFrame(4);
+ scene->_object4.setPosition(Common::Point(360, 80));
+ scene->_object4.animate(ANIM_MODE_2, NULL);
+
+ Common::Point pt(303, 97);
+ NpcMover *mover = new NpcMover();
+ scene->_object4.addMover(mover, &pt, this);
+ break;
+ }
+ case 14:
+ scene->_stripManager.start(110, this);
+ break;
+ case 15:
+ setDelay(10);
+ break;
+ case 16: {
+ scene->_soundHandler1.startSound(90);
+
+ scene->_object6.postInit();
+ scene->_object6.setVisage(16);
+ scene->_object6.setStrip2(6);
+ scene->_object6.setFrame2(2);
+ scene->_object6._moveDiff = Common::Point(20, 20);
+ scene->_object6.setPriority2(20);
+ scene->_object6.setPosition(Common::Point(scene->_object2._position.x - 6, scene->_object2._position.y + 7));
+ scene->_object6.animate(ANIM_MODE_5, NULL);
+
+ Common::Point pt(scene->_object6._position.x - 70, scene->_object6._position.y + 70);
+ NpcMover *mover = new NpcMover();
+ scene->_object6.addMover(mover, &pt, this);
+ break;
+ }
+ case 17: {
+ scene->_soundHandler1.startSound(90);
+ scene->_object6.remove();
+
+ scene->_object7.postInit();
+ scene->_object7.setVisage(16);
+ scene->_object7.setStrip2(6);
+ scene->_object7.setFrame2(1);
+ scene->_object7._moveDiff = Common::Point(20, 20);
+ scene->_object7.setPosition(Common::Point(scene->_object3._position.x - 28, scene->_object3._position.y - 11));
+ scene->_object7.setPriority2(200);
+ scene->_object7.animate(ANIM_MODE_5, NULL);
+
+ Common::Point pt(scene->_object7._position.x - 70, scene->_object7._position.y - 70);
+ NpcMover *mover = new NpcMover();
+ scene->_object7.addMover(mover, &pt, this);
+ break;
+ }
+ case 18:
+ scene->_object7.remove();
+
+ scene->_object5.postInit();
+ scene->_object5.setVisage(16);
+ scene->_object5.setPosition(Common::Point(306, 93));
+ scene->_object5._strip = 3;
+ scene->_object5.setPriority2(200);
+ scene->_object5.animate(ANIM_MODE_2, NULL);
+ setDelay(30);
+ break;
+ case 19: {
+ _globals->_soundHandler.startSound(91);
+ byte adjustData[4] = {0xff, 0xff, 0xff, 0};
+ _globals->_scenePalette.fade(adjustData, true, 0);
+
+ scene->_object1._strip = 7;
+ scene->_object1._frame = 1;
+ scene->_object1.setPosition(Common::Point(314, 112));
+ scene->_object1.addMover(NULL);
+ setDelay(2);
+ }
+ case 20:
+ _globals->_scenePalette.loadPalette(16);
+ _globals->_scenePalette.refresh();
+ setDelay(6);
+ break;
+ case 21:
+ scene->_object1._numFrames = 15;
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 22:
+ _globals->_soundHandler.startSound(92);
+ scene->_stripManager.start(111, this);
+ break;
+ case 23:
+ setDelay(60);
+ break;
+ case 24:
+ _globals->_sceneManager.changeScene(2000);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene1001::postInit(SceneObjectList *OwnerList) {
+ loadScene(16);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerCText);
+ _stripManager.addSpeaker(&_speakerCR);
+ _stripManager.addSpeaker(&_speakerSL);
+ _speakerQText._colour1 = 11;
+
+ _object3.postInit();
+ _object3.setVisage(16);
+ _object3.setStrip2(4);
+ _object3.setPosition(Common::Point(61, 177));
+
+ _globals->_soundHandler.startSound(85);
+ setAction(&_action1);
+}
+
+
+/*--------------------------------------------------------------------------
+ * Scene 1250 -
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene1250::Action1::signal() {
+ Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(120) + 60);
+ break;
+ case 1:
+ scene->_object1.animate(ANIM_MODE_5, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene1250::Action2::signal() {
+ Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ switch (_globals->_randomSource.getRandomNumber(2)) {
+ case 0:
+ scene->_object2.setPosition(Common::Point(163, 75));
+ break;
+ case 1:
+ scene->_object2.setPosition(Common::Point(109, 65));
+ break;
+ case 2:
+ scene->_object2.setPosition(Common::Point(267, 20));
+ break;
+ }
+
+ setDelay(30);
+ break;
+ case 1:
+ scene->_object2.animate(ANIM_MODE_5, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene1250::Action3::signal() {
+ Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ scene->_stripManager.start(1251, this);
+ break;
+ case 2:
+ setDelay(6);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(1000);
+ break;
+ }
+}
+
+void Scene1250::Action4::signal() {
+ Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_stripManager.start(1250, this);
+ break;
+ case 2:
+ setDelay(6);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(2000);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene1250::postInit(SceneObjectList *OwnerList) {
+ loadScene(1250);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _speakerQText._textPos = Common::Point(120, 120);
+ _speakerQText._textWidth = 180;
+
+ _object1.postInit();
+ _object1.setVisage(1250);
+ _object1.setPosition(Common::Point(126, 69));
+ _object1.setStrip2(1);
+ _object1._frame = 1;
+ _object1.setAction(&_action1);
+
+ _object2.postInit();
+ _object2.setVisage(1250);
+ _object2.setPosition(Common::Point(126, 69));
+ _object2.setStrip2(2);
+ _object2.setPriority2(255);
+ _object2._frame = 1;
+ _object2.setAction(&_action2);
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+
+ if ((_globals->_sceneManager._previousScene != 2000) || (_globals->_stripNum != 1250)) {
+ setAction(&_action4);
+ } else {
+ setAction(&_action3);
+ _globals->_soundHandler.startSound(114);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1400 - Ringworld Wall
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene1400::Action1::signal() {
+ Scene1400 *scene = (Scene1400 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1: {
+ SceneItem::display(1400, 0, SET_X, 120, SET_Y, 610, SET_FONT, 2, SET_EXT_BGCOLOUR, 23, SET_KEEP_ONSCREEN, -1, LIST_END);
+
+ Common::Point pt(160, 700);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ _globals->_player.setStrip2(3);
+ _globals->_player.changeZoom(100);
+
+ Common::Point pt(160, 100);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+
+ SceneItem::display(0, 0);
+ setDelay(360);
+ break;
+ }
+ case 3:
+ SceneItem::display(1400, 2, SET_X, 60, SET_Y, _globals->_sceneManager._scene->_sceneBounds.bottom - 80,
+ SET_FONT, 2, SET_FG_COLOUR, 13, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, -1, LIST_END);
+ setDelay(420);
+ break;
+ case 4:
+ SceneItem::display(0, 0);
+ setDelay(360);
+ break;
+ case 5:
+ SceneItem::display(1400, 3, SET_X, 60, SET_Y, _globals->_sceneManager._scene->_sceneBounds.bottom - 80,
+ SET_FONT, 2, SET_FG_COLOUR, 23, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, -1, LIST_END);
+ setDelay(360);
+ break;
+ case 6:
+ SceneItem::display(0, 0);
+ break;
+ case 7: {
+ _globals->_player._frame = 1;
+ _globals->_player.setStrip2(1);
+ _globals->_player._numFrames = 5;
+ _globals->_player.animate(ANIM_MODE_5, this);
+
+ Common::Point pt(205, 70);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, NULL);
+ _globals->_sceneManager._fadeMode = FADEMODE_NONE;
+
+ scene->loadScene(1402);
+ break;
+ }
+ case 8:
+ _globals->_player.setStrip2(2);
+ _globals->_player._numFrames = 10;
+ _globals->_player.animate(ANIM_MODE_2, NULL);
+
+ SceneItem::display(1400, 4, SET_X, 30, SET_Y, _globals->_player._position.y + 10, SET_FONT, 2,
+ SET_FG_COLOUR, 13, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, -1, LIST_END);
+ setDelay(300);
+ break;
+ case 9: {
+ SceneItem::display(0, 0);
+ Common::Point pt(450, 45);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 10:
+ _globals->_sceneManager._scrollerRect = Rect(40, 20, 280, 180);
+ _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
+ _globals->_stripNum = 1500;
+ _globals->_soundHandler.proc3();
+
+ _globals->_sceneManager.changeScene(1500);
+ break;
+ }
+}
+
+void Scene1400::Action1::dispatch() {
+ Action::dispatch();
+
+ if ((_actionIndex > 3) && (_actionIndex < 9))
+ _globals->_sceneText.setPosition(Common::Point(60, _globals->_sceneManager._scene->_sceneBounds.bottom - 80));
+
+ if ((_actionIndex <= 2) && (_globals->_player._percent > 22))
+ _globals->_player.changeZoom(100 - (800 - _globals->_player._position.y));
+
+ if ((_actionIndex >= 9) && (_globals->_player._percent > 22))
+ _globals->_player.changeZoom(100 - (_globals->_player._position.x - 205));
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene1400::postInit(SceneObjectList *OwnerList) {
+ if (_globals->_stripNum != 1400) {
+ loadScene(1401);
+ } else {
+ loadScene(1402);
+ }
+ Scene::postInit();
+
+ _globals->_sceneManager._scrollerRect = Rect(40, 90, 280, 180);
+ _globals->_player.postInit();
+ _globals->_player.setVisage(1401);
+ _globals->_player.animate(ANIM_MODE_2, 0);
+ _globals->_player.setStrip2(4);
+ _globals->_player.setPriority2(4);
+ _globals->_player.disableControl();
+
+ _globals->_player._moveDiff = Common::Point(4, 2);
+ _globals->_player.setPosition(Common::Point(160, 800));
+ _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.y = (_globals->_sceneManager._scene->_sceneBounds.top / 100) * 100;
+
+ setAction(&_action1);
+ _globals->_soundHandler.startSound(118);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 1500 - Ringworld Space-port
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene1500::Action1::signal() {
+ Scene1500 *scene = (Scene1500 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_object1.postInit();
+ scene->_object1.setVisage(1501);
+ scene->_object1._moveDiff = Common::Point(2, 1);
+ scene->_object1.setPosition(Common::Point(204, 85));
+ scene->_object1.animate(ANIM_MODE_2, NULL);
+ scene->_object1._numFrames = 3;
+ scene->_object1.changeZoom(-1);
+
+ Common::Point pt(238, 121);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 1: {
+ Common::Point pt(312, 145);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_object1.setStrip(2);
+ scene->_object1.setFrame(1);
+ scene->_object1._moveDiff.y = 2;
+ scene->_object1._numFrames = 5;
+
+ Common::Point pt(310, 150);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ Common::Point pt(304, 165);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ scene->_object1._numFrames = 3;
+ scene->_object1.setStrip2(3);
+ scene->_object1.animate(ANIM_MODE_2, this);
+
+ Common::Point pt(94, 175);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object1.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ setDelay(30);
+ break;
+ case 6:
+ scene->_soundHandler.startSound(123);
+ scene->_object1.setStrip2(4);
+ scene->_object1.setFrame(1);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 7:
+ scene->_object1.setStrip2(5);
+ scene->_object1.animate(ANIM_MODE_2, NULL);
+ scene->_soundHandler.startSound(124, this);
+ break;
+ case 8:
+ _globals->_soundHandler.startSound(126, this);
+ break;
+ case 9:
+ _globals->_soundHandler.startSound(127);
+ _globals->_sceneManager.changeScene(2000);
+ break;
+ }
+}
+
+void Scene1500::Action2::signal() {
+ Scene1500 *scene = (Scene1500 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(6);
+ break;
+ case 1: {
+ scene->_object2.postInit();
+ scene->_object2.setVisage(1502);
+ scene->_object2.setPriority2(255);
+ scene->_object2.changeZoom(5);
+ scene->_object2._frame = 1;
+ scene->_object2._moveDiff = Common::Point(1, 1);
+ scene->_object2.setPosition(Common::Point(104, 184));
+ scene->_object2.animate(ANIM_MODE_2, NULL);
+
+ Common::Point pt(118, 147);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_object2._moveDiff.x = 5;
+ scene->_object2.changeZoom(-1);
+ Common::Point pt(-55, 200);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ scene->_soundHandler.proc4();
+ _globals->_stripNum = 1505;
+ _globals->_sceneManager.changeScene(1505);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene1500::postInit(SceneObjectList *OwnerList) {
+ loadScene(1500);
+ Scene::postInit();
+
+ if ((_globals->_stripNum == 1500) || ((_globals->_stripNum != 1504) && (_globals->_stripNum != 2751))) {
+ _globals->_soundHandler.startSound(120);
+ setZoomPercents(105, 20, 145, 100);
+
+ setAction(&_action1);
+ } else {
+ setZoomPercents(150, 5, 200, 100);
+
+ _object1.postInit();
+ _object1.setVisage(1501);
+ _object1.setStrip2(5);
+ _object1.setPosition(Common::Point(94, 175));
+ _object1.animate(ANIM_MODE_2, NULL);
+
+ setAction(&_action2);
+ }
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes2.h b/engines/tsage/ringworld_scenes2.h
new file mode 100644
index 0000000000..75843d3570
--- /dev/null
+++ b/engines/tsage/ringworld_scenes2.h
@@ -0,0 +1,152 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES2_H
+#define TSAGE_RINGWORLD_SCENES2_H
+
+#include "common/scummsys.h"
+#include "tsage/ringworld_logic.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+class Scene1000 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ private:
+ void zoom(bool up);
+ public:
+ virtual void signal();
+ };
+
+public:
+ SceneObject _object1, _object2, _object3, _object4;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene1001 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ SpeakerQText _speakerQText;
+ SpeakerSL _speakerSL;
+ SpeakerCText _speakerCText;
+ SpeakerCR _speakerCR;
+ Action1 _action1;
+ SceneObject _object1, _object2, _object3, _object4;
+ SceneObject _object5, _object6, _object7;
+ SoundHandler _soundHandler1, _soundHandler2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene1250 : public Scene {
+public:
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ SpeakerQText _speakerQText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ SceneObject _object1, _object2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene1400 : public Scene {
+public:
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ virtual void dispatch();
+ };
+public:
+ Action1 _action1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+
+};
+
+class Scene1500 : public Scene {
+public:
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ SoundHandler _soundHandler;
+ Action1 _action1;
+ Action2 _action2;
+ SceneObject _object1, _object2, _object3;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes3.cpp b/engines/tsage/ringworld_scenes3.cpp
new file mode 100644
index 0000000000..b37b156907
--- /dev/null
+++ b/engines/tsage/ringworld_scenes3.cpp
@@ -0,0 +1,6098 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "tsage/ringworld_scenes3.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 2000 - Cockpit cutscenes
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2000::Action1::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ error("Old stuff");
+ break;
+ case 1:
+ scene->_stripManager.start(2075, this);
+ break;
+ case 2:
+ setDelay(4);
+ break;
+ case 3:
+ _globals->_stripNum = 0;
+ _globals->_sceneManager.changeScene(1250);
+ break;
+ }
+}
+
+void Scene2000::Action2::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_object2.animate(ANIM_MODE_6, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ break;
+ case 1:
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ if (_globals->_randomSource.getRandomNumber(4) >= 2)
+ _actionIndex = 0;
+ break;
+ case 2:
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ _actionIndex = _globals->_randomSource.getRandomNumber(1);
+ break;
+ }
+}
+
+void Scene2000::Action3::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_object6.animate(ANIM_MODE_5, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ break;
+ case 1:
+ scene->_object6.animate(ANIM_MODE_6, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene2000::Action4::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_object4.animate(ANIM_MODE_5, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ break;
+ case 1:
+ scene->_object4.animate(ANIM_MODE_6, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(179) + 60);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene2000::Action5::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_object3.animate(ANIM_MODE_5, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(125) + 300);
+ break;
+ case 1:
+ scene->_object3.animate(ANIM_MODE_6, NULL);
+ setDelay(_globals->_randomSource.getRandomNumber(125) + 300);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene2000::Action6::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(130);
+ break;
+ case 1:
+ scene->_soundHandler2.startSound(79);
+ scene->_stripManager.start(2000, this);
+ break;
+ case 2:
+ _globals->_soundHandler.startSound(81);
+ scene->_object6.postInit();
+ scene->_object6.setVisage(2003);
+ scene->_object6.setAction(NULL);
+ scene->_object6.setStrip2(2);
+ scene->_object6.setPosition(Common::Point(184, 137));
+ scene->_object6.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_stripManager.start(95, this);
+ break;
+ case 4:
+ scene->_object6.animate(ANIM_MODE_6, this);
+ break;
+ case 5:
+ _globals->_soundHandler.startSound(80);
+ scene->_object6.remove();
+ _globals->_sceneManager.changeScene(1001);
+ break;
+ }
+}
+
+void Scene2000::Action7::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ scene->_stripManager.start(2072, this);
+ break;
+ case 2:
+ setDelay(3);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(2222);
+ break;
+ }
+}
+
+void Scene2000::Action8::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ error("Old stuff");
+ break;
+ case 1:
+ scene->_stripManager.start(2073, this);
+ break;
+ case 2:
+ setDelay(10);
+ break;
+ case 3:
+ _globals->_stripNum = 2005;
+ _globals->_sceneManager.changeScene(1000);
+ break;
+ }
+}
+
+void Scene2000::Action9::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ error("Old stuff");
+ break;
+ case 1:
+ scene->_stripManager.start(2074, this);
+ break;
+ case 2:
+ setDelay(3);
+ break;
+ case 3:
+ _globals->_stripNum = 2008;
+ _globals->_sceneManager.changeScene(9999);
+ break;
+ }
+}
+
+void Scene2000::Action10::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ error("Old stuff");
+ break;
+ case 2:
+ SceneItem::display(2000, 17, SET_Y, 20, SET_X, 110, SET_FONT, 2, SET_BG_COLOUR, -1,
+ SET_FG_COLOUR, 17, SET_WIDTH, 200, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, 1, LIST_END);
+ break;
+ case 3:
+ SceneItem::display(0, 0);
+ _globals->_stripNum = 0;
+ _globals->_sceneManager.changeScene(9999);
+ break;
+ }
+}
+
+void Scene2000::Action11::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ error("Old stuff");
+ break;
+ case 1:
+ scene->_stripManager.start(2076, this);
+ break;
+ case 2:
+ scene->_stripManager.start(2077, this);
+ break;
+ case 3:
+ _globals->_stripNum = 0;
+ _globals->_sceneManager.changeScene(1400);
+ break;
+ }
+}
+
+void Scene2000::Action12::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(2020, this);
+ break;
+ case 2:
+ _globals->_player.disableControl();
+ setDelay(10);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(2300);
+ break;
+ }
+}
+
+void Scene2000::Action13::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ scene->_stripManager.start(2078, this);
+ break;
+ case 2:
+ SceneItem::display(0, 0);
+ _globals->_stripNum = 2751;
+ _globals->_sceneManager.changeScene(1500);
+ break;
+ }
+}
+
+void Scene2000::Action14::signal() {
+ Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(30);
+ break;
+ case 1:
+ scene->_stripManager.start(2070, this);
+ break;
+ case 2:
+ setDelay(60);
+ break;
+ case 3:
+ _globals->_soundHandler.startSound(99);
+ scene->_object8.show();
+ scene->_object8.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ _globals->_soundHandler.startSound(12);
+ scene->_object8.setStrip(2);
+ scene->_object8.setFrame(1);
+ scene->_object9.show();
+ scene->_object10.show();
+ setDelay(60);
+ break;
+ case 5:
+ scene->_stripManager.start(2001, this, scene);
+ break;
+ case 6:
+ _globals->_soundHandler.proc1(0/* was false */);
+ scene->_object8.setStrip(1);
+ scene->_object8.setFrame(scene->_object8.getFrameCount());
+ scene->_object8.animate(ANIM_MODE_6, this);
+
+ scene->_object9.remove();
+ scene->_object10.remove();
+ break;
+ case 7:
+ _globals->_soundHandler.startSound(111);
+ scene->_object8.remove();
+ setDelay(5);
+ break;
+ case 8:
+ scene->_stripManager.start(2071, this);
+ break;
+ case 9:
+ _globals->_stripNum = 1250;
+ _globals->_sceneManager.changeScene(1000);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2000::postInit(SceneObjectList *OwnerList) {
+ loadScene(2000);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerMR);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerGameText);
+ _stripManager.addSpeaker(&_speakerHText);
+
+ _speakerQText._npc = &_object2;
+ _speakerSText._npc = &_object3;
+ _speakerMText._npc = &_object6;
+ _speakerHText._npc = &_object6;
+ _stripManager.setCallback(this);
+
+ _object3.postInit();
+ _object3.setVisage(2002);
+ _object3.setPosition(Common::Point(65, 199));
+
+ _object4.postInit();
+ _object4.setVisage(2002);
+ _object4.setStrip(2);
+ _object4.setPosition(Common::Point(125, 199));
+ _object4.setAction(&_action4);
+
+ _object2.postInit();
+ _object2.setVisage(2001);
+ _object2.setPosition(Common::Point(43, 115));
+ _object2.setAction(&_action2);
+
+ _globals->_player.disableControl();
+
+ _object6.postInit();
+ _object6.setVisage(2003);
+ _object6.setPosition(Common::Point(267, 170));
+ _object6.setAction(&_action3);
+
+ _object8.postInit();
+ _object8.setVisage(2005);
+ _object8.setPosition(Common::Point(169, 133));
+ _object8.setPriority(133);
+ _object8.hide();
+
+ _object9.postInit();
+ _object9.setVisage(2005);
+ _object9.setStrip2(3);
+ _object9.setFrame(4);
+ _object9.setPosition(Common::Point(136, 86));
+ _object9.setPriority2(190);
+ _object9.hide();
+
+ _object10.postInit();
+ _object10.setVisage(2005);
+ _object10.setStrip2(5);
+ _object10.setFrame(4);
+ _object10.setPosition(Common::Point(202, 86));
+ _object10.setPriority2(195);
+ _object10.hide();
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 1000:
+ setAction(&_action7);
+ break;
+ case 1001:
+ _object6.remove();
+ setAction(&_action12);
+ break;
+ case 1500:
+ setAction(&_action13);
+ break;
+ case 2200:
+ _globals->_soundHandler.startSound(111);
+ setAction(&_action14);
+ break;
+ case 2222:
+ _globals->_soundHandler.startSound(115);
+ setAction(&_action8);
+ break;
+ case 3500:
+ setAction(&_action11);
+ break;
+ default:
+ _object6.remove();
+ _globals->_soundHandler.startSound(80);
+ setAction(&_action6);
+ break;
+ }
+
+ _soundHandler1.startSound(78);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2000::stripCallback(int v) {
+ switch (v) {
+ case 0:
+ _object9.setStrip(3);
+ _object9.animate(ANIM_MODE_7, NULL);
+ _object10.setStrip(6);
+ _object10.setFrame(1);
+ _object10.animate(ANIM_MODE_5, NULL);
+ break;
+ case 1:
+ _object10.setStrip(5);
+ _object10.animate(ANIM_MODE_7, NULL);
+ _object9.setStrip(4);
+ _object9.setFrame(1);
+ _object9.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ _object9.animate(ANIM_MODE_NONE, NULL);
+ break;
+ case 3:
+ _object10.setStrip(6);
+ _object10.setFrame(1);
+ _object10.animate(ANIM_MODE_5, NULL);
+ _object9.setStrip(4);
+ _object9.setFrame(1);
+ _object9.animate(ANIM_MODE_5, NULL);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2100 - Starcraft Cockpit
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2100::Action1::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ if (!scene->_field1800)
+ setDelay(1);
+ else {
+ setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL);
+ scene->_field1800 = 0;
+ }
+ break;
+ case 1: {
+ Common::Point pt(157, 62);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3: {
+ Common::Point pt(157, 56);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 4:
+ _globals->_player._strip = 3;
+ setDelay(3);
+ break;
+ case 5:
+ _globals->_player.setPriority2(1);
+ scene->_area1.display();
+ scene->_area2.display();
+ scene->_area3.display();
+ scene->_area4.display();
+
+ scene->_area1.draw(true);
+ _state = 0;
+ _globals->_events.setCursor(CURSOR_USE);
+
+ while (!_state && !_vm->getEventManager()->shouldQuit()) {
+ // Wait for an event
+ Event event;
+ if (!_globals->_events.getEvent(event)) {
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ continue;
+ }
+
+ if (scene->_area1._bounds.contains(event.mousePos)) {
+ scene->_area1.draw(true);
+ _state = scene->_area1._actionId;
+ }
+ if (scene->_area2._bounds.contains(event.mousePos)) {
+ scene->_area1.draw(false);
+ scene->_area2.draw(true);
+ _state = scene->_area2._actionId;
+ }
+ if (scene->_area3._bounds.contains(event.mousePos)) {
+ scene->_area1.draw(false);
+ scene->_area3.draw(true);
+ _state = scene->_area3._actionId;
+ }
+ }
+
+ scene->_soundHandler.startSound(161);
+ scene->_area1.restore();
+ scene->_area2.restore();
+ scene->_area3.restore();
+ scene->_area4.restore();
+
+ if (_state == 2100) {
+ setDelay(1);
+ } else {
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ }
+ break;
+ case 6:
+ if (_state == 2100) {
+ Common::Point pt(157, 65);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ } else {
+ _globals->_sceneManager.changeScene(_state);
+ }
+ break;
+ case 7:
+ _globals->_player.setPriority2(-1);
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 8:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action2::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_object3._numFrames = 5;
+ setDelay(_globals->_randomSource.getRandomNumber(59));
+ break;
+ case 1:
+ scene->_object3.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ setDelay(_globals->_randomSource.getRandomNumber(59));
+ break;
+ case 3:
+ scene->_object3.animate(ANIM_MODE_6, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene2100::Action3::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ case 2:
+ setDelay(_globals->_randomSource.getRandomNumber(119));
+ break;
+ case 1:
+ scene->_object2.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_object2.animate(ANIM_MODE_6, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene2100::Action4::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ if (!scene->_field1800)
+ setDelay(1);
+ else
+ setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL);
+ break;
+ case 1: {
+ Common::Point pt(80, 66);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_player.setVisage(2109);
+ _globals->_player._frame = 1;
+ _globals->_player._strip = 2;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(2120);
+ break;
+ }
+}
+
+void Scene2100::Action5::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL);
+ break;
+ case 2: {
+ Common::Point pt(272, 127);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _globals->_player.checkAngle(&scene->_object3);
+ setDelay(30);
+ break;
+ case 4:
+ _globals->_sceneManager.changeScene(3700);
+ break;
+ }
+}
+
+void Scene2100::Action6::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_object2.setVisage(2806);
+ scene->_object2.setStrip(1);
+ scene->_object2.setStrip2(-1);
+ scene->_object2.changeZoom(-1);
+ scene->_object2.setPosition(Common::Point(155, 116));
+ scene->_object2.setObjectWrapper(new SceneObjectWrapper());
+ scene->_object2.setAction(NULL);
+ scene->_object2.animate(ANIM_MODE_1, NULL);
+
+ Common::Point pt(130, 116);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, NULL);
+ break;
+ }
+ case 1: {
+ scene->_object2.setPriority2(-1);
+ Common::Point pt(153, 67);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, NULL);
+ break;
+ }
+ case 2:
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action7::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL);
+ break;
+ case 2:
+ setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, NULL);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(8100);
+ break;
+ }
+}
+
+void Scene2100::Action8::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL);
+ break;
+ case 2: {
+ Common::Point pt(200, 174);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _globals->_player.checkAngle(&scene->_object3);
+ scene->_stripManager.start((_globals->_inventory._translator._sceneNumber == 1) ? 7720 : 7710, this);
+ break;
+ case 4:
+ if (_globals->_inventory._translator._sceneNumber != 1)
+ _globals->_sceneManager.changeScene(7600);
+ else {
+ _globals->setFlag(24);
+ _globals->_player.enableControl();
+ remove();
+ }
+ break;
+ }
+}
+
+void Scene2100::Action9::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ scene->_stripManager.start(6050, this);
+ break;
+ case 2:
+ scene->_soundHandler.startSound(99);
+ scene->_object4.show();
+ scene->_object4.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_soundHandler.startSound(12);
+ scene->_object4.setStrip(2);
+ scene->_stripManager.start(6051, this, scene);
+ break;
+ case 4:
+ scene->_soundHandler.proc1(0/* was false */);
+ scene->_object4.setStrip(1);
+ scene->_object4.setFrame(scene->_object4.getFrameCount());
+ scene->_object4.animate(ANIM_MODE_6, this);
+ break;
+ case 5:
+ scene->_object4.hide();
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(6010, this);
+ break;
+ case 6:
+ if (scene->_stripManager._field2E8 != 165)
+ setAction(&scene->_action10);
+ else
+ setAction(&scene->_action11);
+ break;
+ }
+}
+
+void Scene2100::Action10::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL);
+ break;
+ case 2: {
+ _globals->_player.disableControl();
+ Common::Point pt(155, 64);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ scene->_object3.setVisage(2105);
+ scene->_object3.setStrip(2);
+ scene->_object3.setFrame(1);
+ scene->_object3._numFrames = 10;
+ scene->_object3.setAction(NULL);
+ scene->_object3.animate(ANIM_MODE_5, this);
+ break;
+ case 4: {
+ scene->_object3.setVisage(2705);
+ scene->_object3.setStrip2(-1);
+ scene->_object3.changeZoom(-1);
+ scene->_object3.setPriority2(-1);
+ scene->_object3.setPosition(Common::Point(260, 156));
+ scene->_object3.setObjectWrapper(new SceneObjectWrapper());
+ scene->_object3.animate(ANIM_MODE_1, NULL);
+
+ Common::Point pt(166, 64);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object3.addMover(mover, &pt, this);
+
+ setAction(&scene->_action6, NULL);
+ break;
+ }
+ case 5:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 6: {
+ _globals->_player.setPriority2(1);
+ Common::Point pt(144, 54);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 7: {
+ scene->_object3.setPriority2(2);
+ Common::Point pt1(163, 55);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object3.addMover(mover1, &pt1, NULL);
+
+ scene->_object2.setPriority2(2);
+ Common::Point pt2(158, 55);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object2.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 8:
+ _globals->_player.setPriority2(1);
+ _globals->_player.setStrip(1);
+ scene->_object3.setPriority2(1);
+ scene->_object3.setStrip(2);
+ scene->_object2.setPriority2(2);
+ scene->_object2.setStrip(3);
+
+ setDelay(45);
+ break;
+ case 9:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 10:
+ _globals->setFlag(70);
+ _globals->_stripNum = 2101;
+ _globals->_sceneManager.changeScene(2320);
+ break;
+ }
+}
+
+void Scene2100::Action11::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ scene->_object3._numFrames = 10;
+ scene->_object3.setAction(NULL);
+ scene->_object3.setVisage(2105);
+ scene->_object3.setStrip(2);
+ scene->_object3.setFrame(1);
+ scene->_object3.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ scene->_object3.setVisage(2705);
+ scene->_object3.setStrip2(-1);
+ scene->_object3.changeZoom(-1);
+ scene->_object3.setPriority2(-1);
+ scene->_object3.setPosition(Common::Point(260, 156));
+ scene->_object3.setObjectWrapper(new SceneObjectWrapper());
+ scene->_object3.animate(ANIM_MODE_1, NULL);
+
+ Common::Point pt(158, 62);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object3.addMover(mover, &pt, this);
+
+ setAction(&scene->_action6, NULL);
+ break;
+ }
+ case 3:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 4: {
+ scene->_object3.setPriority2(1);
+ Common::Point pt1(163, 55);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object3.addMover(mover1, &pt1, NULL);
+
+ scene->_object2.setPriority2(1);
+ Common::Point pt2(158, 55);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object2.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 5:
+ scene->_object3.setStrip(2);
+ scene->_object2.setStrip(3);
+ setDelay(45);
+ break;
+ case 6:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ scene->_object3.remove();
+ scene->_object2.remove();
+ _globals->setFlag(70);
+ _globals->_stripNum = 2102;
+ _globals->_player.enableControl();
+ _globals->_player._canWalk = false;
+ break;
+ }
+}
+
+void Scene2100::Action12::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_stripManager.start(6000, this);
+ break;
+ case 2:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3: {
+ Common::Point pt1(158, 74);
+ NpcMover *mover1 = new NpcMover();
+ _globals->_player.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(158, 68);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object2.addMover(mover2, &pt2, NULL);
+ break;
+ }
+ case 4: {
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, NULL);
+
+ _globals->_player.setPriority2(-1);
+ Common::Point pt1(277, 84);
+ PlayerMover *mover1 = new PlayerMover();
+ _globals->_player.addMover(mover1, &pt1, this);
+
+ scene->_object2.setPriority2(-1);
+ Common::Point pt2(255, 76);
+ PlayerMover *mover2 = new PlayerMover();
+ scene->_object2.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 6:
+ _globals->_player.setStrip(4);
+ scene->_object2.setStrip(4);
+ setDelay(60);
+ break;
+ case 7:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(6052, this);
+ break;
+ case 8:
+ if (scene->_stripManager._field2E8 == 320)
+ _globals->setFlag(74);
+ setDelay(30);
+ break;
+ case 9:
+ _globals->_events.setCursor(OBJECT_STUNNER);
+ scene->_object2.setAction(&scene->_action13);
+ setDelay(60);
+ break;
+ case 10:
+ if (_globals->getFlag(74))
+ setDelay(1);
+ break;
+ case 11:
+ scene->_stripManager.start(2170, this);
+ break;
+ case 12:
+ setDelay(5);
+ break;
+ case 13:
+ scene->_stripManager.start(_globals->getFlag(74) ? 2172 : 2174, this);
+ break;
+ case 14:
+ if (_globals->getFlag(74)) {
+ _globals->_stripNum = 6100;
+ _globals->_sceneManager.changeScene(2320);
+ } else {
+ _globals->_sceneManager.changeScene(6100);
+ }
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action13::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(6);
+ break;
+ case 1: {
+ scene->_object2.setPriority2(113);
+ Common::Point pt(178, 116);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ Common::Point pt(150, 116);
+ NpcMover *mover = new NpcMover();
+ scene->_object2.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ scene->_object2.setVisage(2108);
+ scene->_object2._strip = 3;
+ scene->_object2.setPosition(Common::Point(150, 100));
+ scene->_object2.animate(ANIM_MODE_NONE, NULL);
+ scene->_object2.changeZoom(100);
+ scene->_object2.setAction(&scene->_action3);
+ setDelay(15);
+ break;
+ case 4:
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action14::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(6);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL);
+ break;
+ case 2:
+ setAction(&scene->_sequenceManager, this, 2101, &_globals->_player, NULL);
+ break;
+ case 3:
+ scene->_stripManager.start(6008, this);
+ break;
+ case 4:
+ scene->_soundHandler.startSound(99);
+ scene->_object4.show();
+ scene->_object4.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ scene->_object4.setStrip(2);
+ scene->_stripManager.start(6009, this, scene);
+ break;
+ case 6:
+ scene->_soundHandler.proc1(0/* was false */);
+ scene->_object4.setStrip(1);
+ scene->_object4.setFrame(scene->_object4.getFrameCount());
+ scene->_object4.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ scene->_stripManager.start(6060, this);
+ break;
+ case 8:
+ scene->_object3._numFrames = 10;
+ scene->_object3.setAction(NULL);
+ scene->_object3.setVisage(2105);
+ scene->_object3.setStrip(2);
+ scene->_object3.setFrame(1);
+ scene->_object3.animate(ANIM_MODE_5, this);
+ break;
+ case 9: {
+ scene->_object3.setVisage(2705);
+ scene->_object3.setStrip2(-1);
+ scene->_object3.changeZoom(-1);
+ scene->_object3.setPriority2(-1);
+ scene->_object3.setPosition(Common::Point(260, 156));
+ scene->_object3.setObjectWrapper(new SceneObjectWrapper());
+ scene->_object3.animate(ANIM_MODE_1, NULL);
+
+ Common::Point pt(157, 65);
+ PlayerMover *mover = new PlayerMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 10:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 11: {
+ Common::Point pt(159, 51);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 12:
+ scene->_object3.setStrip(2);
+ setDelay(30);
+ case 13:
+ scene->_object3.setPriority2(1);
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 14:
+ setDelay(90);
+ break;
+ case 15:
+ _globals->_sceneManager.changeScene(7000);
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action15::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(6);
+ break;
+ case 1:
+ scene->_object3.postInit();
+ scene->_object3.setVisage(2705);
+ scene->_object3.animate(ANIM_MODE_1, NULL);
+ scene->_object3.setObjectWrapper(new SceneObjectWrapper());
+ scene->_object3.setPosition(Common::Point(157, 56));
+ scene->_object3.setPriority2(1);
+ scene->_object3.changeZoom(-1);
+
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ scene->_object3.setPriority2(-1);
+ Common::Point pt(177, 68);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+
+ Common::Point pt(272, 140);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ Common::Point pt(266, 150);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ scene->_object3.setPriority2(156);
+
+ Common::Point pt(260, 156);
+ NpcMover *mover = new NpcMover();
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 6:
+ scene->_object3.setVisage(2105);
+ scene->_object3._strip = 1;
+ scene->_object3._frame = 1;
+ scene->_object3.setPosition(Common::Point(256, 156));
+ scene->_object3.animate(ANIM_MODE_5, this);
+ scene->_object3.changeZoom(100);
+
+ scene->_object3.animate(ANIM_MODE_NONE, NULL);
+ break;
+ case 7:
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action16::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ case 4:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_stripManager.start(7001, this);
+ break;
+ case 2:
+ setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL);
+ break;
+ case 3: {
+ _globals->_player.disableControl();
+ Common::Point pt(155, 63);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 6: {
+ Common::Point pt(160, 54);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 7:
+ _globals->_player.setPriority2(1);
+ _globals->_player.setStrip(3);
+ setDelay(45);
+ break;
+ case 8:
+ scene->_soundHandler.startSound(162);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 9:
+ _globals->setFlag(15);
+ _globals->setFlag(36);
+ _globals->_sceneManager.changeScene(7000);
+ remove();
+ break;
+ }
+}
+
+void Scene2100::Action17::signal() {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL);
+ break;
+ case 2:
+ setAction(&scene->_sequenceManager, this, 2101, &_globals->_player, NULL);
+ break;
+ case 3:
+ scene->_stripManager.start(7070, this);
+ break;
+ case 4:
+ scene->_soundHandler.startSound(99);
+ scene->_object4.show();
+ scene->_object4.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ scene->_soundHandler.startSound(12);
+ scene->_object4.setStrip(2);
+ scene->_stripManager.start(7071, this, scene);
+ break;
+ case 6:
+ scene->_soundHandler.proc1(NULL);
+ scene->_object4.setStrip(1);
+ scene->_object4.setFrame(scene->_object4.getFrameCount());
+ scene->_object4.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ scene->_stripManager.start(7072, this);
+ break;
+ case 8:
+ _globals->_inventory._stasisNegator._sceneNumber = 1;
+ _globals->_sceneManager.changeScene(9100);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2100::Hotspot2::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 3);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2100, 29);
+ else {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Hotspot3::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 4);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2100, 29);
+ else {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Hotspot4::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 5);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2100, 6);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Hotspot8::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 12);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2100, 29);
+ else {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Hotspot10::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 13);
+ break;
+ case CURSOR_USE:
+ if (scene->_field1800) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2102;
+ scene->setAction(&scene->_sequenceManager, scene, 2102, &_globals->_player, NULL);
+ } else if (_globals->getFlag(13)) {
+ SceneItem::display2(2100, 28);
+ } else {
+ scene->setAction(&scene->_sequenceManager, scene, 2101, &_globals->_player, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Hotspot14::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(0))
+ SceneItem::display2(2100, 19);
+ else
+ SceneItem::display2(2100, 18);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(1))
+ SceneItem::display2(2100, 21);
+ else
+ SceneItem::display2(2100, 20);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Object1::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 1);
+ break;
+ case CURSOR_USE:
+ scene->setAction(&scene->_action1);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Object2::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2100, 30);
+ break;
+ case CURSOR_TALK:
+ if (_globals->getFlag(72)) {
+ _globals->_player.disableControl();
+ if (!_globals->getFlag(52))
+ scene->setAction(&scene->_sequenceManager, scene, 2111, NULL);
+ else {
+ scene->_sceneMode = _globals->getFlag(53) ? 2112 : 2110;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, NULL);
+ }
+ } else {
+ if (_globals->getFlag(14))
+ SceneItem::display2(2100, 32);
+ else {
+ _globals->setFlag(14);
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2108;
+ scene->setAction(&scene->_sequenceManager, scene, 2109, NULL);
+ }
+ }
+
+ scene->setAction(&scene->_action4);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2100::Object3::doAction(int action) {
+ Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (!_globals->getFlag(59))
+ SceneItem::display2(2100, 34);
+ else
+ error("***I have no response.");
+ break;
+
+ case CURSOR_TALK:
+ if (!_globals->getFlag(59)) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2108;
+ scene->setAction(&scene->_sequenceManager, scene, 2108, NULL);
+ } else {
+ error("***I have no response.");
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene2100::Scene2100() :
+ _hotspot1(0, CURSOR_LOOK, 2100, 2, LIST_END),
+ _hotspot5(0, CURSOR_LOOK, 2100, 9, LIST_END),
+ _hotspot6(0, CURSOR_LOOK, 2100, 7, CURSOR_USE, 2100, 8, LIST_END),
+ _hotspot7(0, CURSOR_LOOK, 2100, 7, CURSOR_USE, 2100, 11, LIST_END),
+ _hotspot9(0, CURSOR_LOOK, 2100, 14, LIST_END),
+ _hotspot11(0, CURSOR_LOOK, 2100, 15, CURSOR_USE, 2100, 16, LIST_END),
+ _hotspot12(0, CURSOR_LOOK, 2100, 24, CURSOR_USE, 2100, 25, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 2100, 17, LIST_END),
+ _hotspot15(0, CURSOR_LOOK, 2100, 22, CURSOR_USE, 2100, 23, LIST_END) {
+}
+
+void Scene2100::postInit(SceneObjectList *OwnerList) {
+ loadScene(2100);
+ Scene::postInit();
+ setZoomPercents(60, 80, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerMR);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerSAL);
+ _stripManager.addSpeaker(&_speakerHText);
+ _stripManager.addSpeaker(&_speakerGameText);
+ _speakerMText._npc = &_object3;
+ _speakerQText._npc = &_globals->_player;
+ _speakerSText._npc = &_object2;
+
+ _object1.postInit();
+ _object1.setVisage(2100);
+ _object1.animate(ANIM_MODE_NONE, NULL);
+ _object1.setPosition(Common::Point(157, 57));
+ _object1.setPriority(5);
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(2101);
+ _hotspot3._frame = 1;
+ _hotspot3.animate(ANIM_MODE_2, NULL);
+ _hotspot3.setPosition(Common::Point(53, 44));
+ _hotspot3.changeZoom(100);
+ _hotspot3.setPriority2(1);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(2101);
+ _hotspot4._frame = 1;
+ _hotspot4._strip = 3;
+ _hotspot4.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot4.setPosition(Common::Point(274, 52));
+ _hotspot4.changeZoom(100);
+ _hotspot4.setPriority2(1);
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(2101);
+ _hotspot5._frame = 1;
+ _hotspot5._strip = 4;
+ _hotspot5.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot5.setPosition(Common::Point(219, 141));
+ _hotspot5.changeZoom(100);
+ _hotspot5.setPriority2(160);
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(2101);
+ _hotspot6._frame = 1;
+ _hotspot6._strip = 5;
+ _hotspot6.setPriority2(175);
+ _hotspot6.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot6.setPosition(Common::Point(97, 142));
+ _hotspot6.changeZoom(100);
+
+ _hotspot7.postInit();
+ _hotspot7.setVisage(2101);
+ _hotspot7._frame = 1;
+ _hotspot7._strip = 6;
+ _hotspot7.animate(ANIM_MODE_NONE, NULL);
+ _hotspot7.setPosition(Common::Point(133, 46));
+ _hotspot7.changeZoom(100);
+ _hotspot7.setPriority2(1);
+
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2101);
+ _hotspot8._frame = 1;
+ _hotspot8._strip = 7;
+ _hotspot8.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot8.setPosition(Common::Point(20, 45));
+ _hotspot8.changeZoom(100);
+ _hotspot8.setPriority2(1);
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(2101);
+ _hotspot2._frame = 1;
+ _hotspot2._strip = 7;
+ _hotspot2.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot2.setPosition(Common::Point(88, 41));
+ _hotspot2.changeZoom(100);
+ _hotspot2.setPriority2(1);
+
+ _hotspot11.setBounds(Rect(139, 74, 173, 96));
+ _hotspot10.setBounds(Rect(71, 100, 91, 135));
+ _hotspot9.setBounds(Rect(225, 110, 251, 136));
+ _hotspot14.setBounds(Rect(100, 97, 216, 130));
+ _hotspot13.setBounds(Rect(13, 124, 94, 168));
+ _hotspot12.setBounds(Rect(217, 141, 307, 155));
+ _hotspot15.setBounds(Rect(14, 90, 46, 107));
+ _hotspot1.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ if (!_globals->getFlag(36) && !_globals->getFlag(70) && !_globals->getFlag(43)) {
+ _object3.postInit();
+ _object3.setPosition(Common::Point(246, 156));
+ _object3.animate(ANIM_MODE_NONE, NULL);
+ _object3.changeZoom(100);
+ _object3.setPriority2(156);
+ _object3.setVisage(2107);
+ _object3.setStrip(1);
+ _object3.setAction(&_action2);
+ _globals->_sceneItems.push_back(&_object3);
+ }
+
+ if (!_globals->getFlag(59) && !_globals->getFlag(70) && !_globals->getFlag(37) && !_globals->getFlag(114)) {
+ _object2.postInit();
+ _object2.setVisage(2108);
+ _object2._strip = 3;
+ _object2.setPosition(Common::Point(150, 100));
+ _object2.animate(ANIM_MODE_NONE, NULL);
+ _object2.changeZoom(100);
+ _object2.setPriority2(113);
+ _object2.setAction(&_action3);
+ _globals->_sceneItems.push_back(&_object2);
+ }
+
+ _globals->_sceneItems.addItems(&_hotspot15, &_hotspot11, &_hotspot10, &_hotspot9, &_hotspot14,
+ &_hotspot13, &_hotspot12, &_hotspot8, &_object1, &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5,
+ &_hotspot6, &_hotspot7, &_hotspot1, NULL);
+
+ _area1.setup(2153, 2, 1, 2100);
+ _area1._pt = Common::Point(200, 31);
+ _area2.setup(2153, 3, 1, 2150);
+ _area2._pt = Common::Point(200, 50);
+ _area3.setup(2153, 4, 1, 2320);
+ _area3._pt = Common::Point(200, 75);
+ _area4.setup(2153, 1, 1, OBJECT_TRANSLATOR);
+ _area4._pt = Common::Point(237, 77);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._moveDiff.x = 4;
+ _globals->_player.changeZoom(-1);
+ _globals->_player.disableControl();
+ _field1800 = 0;
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 2120:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ _object1.setPriority2(-1);
+ _globals->_player.setPriority2(-1);
+ _globals->_player.setPosition(Common::Point(80, 66));
+ _globals->_player.enableControl();
+ break;
+ case 2150:
+ _globals->_player.setPriority2(1);
+ _globals->_player.setPosition(Common::Point(157, 56));
+ _sceneMode = 2104;
+ setAction(&_sequenceManager, this, 2104, &_globals->_player, &_object1, NULL);
+ break;
+ case 2222:
+ if (_globals->_sceneObjects->contains(&_object3))
+ _object3.remove();
+
+ _globals->_player.setPriority2(1);
+ _globals->_player.setPosition(Common::Point(144, 55));
+
+ _object2.setVisage(2806);
+ _object2.changeZoom(-1);
+ _object2.setPosition(Common::Point(158, 55));
+ _object2.setPriority2(1);
+ _object2.setAction(NULL);
+ _object2.setObjectWrapper(new SceneObjectWrapper());
+ _object2.animate(ANIM_MODE_1, NULL);
+ _object2.setStrip(3);
+ setAction(&_action12);
+ break;
+ case 2320:
+ if (_globals->_stripNum == 2321) {
+ if (_globals->_sceneObjects->contains(&_object3))
+ _object3.remove();
+
+ _globals->_player.setPriority2(1);
+ _globals->_player.setPosition(Common::Point(144, 55));
+
+ _object2.postInit();
+ _object2.setVisage(2806);
+ _object2.setStrip(1);
+ _object2.changeZoom(-1);
+ _object2.setPosition(Common::Point(158, 55));
+ _object2.setPriority2(1);
+ _object2.setAction(NULL);
+ _object2.setObjectWrapper(new SceneObjectWrapper());
+ _object2.animate(ANIM_MODE_1, NULL);
+
+ setAction(&_action12);
+ } else if (_globals->_stripNum == 6100) {
+ _globals->_player.setPosition(Common::Point(157, 56));
+ _globals->_player.setPriority2(1);
+
+ _object4.postInit();
+ _object4.setVisage(2102);
+ _object4.setPosition(Common::Point(160, 199));
+ _object4.hide();
+
+ setAction(&_action14);
+ } else {
+ _globals->_player.disableControl();
+ _globals->_player.setPosition(Common::Point(157, 56));
+ _sceneMode = 2104;
+
+ setAction(&_sequenceManager, this, 2104, &_globals->_player, &_object1, NULL);
+ }
+ break;
+ case 3700:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ Scene::setZoomPercents(80, 75, 100, 90);
+
+ if (_globals->_sceneObjects->contains(&_object2))
+ _object2.remove();
+
+ _globals->_player._angle = 225;
+ _globals->_player.setStrip(6);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPriority2(-1);
+ _globals->_player.setPosition(Common::Point(272, 127));
+
+ _object3.setPosition(Common::Point(246, 156));
+ _object3.setPriority2(156);
+ _sceneMode = 2105;
+ setAction(&_sequenceManager, this, 2105, &_object3, NULL);
+ break;
+ case 4250:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ _globals->clearFlag(43);
+
+ _globals->_player.setVisage(2104);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(65, 149));
+ _globals->_player.setPriority2(152);
+ _globals->_player.setStrip(2);
+
+ _object4.postInit();
+ _object4.setVisage(2102);
+ _object4.setPosition(Common::Point(160, 199));
+ _object4.hide();
+
+ _sceneMode = 2107;
+ setAction(&_sequenceManager, this, 2107, &_object4, NULL);
+ break;
+ case 5000:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ if (_globals->_sceneObjects->contains(&_object2))
+ _object2.remove();
+
+ _globals->_player.setStrip(3);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPriority2(1);
+ _globals->_player.setPosition(Common::Point(157, 56));
+
+ _object3.setPosition(Common::Point(246, 156));
+ _object3.setPriority2(156);
+
+ setAction(&_action5);
+ break;
+ case 5100:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ _globals->_player.setVisage(2104);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(65, 149));
+ _globals->_player.setPriority2(152);
+ _globals->_player.setStrip(2);
+
+ _field1800 = 1;
+
+ _object4.postInit();
+ _object4.setVisage(2102);
+ _object4.setPosition(Common::Point(160, 199));
+ _object4.hide();
+
+ _globals->_inventory._stasisBox._sceneNumber = 0;
+ setAction(&_action9);
+ break;
+ case 7000:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ if (_globals->_inventory._stasisBox2._sceneNumber == 1) {
+ _globals->_player.setPriority2(1);
+ _globals->_player.setPosition(Common::Point(157, 56));
+
+ _object4.postInit();
+ _object4.setVisage(2102);
+ _object4.setPosition(Common::Point(160, 199));
+ _object4.hide();
+ _globals->clearFlag(15);
+ _globals->clearFlag(109);
+ _globals->clearFlag(72);
+
+ setAction(&_action17);
+ } else {
+ _globals->_player.setVisage(2104);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(65, 149));
+ _globals->_player.setPriority2(152);
+ _globals->_player.setStrip(2);
+
+ _field1800 = 1;
+ setAction(&_action16);
+ }
+ break;
+ case 7600:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ if (_globals->_sceneObjects->contains(&_object2))
+ _object2.remove();
+
+ _globals->_player.setPriority2(1);
+ _globals->_player.setPosition(Common::Point(157, 56));
+
+ setAction(&_action8);
+ break;
+ case 8100:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ _globals->_player.setVisage(2104);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(65, 149));
+ _globals->_player.setPriority2(152);
+ _globals->_player.setStrip(2);
+
+ _sceneMode = 2106;
+ setAction(&_sequenceManager, this, 2106, NULL);
+ break;
+ case 9750:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ _globals->_player.setVisage(2104);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(65, 149));
+ _globals->_player.setPriority2(152);
+ _globals->_player.setStrip(2);
+
+ _object4.postInit();
+ _object4.setVisage(2102);
+ _object4.setPosition(Common::Point(160, 199));
+ _object4.hide();
+
+ _sceneMode = 2103;
+ setAction(&_sequenceManager, this, 2103, &_object4, NULL);
+ break;
+ default:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ _globals->_player._uiEnabled = true;
+ break;
+ }
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2100::stripCallback(int v) {
+ switch (v) {
+ case 1:
+ _object4._numFrames = 4;
+ _object4.animate(ANIM_MODE_7, NULL);
+ break;
+ case 2:
+ _object4.animate(ANIM_MODE_NONE, NULL);
+ break;
+ }
+}
+
+void Scene2100::signal() {
+ switch (_sceneMode) {
+ case 2101:
+ _field1800 = 1;
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 2102:
+ _field1800 = 0;
+ _globals->_player.enableControl();
+ break;
+ case 2103:
+ _globals->_stripNum = 9000;
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ case 2106:
+ _globals->_sceneManager.changeScene(7000);
+ break;
+ case 2107:
+ _globals->_sceneManager.changeScene(5000);
+ break;
+ case 2104:
+ case 2105:
+ case 2108:
+ case 2110:
+ case 2111:
+ case 2112:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2120 - Encyclopedia
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene2120::Action1::Action1() {
+ _entries.push_back(Entry(0, 0, 0));
+ _entries.push_back(Entry(0, 0, 0));
+ _entries.push_back(Entry(4, 1, 2123));
+ _entries.push_back(Entry(1, 6, 0));
+ _entries.push_back(Entry(2, 8, 0));
+ _entries.push_back(Entry(1, 11, 0));
+ _entries.push_back(Entry(4, 13, 2131));
+ _entries.push_back(Entry(2, 18, 0));
+ _entries.push_back(Entry(4, 21, 0));
+ _entries.push_back(Entry(7, 26, 2128));
+ _entries.push_back(Entry(3, 34, 0));
+ _entries.push_back(Entry(0, 38, 0));
+ _entries.push_back(Entry(3, 39, 2126));
+ _entries.push_back(Entry(3, 43, 0));
+ _entries.push_back(Entry(4, 47, 2125));
+ _entries.push_back(Entry(3, 52, 0));
+ _entries.push_back(Entry(4, 56, 2129));
+ _entries.push_back(Entry(7, 61, 0));
+ _entries.push_back(Entry(2, 69, 2127));
+ _entries.push_back(Entry(7, 72, 2122));
+ _entries.push_back(Entry(0, 80, 2124));
+ _entries.push_back(Entry(0, 81, 0));
+ _entries.push_back(Entry(0, 82, 0));
+ _entries.push_back(Entry(1, 83, 0));
+ _entries.push_back(Entry(2, 85, 2132));
+ _entries.push_back(Entry(1, 88, 2133));
+ _entries.push_back(Entry(2, 90, 2136));
+ _entries.push_back(Entry(1, 93, 0));
+ _entries.push_back(Entry(10, 95, 2135));
+ _entries.push_back(Entry(5, 106, 0));
+ _entries.push_back(Entry(2, 112, 2134));
+ _entries.push_back(Entry(1, 115, 2130));
+ _entries.push_back(Entry(0, 117, 0));
+}
+
+void Scene2120::Action1::signal() {
+ Scene2120 *scene = (Scene2120 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ case 1:
+ // First page of index
+ SceneItem::display(2120, 0, SET_X, 120, SET_FONT, 1, SET_EXT_BGCOLOUR, 7, SET_BG_COLOUR, -1,
+ SET_WIDTH, 200, SET_KEEP_ONSCREEN, -1, SET_TEXT_MODE, 0, LIST_END);
+ break;
+ case 2:
+ // Second page of index
+ SceneItem::display(2120, 1, SET_X, 120, SET_FONT, 1, SET_EXT_BGCOLOUR, 7, SET_BG_COLOUR, -1,
+ SET_WIDTH, 200, SET_KEEP_ONSCREEN, -1, SET_TEXT_MODE, 0, LIST_END);
+ break;
+ case 3:
+ // Display an image associated with the encyclopedia entry
+ SceneItem::display(0, 0);
+
+ scene->_visageHotspot.postInit();
+ scene->_visageHotspot.setVisage(_entries[scene->_subjectIndex]._visage);
+ scene->_visageHotspot.setPosition(Common::Point(129, 180));
+ scene->_visageHotspot.animate(ANIM_MODE_NONE, NULL);
+ scene->_visageVisable = true;
+ break;
+ case 4:
+ // Display page of text
+ SceneItem::display(2121, _entries[scene->_subjectIndex]._lineNum + scene->_lineOffset,
+ SET_X, 130, SET_FONT, 1, SET_EXT_BGCOLOUR, 7, SET_BG_COLOUR, -1, SET_WIDTH, 200,
+ SET_KEEP_ONSCREEN, -1, SET_TEXT_MODE, 0, LIST_END);
+ _actionIndex = 4;
+ break;
+ }
+}
+
+void Scene2120::Action1::dispatch() {
+ Scene2120 *scene = (Scene2120 *)_globals->_sceneManager._scene;
+
+ Event event;
+ if (_globals->_events.getEvent(event) && (event.eventType == EVENT_BUTTON_DOWN)) {
+ if (scene->_listRect.contains(event.mousePos) && (scene->_dbMode != 2)) {
+ scene->_topicArrowHotspot.setPosition(Common::Point(scene->_topicArrowHotspot._position.x, event.mousePos.y));
+ }
+
+ // Subject button handling
+ if (scene->_subjectButton._bounds.contains(event.mousePos) && (scene->_dbMode != 2)) {
+ scene->_arrowHotspot.setPosition(Common::Point(291, 34));
+ scene->_arrowHotspot._strip = 1;
+ scene->_arrowHotspot.animate(ANIM_MODE_5, NULL);
+
+ if (scene->_dbMode == 0)
+ scene->_subjectIndex = (scene->_topicArrowHotspot._position.y - 48) / 8;
+ else
+ scene->_subjectIndex = (scene->_topicArrowHotspot._position.y - 44) / 8 + 16;
+
+ if ((scene->_subjectIndex == 27) && _globals->getFlag(70))
+ _globals->setFlag(75);
+
+ scene->_topicArrowHotspot.hide();
+ scene->_prevDbMode = scene->_dbMode;
+ scene->_dbMode = 2;
+ scene->_lineOffset = 0;
+
+ _actionIndex = !_entries[scene->_subjectIndex]._visage ? 4 : 3;
+ setDelay(30);
+ scene->_soundHandler.startSound(159);
+ }
+
+ // Next Page button handling
+ if (scene->_nextPageButton._bounds.contains(event.mousePos)) {
+ if (!scene->_dbMode) {
+ scene->_arrowHotspot._strip = 2;
+ scene->_arrowHotspot.setPosition(Common::Point(291, 76));
+ scene->_arrowHotspot.animate(ANIM_MODE_5, NULL);
+ scene->_dbMode = 1;
+
+ _actionIndex = 2;
+ setDelay(30);
+ }
+
+ if ((scene->_dbMode == 2) && (scene->_lineOffset < _entries[scene->_subjectIndex]._size)) {
+ if (!scene->_visageVisable) {
+ ++scene->_lineOffset;
+ } else {
+ scene->_visageVisable = false;
+ scene->_visageHotspot.remove();
+ }
+ setDelay(30);
+ }
+
+ if ((scene->_subjectIndex == 20) && scene->_visageVisable) {
+ scene->_visageVisable = false;
+ scene->_visageHotspot.remove();
+ setDelay(30);
+ }
+
+ scene->_soundHandler.startSound(159);
+ }
+
+ // Previous Page button handling
+ if (scene->_previousPageButton._bounds.contains(event.mousePos)) {
+ switch (scene->_dbMode) {
+ case 1:
+ scene->_arrowHotspot._strip = 3;
+ scene->_arrowHotspot.setPosition(Common::Point(291, 117));
+ scene->_arrowHotspot.animate(ANIM_MODE_5, NULL);
+
+ scene->_dbMode = 0;
+ _actionIndex = 1;
+ setDelay(30);
+ break;
+ case 2:
+ if (scene->_lineOffset > 0) {
+ --scene->_lineOffset;
+ setDelay(20);
+ }
+ if ((_entries[scene->_subjectIndex]._visage != 0) && (scene->_lineOffset == 0)) {
+ _actionIndex = 3;
+ setDelay(30);
+ }
+ break;
+ }
+
+ scene->_soundHandler.startSound(159);
+ }
+
+ // Exit button handling
+ if (scene->_exitButton._bounds.contains(event.mousePos)) {
+ if (scene->_dbMode != 2) {
+ // In the index, so return to the previous scene
+ setAction(NULL);
+ SceneItem::display(0, 0);
+
+ _globals->_gfxManagerInstance._font.setFontNumber(2);
+ _globals->_sceneText._fontNumber = 2;
+ _globals->_sceneManager.changeScene(_globals->_sceneManager._previousScene);
+ } else {
+ // Exit out of topic display to index
+ SceneItem::display(0, 0);
+
+ if (_entries[scene->_subjectIndex]._visage)
+ scene->_visageHotspot.remove();
+
+ scene->_arrowHotspot._strip = 4;
+ scene->_arrowHotspot.setPosition(Common::Point(291, 159));
+ scene->_arrowHotspot.animate(ANIM_MODE_5, NULL);
+ scene->_dbMode = scene->_prevDbMode;
+ _actionIndex = scene->_prevDbMode + 1;
+
+ scene->_topicArrowHotspot.show();
+ setDelay(1);
+ }
+
+ scene->_soundHandler.startSound(159);
+ }
+ }
+
+ Action::dispatch();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2120::postInit(SceneObjectList *OwnerList) {
+ loadScene(2120);
+ setZoomPercents(0, 100, 200, 100);
+ _globals->_player.disableControl();
+
+ _listRect = Rect(18, 48, 260, 177);
+ _subjectButton.setBounds(Rect(266, 13, 320, 56));
+ _nextPageButton.setBounds(Rect(266, 56, 320, 98));
+ _previousPageButton.setBounds(Rect(266, 98, 320, 140));
+ _exitButton.setBounds(Rect(266, 140, 320, 182));
+
+ _topicArrowHotspot.postInit();
+ _topicArrowHotspot.setVisage(2120);
+ _topicArrowHotspot.animate(ANIM_MODE_NONE, NULL);
+ _topicArrowHotspot.setPosition(Common::Point(240, 55));
+
+ _arrowHotspot.postInit();
+ _arrowHotspot.setVisage(2121);
+ _arrowHotspot.animate(ANIM_MODE_NONE, NULL);
+ _arrowHotspot._frame = 1;
+ _arrowHotspot.setPosition(Common::Point(400, 200));
+
+ _dbMode = 0;
+ _prevDbMode = 0;
+ _visageVisable = false;
+ _subjectIndex = 0;
+
+ setAction(&_action1);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2120::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+
+ s.syncAsSint16LE(_dbMode);
+ s.syncAsSint16LE(_prevDbMode);
+ s.syncAsSint16LE(_visageVisable);
+ s.syncAsSint16LE(_subjectIndex);
+ s.syncAsSint16LE(_lineOffset);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2150 - Starcraft Level 2
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2150::Action1::signal() {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ Common::Point pt(158, 103);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ _globals->_player.setStrip2(4);
+ Common::Point pt(158, 95);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _globals->_player.setStrip2(-1);
+ _globals->_player._strip = 3;
+ setDelay(10);
+ break;
+ case 4:
+ scene->_area1.display();
+ scene->_area2.display();
+ scene->_area3.display();
+ scene->_area4.display();
+
+ scene->_area2.draw(true);
+ _state = 0;
+ _globals->_events.setCursor(CURSOR_USE);
+
+ while (!_state && !_vm->getEventManager()->shouldQuit()) {
+ // Wait for an event
+ Event event;
+ if (!_globals->_events.getEvent(event)) {
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ continue;
+ }
+
+ if (scene->_area1._bounds.contains(event.mousePos)) {
+ scene->_area2.draw(false);
+ scene->_area1.draw(true);
+ _state = scene->_area1._actionId;
+ }
+ if (scene->_area2._bounds.contains(event.mousePos)) {
+ scene->_area2.draw(true);
+ _state = scene->_area2._actionId;
+ }
+ if (scene->_area3._bounds.contains(event.mousePos)) {
+ scene->_area2.draw(false);
+ scene->_area3.draw(true);
+ _state = scene->_area3._actionId;
+ }
+ }
+
+ scene->_soundHandler.startSound(161);
+ scene->_area1.restore();
+ scene->_area2.restore();
+ scene->_area3.restore();
+ scene->_area4.restore();
+
+ if (_state == 2150) {
+ setDelay(1);
+ } else {
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot1.animate(ANIM_MODE_6, this);
+ }
+ break;
+ case 5:
+ if (_state == 2150) {
+ Common::Point pt(158, 103);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ } else {
+ _globals->_sceneManager.changeScene(_state);
+ }
+ break;
+ case 6:
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot1.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2150::Action2::signal() {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ Common::Point pt(47, 85);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_player.setVisage(2152);
+ _globals->_player.setFrame(1);
+ _globals->_player.setStrip(8);
+ _globals->_player.animate(ANIM_MODE_8, 1, this);
+
+ scene->_soundHandler.startSound(163);
+ break;
+ case 2:
+ scene->_soundHandler.startSound(164);
+ scene->_hotspot10.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start((_globals->_inventory._ale._sceneNumber == 2150) ? 2151 : 2152, this);
+ break;
+ case 4:
+ scene->_hotspot14.postInit();
+ scene->_hotspot14.setVisage(2152);
+ scene->_hotspot14.setStrip(6);
+ scene->_hotspot14.setPosition(Common::Point(59, 54));
+
+ if (scene->_stripManager._field2E8 == 15) {
+ scene->_hotspot14.setFrame(5);
+ _globals->_inventory._ale._sceneNumber = 1;
+ } else {
+ scene->_hotspot14.setFrame(scene->_stripManager._field2E8 - 5);
+ }
+
+ _globals->_player.setFrame(1);
+ _globals->_player.setStrip(7);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ scene->_soundHandler.startSound(164);
+ scene->_hotspot10.animate(ANIM_MODE_6, NULL);
+ scene->_hotspot14.remove();
+
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 6:
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.enableControl();
+
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2150::Hotspot1::doAction(int action) {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2150, 0);
+ break;
+ case CURSOR_USE:
+ scene->setAction(&scene->_action1);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2150::Hotspot2::doAction(int action) {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2150, 1);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2156;
+ scene->setAction(&scene->_sequenceManager, scene, 2156, &_globals->_player, this, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2150::Hotspot4::doAction(int action) {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2150, 3);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2155;
+ scene->setAction(&scene->_sequenceManager, scene, 2155, &_globals->_player, &scene->_hotspot4, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2150::Hotspot7::doAction(int action) {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2150, 7);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2150, 19);
+ else {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2154;
+ scene->setAction(&scene->_sequenceManager, scene, 2154, &_globals->_player, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2150::Hotspot10::doAction(int action) {
+ Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2150, 10);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2150, 19);
+ else
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene2150::Scene2150() :
+ _hotspot3(18, CURSOR_LOOK, 2150, 2, CURSOR_USE, 2150, 18, LIST_END),
+ _hotspot5(17, CURSOR_LOOK, 2150, 4, CURSOR_USE, 2150, 18, LIST_END),
+ _hotspot6(0, CURSOR_LOOK, 2150, 5, CURSOR_USE, 2150, 18, LIST_END),
+ _hotspot8(16, CURSOR_LOOK, 2150, 8, LIST_END),
+ _hotspot9(0, CURSOR_LOOK, 2150, 9, CURSOR_USE, 2150, 13, LIST_END),
+ _hotspot11(0, CURSOR_LOOK, 2150, 12, LIST_END) {
+}
+
+void Scene2150::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(55, 85, 200, 100);
+ loadScene(2150);
+
+ _stripManager.addSpeaker(&_speakerGameText);
+
+ _hotspot7.postInit();
+ _hotspot7.setVisage(2152);
+ _hotspot7._frame = 1;
+ _hotspot7._strip = 2;
+ _hotspot7.animate(ANIM_MODE_8, NULL);
+ _hotspot7.setPosition(Common::Point(122, 62));
+ _hotspot7.changeZoom(100);
+ _hotspot7.setPriority2(76);
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(2151);
+ _hotspot2._frame = 1;
+ _hotspot2._strip = 3;
+ _hotspot2.animate(ANIM_MODE_NONE, NULL);
+ _hotspot2.setPosition(Common::Point(257, 67));
+ _hotspot2.changeZoom(100);
+ _hotspot2.setPriority2(60);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(2151);
+ _hotspot1._frame = 1;
+ _hotspot1._strip = 2;
+ _hotspot1.animate(ANIM_MODE_NONE, NULL);
+ _hotspot1.setPosition(Common::Point(158, 99));
+ _hotspot1.changeZoom(100);
+ _hotspot1.setPriority2(99);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(2150);
+ _hotspot4._frame = 1;
+ _hotspot4._strip = 2;
+ _hotspot4.animate(ANIM_MODE_NONE, NULL);
+ _hotspot4.setPosition(Common::Point(218, 200));
+ _hotspot4.changeZoom(100);
+ _hotspot4.setPriority2(200);
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(2152);
+ _hotspot10.setStrip(5);
+ _hotspot10.setPosition(Common::Point(59, 56));
+
+ _rect1 = Rect(260, 70, 270, 77);
+ _rect2 = Rect(222, 142, 252, 150);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPriority2(-1);
+ _globals->_player.changeZoom(-1);
+ _globals->_player._moveDiff.y = 3;
+
+ _hotspot8.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot9.setBounds(Rect(133, 0, 198, 91));
+ _hotspot11.setBounds(Rect(142, 119, 176, 158));
+
+ _globals->_sceneItems.addItems(&_hotspot1, &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5,
+ &_hotspot6, &_hotspot7, &_hotspot10, &_hotspot9, &_hotspot11, &_hotspot8, NULL);
+
+ _area1.setup(2153, 2, 1, 2100);
+ _area1._pt = Common::Point(200, 31);
+ _area2.setup(2153, 3, 1, 2150);
+ _area2._pt = Common::Point(200, 50);
+ _area3.setup(2153, 4, 1, 2320);
+ _area3._pt = Common::Point(200, 75);
+ _area4.setup(2153, 1, 1, 10);
+ _area4._pt = Common::Point(237, 77);
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 2120:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ _globals->_player.setPosition(Common::Point(108, 99));
+ break;
+ case 2200:
+ _globals->_player.disableControl();
+ _globals->_player.setPosition(Common::Point(159, 240));
+ _sceneMode = 2152;
+ setAction(&_sequenceManager, this, 2152, &_globals->_player, NULL);
+ break;
+ case 2280:
+ _globals->_player.disableControl();
+ _globals->_player._angle = 180;
+ _globals->_player.setPosition(Common::Point(265, 80));
+
+ _hotspot2._frame = _hotspot2.getFrameCount();
+ _sceneMode = 2157;
+ setAction(&_sequenceManager, this, 2157, &_hotspot2, NULL);
+ break;
+ case 2230:
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player._strip = 4;
+ _globals->_player.setPosition(Common::Point(229, 139));
+ break;
+ case 2100:
+ default:
+ _globals->_player.disableControl();
+ _globals->_player.setPosition(Common::Point(158, 95));
+ _globals->_player.setStrip(3);
+ _sceneMode = 2151;
+
+ setAction(&_sequenceManager, this, 2151, &_globals->_player, &_hotspot1, NULL);
+ break;
+ }
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2150::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ _rect1.synchronise(s);
+ _rect2.synchronise(s);
+}
+
+void Scene2150::signal() {
+ switch (_sceneMode) {
+ case 2151:
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.enableControl();
+ break;
+ case 2152:
+ case 2153:
+ case 2157:
+ _globals->_player.enableControl();
+ break;
+ case 2154:
+ _globals->_sceneManager.changeScene(2120);
+ break;
+ case 2155:
+ _globals->_sceneManager.changeScene(2230);
+ break;
+ case 2156:
+ _globals->_sceneManager.changeScene(2280);
+ break;
+ }
+}
+
+void Scene2150::dispatch() {
+ Scene::dispatch();
+
+ if (!_action) {
+ if (_rect1.contains(_globals->_player._position)) {
+ _globals->_player.disableControl();
+ _sceneMode = 2156;
+ setAction(&_sequenceManager, this, 2156, &_globals->_player, &_hotspot2, NULL);
+ }
+ if (_rect2.contains(_globals->_player._position)) {
+ _globals->_player.disableControl();
+ _sceneMode = 2155;
+ setAction(&_sequenceManager, this, 2155, &_globals->_player, &_hotspot4, NULL);
+ }
+ if (_globals->_player._position.y >= 196) {
+ _globals->_player.disableControl();
+ SceneItem::display2(2150, 20);
+
+ _sceneMode = 2153;
+ setAction(&_sequenceManager, this, 2153, &_globals->_player, NULL);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2200 - Starcraft - AutoDoc
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2200::Action1::signal() {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(6);
+ break;
+ case 1:
+ scene->_hotspot4.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ SceneItem::display2(2200, 7);
+ _globals->_sceneManager.changeScene(2150);
+ remove();
+ break;
+ }
+}
+
+void Scene2200::Action2::signal() {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ setDelay(30);
+ break;
+ case 2:
+ scene->_hotspot4.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_hotspot4.setStrip(4);
+ setDelay(30);
+ break;
+ case 4:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(2040, this, scene);
+ break;
+ case 5:
+ scene->_hotspot4.setStrip(4);
+ scene->_hotspot4.animate(ANIM_MODE_NONE, NULL);
+ _globals->_player._uiEnabled = true;
+ remove();
+ break;
+ }
+}
+
+void Scene2200::Action3::signal() {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_soundHandler2.startSound(103);
+
+ scene->_hotspot4.setStrip(4);
+ scene->_hotspot4.animate(ANIM_MODE_NONE, NULL);
+ _globals->_player.disableControl();
+
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(2201);
+ scene->_hotspot2._strip = 2;
+ scene->_hotspot2.setPosition(Common::Point(218, 0));
+
+ Common::Point pt(218, 63);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot2.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_soundHandler2.startSound(104);
+ scene->_hotspot4.setStrip(2);
+ scene->_hotspot4.setFrame(2);
+ setDelay(120);
+ break;
+ case 2:
+ if (_globals->getFlag(83)) {
+ _actionIndex = 8;
+ setDelay(5);
+ } else {
+ for (SynchronisedList<SceneObject *>::iterator i = _globals->_sceneObjects->begin();
+ i != _globals->_sceneObjects->end(); ++i) {
+ (*i)->hide();
+ }
+
+ _globals->_sceneManager._scene->loadScene(66);
+
+ scene->_hotspot6.postInit();
+ scene->_hotspot6.setVisage(66);
+ scene->_hotspot6.setPosition(Common::Point(160, 197));
+
+ scene->_hotspot7.postInit();
+ scene->_hotspot7.setVisage(65);
+ scene->_hotspot7.setStrip(4);
+ scene->_hotspot7.setFrame(1);
+ scene->_hotspot7.setPosition(Common::Point(145, 165));
+
+ SceneItem::display(60, 1, SET_Y, 40, SET_X, 25, SET_FONT, 75, SET_BG_COLOUR, -1, SET_FG_COLOUR, 34,
+ SET_POS_MODE, 0, SET_WIDTH, 280, SET_KEEP_ONSCREEN, 1, LIST_END);
+ _state = 1;
+ setDelay(1800);
+ }
+ break;
+ case 3:
+ case 4:
+ case 5:
+ SceneItem::display(60, _actionIndex - 2, SET_Y, 40, SET_X, 25, SET_FONT, 75, SET_BG_COLOUR, -1, SET_FG_COLOUR, 34,
+ SET_POS_MODE, 0, SET_WIDTH, 280, SET_KEEP_ONSCREEN, 1, LIST_END);
+ setDelay(1800);
+ break;
+ case 6:
+ scene->_hotspot7.remove();
+ SceneItem::display(0, 0);
+ _state = 0;
+ setDelay(5);
+ break;
+ case 7:
+ for (SynchronisedList<SceneObject *>::iterator i = _globals->_sceneObjects->begin();
+ i != _globals->_sceneObjects->end(); ++i)
+ (*i)->show();
+
+ scene->_hotspot6.remove();
+ _globals->_sceneManager._scene->loadScene(2200);
+ setDelay(5);
+ break;
+ case 8:
+ scene->_stripManager.start(2060, this, scene);
+ break;
+ case 9:
+ scene->_hotspot4.setStrip(4);
+ scene->_hotspot4.animate(ANIM_MODE_NONE, NULL);
+ break;
+ case 10:
+ _globals->_sceneManager.changeScene(2000);
+ remove();
+ break;
+ }
+}
+
+void Scene2200::Action3::process(Event &event) {
+ if (!event.handled && ((event.eventType == EVENT_KEYPRESS) || (event.eventType == EVENT_BUTTON_DOWN))) {
+ _state = 0;
+ event.handled = true;
+ setDelay(1);
+ }
+
+ Action::process(event);
+}
+
+void Scene2200::Action4::signal() {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ scene->_stripManager.start(2202, this, scene);
+ break;
+ case 2:
+ scene->_hotspot4.setStrip(4);
+ scene->_hotspot4.animate(ANIM_MODE_NONE, NULL);
+ setDelay(10);
+ break;
+ case 3:
+ _globals->_player._uiEnabled = true;
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2200::Hotspot3::doAction(int action) {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2200, 10);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2200, 11);
+ break;
+ case CURSOR_TALK:
+ _globals->_player._uiEnabled = false;
+ scene->setAction(&scene->_action4);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2200::Hotspot5::doAction(int action) {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2200, 8);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2200, 9);
+ break;
+ case CURSOR_TALK:
+ scene->_sceneMode = 2201;
+ _globals->_player._uiEnabled = false;
+ scene->setAction(&scene->_sequenceManager, scene, 2201, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2200::Hotspot9::doAction(int action) {
+ Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2200, _globals->getFlag(8) ? 1 : 0);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2200, 3);
+ break;
+ case OBJECT_INFODISK:
+ if (_globals->_sceneManager._previousScene == 2310) {
+ scene->_soundHandler2.startSound(35);
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action3);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+
+Scene2200::Scene2200() :
+ _hotspot1(0, CURSOR_LOOK, 2200, 5, CURSOR_USE, 2200, 6, LIST_END),
+ _hotspot10(0, CURSOR_LOOK, 2200, 4, LIST_END) {
+}
+
+void Scene2200::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 200, 200, 200);
+ loadScene(2200);
+
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerMR);
+ _stripManager.addSpeaker(&_speakerGameText);
+
+ _speakerQText._npc = &_globals->_player;
+ _speakerSText._npc = &_hotspot5;
+ _speakerMText._npc = &_hotspot3;
+
+ _stripManager.setCallback(this);
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(2840);
+ _hotspot5.setPosition(Common::Point(50, 235));
+
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2840);
+ _hotspot8.setStrip(2);
+ _hotspot8.setPosition(Common::Point(96, 184));
+ _hotspot8.setPriority2(236);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2640);
+ _globals->_player.setFrame2(3);
+ _globals->_player.setPosition(Common::Point(110, 233));
+ _globals->_player.disableControl();
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 2150:
+ _hotspot5.remove();
+ _hotspot8.remove();
+ break;
+ case 4000:
+ _globals->_soundHandler.startSound(100);
+ _globals->_soundHandler.proc5(true);
+ _globals->_player.remove();
+ _hotspot5.remove();
+ _hotspot8.remove();
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(2202);
+ _hotspot1.setPosition(Common::Point(175, 173));
+ _hotspot1.setPriority2(99);
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(2202);
+ _hotspot3._strip = 2;
+ _hotspot3.setPosition(Common::Point(152, 76));
+ _hotspot3.setPriority2(100);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(2202);
+ _hotspot4._strip = 3;
+ _hotspot4.setPosition(Common::Point(115, 76));
+ _hotspot4.setPriority2(200);
+
+ setAction(&_action1);
+ break;
+ case 2310:
+ default:
+ _globals->_inventory._infoDisk._sceneNumber = 1;
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(2215);
+ _hotspot3.setPosition(Common::Point(144, 132));
+ _globals->_sceneItems.push_back(&_hotspot3);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(2215);
+ _hotspot4._strip = 2;
+ _hotspot4.setPosition(Common::Point(120, 78));
+ _hotspot4.setPriority2(255);
+ _globals->_sceneItems.push_back(&_hotspot4);
+
+ _soundHandler1.startSound(101);
+ _soundHandler2.startSound(100);
+ _globals->_soundHandler.proc5(true);
+
+ _globals->_sceneItems.push_back(&_hotspot5);
+ setAction(&_action2);
+ break;
+ }
+
+ _exitRect = Rect(0, 0, 35, SCREEN_HEIGHT);
+ _hotspot9.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot10.setBounds(Rect(87, 43, 149, 109));
+
+ _globals->_sceneItems.addItems(&_hotspot10, &_hotspot9, NULL);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2200::stripCallback(int v) {
+ switch (v) {
+ case 1:
+ _hotspot4.setStrip(3);
+ _hotspot4.animate(ANIM_MODE_7, 0, NULL);
+ break;
+ case 2:
+ _hotspot4.setStrip(4);
+ _hotspot4.animate(ANIM_MODE_NONE, NULL);
+ break;
+ }
+}
+
+void Scene2200::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ _exitRect.synchronise(s);
+}
+
+void Scene2200::signal() {
+ if ((_sceneMode == 2201) || (_sceneMode == 2202))
+ _globals->_player._uiEnabled = true;
+}
+
+void Scene2200::dispatch() {
+ Scene::dispatch();
+
+ if (!_action) {
+ if (_exitRect.contains(_globals->_player._position))
+ _globals->_sceneManager.changeScene(2150);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2222 - Stasis Field Map
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2222::Action1::signal() {
+ Scene2222 *scene = (Scene2222 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ scene->_stripManager.start(2222, this);
+ break;
+ case 2:
+ setDelay(30);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(1000);
+ break;
+ }
+}
+
+void Scene2222::Action2::signal() {
+ Scene2222 *scene = (Scene2222 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ scene->_stripManager.start(5700, this);
+ break;
+ case 2:
+ setDelay(120);
+ break;
+ case 3:
+ _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2222::postInit(SceneObjectList *OwnerList) {
+ loadScene((_globals->_sceneManager._previousScene == 2000) ? 3400 : 3450);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSR);
+ _stripManager.addSpeaker(&_speakerML);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(3401);
+ _hotspot1.setStrip2(1);
+ _hotspot1._frame = 1;
+ _hotspot1.animate(ANIM_MODE_2, 0);
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(3401);
+ _hotspot2.setStrip2(2);
+ _hotspot2._frame = 2;
+ _hotspot2.animate(ANIM_MODE_2, 0);
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(3401);
+ _hotspot3.setStrip2(2);
+ _hotspot3._frame = 3;
+ _hotspot3.animate(ANIM_MODE_2, 0);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(3401);
+ _hotspot4.setStrip2(2);
+ _hotspot4._frame = 4;
+ _hotspot4.animate(ANIM_MODE_2, 0);
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(3401);
+ _hotspot5.setStrip2(2);
+ _hotspot5._frame = 5;
+ _hotspot5.animate(ANIM_MODE_2, 0);
+
+ if (_globals->_sceneManager._previousScene == 2100) {
+ _hotspot1.setPosition(Common::Point(61, 101));
+ _hotspot2.setPosition(Common::Point(239, 149));
+ _hotspot3.setPosition(Common::Point(184, 85));
+ _hotspot4.setPosition(Common::Point(105, 165));
+ _hotspot5.remove();
+
+ setAction(&_action2);
+ } else {
+ _hotspot1.setPosition(Common::Point(110, 108));
+ _hotspot2.setPosition(Common::Point(175, 136));
+ _hotspot3.setPosition(Common::Point(162, 96));
+ _hotspot4.setPosition(Common::Point(118, 141));
+ _hotspot5.setPosition(Common::Point(124, 107));
+
+ setAction(&_action1);
+ }
+
+ _soundHandler.startSound(116);
+ _globals->_sceneManager._scene->_sceneBounds.centre(_hotspot1._position);
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+
+/*--------------------------------------------------------------------------
+ * Scene 2230 - Starcraft - Quinn's Room
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2230::Action1::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ switch (scene->_field30A) {
+ case 1:
+ scene->setAction(&scene->_action3);
+ break;
+ case 2:
+ scene->setAction(&scene->_action6);
+ break;
+ default:
+ setDelay(10);
+ break;
+ }
+ break;
+ case 1: {
+ Common::Point pt(84, 74);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 3: {
+ Common::Point pt(63, 60);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 4:
+ scene->_hotspot1.animate(ANIM_MODE_6, this);
+ break;
+ case 5:
+ _globals->_sceneManager.changeScene(2150);
+ break;
+ }
+}
+
+void Scene2230::Action2::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ switch (scene->_field30A) {
+ case 2:
+ scene->setAction(&scene->_action6, this);
+ break;
+ default:
+ setDelay(10);
+ break;
+ }
+ break;
+ case 1: {
+ _globals->_player.disableControl();
+ scene->_field30A = 1;
+ _globals->_player._regionBitList |= ~0x80;
+ Common::Point pt(160, 96);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_player.setVisage(2235);
+ _globals->_player.setStrip2(1);
+ _globals->_player.setPriority2(100);
+ _globals->_player._frame = 1;
+ _globals->_player.setPosition(Common::Point(200, 68));
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_soundHandler.startSound(157);
+ _globals->_player._moveDiff = Common::Point(1, 1);
+ _globals->_player.setAction(&scene->_action4);
+ _globals->_player._uiEnabled = true;
+
+ _globals->_events.setCursor(CURSOR_USE);
+ remove();
+ break;
+ }
+}
+
+void Scene2230::Action3::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.setAction(NULL);
+ _globals->_player._moveDiff = Common::Point(5, 3);
+ _globals->_player.setStrip2(_globals->_player._strip);
+
+ Common::Point pt(190, 74);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+
+ scene->_soundHandler.proc3();
+ break;
+ }
+ case 1:
+ _globals->_player._strip = 3;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_player._regionBitList |= 0x80;
+ scene->_field30A = 0;
+
+ _globals->_player.setVisage(0);
+ _globals->_player.setStrip2(-1);
+ _globals->_player.setPriority2(-1);
+ _globals->_player.setPosition(Common::Point(164, 96));
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._canWalk = true;
+
+ _globals->_events.setCursor(CURSOR_USE);
+ remove();
+ }
+}
+
+void Scene2230::Action4::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ Common::Point pt(190 + _globals->_randomSource.getRandomNumber(9), 68);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene2230::Action5::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ switch (scene->_field30A) {
+ case 2:
+ scene->setAction(&scene->_action3, this);
+ break;
+ default:
+ setDelay(10);
+ break;
+ }
+ break;
+ case 1: {
+ _globals->_player.disableControl();
+ Common::Point pt(209, 124);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_player.setPriority2(1430);
+ _globals->_player.setVisage(2232);
+ _globals->_player._strip = 1;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->_events.setCursor(CURSOR_USE);
+ _globals->_player._uiEnabled = true;
+ scene->_field30A = 2;
+ remove();
+ break;
+ }
+}
+
+void Scene2230::Action6::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player._strip = 2;
+ _globals->_player._frame = 1;
+ _globals->_player.setPriority2(-1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 1:
+ scene->_field30A = 0;
+ _globals->_player.setVisage(0);
+ _globals->_player._strip = 1;
+ _globals->_player._canWalk = true;
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ remove();
+ break;
+ }
+}
+
+void Scene2230::Action7::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+
+ switch (scene->_field30A) {
+ case 1:
+ scene->setAction(&scene->_action3, this);
+ break;
+ case 2:
+ scene->setAction(&scene->_action6, this);
+ break;
+ default:
+ setDelay(10);
+ break;
+ }
+ break;
+ case 1: {
+ Common::Point pt(140, 119);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_soundHandler.startSound(158);
+ scene->_hotspot8.setStrip2(2);
+
+ Common::Point pt(scene->_hotspot8._position.x, 97);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot8.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(2231);
+ scene->_hotspot2._strip = 3;
+ scene->_hotspot2.setPosition(Common::Point(166, 116));
+ scene->_hotspot2.setPriority2(131);
+ scene->_hotspot2.animate(ANIM_MODE_5, this);
+
+ scene->_hotspot8._frame = 2;
+ break;
+ case 4:
+ _globals->_sceneItems.push_front(&scene->_hotspot10);
+ _globals->_sceneItems.push_front(&scene->_hotspot11);
+ _globals->_sceneItems.push_front(&scene->_hotspot12);
+
+ scene->_hotspot2.remove();
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2230::Action8::signal() {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+
+ switch (scene->_field30A) {
+ case 1:
+ scene->setAction(&scene->_action3, this);
+ break;
+ case 2:
+ scene->setAction(&scene->_action6, this);
+ break;
+ default:
+ setDelay(10);
+ break;
+ }
+ break;
+ case 1: {
+ Common::Point pt(140, 119);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ _globals->_sceneItems.remove(&scene->_hotspot10);
+ _globals->_sceneItems.remove(&scene->_hotspot11);
+ _globals->_sceneItems.remove(&scene->_hotspot12);
+
+ switch (scene->_field30A) {
+ case 1:
+ scene->setAction(&scene->_action3, this);
+ break;
+ case 2:
+ scene->setAction(&scene->_action6, this);
+ break;
+ default:
+ setDelay(10);
+ break;
+ }
+ break;
+ }
+ case 3:
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(2231);
+ scene->_hotspot2._strip = 3;
+ scene->_hotspot2._frame = scene->_hotspot2.getFrameCount();
+ scene->_hotspot2.setPosition(Common::Point(166, 116));
+ scene->_hotspot2.setPriority2(131);
+ scene->_hotspot2.animate(ANIM_MODE_6, this);
+ break;
+ case 4: {
+ scene->_soundHandler.startSound(158);
+ scene->_hotspot2.remove();
+ scene->_hotspot8._frame = 1;
+
+ Common::Point pt(scene->_hotspot8._position.x, 133);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot8.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ scene->_hotspot8.setStrip2(1);
+ _globals->_player.enableControl();
+
+ remove();
+ break;
+ }
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2230::Hotspot1::doAction(int action) {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2230, 0);
+ break;
+ case CURSOR_USE:
+ scene->setAction(&scene->_action1);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot3::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(4))
+ SceneItem::display2(2230, 1);
+ else {
+ SceneItem::display2(2230, 1);
+ SceneItem::display2(2230, 2);
+ SceneItem::display2(2230, 3);
+ _globals->setFlag(4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot4::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(30))
+ SceneItem::display2(2230, 6);
+ else if (_globals->getFlag(29)) {
+ SceneItem::display2(2230, 5);
+ _globals->setFlag(30);
+ } else {
+ SceneItem::display2(2230, 4);
+ _globals->setFlag(29);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2230, 7);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot5::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(5))
+ SceneItem::display2(2230, 9);
+ else {
+ _globals->setFlag(5);
+ SceneItem::display2(2230, 8);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot6::doAction(int action) {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(6))
+ SceneItem::display2(2230, 11);
+ else {
+ _globals->setFlag(6);
+ SceneItem::display2(2230, 10);
+ }
+ break;
+ case CURSOR_USE:
+ if (scene->_field30A == 1)
+ scene->setAction(&scene->_action3);
+ else if (_globals->getFlag(13))
+ SceneItem::display2(2230, 28);
+ else
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot7::doAction(int action) {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(7))
+ SceneItem::display2(2230, 13);
+ else {
+ _globals->setFlag(6);
+ SceneItem::display2(2230, 12);
+ }
+ break;
+ case CURSOR_USE:
+ if (scene->_field30A == 2)
+ scene->setAction(&scene->_action6);
+ else if (_globals->getFlag(13))
+ SceneItem::display2(2230, 29);
+ else
+ scene->setAction(&scene->_action5);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot8::doAction(int action) {
+ Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (scene->_hotspot8._strip == 1) {
+ if (_globals->getFlag(22))
+ SceneItem::display2(2230, 19);
+ else {
+ _globals->setFlag(22);
+ SceneItem::display2(2230, 14);
+ }
+ } else {
+ if (_globals->getFlag(25))
+ SceneItem::display2(2230, 21);
+ else {
+ _globals->setFlag(25);
+ SceneItem::display2(2230, 20);
+ }
+ }
+ break;
+ case CURSOR_USE:
+ if (scene->_hotspot8._strip == 1)
+ scene->setAction(&scene->_action7);
+ else
+ scene->setAction(&scene->_action8);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot10::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(26))
+ SceneItem::display2(2230, 25);
+ else {
+ _globals->setFlag(26);
+ SceneItem::display2(2230, 24);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2230, 28);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot11::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(27))
+ SceneItem::display2(2230, 23);
+ else {
+ _globals->setFlag(27);
+ SceneItem::display2(2230, 22);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2230, 28);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2230::Hotspot12::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(28))
+ SceneItem::display2(2230, 27);
+ else {
+ _globals->setFlag(28);
+ SceneItem::display2(2230, 26);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2230, 28);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene2230::Scene2230() :
+ _hotspot9(0, CURSOR_LOOK, 2230, 16, CURSOR_USE, 2230, 18, LIST_END) {
+}
+
+void Scene2230::postInit(SceneObjectList *OwnerList) {
+ loadScene(2230);
+ Scene::postInit();
+ setZoomPercents(75, 80, 120, 100);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(2230);
+ _hotspot1._frame = 1;
+ _hotspot1.animate(ANIM_MODE_NONE, 0);
+ _hotspot1.setPosition(Common::Point(72, 69));
+ _hotspot1.changeZoom(100);
+
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2231);
+ _hotspot8._frame = 1;
+ _hotspot8.animate(ANIM_MODE_NONE, 0);
+ _hotspot8.setPosition(Common::Point(164, 133));
+ _hotspot8.changeZoom(100);
+ _hotspot8.setPriority2(129);
+
+ _rect1 = Rect(59, 64, 89, 74);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(80, 80));
+ _globals->_player._moveDiff.y = 3;
+ _globals->_player._regionBitList |= 0x80;
+ _globals->_player.changeZoom(-1);
+
+ _field30A = 0;
+ _globals->_player.enableControl();
+
+ _hotspot5.setBounds(Rect(108, 34, 142, 76));
+ _hotspot4.setBounds(Rect(92, 14, 106, 57));
+ _hotspot6.setBounds(Rect(169, 58, 261, 95));
+ _hotspot7.setBounds(Rect(111, 117, 222, 158));
+ _hotspot3.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot10.setBounds(Rect(170, 96, 176, 106));
+ _hotspot11.setBounds(Rect(158, 109, 164, 115));
+ _hotspot12.setBounds(Rect(170, 109, 177, 115));
+
+ _globals->_sceneItems.addItems(&_hotspot8, &_hotspot5, &_hotspot4, &_hotspot6, &_hotspot7,
+ &_hotspot1, &_hotspot3, NULL);
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2230::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ _rect1.synchronise(s);
+ s.syncAsSint16LE(_field30A);
+}
+
+void Scene2230::dispatch() {
+ Scene::dispatch();
+
+ if (!_action) {
+ if (_rect1.contains(_globals->_player._position))
+ setAction(&_action1);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2280 - Starcraft - Storage Room
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2280::Action1::signal() {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ Common::Point pt(192, 97);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot16.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ Common::Point pt(218, 87);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _globals->_player.setStrip(3);
+ setDelay(10);
+ break;
+ case 4:
+ _globals->_player.setPriority2(1);
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot16.animate(ANIM_MODE_6, this);
+ break;
+ case 5:
+ _globals->_sceneManager.changeScene(7000);
+ break;
+ }
+}
+
+void Scene2280::Action2::signal() {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ Common::Point pt(94, 117);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_soundHandler.startSound(265);
+
+ _globals->_player.setVisage(2162);
+ _globals->_player._frame = 1;
+ _globals->_player._strip = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+
+ scene->_hotspot8.remove();
+ scene->_hotspot10.remove();
+ break;
+ case 2:
+ _globals->_player._frame = 1;
+ _globals->_player._strip = 2;
+ _globals->_player.animate(ANIM_MODE_4, 3, 1, this);
+ break;
+ case 3:
+ _globals->_player.animate(ANIM_MODE_5, this);
+ scene->_hotspot12.remove();
+ break;
+ case 4:
+ scene->_soundHandler.startSound(266);
+ _globals->_player.setVisage(2170);
+ _globals->_player._frame = 1;
+ _globals->_player._strip = 4;
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._moveDiff = Common::Point(4, 1);
+
+ _globals->setFlag(13);
+ SceneItem::display2(2280, 37);
+
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2280::Action3::signal() {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ Common::Point pt(94, 117);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_soundHandler.startSound(265);
+
+ _globals->_player.setVisage(2162);
+ _globals->_player._frame = 6;
+ _globals->_player._strip = 2;
+ _globals->_player.animate(ANIM_MODE_4, 3, -1, this);
+ break;
+ case 2:
+ scene->_hotspot12.postInit();
+ scene->_hotspot12.setVisage(2280);
+ scene->_hotspot12._strip = 2;
+ scene->_hotspot12._frame = 3;
+ scene->_hotspot12.setPosition(Common::Point(88, 76));
+ scene->_hotspot12.setPriority2(1);
+
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ _globals->_player._strip = 1;
+ _globals->_player._frame = 12;
+
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 4:
+ scene->_hotspot8.postInit();
+ scene->_hotspot8.setVisage(2280);
+ scene->_hotspot8._strip = 2;
+ scene->_hotspot8._frame = 1;
+ scene->_hotspot8.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot8.setPosition(Common::Point(79, 108));
+ scene->_hotspot8.changeZoom(100);
+ scene->_hotspot8.setPriority2(1);
+
+ scene->_hotspot10.postInit();
+ scene->_hotspot10.setVisage(2280);
+ scene->_hotspot10._strip = 2;
+ scene->_hotspot10._frame = 2;
+ scene->_hotspot10.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot10.setPosition(Common::Point(79, 104));
+ scene->_hotspot10.changeZoom(100);
+ scene->_hotspot10.setPriority2(1);
+
+ _globals->clearFlag(13);
+
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._strip = 4;
+ _globals->_player._moveDiff = Common::Point(3, 5);
+
+ SceneItem::display2(2280, 38);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2280::Action4::signal() {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ switch (_state) {
+ case 1:
+ case 51: {
+ Common::Point pt(163, 67);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6:
+ case 50: {
+ Common::Point pt(173, 63);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ }
+ break;
+ }
+ case 1:
+ _globals->_player.setVisage(2161);
+ _globals->_player._strip = 1;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ switch (_state) {
+ case 1:
+ scene->_hotspot18.remove();
+ _globals->_inventory._scanner._sceneNumber = 1;
+ break;
+ case 6:
+ scene->_hotspot17.remove();
+ _globals->_inventory._medkit._sceneNumber = 1;
+ break;
+ case 50:
+ scene->_hotspot17.postInit();
+ scene->_hotspot17.setVisage(2161);
+ scene->_hotspot17._strip = 2;
+ scene->_hotspot17._frame = 1;
+ scene->_hotspot17.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot17.setPosition(Common::Point(162, 39));
+ scene->_hotspot17.changeZoom(100);
+ scene->_hotspot17.setPriority2(1);
+
+ _globals->_inventory._medkit._sceneNumber = 2280;
+ _globals->_sceneItems.push_front(&scene->_hotspot17);
+ break;
+ case 51:
+ scene->_hotspot18.postInit();
+ scene->_hotspot18.setVisage(2161);
+ scene->_hotspot18._strip = 2;
+ scene->_hotspot18._frame = 2;
+ scene->_hotspot18.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot18.setPosition(Common::Point(152, 43));
+ scene->_hotspot18.changeZoom(100);
+ scene->_hotspot18.setPriority2(1);
+
+ _globals->_inventory._scanner._sceneNumber = 2280;
+ _globals->_sceneItems.push_front(&scene->_hotspot18);
+ break;
+ }
+
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ _globals->_player.enableControl();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._strip = 2;
+
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2280::Hotspot1::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(16))
+ SceneItem::display2(2280, 22);
+ else {
+ _globals->setFlag(16);
+ SceneItem::display2(2230, 21);
+ }
+ break;
+ case CURSOR_USE:
+ if (!_globals->getFlag(15))
+ SceneItem::display2(2280, 23);
+ else if (!_globals->getFlag(13))
+ SceneItem::display2(2280, 46);
+ else {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action1);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot2::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(2))
+ SceneItem::display2(2280, 1);
+ else {
+ _globals->setFlag(2);
+ SceneItem::display2(2280, 0);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2280, 2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot4::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(21))
+ SceneItem::display2(2280, 33);
+ else {
+ _globals->setFlag(21);
+ SceneItem::display2(2280, 32);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2280, 34);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot7::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2280, 24);
+ break;
+ case OBJECT_SCANNER:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2280, 43);
+ else {
+ _globals->_player.disableControl();
+ scene->_action4._state = 51;
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_events._currentCursor = CURSOR_700;
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ case OBJECT_MEDKIT:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2280, 43);
+ else {
+ _globals->_player.disableControl();
+ scene->_action4._state = 50;
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_events._currentCursor = CURSOR_700;
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot8::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2280, 3);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot10::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2280, 4);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot12::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2280, 11);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot14::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2280, 3);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ if (_globals->getFlag(13))
+ scene->setAction(&scene->_action3);
+ else
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot17::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(18))
+ SceneItem::display2(2280, 26);
+ else {
+ _globals->setFlag(18);
+ SceneItem::display2(2280, 25);
+ }
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2280, 29);
+ else {
+ _globals->_player.disableControl();
+ scene->_action4._state = 6;
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2280::Hotspot18::doAction(int action) {
+ Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(19))
+ SceneItem::display2(2280, 28);
+ else {
+ _globals->setFlag(19);
+ SceneItem::display2(2280, 27);
+ }
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2280, 29);
+ else {
+ _globals->_player.disableControl();
+ scene->_action4._state = 1;
+ scene->setAction(&scene->_action4);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene2280::Scene2280() :
+ _hotspot3(0, CURSOR_LOOK, 2280, 30, CURSOR_USE, 31, 0, LIST_END),
+ _hotspot5(0, CURSOR_LOOK, 2280, 35, CURSOR_USE, 2280, 36, LIST_END),
+ _hotspot6(0, CURSOR_LOOK, 2280, 19, CURSOR_USE, 2280, 20, LIST_END),
+ _hotspot9(0, CURSOR_LOOK, 2280, 5, CURSOR_USE, 2280, 6, LIST_END),
+ _hotspot11(0, CURSOR_LOOK, 2280, 7, CURSOR_USE, 2280, 8, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 2280, 9, CURSOR_USE, 2280, 10, LIST_END),
+ _hotspot15(0, CURSOR_LOOK, 2280, 45, LIST_END),
+ _hotspot16(0, CURSOR_LOOK, 2280, 16, CURSOR_USE, 2280, 42, LIST_END) {
+}
+
+void Scene2280::postInit(SceneObjectList *OwnerList) {
+ loadScene(2280);
+ Scene::postInit();
+ setZoomPercents(0, 70, 200, 100);
+
+ _hotspot16.postInit();
+ _hotspot16.setVisage(2281);
+ _hotspot16.setPosition(Common::Point(208, 90));
+ _hotspot16.setPriority2(80);
+
+ if (_globals->_inventory._medkit._sceneNumber == 2280) {
+ _hotspot17.postInit();
+ _hotspot17.setVisage(2161);
+ _hotspot17._strip = 2;
+ _hotspot17.setPosition(Common::Point(162, 39));
+ _hotspot17.setPriority2(1);
+
+ _globals->_sceneItems.push_back(&_hotspot17);
+ }
+
+ if (_globals->_inventory._scanner._sceneNumber == 2280) {
+ _hotspot18.postInit();
+ _hotspot18.setVisage(2161);
+ _hotspot18._strip = 2;
+ _hotspot18._frame = 2;
+ _hotspot17.setPosition(Common::Point(152, 43));
+ _hotspot17.setPriority2(1);
+
+ _globals->_sceneItems.push_back(&_hotspot17);
+ }
+
+ if (!_globals->getFlag(13)) {
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2280);
+ _hotspot8._strip = 2;
+ _hotspot8.setPosition(Common::Point(79, 108));
+ _hotspot8.setPriority2(1);
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(2280);
+ _hotspot10._strip = 2;
+ _hotspot10._frame = 2;
+ _hotspot10.setPosition(Common::Point(79, 104));
+ _hotspot10.setPriority2(2);
+
+ _hotspot12.postInit();
+ _hotspot12.setVisage(2280);
+ _hotspot12._strip = 2;
+ _hotspot12._frame = 3;
+ _hotspot12.setPosition(Common::Point(88, 76));
+ _hotspot12.setPriority2(1);
+
+ _globals->_sceneItems.addItems(&_hotspot8, &_hotspot10, &_hotspot12, NULL);
+ }
+
+ _hotspot14.setBounds(Rect(70, 50, 90, 104));
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(2280);
+ _hotspot9.setPosition(Common::Point(104, 96));
+ _hotspot9.setPriority2(1);
+
+ _hotspot11.postInit();
+ _hotspot11.setVisage(2280);
+ _hotspot11._frame = 2;
+ _hotspot11.setPosition(Common::Point(130, 79));
+ _hotspot11.setPriority2(1);
+
+ _hotspot13.postInit();
+ _hotspot13.setVisage(2280);
+ _hotspot13._frame = 3;
+ _hotspot13.setPosition(Common::Point(113, 63));
+ _hotspot13.setPriority2(1);
+
+ _hotspot1.setBounds(Rect(225, 70, 234, 80));
+ _hotspot2.setBounds(Rect(44, 78, 56, 105));
+ _hotspot3.setBounds(Rect(47, 108, 56, 117));
+ _hotspot4.setBounds(Rect(56, 78, 69, 101));
+ _hotspot5.setBounds(Rect(56, 108, 66, 113));
+ _hotspot6.setBounds(Rect(261, 39, 276, 90));
+ _hotspot7.setBounds(Rect(142, 19, 174, 38));
+ _hotspot15.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ _exitRect = Rect(145, 180, 195, 195);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(146, 161));
+ _globals->_player.changeZoom(-1);
+ _globals->_player._moveDiff = Common::Point(4, 3);
+
+ if ((_globals->_sceneManager._previousScene != 7300) && (_globals->_sceneManager._previousScene != 7000)) {
+ _globals->_player.enableControl();
+ } else {
+ _globals->setFlag(109);
+ _globals->_player.setPriority2(76);
+ _globals->_player.disableControl();
+
+ _sceneMode = 2281;
+ setAction(&_sequenceManager, this, 2281, &_globals->_player, &_hotspot16, NULL);
+
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ }
+
+ _globals->_sceneItems.addItems(&_hotspot13, &_hotspot11, &_hotspot9, &_hotspot14, &_hotspot7,
+ &_hotspot6, &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5, &_hotspot1, &_hotspot16, &_hotspot15, NULL);
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+}
+
+void Scene2280::signal() {
+ if (_sceneMode == 2281) {
+ _globals->_player.setPriority2(-1);
+ _globals->_player.enableControl();
+ }
+}
+
+void Scene2280::dispatch() {
+ Scene::dispatch();
+ if (!_action) {
+ if (_exitRect.contains(_globals->_player._position))
+ _globals->_sceneManager.changeScene(2150);
+ }
+}
+
+void Scene2280::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ _exitRect.synchronise(s);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2300 - Starcraft - Hanger Bay
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2300::Action1::signal() {
+ Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1: {
+ Common::Point pt(SCREEN_WIDTH, SCREEN_HEIGHT);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot2.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_hotspot8.setAction(&scene->_action4);
+ scene->_soundHandler2.startSound(21);
+
+ Common::Point pt1(95, scene->_hotspot5._position.y);
+ NpcMover *mover1 = new NpcMover();
+ scene->_hotspot5.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(99, scene->_hotspot6._position.y);
+ NpcMover *mover2 = new NpcMover();
+ scene->_hotspot6.addMover(mover2, &pt2, NULL);
+ break;
+ }
+ case 3:
+ setDelay(2);
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ case 4: {
+ scene->_hotspot5.setVisage(93);
+ scene->_hotspot6.setVisage(94);
+ scene->_hotspot5.setStrip(1);
+ scene->_hotspot6.setStrip(1);
+ scene->_hotspot5.changeZoom(50);
+ scene->_hotspot6.changeZoom(50);
+ scene->_hotspot5._moveDiff.x = 5;
+ scene->_hotspot6._moveDiff.x = 5;
+ scene->_hotspot5.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot6.animate(ANIM_MODE_1, NULL);
+
+ Common::Point pt1(178, 147);
+ NpcMover *mover1 = new NpcMover();
+ scene->_hotspot5.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(170, 145);
+ NpcMover *mover2 = new NpcMover();
+ scene->_hotspot6.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 6:
+ scene->_soundHandler1.startSound(28);
+ _globals->_player.disableControl();
+
+ scene->_hotspot2.setVisage(40);
+ scene->_hotspot2.setStrip(4);
+ scene->_hotspot2.setFrame(1);
+ scene->_hotspot2.animate(ANIM_MODE_5, NULL);
+
+ _globals->_player.setVisage(40);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 7:
+ _globals->_soundHandler.startSound(77, this);
+ break;
+ case 8:
+ _globals->_game.endGame(2300, 0);
+ break;
+ case 9:
+ if (scene->_hotspot5._mover)
+ scene->_hotspot5.addMover(NULL);
+ if (scene->_hotspot6._mover)
+ scene->_hotspot6.addMover(NULL);
+
+ scene->_hotspot5.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot6.animate(ANIM_MODE_NONE, NULL);
+
+ _globals->_player.disableControl();
+ _globals->_player.setVisage(2672);
+ _globals->_player._strip = 5;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 10:
+ _globals->_player.setVisage(2674);
+ _globals->_player._strip = 5;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 11:
+ scene->_soundHandler1.startSound(28);
+
+ scene->_hotspot5._strip = 2;
+ scene->_hotspot6._strip = 2;
+ scene->_hotspot5._frame = 1;
+ scene->_hotspot6._frame = 1;
+ scene->_hotspot5.animate(ANIM_MODE_5, NULL);
+ scene->_hotspot6.animate(ANIM_MODE_5, NULL);
+ scene->_hotspot5.setPriority2(20);
+ scene->_hotspot6.setPriority2(20);
+
+ _globals->_player.setVisage(2672);
+ _globals->_player._strip = 5;
+ _globals->_player._frame = _globals->_player.getFrameCount();
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 12:
+ scene->_soundHandler1.startSound(77);
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(4);
+ _globals->_player._uiEnabled = false;
+ setDelay(60);
+ break;
+ case 13:
+ scene->_stripManager.start(2300, this);
+ break;
+ case 14:
+ setDelay(5);
+ _actionIndex = 16;
+ break;
+ case 15: {
+ Common::Point pt1(101, 148);
+ PlayerMover *mover1 = new PlayerMover();
+ _globals->_player.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(scene->_hotspot5._position.x + 5, scene->_hotspot5._position.y + 5);
+ NpcMover *mover2 = new NpcMover();
+ scene->_hotspot2.addMover(mover2, &pt2, NULL);
+ break;
+ }
+ case 16:
+ _globals->_sceneManager.changeScene(2000);
+ remove();
+ break;
+ }
+}
+
+void Scene2300::Action2::signal() {
+ Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(30);
+ break;
+ case 1: {
+ Common::Point pt(153, 135);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(2030, this);
+ break;
+ case 3:
+ _globals->_player.enableControl();
+ setDelay(600);
+ break;
+ case 4: {
+ _globals->_player.disableControl();
+
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(2801);
+ scene->_hotspot2.setPosition(Common::Point(109, 145));
+ scene->_hotspot2.changeZoom(50);
+ scene->_hotspot2.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot2.setObjectWrapper(new SceneObjectWrapper());
+
+ Common::Point pt(160, 145);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot2.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ scene->_stripManager.start(2032, this);
+ break;
+ case 6:
+ scene->_hotspot2.setVisage(93);
+ scene->_hotspot2.setStrip(3);
+ scene->_hotspot2.setFrame(1);
+ scene->_hotspot2.animate(ANIM_MODE_5, this);
+
+ scene->_soundHandler1.startSound(28);
+ scene->_soundHandler2.startSound(97);
+ break;
+ case 7:
+ scene->_hotspot7._strip = 2;
+ scene->_hotspot7._frame = 1;
+ scene->_hotspot7.animate(ANIM_MODE_7, this);
+ break;
+ case 8:
+ scene->_hotspot2.animate(ANIM_MODE_6, this);
+ break;
+ case 9:
+ scene->_stripManager.start(2035, this);
+ break;
+ case 10:
+ _globals->_sceneManager.changeScene(2310);
+ break;
+ }
+}
+
+void Scene2300::Action3::signal() {
+ Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ Common::Point pt(153, 135);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_player.disableControl();
+ _globals->_player.setVisage(2672);
+ _globals->_player._strip = 2;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_player.setVisage(2674);
+ _globals->_player._strip = 2;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_soundHandler1.startSound(97);
+ scene->_soundHandler2.startSound(28);
+
+ scene->_hotspot7._strip = 2;
+ scene->_hotspot7._frame = 1;
+ scene->_hotspot7.animate(ANIM_MODE_5, this);
+
+ _globals->_player.setVisage(2672);
+ _globals->_player._strip = 2;
+ _globals->_player._frame = _globals->_player.getFrameCount();
+ _globals->_player.animate(ANIM_MODE_6, NULL);
+ break;
+ case 4:
+ scene->_soundHandler2.startSound(97);
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(1);
+ scene->_stripManager.start(2034, this);
+ break;
+ case 5:
+ setDelay(10);
+ break;
+ case 6:
+ _globals->_sceneManager.changeScene(2310);
+ break;
+ }
+}
+
+void Scene2300::Action4::signal() {
+ Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_hotspot8.animate(ANIM_MODE_5, this);
+ scene->_soundHandler1.startSound(11);
+ break;
+ case 1:
+ scene->_hotspot9.postInit();
+ scene->_hotspot9.setVisage(2301);
+ scene->_hotspot9.setStrip2(2);
+ scene->_hotspot9.setFrame(3);
+ scene->_hotspot9.setPosition(Common::Point(273, 199));
+ scene->_hotspot9.setPriority2(19);
+ scene->_hotspot9.animate(ANIM_MODE_5, this);
+ scene->_soundHandler1.startSound(11);
+ break;
+ case 2:
+ scene->_hotspot8.remove();
+
+ scene->_hotspot10.postInit();
+ scene->_hotspot10.setVisage(2301);
+ scene->_hotspot10.setStrip(3);
+ scene->_hotspot10.setFrame(4);
+ scene->_hotspot10.setPosition(Common::Point(292, 113));
+ scene->_hotspot10.animate(ANIM_MODE_5, this);
+ scene->_soundHandler1.startSound(11);
+ break;
+ case 3:
+ scene->_soundHandler1.startSound(13);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2300::Hotspot5::doAction(int action) {
+ Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ _globals->_player.disableControl();
+ _globals->_player.addMover(NULL);
+ scene->_action1.setActionIndex(9);
+ scene->_action1.setDelay(1);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(2300, 3);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2300, 4);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2300::Hotspot6::doAction(int action) {
+ Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ scene->setAction(&scene->_action3);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(2300, 2);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(2300, 21);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene2300::Scene2300() :
+ _hotspot11(0, CURSOR_LOOK, 2300, 6, CURSOR_USE, 2300, 14, LIST_END),
+ _hotspot12(0, CURSOR_LOOK, 2300, 5, CURSOR_USE, 2300, 13, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 2300, 9, CURSOR_USE, 2300, 20, LIST_END),
+ _hotspot14(0, CURSOR_LOOK, 2300, 7, CURSOR_USE, 2300, 15, LIST_END),
+ _hotspot15(0, CURSOR_LOOK, 2300, 1, LIST_END) {
+}
+
+void Scene2300::postInit(SceneObjectList *OwnerList) {
+ loadScene(2300);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerML);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+
+ _globals->_inventory._stunner._sceneNumber = 1;
+ _globals->_inventory._infoDisk._sceneNumber = 1;
+
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2301);
+ _hotspot8.setPosition(Common::Point(288, 74));
+
+ _globals->_soundHandler.startSound(96);
+ if (_globals->_sceneManager._previousScene == 2000) {
+ _hotspot8.remove();
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(2301);
+ _hotspot9.setStrip2(2);
+ _hotspot9._frame = _hotspot9.getFrameCount();
+ _hotspot9.setPosition(Common::Point(273, 199));
+ _hotspot9.setPriority2(1);
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(2301);
+ _hotspot10.setStrip(3);
+ _hotspot10._frame = _hotspot10.getFrameCount();
+ _hotspot10.setPosition(Common::Point(292, 113));
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.setPosition(Common::Point(109, 139));
+ _globals->_player.changeZoom(40);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.disableControl();
+
+ _hotspot7.postInit();
+ _hotspot7.setVisage(2302);
+ _hotspot7.animate(ANIM_MODE_2, NULL);
+ _hotspot7.setPosition(Common::Point(229, 125));
+ _hotspot7._numFrames = 5;
+
+ _soundHandler1.startSound(95);
+ _soundHandler2.startSound(96);
+ _globals->_sceneItems.push_back(&_hotspot7);
+
+ setAction(&_action2);
+ } else {
+ _hotspot8._numFrames = 3;
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(2331);
+ _hotspot3.setStrip(7);
+ _hotspot3.setPosition(Common::Point(231, 190));
+ _hotspot3.changeZoom(40);
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(2801);
+ _hotspot2.setPosition(Common::Point(269, 195));
+ _hotspot2.changeZoom(50);
+ _hotspot2.animate(ANIM_MODE_1, NULL);
+ _hotspot2.setObjectWrapper(new SceneObjectWrapper());
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(2331);
+ _hotspot1.setStrip(7);
+ _hotspot1.setPosition(Common::Point(255, 190));
+ _hotspot1.changeZoom(40);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.setPosition(Common::Point(203, 191));
+ _globals->_player.changeZoom(40);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.disableControl();
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(91);
+ _hotspot5.setPosition(Common::Point(343, 145));
+ _hotspot5._moveDiff = Common::Point(35, 35);
+ _hotspot5.changeZoom(40);
+ _hotspot5.setObjectWrapper(new SceneObjectWrapper());
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(92);
+ _hotspot6.setPosition(Common::Point(343, 130));
+ _hotspot6._moveDiff = Common::Point(35, 35);
+ _hotspot6.changeZoom(40);
+ _hotspot6.setObjectWrapper(new SceneObjectWrapper());
+
+ _globals->_sceneItems.push_back(&_hotspot5);
+ setAction(&_action1);
+ }
+
+ _hotspot12._sceneRegionId = 8;
+ _hotspot11._sceneRegionId = 9;
+ _hotspot13._sceneRegionId = 10;
+ _hotspot14._sceneRegionId = 11;
+
+ _hotspot15.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _globals->_sceneItems.addItems(&_hotspot12, &_hotspot11, &_hotspot13, &_hotspot14, &_hotspot15, NULL);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2310 - Starcraft - Copy Protection Screen
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene2310::Scene2310() {
+ _pageList[0].set(0, 0, 0, 0, 0, 0);
+ _pageList[1].set(1, 0, 3, 2, 1, 4);
+ _pageList[2].set(2, 1, 4, 3, 2, 0);
+ _pageList[3].set(3, 2, 0, 4, 3, 1);
+ _pageList[4].set(4, 3, 1, 0, 2, 4);
+ _pageList[5].set(5, 4, 2, 1, 3, 0);
+ _pageList[6].set(6, 0, 4, 2, 3, 1);
+ _pageList[7].set(7, 1, 0, 2, 4, 3);
+ _pageList[8].set(8, 2, 1, 3, 0, 4);
+ _pageList[9].set(9, 3, 2, 4, 1, 0);
+ _pageList[10].set(10, 4, 1, 2, 0, 3);
+ _pageList[11].set(11, 0, 2, 3, 4, 1);
+ _pageList[12].set(12, 1, 2, 0, 4, 3);
+ _pageList[13].set(13, 2, 4, 0, 3, 1);
+ _pageList[14].set(14, 3, 4, 1, 0, 2);
+ _pageList[15].set(15, 4, 3, 1, 2, 0);
+ _pageList[16].set(16, 0, 1, 4, 2, 3);
+ _pageList[17].set(17, 1, 3, 4, 0, 2);
+ _pageList[18].set(18, 2, 3, 0, 1, 4);
+ _pageList[19].set(19, 3, 0, 1, 4, 2);
+ _pageList[20].set(20, 4, 0, 3, 1, 2);
+}
+
+void Scene2310::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ loadScene(2301);
+ Common::Point pointList[5] = { Common::Point(142, 82), Common::Point(158, 82), Common::Point(174, 82),
+ Common::Point(190, 82), Common::Point(205, 82) };
+
+ for (int idx = 0; idx < 5; ++idx) {
+ _wireList[idx].postInit();
+ _wireList[idx].setVisage(2300);
+ _wireList[idx]._strip = idx + 1;
+ _wireList[idx]._frame = 1;
+ _wireList[idx].setPosition(pointList[idx]);
+ }
+
+ _rectList[0].set(135, 70, 151, 140);
+ _rectList[1].set(151, 70, 167, 140);
+ _rectList[2].set(167, 70, 183, 140);
+ _rectList[3].set(183, 70, 199, 140);
+ _rectList[4].set(199, 70, 215, 140);
+
+ _globals->_player.disableControl();
+ _globals->_events.setCursor(CURSOR_WALK);
+
+ _wireIndex = 5;
+ _pageIndex = _globals->_randomSource.getRandomNumber(19) + 1;
+ signal();
+}
+
+void Scene2310::signal() {
+ switch (_sceneMode++) {
+ case 0: {
+ Common::String fmtString = _vm->_dataManager->getMessage(2300, 22);
+ Common::String msg = Common::String::format(fmtString.c_str(), _pageList[_pageIndex]._pageNumber);
+
+ _sceneText._width = 280;
+ _sceneText._textMode = ALIGN_CENTRE;
+ _sceneText._colour1 = 35;
+ _sceneText._fontNumber = 2;
+ _sceneText.setup(msg);
+ _sceneText.setPriority2(255);
+ _sceneText.setPosition(Common::Point(30, 20));
+ break;
+ }
+ case 1: {
+ Common::String msg = _vm->_dataManager->getMessage(2300, 23);
+ _sceneText.setup(msg);
+ _sceneText.setPriority2(255);
+ _sceneText.setPosition(Common::Point(30, 170));
+
+ _globals->_sceneObjects->draw();
+ _globals->_events.waitForPress();
+
+ _sceneText.hide();
+ _globals->_sceneObjects->draw();
+
+ _globals->_sceneManager.changeScene(2200);
+ break;
+ }
+ }
+}
+
+void Scene2310::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+
+ s.syncAsSint16LE(_wireIndex);
+ s.syncAsSint16LE(_pageIndex);
+}
+
+void Scene2310::process(Event &event) {
+ int frameNum = 0;
+
+ if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) {
+ int idx = 0;
+ while (idx < 5) {
+ if (_rectList[idx].contains(event.mousePos))
+ break;
+ ++idx;
+ }
+
+ if (idx < 5) {
+ // In handled rectangle area
+ if (_wireIndex == 5) {
+ // No wire is currently active, so start moving designated wire
+ _wireIndex = idx;
+ frameNum = idx + 2;
+
+ if (event.mousePos.y > 105)
+ idx = findObject(idx);
+
+ if (idx != 5) {
+ _wireList[idx].hide();
+ _globals->_sceneObjects->draw();
+ _wireList[idx].setFrame(frameNum);
+
+ _wireList[idx].show();
+ _globals->_sceneObjects->draw();
+ }
+ } else {
+ // End the moving of the currently active wire
+ _wireList[_wireIndex].setFrame(idx + 2);
+ _wireIndex = 5;
+
+ // Check if solution has been reached
+ int idx2 = 0;
+ do {
+ int objIndex = findObject(idx2);
+ if (_pageList[_pageIndex]._connectionList[idx2] != objIndex)
+ // Mismatch
+ break;
+ } while (++idx2 < 5);
+
+ if (idx2 == 5)
+ // All the entries are correct
+ signal();
+ }
+
+ event.handled = true;
+ } else if (_wireIndex != 5) {
+ // Reset the active wire back to unplugged
+ _wireList[_wireIndex].setFrame(1);
+ _wireIndex = 5;
+ }
+ }
+}
+
+void Scene2310::dispatch() {
+ if ((_vm->getFeatures() & GF_CD) && !ConfMan.getBool("copy_protection")) {
+ // CD version of Ringworld has the copy protection disabled
+ signal();
+ } else if (_wireIndex != 5) {
+ for (int idx = 0; idx < 5; ++idx) {
+ if (_rectList[idx].contains(_globals->_events._mousePos)) {
+ _wireList[_wireIndex].setFrame(idx + 2);
+ return;
+ }
+ }
+
+ _wireList[_wireIndex].setFrame(1);
+ }
+}
+
+int Scene2310::findObject(int objIndex) {
+ for (int idx = 0; idx < 5; ++idx) {
+ if (_wireList[idx]._frame == (objIndex + 2))
+ return idx;
+ }
+
+ return 5;
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2320 - Starcraft - Lander Bay
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2320::Action1::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ if (_globals->_sceneManager._previousScene == 2120)
+ _actionIndex = 3;
+ break;
+ case 1: {
+ Common::Point pt(513, 144);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot11.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ Common::Point pt(510, 164);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot11.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ setAction(&scene->_sequenceManager2, this, 2328, &scene->_hotspot11, NULL);
+ break;
+ case 4:
+ scene->_hotspot11.animate(ANIM_MODE_NONE);
+ setDelay(120);
+ _actionIndex = 3;
+ break;
+ }
+}
+
+void Scene2320::Action2::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_soundHandler.startSound(253);
+ scene->_hotspot13.setPriority2(99);
+
+ Common::Point pt(scene->_hotspot13._position.x, 200);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot13.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_hotspot13.hide();
+ remove();
+ break;
+ }
+}
+
+void Scene2320::Action3::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ Common::Point pt(320, 86);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 1:
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot6.animate(ANIM_MODE_5, this);
+ break;
+ case 2: {
+ Common::Point pt(320, 79);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ scene->_hotspot6.setPriority2(scene->_hotspot6._priority - 1);
+ _globals->_player._strip = 3;
+ setDelay(10);
+ break;
+ case 4:
+ scene->_area1.display();
+ scene->_area2.display();
+ scene->_area3.display();
+ scene->_area4.display();
+
+ scene->_area3.draw(true);
+ _state = 0;
+ _globals->_events.setCursor(CURSOR_USE);
+
+ while (!_state && !_vm->getEventManager()->shouldQuit()) {
+ // Wait for an event
+ Event event;
+ if (!_globals->_events.getEvent(event)) {
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ continue;
+ }
+
+ if (scene->_area1._bounds.contains(event.mousePos)) {
+ scene->_area1.draw(true);
+ scene->_area3.draw(false);
+ _state = scene->_area1._actionId;
+ }
+ if (scene->_area2._bounds.contains(event.mousePos)) {
+ scene->_area3.draw(false);
+ scene->_area2.draw(true);
+ _state = scene->_area2._actionId;
+ }
+ if (scene->_area3._bounds.contains(event.mousePos)) {
+ scene->_area3.draw(true);
+ _state = scene->_area3._actionId;
+ }
+ }
+
+ scene->_soundHandler.startSound(161);
+ scene->_area1.restore();
+ scene->_area2.restore();
+ scene->_area3.restore();
+ scene->_area4.restore();
+
+ if (_state == 2320) {
+ setDelay(10);
+ } else {
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot6.animate(ANIM_MODE_6, this);
+ }
+ break;
+ case 5: {
+ if (_state == 2320)
+ _globals->_player.setPriority2(-1);
+ else
+ _globals->_sceneManager.changeScene(_state);
+
+ Common::Point pt(320, 86);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6:
+ scene->_soundHandler.startSound(162);
+ scene->_hotspot6.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2320::Action4::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1: {
+ Common::Point pt(213, 84);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ case 16:
+ _globals->_player.setVisage(2109);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->_player.animate(ANIM_MODE_6, NULL);
+ scene->setAction(&scene->_action2);
+ break;
+ case 4: {
+ scene->_hotspot16.postInit();
+ scene->_hotspot16.setVisage(2331);
+ scene->_hotspot16.setStrip(3);
+ scene->_hotspot16.setPriority2(149);
+ scene->_hotspot16.setPosition(Common::Point(320, 202));
+ scene->_hotspot16.show();
+
+ Common::Point pt(320, 121);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot16.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ scene->_hotspot16.setPriority2(200);
+ Common::Point pt(320, 180);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot16.addMover(mover, &pt, this);
+ break;
+ }
+ case 6: {
+ scene->_hotspot16.setPriority2(-1);
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ Common::Point pt(233, 176);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 7: {
+ Common::Point pt(291, 194);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 8:
+ _globals->_player.setStrip(5);
+ _globals->_player.setFrame(1);
+ setDelay(13);
+ break;
+ case 9:
+ if (!_globals->getFlag(109)) {
+ SceneItem::display2(2320, 19);
+ } else {
+ _globals->_sceneManager.changeScene(7600);
+ }
+ break;
+ case 10:
+ if (_globals->getFlag(109)) {
+ _globals->_soundHandler.startSound(40);
+ _globals->_soundHandler.proc5(true);
+
+ Common::Point pt(303, 240);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ } else {
+ setDelay(3);
+ }
+ break;
+ case 11:
+ if (_globals->getFlag(109)) {
+ _globals->_sceneManager.changeScene(7600);
+ } else {
+ SceneItem::display2(2320, 19);
+ setDelay(3);
+ }
+ break;
+ case 12:
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 13:
+ _globals->_player.setVisage(0);
+ _globals->_player.setPosition(Common::Point(291, 194));
+ _globals->_player.setStrip(5);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ scene->_hotspot16.show();
+ setDelay(3);
+ break;
+ case 14: {
+ Common::Point pt(233, 176);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 15: {
+ Common::Point pt(213, 85);
+ PlayerMover *mover = new PlayerMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 17: {
+ _globals->_player.animate(ANIM_MODE_6, NULL);
+ scene->_hotspot16.setPriority2(160);
+
+ Common::Point pt(320, 121);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot16.addMover(mover, &pt, this);
+ break;
+ }
+ case 18: {
+ Common::Point pt(320, 202);
+ PlayerMover *mover = new PlayerMover();
+ scene->_hotspot16.addMover(mover, &pt, this);
+ break;
+ }
+ case 19: {
+ scene->_hotspot16.remove();
+ scene->_soundHandler.startSound(253);
+
+ scene->_hotspot13.show();
+ Common::Point pt(319, 157);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot13.addMover(mover, &pt, this);
+ break;
+ }
+ case 20:
+ _globals->_player.enableControl();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ scene->_hotspot13.setPriority2(1);
+ remove();
+ break;
+ }
+}
+
+void Scene2320::Action5::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_PLAYER_MOVER(163, 126);
+ break;
+ case 1:
+ ADD_PLAYER_MOVER(165, 132);
+ break;
+ case 2:
+ setDelay(2);
+ break;
+ case 3:
+ if (!_globals->getFlag(59))
+ setDelay(10);
+ else
+ scene->_stripManager.start(2323, this);
+ break;
+ case 4:
+ _globals->_player.setVisage(2347);
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPriority2(137);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 6:
+ if (_globals->getFlag(72))
+ _globals->_sceneManager.changeScene(7000);
+ else if (_globals->getFlag(59))
+ _globals->_sceneManager.changeScene(5000);
+ else if (!_globals->getFlag(43) || (_globals->_inventory._ale._sceneNumber != 1))
+ setDelay(10);
+ else {
+ scene->_hotspot11.setAction(NULL);
+ scene->_hotspot11.setVisage(2705);
+ scene->_hotspot11.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot11.setObjectWrapper(new SceneObjectWrapper());
+
+ Common::Point pt(185, 135);
+ NpcMover *mover = new NpcMover();
+ scene->_hotspot11.addMover(mover, &pt, NULL);
+
+ _globals->clearFlag(53);
+ scene->_stripManager.start(2325, this);
+ }
+ break;
+ case 7:
+ setDelay(10);
+ break;
+ case 8:
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ }
+}
+
+void Scene2320::Action6::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 2:
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ _globals->_player.setVisage(0);
+ _globals->_player.setStrip(3);
+ _globals->_player.setPriority2(-1);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ setDelay(60);
+ break;
+ case 4:
+ if ((_globals->_sceneManager._previousScene != 4000) || _globals->getFlag(43))
+ setDelay(3);
+ else if (_globals->getFlag(35)) {
+ _globals->setFlag(43);
+ scene->_stripManager.start(4200, this);
+ _globals->setFlag(69);
+ } else if (_globals->getFlag(36)) {
+ setDelay(3);
+ } else {
+ _globals->setFlag(43);
+ scene->_stripManager.start(4210, this);
+ break;
+ }
+ break;
+ case 5:
+ if (_globals->_sceneObjects->contains(&scene->_hotspot11)) {
+ scene->_hotspot11.setAction(&scene->_action1);
+
+ if (_globals->_sceneObjects->contains(&scene->_hotspot10)) {
+ ADD_MOVER(scene->_hotspot10, 491, 160);
+ } else {
+ setDelay(60);
+ }
+
+ _globals->_sceneItems.push_front(&scene->_hotspot11);
+ } else {
+ setDelay(3);
+ }
+ break;
+ case 6:
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene2320::Action7::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ _globals->_soundHandler.startSound(162);
+ scene->_hotspot6.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ scene->_hotspot10.setPriority2(-1);
+ ADD_MOVER_NULL(scene->_hotspot10, 321, 94);
+ scene->_hotspot11.setPriority2(-1);
+ ADD_MOVER_NULL(scene->_hotspot11, 346, 85);
+
+ _globals->_player.setPriority2(-1);
+ ADD_MOVER(_globals->_player, 297, 89);
+ break;
+ case 3:
+ ADD_PLAYER_MOVER(462, 182);
+ break;
+ case 4:
+ ADD_MOVER(scene->_hotspot11, 391, 88);
+ break;
+ case 5:
+ ADD_MOVER(scene->_hotspot11, 500, 164);
+ ADD_MOVER(scene->_hotspot10, 382, 93);
+ _globals->_player.setStrip(3);
+ break;
+ case 6:
+ ADD_MOVER_NULL(scene->_hotspot10, 491, 160);
+ ADD_MOVER(_globals->_player, 391, 88);
+
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 7:
+ ADD_PLAYER_MOVER(462, 182);
+ break;
+ case 8:
+ _globals->_player.setStrip(7);
+ setDelay(15);
+ break;
+ case 9:
+ scene->_stripManager.start(6020, this);
+ break;
+ case 10:
+ setDelay(6);
+ break;
+ case 11:
+ scene->_stripManager.start(6022, this);
+ break;
+ case 12:
+ _globals->_player.enableControl();
+ _globals->_inventory._stasisBox._sceneNumber = 2320;
+ break;
+ }
+}
+
+void Scene2320::Action8::signal() {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ ADD_PLAYER_MOVER(462, 182);
+ break;
+ case 2:
+ _globals->_player.setStrip(7);
+ setDelay(5);
+ break;
+ case 3:
+ scene->_speakerGameText.setTextPos(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + 30, 10));
+ scene->_stripManager.start(_globals->getFlag(75) ? 6030 : 2320, this);
+ break;
+ case 4:
+ if (_globals->getFlag(75))
+ setDelay(3);
+ else
+ _globals->_player.enableControl();
+ break;
+ case 5:
+ _globals->_inventory._stasisBox._sceneNumber = 2320;
+ scene->_sceneMode = 2326;
+ scene->_speakerGameText.setTextPos(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + 30, 10));
+ scene->setAction(&scene->_sequenceManager1, scene, 2326, &_globals->_player, &scene->_hotspot11, NULL);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2320::Hotspot5::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 13);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(70))
+ SceneItem::display2(2320, 33);
+ else if (_globals->getFlag(13))
+ SceneItem::display2(2320, 18);
+ else
+ scene->setAction(&scene->_action5);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot6::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 2);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action3);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot8::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 23);
+ break;
+ case CURSOR_USE:
+ scene->_sceneMode = 2336;
+ scene->setAction(&scene->_sequenceManager1, scene, 2336, &_globals->_player, this, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot10::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 26);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2329;
+
+ if (_globals->getFlag(13)) {
+ scene->_stripManager.start(2337, scene);
+ } else if (_globals->getFlag(70)) {
+ scene->setAction(&scene->_action8);
+ } else if (_globals->getFlag(109)) {
+ scene->setAction(&scene->_sequenceManager1, scene, 2337, NULL);
+ } else if (!_state) {
+ ++_state;
+ scene->setAction(&scene->_sequenceManager1, scene, 2334, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 2335, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot11::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 25);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2329;
+
+ if (_globals->getFlag(13)) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5000;
+ scene->_stripManager.start(2336, scene);
+ } else if (_globals->getFlag(70)) {
+ scene->setAction(&scene->_action8);
+ } else {
+ scene->_sceneMode = 2329;
+
+ if (_globals->_inventory._ale._sceneNumber == 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 2329, NULL);
+ } else if (!_globals->getFlag(110)) {
+ _globals->setFlag(110);
+ scene->setAction(&scene->_sequenceManager1, scene, 2330, NULL);
+ } else if (_globals->_inventory._peg._sceneNumber != 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 2331, NULL);
+ } else if (!_state) {
+ ++_state;
+ scene->setAction(&scene->_sequenceManager1, scene, 2332, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager1, scene, 2333, NULL);
+ }
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot12::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 5);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2320, 24);
+ else {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 2322;
+ scene->setAction(&scene->_sequenceManager1, scene, 2322, &_globals->_player, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot14::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 17);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(24)) {
+ _globals->clearFlag(24);
+ _globals->_player.disableControl();
+
+ scene->_hotspot8.postInit();
+ scene->_hotspot8.setVisage(2345);
+ scene->_hotspot8.setPosition(Common::Point(634, 65));
+ scene->_hotspot8.hide();
+
+ _globals->_sceneItems.push_front(&scene->_hotspot8);
+ _globals->_inventory._waldos._sceneNumber = 2320;
+
+ scene->_hotspot9.postInit();
+ scene->_hotspot9.setVisage(2345);
+ scene->_hotspot9._strip = 6;
+ scene->_hotspot9.setPosition(Common::Point(536, 103));
+ scene->_hotspot9.setPriority2(200);
+ scene->_hotspot9.hide();
+
+ scene->_hotspot16.postInit();
+ scene->_hotspot16.setVisage(2345);
+ scene->_hotspot16.setStrip(8);
+ scene->_hotspot16.setPosition(Common::Point(536, 103));
+ scene->_hotspot16.hide();
+
+ scene->_sceneMode = 2324;
+ scene->setAction(&scene->_sequenceManager1, scene, 2324, &_globals->_player, &scene->_hotspot7,
+ &scene->_hotspot8, &scene->_hotspot9, &scene->_hotspot16, NULL);
+ } else if (_globals->getFlag(13)) {
+ SceneItem::display2(2320, 24);
+ } else if (!_globals->getFlag(76)) {
+ SceneItem::display2(2320, 28);
+ } else if (!_globals->_inventory._waldos._sceneNumber) {
+ SceneItem::display2(2320, 27);
+ } else {
+ SceneItem::display2(2320, 29);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene2320::Hotspot15::doAction(int action) {
+ Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(2320, 16);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(13))
+ SceneItem::display2(2320, 24);
+ else
+ scene->setAction(&scene->_action4);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+Scene2320::Scene2320() :
+ _hotspot1(0, CURSOR_LOOK, 2320, 0, LIST_END),
+ _hotspot2(0, CURSOR_LOOK, 2320, 1, LIST_END),
+ _hotspot3(0, CURSOR_LOOK, 2320, 11, LIST_END),
+ _hotspot4(0, CURSOR_LOOK, 2320, 14, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 2320, 12, LIST_END)
+{
+}
+
+void Scene2320::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(60, 75, 100, 100);
+
+ _stripManager.addSpeaker(&_speakerMR);
+ _stripManager.addSpeaker(&_speakerML);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerSR);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerSAL);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerGameText);
+
+ _speakerMText._npc = &_hotspot11;
+ _speakerQText._npc = &_globals->_player;
+ _hotspotPtr = &_hotspot10;
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(2321);
+ _hotspot6.setPosition(Common::Point(320, 67));
+
+ _hotspot7.postInit();
+ _hotspot7.setVisage(2344);
+ _hotspot7.setPosition(Common::Point(604, 92));
+
+ _hotspot13.postInit();
+ _hotspot13.setVisage(2323);
+ _hotspot13.setPosition(Common::Point(319, 157));
+ _hotspot13.setPriority2(1);
+
+ _hotspot12.postInit();
+ _hotspot12.setVisage(2321);
+ _hotspot12._strip = 4;
+ _hotspot12.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot12.setPosition(Common::Point(412, 46));
+
+ if (_globals->_inventory._waldos._sceneNumber == 2320) {
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2345);
+ _hotspot8.setStrip(5);
+ _hotspot8.setFrame(8);
+ _hotspot8.setPosition(Common::Point(541, 103));
+ _hotspot8.setPriority2(201);
+
+ _globals->_sceneItems.push_back(&_hotspot8);
+ }
+
+ _area1.setup(2100, 2, 1, 2150);
+ _area1._pt = Common::Point(200, 31);
+ _area2.setup(2153, 3, 1, 2150);
+ _area2._pt = Common::Point(200, 50);
+ _area3.setup(2153, 4, 1, 2320);
+ _area3._pt = Common::Point(200, 75);
+ _area4.setup(2153, 1, 1, 10);
+ _area4._pt = Common::Point(237, 77);
+
+ if (_globals->getFlag(43)) {
+ _hotspot11.postInit();
+ _hotspot11.setVisage(2705);
+ _hotspot11._strip = 3;
+ _hotspot11.setPosition(Common::Point(510, 156));
+ _hotspot11._state = 0;
+ _hotspot11.setAction(&_action1);
+
+ _globals->_sceneItems.push_back(&_hotspot11);
+ }
+
+ _globals->_player.postInit();
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(320, 79));
+ _globals->_player.setPriority2(10);
+ _globals->_player.changeZoom(-1);
+ _globals->_player._moveDiff.y = 3;
+ _globals->_player.disableControl();
+
+ if (_globals->getFlag(114)) {
+ _hotspot10.postInit();
+ _hotspot10.setVisage(2806);
+ _hotspot10.setPosition(Common::Point(481, 162));
+ _hotspot10.changeZoom(-1);
+ _hotspot10.setStrip(5);
+ _hotspot10._state = 0;
+
+ _globals->_sceneItems.push_back(&_hotspot10);
+ }
+
+ if (_globals->getFlag(70)) {
+ _hotspot11.postInit();
+ _hotspot11.setVisage(2705);
+ _hotspot11.setPosition(Common::Point(500, 164));
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(2806);
+ _hotspot10.setPosition(Common::Point(481, 162));
+ _hotspot10.changeZoom(-1);
+ _hotspot10.setStrip(5);
+
+ _globals->_sceneItems.addItems(&_hotspot11, &_hotspot10, NULL);
+ }
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 2120:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ _globals->_player.setPriority2(-1);
+ _globals->_player.setPosition(Common::Point(389, 72));
+ _globals->_player.enableControl();
+ break;
+ case 4000:
+ if (!_globals->getFlag(36) && !_globals->getFlag(43)) {
+ _hotspot11.postInit();
+ _hotspot11.setVisage(2705);
+ _hotspot11.setPosition(Common::Point(178, 118));
+ _hotspot11.animate(ANIM_MODE_1, NULL);
+ }
+ // Deliberate fall-through
+ case 4250:
+ case 5000:
+ case 7000:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ if ((_globals->_sceneManager._previousScene == 7000) && !_globals->getFlag(80))
+ _globals->setFlag(36);
+
+ _globals->_player.disableControl();
+ _globals->_player.animate(ANIM_MODE_NONE, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setVisage(2347);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(5);
+ _globals->_player.setPriority2(137);
+ _globals->_player.setPosition(Common::Point(165, 132));
+
+ setAction(&_action6);
+ break;
+ case 6100:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2345);
+ _hotspot8.setPosition(Common::Point(634, 65));
+ _hotspot8.hide();
+
+ _sceneMode = 2325;
+ setAction(&_sequenceManager1, this, 2325, &_globals->_player, &_hotspot6, &_hotspot8, &_hotspot7, NULL);
+ break;
+ case 7600:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ _soundHandler.startSound(21);
+
+ _globals->_player.setVisage(2323);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(_globals->_player.getFrameCount());
+ _globals->_player.setPosition(Common::Point(303, 176));
+ _globals->_player.setPriority2(-1);
+ _globals->_player.disableControl();
+
+ _hotspot13.setPosition(Common::Point(319, 199));
+
+ _hotspot16.postInit();
+ _hotspot16.setVisage(2331);
+ _hotspot16._strip = 3;
+ _hotspot16.setPriority2(160);
+ _hotspot16.setPosition(Common::Point(320, 202));
+ _hotspot16.hide();
+
+ _sceneMode = 2338;
+ setAction(&_sequenceManager1, this, 2338, &_globals->_player, &_hotspot16, &_hotspot13, NULL);
+ break;
+ default:
+ switch (_globals->_stripNum) {
+ case 2101:
+ _globals->_player.disableControl();
+ _globals->_player.setStrip(3);
+ _globals->_player.setPosition(Common::Point(307, 84));
+
+ _hotspot11.postInit();
+ _hotspot11.setVisage(2705);
+ _hotspot11._strip = 2;
+ _hotspot11.setPriority2(10);
+ _hotspot11.setPosition(Common::Point(322, 80));
+ _hotspot11.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot11.animate(ANIM_MODE_1, NULL);
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(2806);
+ _hotspot10.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot10.changeZoom(-1);
+ _hotspot10.setPriority2(10);
+ _hotspot10.setPosition(Common::Point(318, 89));
+ _hotspot10._strip = 3;
+ _hotspot10.animate(ANIM_MODE_1, NULL);
+
+ setAction(&_action7);
+ break;
+ case 6100:
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2345);
+ _hotspot8.setPosition(Common::Point(634, 65));
+ _hotspot8.hide();
+
+ _sceneMode = 2325;
+ setAction(&_sequenceManager1, this, 2325, &_globals->_player, &_hotspot6, &_hotspot8, &_hotspot7, NULL);
+ break;
+ default:
+ _globals->_soundHandler.startSound(160);
+ _globals->_soundHandler.proc5(true);
+ _sceneMode = 2321;
+
+ _globals->_player.setStrip(3);
+ setAction(&_sequenceManager1, this, 2321, &_globals->_player, &_hotspot6, NULL);
+ break;
+ }
+ }
+
+ _globals->_stripNum = 0;
+ _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position);
+ loadScene(2320);
+
+ _hotspot14._sceneRegionId = 8;
+ _hotspot1.setBounds(Rect(0, 0, 640, 200));
+ _hotspot2.setBounds(Rect(278, 0, 362, 61));
+ _hotspot3.setBounds(Rect(282, 62, 367, 98));
+ _hotspot4.setBounds(Rect(67, 38, 112, 113));
+ _hotspot5.setBounds(Rect(104, 122, 174, 157));
+ _hotspot15.setBounds(Rect(191, 53, 205, 63));
+
+ _globals->_sceneItems.addItems(&_hotspot14, &_hotspot15, &_hotspot5, &_hotspot6, &_hotspot12,
+ &_hotspot13, &_hotspot4, &_hotspot3, &_hotspot2, &_hotspot1, NULL);
+}
+
+void Scene2320::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ SYNC_POINTER(_hotspotPtr);
+}
+
+void Scene2320::signal() {
+ switch (_sceneMode) {
+ case 2321:
+ case 2327:
+ case 2329:
+ if (_globals->getFlag(43) && !_hotspot11._action)
+ _hotspot11.setAction(&_action1);
+ _globals->_player.enableControl();
+ break;
+ case 2322:
+ _globals->_sceneManager.changeScene(2120);
+ break;
+ case 2323:
+ _globals->_player.disableControl();
+ break;
+ case 2338:
+ case 2324:
+ _hotspot16.remove();
+ _globals->_player.enableControl();
+ break;
+ case 2325:
+ _globals->setFlag(76);
+ _globals->clearFlag(70);
+ _globals->_stripNum = 6100;
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ case 2326:
+ _globals->clearFlag(70);
+ _globals->_inventory._nullifier._sceneNumber = 1;
+ _globals->_stripNum = 2321;
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ case 2336:
+ _globals->setFlag(77);
+ _globals->_inventory._waldos._sceneNumber = 1;
+ _hotspot8.remove();
+ break;
+ case 5000:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 2400 - Descending in Lander
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene2400::Action1::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ ADD_MOVER(_globals->_player, 160, 71);
+ break;
+ case 2:
+ ADD_MOVER(_globals->_player, 160, 360);
+ break;
+ case 3:
+ _globals->_player._moveDiff = Common::Point(1, 1);
+ ADD_MOVER(_globals->_player, 140, 375);
+ break;
+ case 4:
+ ADD_MOVER(_globals->_player, 87, 338);
+ break;
+ case 5:
+ _globals->_player.hide();
+ setDelay(60);
+ break;
+ case 6:
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ }
+}
+
+void Scene2400::Action1::dispatch() {
+ Action::dispatch();
+ if ((_actionIndex == 4) && (_globals->_player._percent > 5))
+ _globals->_player.changeZoom(_globals->_player._percent - 2);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene2400::postInit(SceneObjectList *OwnerList) {
+ loadScene(2400);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2410);
+ _globals->_player.setPosition(Common::Point(340, -10));
+ _globals->_player.animate(ANIM_MODE_2, NULL);
+ _globals->_player.disableControl();
+
+ setAction(&_action1);
+
+ _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y);
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
+
+ _globals->_soundHandler.startSound(153);
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes3.h b/engines/tsage/ringworld_scenes3.h
new file mode 100644
index 0000000000..61aac522f2
--- /dev/null
+++ b/engines/tsage/ringworld_scenes3.h
@@ -0,0 +1,905 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES3_H
+#define TSAGE_RINGWORLD_SCENES3_H
+
+#include "common/scummsys.h"
+#include "tsage/core.h"
+#include "tsage/converse.h"
+#include "tsage/ringworld_logic.h"
+
+namespace tSage {
+
+class Scene2000 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action9 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action10 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action11 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action12 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action13 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action14 : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SpeakerSL _speakerSL;
+ SpeakerQR _speakerQR;
+ SpeakerMR _speakerMR;
+ SpeakerQText _speakerQText;
+ SpeakerMText _speakerMText;
+ SpeakerSText _speakerSText;
+ SpeakerHText _speakerHText;
+ SpeakerGameText _speakerGameText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ Action9 _action9;
+ Action10 _action10;
+ Action11 _action11;
+ Action12 _action12;
+ Action13 _action13;
+ Action14 _action14;
+ SceneObject _object1, _object2, _object3, _object4, _object5;
+ SceneObject _object6, _object7, _object8, _object9, _object10;
+ SoundHandler _soundHandler1, _soundHandler2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void stripCallback(int v);
+};
+
+class Scene2100 : public Scene {
+ /* Actions */
+ class Action1 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action9 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action10 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action11 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action12 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action13 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action14 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action15 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action16 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action17 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot14 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+ /* Objects */
+ class Object1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SoundHandler _soundHandler;
+ SpeakerMText _speakerMText;
+ SpeakerMR _speakerMR;
+ SpeakerQL _speakerQL;
+ SpeakerQR _speakerQR;
+ SpeakerQText _speakerQText;
+ SpeakerGameText _speakerGameText;
+ SpeakerSText _speakerSText;
+ SpeakerSL _speakerSL;
+ SpeakerSAL _speakerSAL;
+ SpeakerHText _speakerHText;
+
+ DisplayHotspot _hotspot1;
+ Hotspot2 _hotspot2;
+ Hotspot3 _hotspot3;
+ Hotspot4 _hotspot4;
+ DisplayHotspot _hotspot5, _hotspot6, _hotspot7;
+ Hotspot8 _hotspot8;
+ DisplayHotspot _hotspot9;
+ Hotspot10 _hotspot10;
+ DisplayHotspot _hotspot11, _hotspot12, _hotspot13;
+ Hotspot14 _hotspot14;
+ DisplayHotspot _hotspot15;
+
+ Object1 _object1;
+ Object2 _object2;
+ Object3 _object3;
+ SceneObject _object4;
+
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ Action9 _action9;
+ Action10 _action10;
+ Action11 _action11;
+ Action12 _action12;
+ Action13 _action13;
+ Action14 _action14;
+ Action15 _action15;
+ Action16 _action16;
+ Action17 _action17;
+ int _field1800;
+ SceneArea _area1, _area2, _area3, _area4;
+
+ Scene2100();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void stripCallback(int v);
+ virtual void signal();
+};
+
+class Scene2120 : public Scene {
+ /* Actions */
+ class Entry {
+ public:
+ int _size;
+ int _lineNum;
+ int _visage;
+
+ Entry() { _size = 0; _lineNum = 0; _visage = 0; }
+ Entry(int size, int lineNum, int visage) { _size = size; _lineNum = lineNum; _visage = visage; }
+ };
+
+ class Action1 : public Action {
+ private:
+ Common::Array<Entry> _entries;
+ public:
+ Action1();
+
+ virtual void signal();
+ virtual void dispatch();
+ };
+
+public:
+ SoundHandler _soundHandler;
+ SceneObject _topicArrowHotspot, _arrowHotspot, _visageHotspot;
+ SceneObject _subjectButton, _nextPageButton, _previousPageButton, _exitButton;
+ Action1 _action1;
+ Rect _listRect;
+ int _dbMode, _prevDbMode;
+ bool _visageVisable;
+ int _subjectIndex;
+ int _lineOffset;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+};
+
+class Scene2150 : public Scene {
+ /* Actions */
+ class Action1 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot7 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager;
+ SpeakerGameText _speakerGameText;
+
+ Rect _rect1, _rect2;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ DisplayHotspot _hotspot3;
+ Hotspot4 _hotspot4;
+ DisplayHotspot _hotspot5, _hotspot6;
+ Hotspot7 _hotspot7;
+ DisplayHotspot _hotspot8, _hotspot9;
+ Hotspot10 _hotspot10;
+ DisplayHotspot _hotspot11;
+ SceneObject _hotspot12, _hotspot13, _hotspot14;
+ SceneArea _area1, _area2, _area3, _area4;
+ Action1 _action1;
+ Action2 _action2;
+
+ Scene2150();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene2200 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public ActionExt {
+ public:
+ virtual void signal();
+ virtual void process(Event &event);
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot9 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SpeakerMText _speakerMText;
+ SpeakerSText _speakerSText;
+ SpeakerQText _speakerQText;
+ SpeakerSL _speakerSL;
+ SpeakerQR _speakerQR;
+ SpeakerQL _speakerQL;
+ SpeakerMR _speakerMR;
+ SpeakerGameText _speakerGameText;
+ Rect _exitRect;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ DisplayHotspot _hotspot1;
+ Hotspot3 _hotspot3;
+ Hotspot5 _hotspot5;
+ Hotspot9 _hotspot9;
+ DisplayHotspot _hotspot10;
+ SceneObject _hotspot2, _hotspot4;
+ SceneObject _hotspot6, _hotspot7, _hotspot8;
+ SoundHandler _soundHandler1, _soundHandler2;
+
+ Scene2200();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void stripCallback(int v);
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene2222 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+
+public:
+ SoundHandler _soundHandler;
+ SpeakerSText _speakerSText;
+ SpeakerMText _speakerMText;
+ SpeakerQText _speakerQText;
+ SpeakerML _speakerML;
+ SpeakerSR _speakerSR;
+ Action1 _action1;
+ Action2 _action2;
+ SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene2230 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot7 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot11 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot12 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ Hotspot1 _hotspot1;
+ Hotspot3 _hotspot3;
+ Hotspot4 _hotspot4;
+ SceneObject _hotspot2;
+ Hotspot5 _hotspot5;
+ Hotspot6 _hotspot6;
+ Hotspot7 _hotspot7;
+ Hotspot8 _hotspot8;
+ DisplayHotspot _hotspot9;
+ Hotspot10 _hotspot10;
+ Hotspot11 _hotspot11;
+ Hotspot12 _hotspot12;
+ Rect _rect1;
+ int _field30A;
+
+ Scene2230();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+ virtual void dispatch();
+};
+
+class Scene2280 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot7 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot12 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot14 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot15 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot16 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot17 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot18 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager;
+ Rect _exitRect;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ DisplayHotspot _hotspot3;
+ Hotspot4 _hotspot4;
+ DisplayHotspot _hotspot5, _hotspot6;
+ Hotspot7 _hotspot7;
+ Hotspot8 _hotspot8;
+ DisplayHotspot _hotspot9;
+ Hotspot10 _hotspot10;
+ DisplayHotspot _hotspot11;
+ Hotspot12 _hotspot12;
+ DisplayHotspot _hotspot13;
+ Hotspot14 _hotspot14;
+ DisplayHotspot _hotspot15, _hotspot16;
+ Hotspot17 _hotspot17;
+ Hotspot18 _hotspot18;
+
+ Scene2280();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene2300 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot12 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot13 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler1, _soundHandler2;
+ SpeakerSL _speakerSL;
+ SpeakerML _speakerML;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4;
+ Hotspot5 _hotspot5;
+ Hotspot6 _hotspot6;
+ SceneObject _hotspot7, _hotspot8, _hotspot9, _hotspot10;
+ DisplayHotspot _hotspot11, _hotspot12, _hotspot13, _hotspot14, _hotspot15;
+
+ Scene2300();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene2310 : public Scene {
+private:
+ int findObject(int objIndex);
+
+ /* Custom classes */
+ class ProtectionEntry {
+ public:
+ int _pageNumber;
+ int _connectionList[5];
+
+ void set(int pageNumber, int v1, int v2, int v3, int v4, int v5) {
+ _pageNumber = pageNumber;
+ _connectionList[0] = v1; _connectionList[1] = v2; _connectionList[2] = v3;
+ _connectionList[3] = v4; _connectionList[4] = v5;
+ }
+ };
+
+public:
+ SequenceManager _sequenceManager;
+ int _wireIndex, _pageIndex;
+ SceneObject _wireList[5];
+ Rect _rectList[5];
+ SceneText _sceneText;
+ ProtectionEntry _pageList[21];
+
+ Scene2310();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene2320 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public ActionExt {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObjectExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot11 : public SceneObjectExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot12 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot14 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot15 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager1, _sequenceManager2;
+ SpeakerMText _speakerMText;
+ SpeakerMR _speakerMR;
+ SpeakerML _speakerML;
+ SpeakerQText _speakerQText;
+ SpeakerQL _speakerQL;
+ SpeakerQR _speakerQR;
+ SpeakerSAL _speakerSAL;
+ SpeakerSL _speakerSL;
+ SpeakerSR _speakerSR;
+ SpeakerSText _speakerSText;
+ SpeakerGameText _speakerGameText;
+ SceneArea _area1, _area2, _area3, _area4;
+ DisplayHotspot _hotspot1, _hotspot2, _hotspot3, _hotspot4;
+ Hotspot5 _hotspot5;
+ Hotspot6 _hotspot6;
+ SceneObject _hotspot7, _hotspot9;
+ Hotspot8 _hotspot8;
+ Hotspot10 _hotspot10;
+ Hotspot11 _hotspot11;
+ Hotspot12 _hotspot12;
+ DisplayHotspot _hotspot13;
+ Hotspot14 _hotspot14;
+ Hotspot15 _hotspot15;
+ SceneObject _hotspot16;
+ SceneItem *_hotspotPtr;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+
+ Scene2320();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+ virtual void signal();
+};
+
+class Scene2400 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ virtual void dispatch();
+ };
+public:
+ Action1 _action1;
+ SceneObject _object;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes4.cpp b/engines/tsage/ringworld_scenes4.cpp
new file mode 100644
index 0000000000..89feb223a1
--- /dev/null
+++ b/engines/tsage/ringworld_scenes4.cpp
@@ -0,0 +1,253 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "tsage/ringworld_scenes4.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 3500 - Ringworld Scan
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene3500::Action1::signal() {
+ Scene3500 *scene = (Scene3500 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_stripManager.start(3500, this);
+ break;
+ case 2:
+ setDelay(3);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(9999);
+ break;
+ }
+}
+
+void Scene3500::Action2::signal() {
+ Scene3500 *scene = (Scene3500 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_stripManager.start(3501, this);
+ break;
+ case 2:
+ setDelay(3);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(2012);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene3500::postInit(SceneObjectList *OwnerList) {
+ loadScene((_globals->_stripNum == 3600) ? 3600 : 3500);
+ Scene::postInit();
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerSText);
+
+ _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds);
+ _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.top / 160) * 160;
+
+ setAction((_globals->_stripNum == 3600) ? (Action *)&_action2 : (Action *)&_action1);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 3700 - Remote Viewer
+ *
+ *--------------------------------------------------------------------------*/
+
+#define VIEW_FRAME_DELAY 10
+
+Scene3700::Viewer::Viewer() {
+ _images1.setVisage(3705, 1);
+ _images2.setVisage(3705, 2);
+
+ _frameList[0] = 1;
+ for (int idx = 1; idx <= 3; ++idx)
+ _frameList[idx] = _globals->_randomSource.getRandomNumber(4) + 1;
+
+ _active = true;
+ _countdownCtr = 0;
+ _percentList[0] = 120;
+ _percentList[1] = 50;
+ _percentList[2] = 75;
+ _percentList[3] = 114;
+}
+
+void Scene3700::Viewer::synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ s.syncAsByte(_active);
+ s.syncAsSint16LE(_countdownCtr);
+ for (int idx = 0; idx < 4; ++idx) {
+ s.syncAsSint16LE(_frameList[idx]);
+ s.syncAsSint16LE(_percentList[idx]);
+ }
+}
+
+void Scene3700::Viewer::dispatch() {
+ if (_active) {
+ if (_countdownCtr-- <= 0) {
+ _countdownCtr = VIEW_FRAME_DELAY;
+
+ for (int idx = 3; idx > 1; --idx)
+ _frameList[idx] = _frameList[idx - 1];
+
+ int newFrame;
+ do {
+ newFrame = _globals->_randomSource.getRandomNumber(4) + 1;
+ } while (newFrame == _frameList[2]);
+
+ _frameList[1] = newFrame;
+ _flags |= OBJFLAG_PANES;
+ }
+ }
+}
+
+void Scene3700::Viewer::reposition() {
+ _bounds = Rect(123, 40, 285, 123);
+}
+
+void Scene3700::Viewer::draw() {
+ Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(1);
+
+ for (int idx = 0; idx < 4; ++idx) {
+ Visage &v = (idx == 0) ? _images1 : _images2;
+
+ GfxSurface img = v.getFrame(_frameList[idx]);
+ Rect destRect = img.getBounds();
+ destRect.resize(img, (_position.x - _globals->_sceneOffset.x),
+ (_position.y - _globals->_sceneOffset.y - _yDiff), _percentList[idx]);
+
+ destRect.translate(-_globals->_sceneManager._scene->_sceneBounds.left,
+ -_globals->_sceneManager._scene->_sceneBounds.top);
+
+ _globals->gfxManager().copyFrom(img, destRect, priorityRegion);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene3700::Action1::signal() {
+ Scene3700 *scene = (Scene3700 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_stripManager.start(2162, this);
+ break;
+ case 2:
+ scene->_viewer._active = false;
+ setDelay(90);
+ break;
+ case 3:
+ scene->_soundHandler.startSound(196);
+ scene->_viewer.hide();
+
+ scene->_hotspot1.postInit();
+ scene->_hotspot1.setVisage(3710);
+ scene->_hotspot1.setStrip(1);
+ scene->_hotspot1.setFrame(1);
+ scene->_hotspot1.setPosition(Common::Point(204, 120));
+
+ setDelay(90);
+ break;
+ case 4:
+ scene->_soundHandler.startSound(197);
+ scene->_hotspot1.hide();
+
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(3710);
+ scene->_hotspot2.setStrip(2);
+ scene->_hotspot2.setFrame(1);
+ scene->_hotspot2.setPosition(Common::Point(204, 120));
+
+ setDelay(30);
+ break;
+ case 5:
+ scene->_soundHandler.startSound(198);
+ scene->_hotspot2.hide();
+ scene->_hotspot1.show();
+ setDelay(90);
+ break;
+ case 6:
+ scene->_stripManager.start(2166, this);
+ break;
+ case 7:
+ setDelay(60);
+ break;
+ case 8:
+ scene->_hotspot1.remove();
+ scene->_hotspot2.show();
+ _globals->setFlag(59);
+ setDelay(30);
+ break;
+ case 9:
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene3700::postInit(tSage::SceneObjectList *OwnerList) {
+ Scene::postInit();
+ loadScene(3700);
+
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerMR);
+ _speakerSText.setTextPos(Common::Point(20, 15));
+ _speakerMText.setTextPos(Common::Point(20, 15));
+
+ _viewer.postInit();
+ _viewer.setVisage(3705);
+ _viewer.setStrip(1);
+ _viewer.setFrame(2);
+ _viewer.setPosition(Common::Point(195, 83));
+
+ setAction(&_action1);
+ _globals->_soundHandler.startSound(195);
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes4.h b/engines/tsage/ringworld_scenes4.h
new file mode 100644
index 0000000000..f5dac297fc
--- /dev/null
+++ b/engines/tsage/ringworld_scenes4.h
@@ -0,0 +1,95 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES4_H
+#define TSAGE_RINGWORLD_SCENES4_H
+
+#include "common/scummsys.h"
+#include "tsage/core.h"
+#include "tsage/converse.h"
+#include "tsage/ringworld_logic.h"
+
+namespace tSage {
+
+class Scene3500 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ SpeakerSText _speakerSText;
+ SpeakerMText _speakerMText;
+ SpeakerQText _speakerQText;
+ Action1 _action1;
+ Action2 _action2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene3700 : public Scene {
+ /* Custom classes */
+ class Viewer : public SceneObject {
+ public:
+ Visage _images1;
+ Visage _images2;
+
+ int _frameList[4];
+ int _percentList[4];
+ bool _active;
+ int _countdownCtr;
+
+ Viewer();
+ virtual Common::String getClassName() { return "Viewer"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void dispatch();
+ virtual void reposition();
+ virtual void draw();
+ };
+
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ Viewer _viewer;
+ Action1 _action1;
+ SceneObject _hotspot1, _hotspot2;
+ SpeakerSText _speakerSText;
+ SpeakerMText _speakerMText;
+ SpeakerMR _speakerMR;
+ SoundHandler _soundHandler;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes5.cpp b/engines/tsage/ringworld_scenes5.cpp
new file mode 100644
index 0000000000..de29a1cefc
--- /dev/null
+++ b/engines/tsage/ringworld_scenes5.cpp
@@ -0,0 +1,4356 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "tsage/ringworld_scenes5.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 4000 - Village
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4000::Action1::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ scene->_hotspot5.postInit();
+ scene->_hotspot5.setVisage(2870);
+ scene->_hotspot5.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot5.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot5.setPosition(Common::Point(116, 160));
+
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot5, 208, 169);
+
+ _globals->_inventory._ale._sceneNumber = 0;
+ _globals->clearFlag(42);
+ _globals->clearFlag(36);
+ _globals->clearFlag(43);
+ _globals->clearFlag(37);
+ break;
+ }
+ case 1: {
+ scene->_hotspot9.postInit();
+ scene->_hotspot9.setVisage(4001);
+ scene->_hotspot9.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot9.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot9.setPosition(Common::Point(314, 132));
+
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot9, 288, 167);
+
+ scene->_hotspot4.postInit();
+ scene->_hotspot4.setVisage(4006);
+ scene->_hotspot4.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot4.setStrip(1);
+ scene->_hotspot4.setPosition(Common::Point(207, 136));
+
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot4, 220, 151);
+
+ scene->_hotspot7.postInit();
+ scene->_hotspot7.setVisage(2701);
+ scene->_hotspot7.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot7.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot7._moveDiff = Common::Point(4, 2);
+ scene->_hotspot7.setPosition(Common::Point(300, 135));
+
+ ADD_PLAYER_MOVER_NULL(_globals->_player, 266, 169);
+ break;
+ }
+ case 2:
+ scene->_stripManager.start(4400, this);
+ break;
+ case 3: {
+ Common::Point pt1(30, 86);
+ PlayerMover *mover1 = new PlayerMover();
+ scene->_hotspot7.addMover(mover1, &pt1, this);
+
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot5, 3, 86);
+ break;
+ }
+ case 4:
+ ADD_MOVER(scene->_hotspot7, -30, 86);
+ ADD_MOVER(scene->_hotspot5, -40, 86);
+ break;
+ case 5:
+ _globals->_soundHandler.startSound(155);
+ _globals->setFlag(43);
+ _globals->setFlag(114);
+ scene->_stripManager.start(4430, this);
+ break;
+ case 6:
+ ADD_PLAYER_MOVER_THIS(scene->_hotspot4, 277, 175);
+ ADD_PLAYER_MOVER_NULL(_globals->_player, 258, 187);
+ break;
+ case 7:
+ scene->_stripManager.start(4440, this);
+ break;
+ case 8:
+ setDelay(30);
+ break;
+ case 9:
+ _globals->setFlag(96);
+ _globals->_sceneManager.changeScene(4025);
+ break;
+ }
+}
+
+void Scene4000::Action2::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setAction(&scene->_sequenceManager1, this, 4001, &_globals->_player, NULL);
+
+ scene->_hotspot5.postInit();
+ scene->_hotspot5.setVisage(2801);
+ scene->_hotspot5.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot5.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot5._moveDiff.x = 5;
+ scene->_hotspot5.setPosition(Common::Point(-8, 88));
+
+ scene->_hotspot3.setAction(&scene->_sequenceManager3, NULL, 4003, &scene->_hotspot5, NULL);
+ scene->_hotspot7.setAction(&scene->_sequenceManager2, NULL, 4002, &scene->_hotspot7, NULL);
+ break;
+ case 1:
+ _globals->_player.disableControl();
+
+ scene->_hotspot3.remove();
+ ADD_MOVER(scene->_hotspot9, scene->_hotspot5._position.x + 30, scene->_hotspot5._position.y - 10);
+ break;
+ case 2:
+ _globals->_player.checkAngle(&scene->_hotspot9);
+ scene->_hotspot5.checkAngle(&scene->_hotspot9);
+ scene->_hotspot7.checkAngle(&scene->_hotspot9);
+ scene->_stripManager.start(4000, this);
+ break;
+ case 3:
+ scene->_hotspot2.setVisage(4017);
+ scene->_hotspot2.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot2.setStrip(2);
+
+ ADD_MOVER(scene->_hotspot2, 116, 160);
+ ADD_MOVER(scene->_hotspot5, 116, 160);
+
+ _globals->setFlag(37);
+ break;
+ case 4:
+ break;
+ case 5:
+ scene->_stripManager.start(4010, this);
+ break;
+ case 6:
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot9, 230, 149);
+ ADD_PLAYER_MOVER(210, 136);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot7, 210, 133);
+ break;
+ case 7:
+ _globals->_sceneManager.changeScene(4045);
+ break;
+ }
+}
+
+void Scene4000::Action3::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_hotspot8.setVisage(4017);
+ scene->_hotspot8.setFrame2(-1);
+ scene->_hotspot8.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot8.setObjectWrapper(new SceneObjectWrapper());
+ ADD_MOVER(scene->_hotspot8, 118, 145);
+ break;
+ case 1:
+ scene->_hotspot8.remove();
+ remove();
+ break;
+ }
+}
+
+void Scene4000::Action4::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player._uiEnabled = false;
+ ADD_MOVER(_globals->_player, 257, 57);
+ break;
+ case 1:
+ _globals->_player.setVisage(4000);
+ _globals->_player.setPosition(Common::Point(258, 83));
+ _globals->_player._frame = 1;
+ _globals->_player._strip = 3;
+ _globals->_player.animate(ANIM_MODE_4, 2, 1, this);
+ break;
+ case 2:
+ scene->_hotspot6.postInit();
+ scene->_hotspot6.setVisage(4000);
+ scene->_hotspot6.setStrip(7);
+ scene->_hotspot6.setFrame(3);
+ scene->_hotspot6.setPosition(Common::Point(268, 44));
+
+ _globals->_inventory._rope._sceneNumber = 4000;
+ _globals->_events.setCursor(CURSOR_USE);
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ _globals->_player.setVisage(2602);
+ _globals->_player.setPosition(Common::Point(257, 57));
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._uiEnabled = true;
+
+ _globals->setFlag(41);
+ remove();
+ break;
+ }
+}
+
+void Scene4000::Action5::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(15);
+ break;
+ case 1:
+ scene->_stripManager.start(_globals->_stripNum, this);
+ break;
+ case 2:
+ setDelay(10);
+ break;
+ case 3:
+ scene->_hotspot8.setVisage(4017);
+ scene->_hotspot8.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot8.setFrame2(-1);
+ scene->_hotspot8.setAction(&scene->_action3);
+
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4000::Action6::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(30);
+ break;
+ case 1:
+ setAction(&scene->_sequenceManager1, this, 4001, &_globals->_player, NULL);
+
+ if (!_globals->getFlag(36))
+ scene->_hotspot7.setAction(&scene->_sequenceManager2, NULL, 4002, &scene->_hotspot7, NULL);
+ break;
+ case 2:
+ _globals->_player.disableControl();
+ ADD_MOVER(scene->_hotspot9, _globals->_player._position.x + 30, _globals->_player._position.y - 5);
+ break;
+ case 3:
+ scene->_stripManager.start(_globals->getFlag(35) ? 4500 : 4502, this);
+ break;
+ case 4:
+ _globals->clearFlag(35);
+ ADD_MOVER_NULL(scene->_hotspot9, 292, 138);
+ ADD_PLAYER_MOVER(283, 147);
+
+ if (!_globals->getFlag(36)) {
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot7, 280, 150);
+ }
+ break;
+ case 5:
+ _globals->_sceneManager.changeScene(4100);
+ break;
+ }
+}
+
+void Scene4000::Action7::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+
+ scene->_hotspot6.setFrame(1);
+ ADD_MOVER(_globals->_player, 247, 53);
+ break;
+ case 1:
+ _globals->_player.setVisage(4008);
+ _globals->_player.setStrip(4);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPriority2(16);
+ _globals->_player.setPosition(Common::Point(260, 55));
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_sceneManager.changeScene(4050);
+ break;
+ }
+}
+
+void Scene4000::Action8::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ if (_globals->getFlag(41))
+ scene->_hotspot6.setFrame(2);
+
+ ADD_MOVER(_globals->_player, 289, 53);
+ break;
+ case 1:
+ _globals->_player.setVisage(4008);
+ _globals->_player.setStrip(5);
+ _globals->_player.setPriority(16);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(283, 52));
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_player.remove();
+ setDelay(60);
+ break;
+ case 3:
+ _globals->_soundHandler.startSound(170);
+ scene->_hotspot27.setVisage(4000);
+ scene->_hotspot27.setStrip(6);
+ scene->_hotspot27.animate(ANIM_MODE_2, NULL);
+ setDelay(60);
+ break;
+ case 4:
+ _globals->_soundHandler.startSound(77, this);
+ break;
+ case 5:
+ _globals->_game.endGame(4000, 15);
+ remove();
+ break;
+ }
+}
+
+void Scene4000::Action9::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(119) + 240);
+ break;
+ case 1:
+ static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_8, 1, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene4000::Action10::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(119) + 240);
+ break;
+ case 1:
+ static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_8, 1, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene4000::Action11::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_MOVER(scene->_hotspot3, -30, 70);
+ break;
+ case 1:
+ setDelay(60);
+ break;
+ case 2:
+ scene->_hotspot5.postInit();
+ scene->_hotspot5.setVisage(2801);
+ scene->_hotspot5.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot5.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot5._moveDiff.x = 4;
+ scene->_hotspot5.setPosition(Common::Point(-8, 88));
+
+ setAction(&scene->_sequenceManager1, this, 4001, &_globals->_player, NULL);
+
+ scene->_hotspot7.setPosition(Common::Point(-210, 139));
+ scene->_hotspot7.setAction(&scene->_sequenceManager2, NULL, 4002, &scene->_hotspot7, NULL);
+ scene->_hotspot3.setAction(&scene->_sequenceManager3, NULL, 4003, &scene->_hotspot5, NULL);
+ break;
+ case 3:
+ scene->_stripManager.start(8000, this);
+ break;
+ case 4:
+ ADD_MOVER(scene->_hotspot4, 263, 187);
+ scene->_hotspot4.animate(ANIM_MODE_1, NULL);
+ break;
+ case 5:
+ scene->_soundHandler1.proc3();
+ scene->_hotspot11.remove();
+
+ ADD_MOVER(_globals->_player, 340, 163);
+ ADD_MOVER_NULL(scene->_hotspot7, 340, 169);
+ ADD_MOVER_NULL(scene->_hotspot5, 340, 165);
+ break;
+ case 6:
+ _globals->_sceneManager.changeScene(4250);
+ break;
+ }
+}
+
+void Scene4000::Action12::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(5);
+ break;
+ case 1:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(4015, this);
+ break;
+ case 2:
+ _globals->setFlag(32);
+ if (scene->_stripManager._field2E8 == 275) {
+ _globals->setFlag(82);
+ ADD_MOVER_NULL(scene->_hotspot9, 292, 138);
+ ADD_PLAYER_MOVER(283, 147);
+ } else {
+ setDelay(30);
+ }
+ break;
+ case 3:
+ if (scene->_stripManager._field2E8 == 275) {
+ _globals->_sceneManager.changeScene(4100);
+ } else {
+ ADD_PLAYER_MOVER_THIS(scene->_hotspot9, 300, 132);
+ }
+ break;
+ case 4:
+ scene->_hotspot9.hide();
+ scene->_stripManager.start(4020, this);
+ break;
+ case 5:
+ _globals->setFlag(35);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4000::Action13::signal() {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ scene->_soundHandler2.startSound(151);
+ scene->_soundHandler2.proc5(true);
+ ADD_MOVER(scene->_hotspot3, -30, 70);
+ break;
+ case 2:
+ scene->_soundHandler2.proc4();
+ _globals->_sceneManager.changeScene(4010);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4000::Hotspot7::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(4000, 31);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 29);
+ break;
+ case CURSOR_TALK:
+ if (_globals->getFlag(31)) {
+ if (!_globals->getFlag(111)) {
+ _globals->setFlag(111);
+ _globals->_stripNum = 4070;
+ } else if (!_globals->getFlag(33))
+ _globals->_stripNum = 4094;
+ else if (!_globals->getFlag(112)) {
+ _globals->setFlag(112);
+ _globals->_stripNum = 4300;
+ } else if (!_globals->getFlag(113)) {
+ _globals->setFlag(113);
+ _globals->_stripNum = 4093;
+ } else
+ _globals->_stripNum = 4094;
+ } else {
+ if (!_globals->getFlag(33))
+ _globals->_stripNum = 4094;
+ else if (!_globals->getFlag(112)) {
+ _globals->setFlag(112);
+ _globals->_stripNum = 4300;
+ } else
+ _globals->_stripNum = 4094;
+ }
+
+ scene->setAction(&scene->_action5);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot8::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(4000, 26);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 25);
+ break;
+ case CURSOR_TALK:
+ if (_globals->_inventory._peg._sceneNumber == 1)
+ SceneItem::display2(4000, 34);
+ else {
+ switch (_ctr) {
+ case 0:
+ _globals->_stripNum = 4090;
+ break;
+ case 1:
+ _globals->_stripNum = 4091;
+ break;
+ case 2:
+ _globals->_stripNum = 4092;
+ break;
+ default:
+ SceneItem::display2(4000, 34);
+ break;
+ }
+
+ if (_globals->_stripNum) {
+ setAction(NULL);
+ addMover(NULL);
+ ++_ctr;
+ scene->setAction(&scene->_action5);
+ }
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot9::doAction(int action) {
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(4000, 28);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 27);
+ break;
+ case CURSOR_TALK:
+ error("*** Do we need dialog.");
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot10::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 30);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ if (_globals->getFlag(40)) {
+ scene->_sceneMode = 4005;
+ scene->setAction(&scene->_sequenceManager1, scene, 4005, &_globals->_player, NULL);
+ } else {
+ scene->_sceneMode = 4004;
+ scene->setAction(&scene->_sequenceManager1, scene, 4004, &_globals->_player, &scene->_hotspot10, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot12::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 13);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4000, 19);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4000, 20);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(40))
+ SceneItem::display2(4000, 37);
+ else {
+ _globals->_player.disableControl();
+ if (_globals->_sceneObjects->contains(&scene->_hotspot7))
+ _globals->clearFlag(96);
+
+ scene->_sceneMode = 4012;
+ scene->setAction(&scene->_sequenceManager1, scene, 4012, &_globals->_player, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot13::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 21);
+ break;
+ case OBJECT_ROPE:
+ if (_globals->getFlag(40))
+ scene->setAction(&scene->_action4);
+ else
+ SceneItem::display2(4000, 22);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 16);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4000, 17);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4000, 18);
+ break;
+ case OBJECT_LADDER:
+ _globals->_player.disableControl();
+
+ scene->_hotspot10.postInit();
+ scene->_hotspot10.setVisage(4000);
+ scene->_hotspot10.setStrip(5);
+ scene->_hotspot10.setPosition(Common::Point(245, 147));
+ scene->_hotspot10.hide();
+ _globals->_sceneItems.push_front(&scene->_hotspot10);
+
+ if (_globals->_sceneObjects->contains(&scene->_hotspot8)) {
+ scene->_hotspot8.setAction(NULL);
+ ADD_MOVER_NULL(scene->_hotspot8, 118, 145);
+ }
+
+ scene->_sceneMode = 4004;
+ scene->setAction(&scene->_sequenceManager1, scene, 4011, &_globals->_player, &scene->_hotspot10, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot17::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 23);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(40))
+ scene->setAction(&scene->_action7);
+ else
+ SceneItem::display2(4000, 24);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot18::doAction(int action) {
+ Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, 36);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(40))
+ scene->setAction(&scene->_action8);
+ else
+ SceneItem::display2(4000, 24);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4000::Hotspot23::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4000, _globals->getFlag(31) ? 10 : 9);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4000::Scene4000() :
+ _hotspot11(0, CURSOR_LOOK, 4000, 14, CURSOR_USE, 4000, 32, OBJECT_STUNNER, 4000, 33,
+ OBJECT_SCANNER, 4000, 19, LIST_END),
+ _hotspot19(0, CURSOR_LOOK, 4000, 7, LIST_END),
+ _hotspot20(0, CURSOR_LOOK, 4000, 3, LIST_END),
+ _hotspot21(0, CURSOR_LOOK, 4000, 1, LIST_END),
+ _hotspot22(0, CURSOR_LOOK, 4000, 8, LIST_END),
+ _hotspot24(0, CURSOR_LOOK, 4000, 11, LIST_END),
+ _hotspot25(0, CURSOR_LOOK, 4000, 4, LIST_END),
+ _hotspot26(0, CURSOR_LOOK, 4000, 0, LIST_END) {
+}
+
+void Scene4000::postInit(SceneObjectList *OwnerList) {
+ loadScene(4000);
+ Scene::postInit();
+ setZoomPercents(0, 20, 70, 50);
+
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerML);
+ _stripManager.addSpeaker(&_speakerMR);
+ _stripManager.addSpeaker(&_speakerSR);
+ _stripManager.addSpeaker(&_speakerCHFL);
+ _stripManager.addSpeaker(&_speakerPL);
+ _stripManager.addSpeaker(&_speakerPText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerCHFR);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerCHFText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerMText);
+
+ _speakerCHFText._npc = &_hotspot9;
+ _speakerSText._npc = &_hotspot5;
+ _speakerMText._npc = &_hotspot7;
+ _speakerPText._npc = &_hotspot4;
+ _speakerQText._npc = &_globals->_player;
+
+ _hotspot13.setBounds(Rect(263, 41, 278, 55));
+ _hotspot14.setBounds(Rect(140, 177, 140 /*96*/, 204));
+ _hotspot15.setBounds(Rect(227, 101, 264, 143));
+ _hotspot16.setBounds(Rect(306, 100, 319, 148));
+ _hotspot17.setBounds(Rect(231, 53, 254, 60));
+ _hotspot18.setBounds(Rect(285, 51, 310, 60));
+ _hotspot26.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot21.setBounds(Rect(28, 7, 53, 64));
+ _hotspot22.setBounds(Rect(125, 155, 140, 189));
+ _hotspot23.setBounds(Rect(205, 102, 220, 142));
+ _hotspot24.setBounds(Rect(270, 111, 297, 147));
+
+ _hotspot19._sceneRegionId = 16;
+ _hotspot20._sceneRegionId = 18;
+ _hotspot25._sceneRegionId = 17;
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(4000);
+ _hotspot1.setPriority2(1);
+ _hotspot1.setFrame(2);
+ _hotspot1.setPosition(Common::Point(242, 59));
+ _hotspot1.animate(ANIM_MODE_2, NULL);
+
+ _hotspot27.postInit();
+ _hotspot27.setVisage(4000);
+ _hotspot27.setStrip(2);
+ _hotspot27.setPriority2(1);
+ _hotspot27.setFrame(2);
+ _hotspot27.setPosition(Common::Point(299, 59));
+ _hotspot27.animate(ANIM_MODE_2, NULL);
+
+ if (_globals->_inventory._ladder._sceneNumber != 4000) {
+ _hotspot8.postInit();
+ _hotspot8.setVisage(4018);
+ _hotspot8.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot8._strip = 2;
+ _hotspot8._numFrames = 5;
+ _hotspot8.setPosition(Common::Point(306, 154));
+ _hotspot8.setAction(&_action9);
+ }
+
+ _hotspot12.postInit();
+ _hotspot12.setVisage(4000);
+ _hotspot12.setStrip(3);
+ _hotspot12.setFrame(3);
+ _hotspot12.setPriority2(200);
+ _hotspot12.setPosition(Common::Point(281, 176));
+
+ if (_globals->getFlag(34)) {
+ _soundHandler1.startSound(156);
+
+ _hotspot11.postInit();
+ _hotspot11.setVisage(4000);
+ _hotspot11.setStrip(4);
+ _hotspot11.setPosition(Common::Point(312, 174));
+ _hotspot11.setPriority2(200);
+ _hotspot11.animate(ANIM_MODE_8, 0, NULL);
+
+ _globals->_sceneItems.push_back(&_hotspot11);
+ }
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2602);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(-28, 86));
+
+ if (!_globals->getFlag(36) && !_globals->getFlag(43)) {
+ _hotspot7.postInit();
+ _hotspot7.setVisage(2701);
+ _hotspot7.animate(ANIM_MODE_1, NULL);
+ _hotspot7.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot7._moveDiff = Common::Point(4, 2);
+ _hotspot7.setPosition(Common::Point(-210, 139));
+
+ _globals->_sceneItems.push_back(&_hotspot7);
+ }
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 2320:
+ _globals->_soundHandler.startSound(155);
+
+ if (_globals->_inventory._ale._sceneNumber == 1) {
+ _hotspot9.postInit();
+ _hotspot9.setVisage(4001);
+ _hotspot9.animate(ANIM_MODE_1, NULL);
+ _hotspot9.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot9.setPosition(Common::Point(314, 132));
+
+ setAction(&_action6);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 4001;
+ setAction(&_sequenceManager1, this, 4001, &_globals->_player, NULL);
+
+ if (!_globals->getFlag(36) && !_globals->getFlag(43))
+ _hotspot7.setAction(&_sequenceManager2, NULL, 4002, &_hotspot7, NULL);
+ }
+
+ if (_globals->getFlag(42))
+ _hotspot8.setAction(&_action3);
+ else if (_globals->getFlag(91))
+ _hotspot8.remove();
+ break;
+
+ case 4010:
+ _hotspot7.setPosition(Common::Point(-210, 139));
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(4001);
+ _hotspot9.animate(ANIM_MODE_1, NULL);
+ _hotspot9.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot9.setPosition(Common::Point(314, 132));
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(4018);
+ _hotspot2._strip = 1;
+ _hotspot2._numFrames = 5;
+ _hotspot2.setPosition(Common::Point(182, 146));
+ _hotspot2.setAction(&_action10);
+
+ setAction(&_action2);
+ break;
+
+ case 4025:
+ if (_globals->_inventory._ladder._sceneNumber != 4000)
+ _hotspot8.remove();
+
+ _globals->_player.setPosition(Common::Point(260, 185));
+
+ if (!_globals->getFlag(36) && !_globals->getFlag(43))
+ _hotspot7.setPosition(Common::Point(246, 146));
+
+ if (_globals->getFlag(96)) {
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4006);
+ _hotspot4.animate(ANIM_MODE_1, NULL);
+ _hotspot4.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot4.setPosition(Common::Point(290, 163));
+ }
+
+ if (_globals->_stripNum == 4025) {
+ _soundHandler1.startSound(182);
+ _hotspot11.remove();
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(2801);
+ _hotspot5.animate(ANIM_MODE_1, NULL);
+ _hotspot5.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot5._moveDiff.x = 4;
+ _hotspot5.setPosition(Common::Point(-18, 86));
+
+ _globals->_player.disableControl();
+
+ if (!_globals->getFlag(96)) {
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4006);
+ _hotspot4.animate(ANIM_MODE_1, NULL);
+ _hotspot4.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot4.setPosition(Common::Point(195, 128));
+
+ Common::Point pt(268, 157);
+ PlayerMover *mover = new PlayerMover();
+ _hotspot4.addMover(mover, &pt, NULL);
+ }
+
+ _sceneMode = 4003;
+ setAction(&_sequenceManager1, this, 4003, &_hotspot5, NULL);
+ } else if (_globals->getFlag(96)) {
+ _globals->_player.disableControl();
+ _sceneMode = 4013;
+ setAction(&_sequenceManager1, this, 4013, &_hotspot4, NULL);
+ }
+
+ _globals->clearFlag(96);
+ break;
+
+ case 4045:
+ _globals->_player.enableControl();
+
+ if (_globals->_inventory._ladder._sceneNumber != 4000) {
+ _hotspot8.postInit();
+ _hotspot8.setVisage(4017);
+ _hotspot8.animate(ANIM_MODE_1, NULL);
+ _hotspot8.setPosition(Common::Point(199, 188));
+ _hotspot8.setAction(&_action3);
+ }
+
+ _globals->_player.setPosition(Common::Point(208, 153));
+ if (!_globals->getFlag(36) && !_globals->getFlag(43))
+ _hotspot7.setPosition(Common::Point(246, 146));
+
+ if (_globals->getFlag(39)) {
+ _globals->clearFlag(39);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4006);
+ _hotspot4.animate(ANIM_MODE_1, NULL);
+ _hotspot4.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot4.setPosition(Common::Point(219, 150));
+
+ _globals->_player.disableControl();
+ setAction(&_sequenceManager1, this, 4010, &_globals->_player, NULL);
+ }
+
+ if (_globals->_stripNum == 4000) {
+ _globals->_stripNum = 0;
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(4001);
+ _hotspot9.animate(ANIM_MODE_1, NULL);
+ _hotspot9.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot9.setPosition(Common::Point(231, 159));
+ _hotspot9.setStrip(4);
+
+ setAction(&_action12);
+ }
+ break;
+
+ case 4050:
+ _globals->_soundHandler.startSound(155);
+ _globals->_player.disableControl();
+
+ if (_globals->_stripNum == 4050) {
+ _globals->_player.setVisage(4008);
+ _globals->_player.setStrip(4);
+ _globals->_player.setFrame(_globals->_player.getFrameCount());
+ _globals->_player.setPriority2(16);
+ _globals->_player.setPosition(Common::Point(260, 55));
+
+ _sceneMode = 4007;
+ setAction(&_sequenceManager1, this, 4007, &_globals->_player, NULL);
+ } else {
+ _globals->_player.setPosition(Common::Point(208, 153));
+ _globals->_player.enableControl();
+ }
+
+ if (_globals->_inventory._ladder._sceneNumber != 4000)
+ _hotspot8.remove();
+ break;
+
+ case 4100:
+ _globals->_player.enableControl();
+ _globals->_player.setPosition(Common::Point(270, 155));
+
+ if (_globals->getFlag(42) && (_globals->_inventory._ladder._sceneNumber != 4000)) {
+ _hotspot8.setVisage(4017);
+ _hotspot8.animate(ANIM_MODE_1, NULL);
+ _hotspot8.setPosition(Common::Point(244, 151));
+ _hotspot8.setAction(&_action3);
+ }
+
+ if (!_globals->getFlag(36) && !_globals->getFlag(43))
+ _hotspot7.setPosition(Common::Point(246, 146));
+ break;
+
+ default:
+ _globals->_soundHandler.startSound(155);
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(4002);
+ _hotspot3._moveDiff = Common::Point(10, 10);
+ _hotspot3.setPosition(Common::Point(-100, 80));
+ _hotspot3.changeZoom(-1);
+ _hotspot3.setPosition(Common::Point(130, -1));
+ _hotspot3.animate(ANIM_MODE_2, NULL);
+
+ if (_globals->_stripNum == 9000) {
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4006);
+ _hotspot4.setPosition(Common::Point(235, 153));
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(4001);
+ _hotspot9.setStrip(3);
+ _hotspot9.setPosition(Common::Point(255, 153));
+
+ setAction(&_action11);
+ _globals->_inventory._ladder._sceneNumber = 4100;
+ _globals->_inventory._rope._sceneNumber = 4150;
+
+ _soundHandler1.startSound(156);
+
+ _hotspot11.postInit();
+ _hotspot11.setVisage(4000);
+ _hotspot11.setStrip(4);
+ _hotspot11.setPosition(Common::Point(312, 174));
+ _hotspot11.setPriority2(200);
+ _hotspot11.animate(ANIM_MODE_8, 0, NULL);
+ } else {
+ if (!_globals->getFlag(37)) {
+ _hotspot2.postInit();
+ _hotspot2.setVisage(4018);
+ _hotspot2._strip = 1;
+ _hotspot2._numFrames = 5;
+ _hotspot2.setPosition(Common::Point(182, 146));
+ _hotspot2.setAction(&_action10);
+ }
+
+ _hotspot7.setPosition(Common::Point(-210, 139));
+ setAction(&_action13);
+ }
+ break;
+ }
+
+ if (_globals->_inventory._ladder._sceneNumber == 4000) {
+ _hotspot10.postInit();
+ _hotspot10.setVisage(4000);
+ _hotspot10.setStrip(5);
+ _hotspot10.setPosition(Common::Point(245, 147));
+
+ _globals->_sceneItems.push_back(&_hotspot10);
+ }
+
+ if (_globals->_inventory._rope._sceneNumber == 4000) {
+ _hotspot6.postInit();
+ _hotspot6.setVisage(4000);
+ _hotspot6.setStrip(7);
+ _hotspot6.setPriority2(1);
+ _hotspot6.setPosition(Common::Point(268, 44));
+ }
+
+ _globals->_sceneItems.addItems(&_hotspot8, &_hotspot17, &_hotspot18, &_hotspot14, &_hotspot15,
+ &_hotspot16, &_hotspot12, &_hotspot13, &_hotspot21, &_hotspot20, &_hotspot22, &_hotspot23,
+ &_hotspot24, &_hotspot25, &_hotspot19, &_hotspot26, NULL);
+}
+
+void Scene4000::signal() {
+ switch (_sceneMode) {
+ case 4001:
+ _globals->_player.enableControl();
+ break;
+ case 4002:
+ case 4011:
+ break;
+ case 4003:
+ _sceneMode = 4014;
+ setAction(&_sequenceManager1, this, 4014, &_globals->_player, &_hotspot5, NULL);
+ break;
+ case 4004:
+ _globals->_inventory._ladder._sceneNumber = 4000;
+ // Deliberate fall-through
+ case 4007:
+ _globals->_events.setCursor(CURSOR_USE);
+ _globals->setFlag(40);
+ break;
+ case 4005:
+ _globals->_player.enableControl();
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->clearFlag(40);
+ break;
+ case 4006:
+ _globals->_sceneManager.changeScene(4045);
+ break;
+ case 4008:
+ _globals->_sceneManager.changeScene(2320);
+ break;
+ case 4009:
+ _globals->_sceneManager.changeScene(2200);
+ break;
+ case 4010:
+ _globals->setFlag(38);
+ _hotspot4.remove();
+ break;
+ case 4012:
+ _globals->_player.checkAngle(&_hotspot12);
+ _globals->_sceneManager.changeScene(4025);
+ break;
+ case 4013:
+ _globals->_player.enableControl();
+ _hotspot4.remove();
+ break;
+ case 4014:
+ _globals->_sceneManager.changeScene(4250);
+ break;
+ case 4015:
+ ADD_MOVER_NULL(_hotspot7, 0, _hotspot7._position.y - 5);
+ break;
+ }
+}
+
+void Scene4000::dispatch() {
+ Scene::dispatch();
+
+ if ((_globals->_player.getRegionIndex() == 10) || (_globals->_player.getRegionIndex() == 6))
+ _globals->_player.setPriority2(200);
+ if (_globals->_player.getRegionIndex() == 11)
+ _globals->_player.setPriority2(-1);
+ if (_globals->_player.getRegionIndex() == 5)
+ _globals->_player.setPriority2(94);
+
+ if (_globals->_sceneObjects->contains(&_hotspot5)) {
+ if ((_hotspot5.getRegionIndex() == 10) || (_hotspot5.getRegionIndex() == 6))
+ _hotspot5.setPriority2(200);
+ if (_hotspot5.getRegionIndex() == 11)
+ _hotspot5.setPriority2(-1);
+ if (_hotspot5.getRegionIndex() == 5)
+ _hotspot5.setPriority2(94);
+ }
+
+ if (_globals->_sceneObjects->contains(&_hotspot7)) {
+ if (!_hotspot7._mover)
+ _hotspot7.checkAngle(&_globals->_player);
+ if (!_action && _globals->_player.getRegionIndex() == 23) {
+ ADD_MOVER_NULL(_hotspot7, 204, 186);
+ }
+
+ if ((_hotspot7.getRegionIndex() == 10) || (_hotspot7.getRegionIndex() == 6))
+ _hotspot7.setPriority2(200);
+ if (_hotspot7.getRegionIndex() == 11)
+ _hotspot7.setPriority2(-1);
+ if (_hotspot7.getRegionIndex() == 5)
+ _hotspot7.setPriority2(94);
+ }
+
+ if (!_action) {
+ if ((_globals->_inventory._peg._sceneNumber == 1) && _globals->getFlag(34) &&
+ _globals->getFlag(37) && !_globals->getFlag(40)) {
+ _globals->_player.disableControl();
+ _soundHandler1.startSound(177);
+ _globals->_soundHandler.startSound(178);
+
+ setAction(&_action1);
+ }
+
+ if (_globals->_player.getRegionIndex() == 2)
+ _globals->_sceneManager.changeScene(4045);
+ if (_globals->_player.getRegionIndex() == 15)
+ _globals->_sceneManager.changeScene(4100);
+
+ if ((_globals->_player._position.x > 5) && (_globals->_player._position.y < 100)) {
+ _globals->_player.disableControl();
+
+ if (!_globals->_sceneObjects->contains(&_hotspot7) || (_hotspot7._position.y <= 100)) {
+ _sceneMode = 4008;
+ setAction(&_sequenceManager1, this, 4008, &_globals->_player, NULL);
+ } else {
+ _sceneMode = 4015;
+ _globals->_player.addMover(NULL);
+ setAction(&_sequenceManager1, this, 4015, &_globals->_player, &_hotspot7, NULL);
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4010 - Village - Outside Lander
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4010::postInit(SceneObjectList *OwnerList) {
+ loadScene(4010);
+ Scene::postInit();
+ setZoomPercents(0, 20, 70, 50);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _speakerSText._npc = &_hotspot1;
+ _speakerMText._npc = &_hotspot2;
+ _speakerQText._npc = &_globals->_player;
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(-38, 175));
+ _globals->_player.changeZoom(75);
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(2705);
+ _hotspot2.animate(ANIM_MODE_1, NULL);
+ _hotspot2.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot2._moveDiff = Common::Point(4, 2);
+ _hotspot2.setPosition(Common::Point(-50, 185));
+ _hotspot2.changeZoom(75);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(2806);
+ _hotspot1.setPosition(Common::Point(-20, 175));
+ _hotspot1.changeZoom(75);
+ _hotspot1.animate(ANIM_MODE_1, NULL);
+ _hotspot1.setObjectWrapper(new SceneObjectWrapper());
+
+ _globals->_player.disableControl();
+ setAction(&_sequenceManager, this, 4017, &_globals->_player, &_hotspot1, &_hotspot2, NULL);
+}
+
+void Scene4010::signal() {
+ _globals->_sceneManager.changeScene(4000);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4025 - Village - Puzzle Board
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4025::Action1::signal() {
+ Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_armHotspot._strip = scene->_pegPtr->_armStrip;
+ scene->_armHotspot._frame = 4;
+ scene->_armHotspot.animate(ANIM_MODE_4, 2, -1, this);
+
+ if (scene->_pegPtr->_armStrip > 3) {
+ if (scene->_hole1._armStrip == scene->_pegPtr->_armStrip)
+ scene->_hole1._pegPtr = NULL;
+ if (scene->_hole2._armStrip == scene->_pegPtr->_armStrip)
+ scene->_hole2._pegPtr = NULL;
+ if (scene->_hole3._armStrip == scene->_pegPtr->_armStrip)
+ scene->_hole3._pegPtr = NULL;
+ if (scene->_hole4._armStrip == scene->_pegPtr->_armStrip)
+ scene->_hole4._pegPtr = NULL;
+ if (scene->_hole5._armStrip == scene->_pegPtr->_armStrip)
+ scene->_hole5._pegPtr = NULL;
+ }
+ break;
+ case 1:
+ scene->_pegPtr->hide();
+
+ if (scene->_pegPtr2) {
+ if (scene->_pegPtr->_armStrip == 3)
+ scene->_pegPtr2->_strip = 2;
+
+ scene->_pegPtr2->setPosition(scene->_pegPtr->_position);
+ scene->_pegPtr2->show();
+ scene->_pegPtr2->_armStrip = scene->_pegPtr->_armStrip;
+ }
+
+ scene->_pegPtr->_armStrip = 0;
+ scene->_pegPtr->setPosition(Common::Point(-10, -10));
+ scene->_pegPtr2 = scene->_pegPtr;
+ scene->_armHotspot.animate(ANIM_MODE_5, this);
+ break;
+
+ case 2:
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_USE);
+ remove();
+ break;
+ }
+}
+
+void Scene4025::Action2::signal() {
+ Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_armHotspot._strip = scene->_holePtr->_armStrip;
+ scene->_armHotspot.animate(ANIM_MODE_4, 2, -1, this);
+ break;
+ case 1:
+ if (!scene->_pegPtr2) {
+ // Getting a peg from a hole
+ scene->_holePtr->_pegPtr->hide();
+ scene->_pegPtr = scene->_holePtr->_pegPtr;
+ scene->_pegPtr->_armStrip = 0;
+ scene->_pegPtr->setPosition(Common::Point(-10, -10));
+ scene->_pegPtr2 = scene->_holePtr->_pegPtr;
+ scene->_holePtr->_pegPtr = NULL;
+ } else {
+ // Placing a peg into a hole
+ scene->_pegPtr2 = NULL;
+ if (scene->_holePtr->_pegPtr) {
+ scene->_holePtr->_pegPtr->hide();
+ scene->_pegPtr2 = scene->_holePtr->_pegPtr;
+ }
+
+ assert(scene->_pegPtr);
+ scene->_pegPtr->setPosition(scene->_holePtr->_newPosition);
+ scene->_pegPtr->setStrip(1);
+ scene->_pegPtr->show();
+ scene->_pegPtr->_armStrip = scene->_holePtr->_armStrip;
+
+ scene->_holePtr->_pegPtr = scene->_pegPtr;
+ scene->_pegPtr = scene->_pegPtr2;
+ }
+ scene->_armHotspot.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_player._uiEnabled = true;
+ _globals->_events.setCursor(CURSOR_USE);
+ remove();
+ break;
+ }
+}
+
+void Scene4025::Action3::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ _globals->_scenePalette.addRotation(64, 111, -1);
+ setDelay(120);
+ break;
+ case 1:
+ _globals->clearFlag(34);
+ _globals->_stripNum = 4025;
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4025::Hole::synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ SYNC_POINTER(_pegPtr);
+ s.syncAsSint16LE(_armStrip);
+ s.syncAsSint16LE(_newPosition.x);
+ s.syncAsSint16LE(_newPosition.y);
+}
+
+void Scene4025::Hole::doAction(int action) {
+ Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4025, 3);
+ break;
+ case CURSOR_USE:
+ if (!scene->_pegPtr && !_pegPtr) {
+ setAction(&scene->_sequenceManager, scene, 4028, NULL);
+ } else {
+ _globals->_player.disableControl();
+ scene->_holePtr = this;
+ scene->setAction(&scene->_action2);
+ }
+ break;
+ case OBJECT_PEG:
+ if (!scene->_pegPtr2) {
+ _globals->_player.disableControl();
+ _globals->_events.setCursor(CURSOR_USE);
+ _globals->_inventory._peg._sceneNumber = 4025;
+
+ scene->_pegPtr = &scene->_peg5;
+ scene->_holePtr = this;
+ scene->_pegPtr->_armStrip = 0;
+ scene->_pegPtr2 = scene->_pegPtr;
+
+ scene->setAction(&scene->_action2);
+ } else {
+ scene->_sceneMode = 4027;
+ scene->setAction(&scene->_sequenceManager, scene, 4027, NULL);
+ }
+ break;
+ }
+}
+
+void Scene4025::Peg::synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ s.syncAsSint16LE(_field88);
+ SYNC_POINTER(_armStrip);
+}
+
+void Scene4025::Peg::doAction(int action) {
+ Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4025, 1);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_pegPtr = this;
+ scene->setAction(&scene->_action1);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4025::Scene4025() : Scene() {
+ _holePtr = NULL;
+ _pegPtr = _pegPtr2 = NULL;
+}
+
+void Scene4025::postInit(SceneObjectList *OwnerList) {
+ loadScene(4025);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _globals->_events.setCursor(CURSOR_USE);
+ _pegPtr = _pegPtr2 = NULL;
+
+ _peg1.postInit();
+ _peg1._field88 = 1;
+ _peg1.setVisage(4025);
+ _peg1.setStrip(2);
+ _peg1.setFrame(1);
+ _peg1.setPosition(Common::Point(203, 61));
+
+ _peg2.postInit();
+ _peg2._field88 = 4;
+ _peg2.setVisage(4025);
+ _peg2.setStrip(2);
+ _peg2.setFrame(2);
+ _peg2.setPosition(Common::Point(195, 57));
+
+ _peg3.postInit();
+ _peg3._field88 = 0;
+ _peg3.setVisage(4025);
+ _peg3.setStrip(2);
+ _peg3.setFrame(3);
+ _peg3.setPosition(Common::Point(202, 66));
+
+ _peg4.postInit();
+ _peg4._field88 = 3;
+ _peg4.setVisage(4025);
+ _peg4.setStrip(2);
+ _peg4.setFrame(4);
+ _peg4.setPosition(Common::Point(194, 68));
+
+ _peg5.postInit();
+ _peg5._field88 = 2;
+ _peg5.setVisage(4025);
+ _peg5.setStrip(1);
+ _peg5.setFrame(5);
+ _peg5.hide();
+
+ _hole1.postInit();
+ _hole1.setVisage(4025);
+ _hole1.setStrip(1);
+ _hole1.setFrame2(6);
+ _hole1.setPosition(Common::Point(123, 51));
+ _hole1._pegPtr = NULL;
+ _hole1._newPosition = Common::Point(123, 44);
+ _hole1._armStrip = 8;
+
+ _hole2.postInit();
+ _hole2.setVisage(4025);
+ _hole2.setStrip(1);
+ _hole2.setFrame2(7);
+ _hole2.setPosition(Common::Point(167, 51));
+ _hole2._pegPtr = NULL;
+ _hole2._newPosition = Common::Point(166, 44);
+ _hole2._armStrip = 7;
+
+ _hole3.postInit();
+ _hole3.setVisage(4025);
+ _hole3.setStrip(1);
+ _hole3.setFrame2(8);
+ _hole3.setPosition(Common::Point(145, 69));
+ _hole3._pegPtr = NULL;
+ _hole3._newPosition = Common::Point(145, 60);
+ _hole3._armStrip = 6;
+
+ _hole4.postInit();
+ _hole4.setVisage(4025);
+ _hole4.setStrip(1);
+ _hole4.setFrame2(6);
+ _hole4.setPosition(Common::Point(123, 87));
+ _hole4._pegPtr = NULL;
+ _hole4._newPosition = Common::Point(123, 80);
+ _hole4._armStrip = 5;
+
+ _hole5.postInit();
+ _hole5.setVisage(4025);
+ _hole5.setStrip(1);
+ _hole5.setFrame2(10);
+ _hole5.setPosition(Common::Point(167, 87));
+ _hole5._pegPtr = NULL;
+ _hole5._newPosition = Common::Point(166, 80);
+ _hole5._armStrip = 4;
+
+ _hole1.setPriority2(1);
+ _hole2.setPriority2(1);
+ _hole3.setPriority2(1);
+ _hole4.setPriority2(1);
+ _hole5.setPriority2(1);
+
+ _armHotspot.postInit();
+ _armHotspot.setVisage(4025);
+ _armHotspot.setPosition(Common::Point(190, 161));
+ _armHotspot.setStrip(3);
+ _armHotspot.setFrame(4);
+
+ _globals->_sceneItems.addItems(&_hole1, &_hole2, &_hole3, &_hole4, &_hole5,
+ &_peg1, &_peg2, &_peg3, &_peg4, &_peg5, NULL);
+
+ _globals->_player._uiEnabled = true;
+ _globals->_player.disableControl();
+ setAction(&_sequenceManager, this, 4026, NULL);
+}
+
+void Scene4025::synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ SYNC_POINTER(_pegPtr);
+ SYNC_POINTER(_pegPtr2);
+ SYNC_POINTER(_holePtr);
+}
+
+void Scene4025::remove() {
+ _globals->_scenePalette.clearListeners();
+ Scene::remove();
+}
+
+void Scene4025::signal() {
+ if (_sceneMode != 4027) {
+ if (_sceneMode != 4028) {
+ _gfxButton.setText(EXIT_MSG);
+ _gfxButton._bounds.centre(144, 107);
+ _gfxButton.draw();
+ _gfxButton._bounds.expandPanes();
+ }
+
+ _globals->_player._uiEnabled = true;
+ }
+
+ _globals->_events.setCursor(CURSOR_USE);
+}
+
+void Scene4025::process(Event &event) {
+ Scene::process(event);
+
+ if (_gfxButton.process(event)) {
+ if (_globals->_inventory._peg._sceneNumber == 4025)
+ _globals->_inventory._peg._sceneNumber = 1;
+
+ _globals->_sceneManager.changeScene(4000);
+ }
+}
+
+void Scene4025::dispatch() {
+ if (!_action && (_peg1._armStrip == 7) && (_peg2._armStrip == 4) && (_peg3._armStrip == 8) &&
+ (_peg4._armStrip == 5) && (_peg5._armStrip == 6))
+ setAction(&_action3);
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4045 - Village - Temple Antechamber
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4045::Action1::signal() {
+ Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(60);
+ break;
+ case 1:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(4040, this, scene);
+ break;
+ case 2:
+ scene->_hotspot5.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot4.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ setDelay(60);
+ break;
+ case 4:
+ scene->_hotspot4.animate(ANIM_MODE_6, this);
+ break;
+ case 5:
+ ADD_MOVER(_globals->_player, 150, 300);
+ break;
+ case 6:
+ _globals->_stripNum = 4000;
+ _globals->_sceneManager.changeScene(4000);
+ remove();
+ break;
+ }
+}
+
+void Scene4045::Action2::signal() {
+ Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(15);
+ break;
+ case 1:
+ scene->_stripManager.start(_globals->_stripNum, this, scene);
+ break;
+ case 2:
+ scene->_hotspot5.animate(ANIM_MODE_NONE, NULL);
+ setDelay(10);
+ break;
+ case 3:
+ if (_globals->getFlag(38)) {
+ _globals->_player.enableControl();
+ remove();
+ } else {
+ ADD_MOVER(_globals->_player, 150, 300);
+ }
+ break;
+ case 4:
+ _globals->setFlag(39);
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ }
+}
+
+void Scene4045::Action3::signal() {
+ Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ scene->_hotspot4.animate(ANIM_MODE_5, this);
+ break;
+ case 1:
+ scene->_stripManager.start(4504, this, scene);
+ break;
+ case 2:
+ scene->_hotspot4.animate(ANIM_MODE_6, NULL);
+ scene->_hotspot5.animate(ANIM_MODE_NONE, NULL);
+ ADD_MOVER(_globals->_player, 91, 1264);
+ break;
+ case 3:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4045::Hotspot1::doAction(int action) {
+ Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_STUNNER:
+ SceneItem::display2(4045, 19);
+ break;
+ case CURSOR_LOOK:
+ SceneItem::display2(4045, (_strip == 1) ? 5 : 14);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(4045, 18);
+ break;
+ case CURSOR_TALK:
+ if (_strip == 5) {
+ setStrip(6);
+ animate(ANIM_MODE_NONE, 0);
+ }
+ if (_globals->_player._position.y < 135) {
+ scene->_sceneMode = 4046;
+ _numFrames = 10;
+ _globals->_player.disableControl();
+
+ scene->setAction(&scene->_sequenceManager, this, 4046, &_globals->_player, this, NULL);
+ } else {
+ if (!_globals->getFlag(31)) {
+ _globals->setFlag(31);
+ _globals->_stripNum = 4080;
+ } else if (!_globals->getFlag(38))
+ _globals->_stripNum = 4060;
+ else
+ _globals->_stripNum = 4503;
+
+ scene->setAction(&scene->_action2);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4045::Hotspot2::doAction(int action) {
+ Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4045, 9);
+ break;
+ case CURSOR_TALK:
+ scene->_sceneMode = 4102;
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_sequenceManager, scene, 4104, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4045::Hotspot6::doAction(int action) {
+ Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4045, 17);
+ break;
+ case CURSOR_USE:
+ if (_globals->_player._position.y < 135) {
+ SceneItem::display2(4045, 16);
+ _globals->_inventory._peg._sceneNumber = 1;
+ _globals->_events.setCursor(CURSOR_WALK);
+ remove();
+ } else {
+ scene->_sceneMode = 4047;
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_sequenceManager, scene, 4047, &_globals->_player, &scene->_hotspot1, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4045::Scene4045() :
+ _hotspot3(0, CURSOR_LOOK, 4045, 1, CURSOR_USE, 4100, 21, LIST_END),
+ _hotspot7(9, CURSOR_LOOK, 4045, 0, CURSOR_USE, 4045, 15, LIST_END),
+ _hotspot8(10, CURSOR_LOOK, 4045, 2, LIST_END),
+ _hotspot9(11, CURSOR_LOOK, 4045, 3, CURSOR_USE, 4045, 15, LIST_END),
+ _hotspot10(12, CURSOR_LOOK, 4045, 4, CURSOR_USE, 4045, 19, LIST_END),
+ _hotspot11(13, CURSOR_LOOK, 4045, 6, CURSOR_USE, 4045, 15, LIST_END),
+ _hotspot12(14, CURSOR_LOOK, 4045, 7, CURSOR_USE, 4045, 29, LIST_END),
+ _hotspot13(15, CURSOR_LOOK, 4045, 8, CURSOR_USE, 4045, 19, LIST_END),
+ _hotspot14(0, CURSOR_LOOK, 4045, 10, LIST_END) {
+
+ _hotspot14.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+}
+
+void Scene4045::postInit(SceneObjectList *OwnerList) {
+ loadScene(4045);
+ Scene::postInit();
+ setZoomPercents(100, 60, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerML);
+ _stripManager.addSpeaker(&_speakerPR);
+ _stripManager.addSpeaker(&_speakerPText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.setCallback(this);
+
+ _speakerQText._textPos.y = 140;
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(4045);
+ _hotspot3.setPosition(Common::Point(47, 111));
+ _hotspot3.animate(ANIM_MODE_2, NULL);
+ _hotspot3.setPriority2(156);
+ _globals->_sceneItems.push_back(&_hotspot3);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(4200);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._moveDiff = Common::Point(7, 4);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(4051);
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(4051);
+ _hotspot5.setStrip(4);
+ _hotspot5.setPriority2(152);
+
+ if(_globals->_sceneManager._previousScene == 4050) {
+ _globals->_soundHandler.startSound(155);
+ _globals->_player.setPosition(Common::Point(72, 128));
+ _globals->_player.enableControl();
+
+ _hotspot1.setStrip(5);
+ _hotspot1.setPosition(Common::Point(173, 99));
+ _hotspot1._numFrames = 1;
+ _hotspot1.animate(ANIM_MODE_2, NULL);
+
+ _hotspot5.setPosition(Common::Point(177, 40));
+
+ if (_globals->_inventory._peg._sceneNumber == 4045) {
+ _hotspot6.postInit();
+ _hotspot6.setVisage(4045);
+ _hotspot6.setStrip(2);
+ _hotspot6.setPosition(Common::Point(108, 82));
+ _globals->_sceneItems.push_back(&_hotspot6);
+ }
+ } else {
+ _globals->_player.setPosition(Common::Point(108, 192));
+ _globals->_player.setStrip(4);
+
+ if (!_globals->getFlag(36) && !_globals->getFlag(43)) {
+ _hotspot2.postInit();
+ _hotspot2.setVisage(4102);
+ _hotspot2.animate(ANIM_MODE_NONE, NULL);
+ _hotspot2.setStrip(3);
+ _hotspot2.changeZoom(-1);
+ _hotspot2.setPosition(Common::Point(66, 209));
+ _globals->_sceneItems.push_back(&_hotspot2);
+ }
+
+ if (_globals->getFlag(31)) {
+ _hotspot1.setVisage(4051);
+ _hotspot1.setStrip(5);
+ _hotspot1.setPosition(Common::Point(173, 99));
+ _hotspot1._numFrames = 1;
+ _hotspot1.animate(ANIM_MODE_2, NULL);
+
+ _hotspot5.setPosition(Common::Point(177, 40));
+
+ if (_globals->_inventory._peg._sceneNumber == 4045) {
+ _hotspot6.postInit();
+ _hotspot6.setVisage(4045);
+ _hotspot6.setStrip(2);
+ _hotspot6.setPosition(Common::Point(108, 82));
+ _globals->_sceneItems.push_back(&_hotspot6);
+ }
+ } else {
+ _hotspot1.setPosition(Common::Point(186, 149));
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4051);
+ _hotspot4.setStrip(2);
+ _hotspot4.setPriority2(152);
+ _hotspot4.setPosition(Common::Point(202, 80));
+
+ _hotspot5.setPosition(Common::Point(192, 77));
+ _globals->setFlag(31);
+ setAction(&_action1);
+
+ _globals->_player.disableControl();
+ }
+ }
+
+ _globals->_sceneItems.addItems(&_hotspot1, &_hotspot7, &_hotspot8, &_hotspot9, &_hotspot10,
+ &_hotspot13, &_hotspot11, &_hotspot12, &_hotspot14, NULL);
+}
+
+void Scene4045::stripCallback(int v) {
+ switch (v) {
+ case 1:
+ _hotspot5.animate(ANIM_MODE_7, 0, NULL);
+ break;
+ case 2:
+ _hotspot5.animate(ANIM_MODE_NONE, NULL);
+ break;
+ }
+}
+
+void Scene4045::signal() {
+ switch (_sceneMode) {
+ case 4046:
+ case 4047:
+ _hotspot5.animate(ANIM_MODE_NONE, NULL);
+ break;
+ case 4050:
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ case 4102:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene4045::dispatch() {
+ if (!_action) {
+ if (_globals->_player.getRegionIndex() == 8) {
+ _globals->_player.addMover(NULL);
+ if (_hotspot1._strip == 1) {
+ _globals->_player.disableControl();
+ _sceneMode = 4046;
+ _hotspot1._numFrames = 10;
+ setAction(&_sequenceManager, this, 4046, &_globals->_player, &_hotspot1, NULL);
+ } else {
+ setAction(&_action3);
+ }
+ }
+
+ if (_globals->_player.getRegionIndex() == 10)
+ _globals->_sceneManager.changeScene(4050);
+ if (_globals->_player._position.y >= 196) {
+ _sceneMode = 4050;
+ _globals->_player.disableControl();
+ setAction(&_sequenceManager, this, 4105, &_globals->_player, NULL);
+ }
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4000 - Village - Temple
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4050::Action1::signal() {
+ Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ ADD_PLAYER_MOVER(204, 152);
+ break;
+ case 2:
+ _globals->_player.checkAngle(&scene->_hotspot17);
+
+ scene->_hotspot14.postInit();
+ scene->_hotspot14.setVisage(4050);
+ scene->_hotspot14.setStrip(2);
+ scene->_hotspot14.setPosition(Common::Point(91, 154));
+ scene->_hotspot14.setPriority2(200);
+ break;
+ case 3:
+ _globals->_events.waitForPress();
+ _globals->setFlag(45);
+ scene->_hotspot14.remove();
+
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4050::Action2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(120);
+ break;
+ case 1:
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_player.setVisage(4202);
+ _globals->_player.changeZoom(100);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(192, 130));
+
+ ADD_MOVER(_globals->_player, 215, 130);
+ break;
+ case 3:
+ _globals->_player.setVisage(4052);
+ _globals->_player.setStrip(5);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(236, 130));
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ _globals->_player.setVisage(4202);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setPosition(Common::Point(210, 185));
+ _globals->_player.setPriority2(-1);
+ _globals->_player.enableControl();
+
+ remove();
+ break;
+ }
+}
+
+void Scene4050::Action3::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ ADD_PLAYER_MOVER(210, 185);
+ break;
+ case 1:
+ _globals->_player.setPriority2(200);
+ _globals->_player.setVisage(4052);
+ _globals->_player.setStrip(5);
+ _globals->_player.changeZoom(100);
+ _globals->_player.setFrame(_globals->_player.getFrameCount());
+ _globals->_player.setPosition(Common::Point(236, 130));
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 2:
+ _globals->_player.setVisage(4202);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(215, 130));
+ ADD_MOVER(_globals->_player, 212, 130);
+ break;
+ case 3:
+ _globals->_stripNum = 4050;
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ }
+}
+
+void Scene4050::Action4::signal() {
+ Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_MOVER(_globals->_player, 189, 135);
+ _globals->_player.setPriority2(200);
+ break;
+ case 1:
+ _globals->_player._moveDiff.y = 3;
+ _globals->_player.setStrip2(3);
+ _globals->_player._frame = 1;
+ _globals->_player.setPosition(Common::Point(189, 129));
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ _globals->_player.setVisage(4202);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(192, 130));
+ _globals->_player.changeZoom(100);
+ ADD_MOVER(_globals->_player, 215, 130);
+
+ scene->_hotspot16.postInit();
+ scene->_hotspot16.setVisage(4052);
+ scene->_hotspot16.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot16.setStrip2(6);
+ scene->_hotspot16.setPosition(Common::Point(160, 240));
+ ADD_MOVER(scene->_hotspot16, 172, 188);
+ break;
+ case 3:
+ _globals->_player.setVisage(4052);
+ _globals->_player.setStrip(5);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(238, 130));
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 4:
+ _globals->_player.setVisage(4052);
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(216, 184));
+ _globals->_player.setPriority2(-1);
+ break;
+ case 5:
+ scene->_hotspot16.setStrip2(4);
+ scene->_hotspot16.setFrame(1);
+ scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);;
+ break;
+ case 6:
+ scene->_hotspot16.animate(ANIM_MODE_5, NULL);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 7:
+ _globals->_player.setVisage(4202);
+ _globals->_player.setStrip(6);
+ _globals->_player.setFrame(1);
+
+ scene->_stripManager.start(4051, this);
+ break;
+ case 8:
+ setDelay(15);
+ break;
+ case 9:
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4050::Hotspot14::doAction(int action) {
+ Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4050, 14);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ setAction(&scene->_action3);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4050::Hotspot17::doAction(int action) {
+ Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ scene->setAction(&scene->_action1);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(4050, 24);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4050::Scene4050() :
+ _hotspot1(0, CURSOR_LOOK, 4050, 0, LIST_END),
+ _hotspot2(0, CURSOR_LOOK, 4050, 1, CURSOR_USE, 4050, 15, LIST_END),
+ _hotspot3(0, CURSOR_LOOK, 4050, 2, CURSOR_USE, 4050, 16, LIST_END),
+ _hotspot4(0, CURSOR_LOOK, 4050, 4, LIST_END),
+ _hotspot5(0, CURSOR_LOOK, 4050, 5, LIST_END),
+ _hotspot6(0, CURSOR_LOOK, 4050, 5, LIST_END),
+ _hotspot7(0, CURSOR_LOOK, 4050, 6, CURSOR_USE, 4050, 18, LIST_END),
+ _hotspot8(0, CURSOR_LOOK, 4050, 7, CURSOR_USE, 4050, 19, LIST_END),
+ _hotspot9(0, CURSOR_LOOK, 4050, 8, CURSOR_USE, 4050, 20, LIST_END),
+ _hotspot10(0, CURSOR_LOOK, 4050, 9, CURSOR_USE, 4050, 21, LIST_END),
+ _hotspot11(0, CURSOR_LOOK, 4050, 10, CURSOR_USE, 4050, 22, LIST_END),
+ _hotspot12(0, CURSOR_LOOK, 4050, 11, CURSOR_USE, 4050, 23, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 4050, 3, CURSOR_USE, 4050, 17, LIST_END) {
+}
+
+void Scene4050::postInit(SceneObjectList *OwnerList) {
+ loadScene(4050);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerPText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerGameText);
+
+ _globals->_player.postInit();
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 4000:
+ if (_globals->getFlag(41)) {
+ _hotspot15.postInit();
+ _hotspot15.setVisage(4054);
+ _hotspot15.setPosition(Common::Point(206, 103));
+ _globals->_sceneItems.push_back(&_hotspot15);
+
+ _globals->_player.setVisage(4008);
+ _globals->_player.setPosition(Common::Point(206, 62));
+ _globals->_player.changeZoom(130);
+ _globals->_player.setPriority2(200);
+ _globals->_player.setStrip(2);
+
+ setAction(&_action2);
+ _globals->_soundHandler.startSound(175);
+ } else {
+ _globals->_player.setVisage(5315);
+ _globals->_player.setPosition(Common::Point(189, 83));
+ _globals->_player.changeZoom(130);
+ _globals->_player.setStrip2(2);
+ _globals->_player._moveDiff.y = 10;
+ _globals->_player.animate(ANIM_MODE_2, NULL);
+
+ setAction(&_action4);
+ _globals->_soundHandler.startSound(176);
+ }
+ break;
+ case 4045:
+ _hotspot15.postInit();
+ _hotspot15.setVisage(4054);
+ _hotspot15.setPosition(Common::Point(206, 103));
+ _globals->_sceneItems.push_back(&_hotspot15);
+
+ _globals->_player.setVisage(4202);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(193, 193));
+
+ _globals->_soundHandler.startSound(175);
+ break;
+ default:
+ break;
+ }
+
+ _hotspot13.postInit();
+ _hotspot13.setVisage(4053);
+ _hotspot13.animate(ANIM_MODE_2, NULL);
+ _hotspot13.setPosition(Common::Point(190, 97));
+
+ _hotspot17.postInit();
+ _hotspot17.setVisage(4050);
+ _hotspot17.setPosition(Common::Point(209, 119));
+ _hotspot17.setPriority2(2);
+
+ _hotspot1.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot2.setBounds(Rect(150, 25, 198, 125));
+ _hotspot3.setBounds(Rect(56, 94, 88, 153));
+ _hotspot4.setBounds(Rect(170, 7, 209, 18));
+ _hotspot5.setBounds(Rect(190, 72, 212, 92));
+ _hotspot6.setBounds(Rect(122, 75, 145, 93));
+ _hotspot7.setBounds(Rect(109, 103, 263, 158));
+ _hotspot8.setBounds(Rect(157, 160, 213, 173));
+ _hotspot9.setBounds(Rect(95, 157, 120, 178));
+ _hotspot10.setBounds(Rect(278, 43, 310, 115));
+ _hotspot11.setBounds(Rect(263, 105, 279, 147));
+ _hotspot12.setBounds(Rect(258, 154, 307, 180));
+
+ _globals->_sceneItems.addItems(&_hotspot17, &_hotspot12, &_hotspot11, &_hotspot10, &_hotspot13,
+ &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5, &_hotspot6, &_hotspot8, &_hotspot9,
+ &_hotspot7, &_hotspot1, NULL);
+}
+
+void Scene4050::signal() {
+
+}
+
+void Scene4050::dispatch() {
+
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4100 - Village - Hut
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4100::Action1::signal() {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(10);
+ break;
+ case 1:
+ scene->_stripManager.start(_globals->_stripNum, this);
+ break;
+ case 2:
+ setDelay(30);
+ break;
+ case 3:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4100::Action2::signal() {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.changeZoom(95);
+ scene->_hotspot2.setVisage(4120);
+ scene->_hotspot2.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot2.setStrip2(4);
+ scene->_hotspot2.setPriority2(100);
+ scene->_hotspot2.setPosition(Common::Point(214, 119));
+
+ setDelay(3);
+ break;
+ case 1:
+ ADD_MOVER(scene->_hotspot2, 249, 131);
+ break;
+ case 2:
+ scene->_hotspot2.setStrip2(3);
+ scene->_hotspot2.setFrame2(5);
+ scene->_hotspot2.animate(ANIM_MODE_NONE, NULL);
+ setDelay(3);
+ break;
+ case 3:
+ remove();
+ break;
+ }
+}
+
+
+void Scene4100::Action3::signal() {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->clearFlag(43);
+ _globals->clearFlag(36);
+ setDelay(15);
+ break;
+ case 1:
+ scene->_stripManager.start(4505, this);
+ break;
+ case 2:
+ scene->setAction(&scene->_action2);
+ case 3:
+ scene->_stripManager.start(4510, this);
+ break;
+ case 4:
+ setDelay(15);
+ break;
+ case 5:
+ _globals->_sceneManager.changeScene(4150);
+ break;
+ }
+}
+
+void Scene4100::Action4::signal() {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ scene->_hotspot1.setVisage(4105);
+ scene->_hotspot1.setFrame(1);
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->clearFlag(43);
+ _globals->setFlag(42);
+ scene->_stripManager.start(4119, this);
+ case 4:
+ setDelay(15);
+ break;
+ case 5:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4100::Action5::signal() {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_PLAYER_MOVER(58, 151);
+ break;
+ case 1:
+ if (_globals->_inventory._ladder._sceneNumber == 4100) {
+ _globals->_inventory._ladder._sceneNumber = 1;
+ scene->_hotspot6.remove();
+ } else {
+ scene->_hotspot6.postInit();
+ scene->_hotspot6.setVisage(4101);
+ scene->_hotspot6.setPosition(Common::Point(49, 144));
+
+ _globals->_inventory._ladder._sceneNumber = 4100;
+ _globals->_sceneItems.push_front(&scene->_hotspot6);
+ }
+
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+
+void Scene4100::Action6::signal() {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ scene->_stripManager.start(4103, this);
+ ADD_PLAYER_MOVER(245, 167);
+ break;
+ case 1:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4100::Hotspot1::doAction(int action) {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4100, _globals->getFlag(42) ? 24 : 12);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4100, 16);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(4100, 22);
+ break;
+ case CURSOR_TALK:
+ if (_globals->_inventory._peg._sceneNumber == 1) {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_sequenceManager, scene, 4109, NULL);
+ } else if (_globals->getFlag(42)) {
+ scene->setAction(&scene->_sequenceManager, scene, 4102, NULL);
+ } else {
+ if (_globals->getFlag(33))
+ _globals->_stripNum = 4077;
+ else if (_globals->getFlag(82)) {
+ _globals->clearFlag(82);
+ _globals->_stripNum = 4100;
+ } else {
+ _globals->_stripNum = 4075;
+ _globals->setFlag(33);
+ }
+
+ scene->setAction(&scene->_action1);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4100::Hotspot2::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ error("*** The Chief's daughter... WOW!");
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4100::Hotspot5::doAction(int action) {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4100, 14);
+ break;
+ case CURSOR_TALK:
+ scene->_sceneMode = 4102;
+ scene->setAction(&scene->_sequenceManager, scene, 4104, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4100::Hotspot6::doAction(int action) {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4100, 2);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(42)) {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action5);
+ } else {
+ scene->_sceneMode = 4102;
+ scene->setAction(&scene->_sequenceManager, scene, 4103, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+
+void Scene4100::Hotspot14::doAction(int action) {
+ Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4100, 0);
+ break;
+ case OBJECT_LADDER:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action5);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+Scene4100::Scene4100() :
+ _hotspot3(0, CURSOR_LOOK, 4100, 10, CURSOR_USE, 4100, 21, LIST_END),
+ _hotspot4(0, CURSOR_LOOK, 4100, 8, LIST_END),
+ _hotspot7(0, CURSOR_USE, 4100, 3, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot8(0, CURSOR_LOOK, 4100, 5, LIST_END),
+ _hotspot9(0, CURSOR_LOOK, 4100, 6, CURSOR_USE, 4100, 20, LIST_END),
+ _hotspot10(0, CURSOR_LOOK, 4100, 7, CURSOR_USE, 4100, 19, LIST_END),
+ _hotspot11(0, CURSOR_LOOK, 4100, 8, CURSOR_USE, 4100, 18, LIST_END),
+ _hotspot12(0, CURSOR_LOOK, 4100, 9, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 4100, 11, CURSOR_USE, 4100, 17, LIST_END) {
+}
+
+void Scene4100::postInit(SceneObjectList *OwnerList) {
+ loadScene(4100);
+ Scene::postInit();
+ setZoomPercents(135, 80, 190, 100);
+
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerCHFText);
+ _stripManager.addSpeaker(&_speakerCDRText);
+ _stripManager.addSpeaker(&_speakerCDR);
+ _stripManager.addSpeaker(&_speakerML);
+ _stripManager.addSpeaker(&_speakerQR);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(4200);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(4);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(88, 180));
+ _globals->_player._moveDiff = Common::Point(7, 4);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(4102);
+ _hotspot1.setPriority2(129);
+ _hotspot1.setPosition(Common::Point(171, 120));
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(4130);
+ _hotspot3.animate(ANIM_MODE_2, NULL);
+ _hotspot3.setPriority2(200);
+ _hotspot3.setPosition(Common::Point(272, 110));
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4130);
+ _hotspot4.animate(ANIM_MODE_2, NULL);
+ _hotspot4.setStrip2(2);
+ _hotspot4.setPosition(Common::Point(152, 167));
+
+ if (_globals->getFlag(36)) {
+ _hotspot1.setVisage(4105);
+ _hotspot1.setStrip(1);
+ _hotspot1.setFrame(4);
+ } else if (!_globals->getFlag(43)) {
+ _hotspot5.postInit();
+ _hotspot5.setVisage(4102);
+ _hotspot5.setStrip2(3);
+ _hotspot5.setFrame(2);
+ _hotspot5.setPosition(Common::Point(65, 188));
+
+ _globals->_sceneItems.push_back(&_hotspot5);
+ }
+
+ if (_globals->_inventory._ladder._sceneNumber == 4100) {
+ _hotspot6.postInit();
+ _hotspot6.setVisage(4101);
+ _hotspot6.setPosition(Common::Point(49, 144));
+
+ _globals->_sceneItems.push_back(&_hotspot6);
+ }
+
+ _hotspot14.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot7._sceneRegionId = 16;
+ _hotspot8.setBounds(Rect(90, 0, 211, 113));
+ _hotspot9.setBounds(Rect(207, 96, 235, 115));
+ _hotspot10.setBounds(Rect(87, 81, 212, 107));
+ _hotspot11.setBounds(Rect(61, 148, 243, 168));
+ _hotspot12.setBounds(Rect(229, 59, 256, 122));
+ _hotspot13.setBounds(Rect(255, 152, 286, 183));
+
+ _globals->_sceneItems.addItems(&_hotspot3, &_hotspot1, &_hotspot13, &_hotspot12, &_hotspot4,
+ &_hotspot11, &_hotspot9, &_hotspot7, &_hotspot10, &_hotspot8, &_hotspot14, NULL);
+
+ if (_globals->_sceneManager._previousScene == 4150) {
+ _globals->_soundHandler.startSound(155);
+
+ if (!_globals->getFlag(42)) {
+ _hotspot1.setVisage(4104);
+ _hotspot1.setPosition(Common::Point(152, 118));
+ _hotspot1.setStrip2(-1);
+ _hotspot1.setFrame2(-1);
+ _hotspot1.setFrame(1);
+
+ _globals->_player.setStrip(2);
+ _globals->_player.disableControl();
+ setAction(&_action4);
+
+ _globals->clearFlag(43);
+ }
+
+ _globals->_player.setPosition(Common::Point(252, 139));
+ _globals->_player.setStrip(2);
+ } else {
+ if ((_globals->_inventory._ale._sceneNumber == 4100) && !_globals->getFlag(42)) {
+ _globals->_player.disableControl();
+ setAction(&_action3);
+ }
+ if (_globals->getFlag(35)) {
+ _globals->_player.disableControl();
+ _sceneMode = 4101;
+ setAction(&_sequenceManager, this, 4101, &_globals->_player, NULL);
+ }
+ }
+}
+
+void Scene4100::signal() {
+ switch (_sceneMode) {
+ case 4101:
+ _globals->_sceneManager.changeScene(4000);
+ break;
+ case 4102:
+ case 4103:
+ case 4109:
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene4100::dispatch() {
+ if (!_action) {
+ if ((_globals->_player.getRegionIndex() == 15) && !_globals->getFlag(42))
+ setAction(&_action6);
+
+ if (_globals->_player.getRegionIndex() == 8)
+ _globals->_sceneManager.changeScene(4150);
+
+ if (_globals->_player._position.y >= 196) {
+ _globals->_player.disableControl();
+ _sceneMode = 4101;
+ setAction(&_sequenceManager, this, 4105, &_globals->_player, NULL);
+ }
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4150 - Village - Bedroom
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4150::Action1::signal() {
+ Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene;
+ byte adjustData[4] = {0, 0, 0, 0};
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1:
+ scene->_stripManager.start(4520, this);
+ break;
+ case 2:
+ setDelay(15);
+ break;
+ case 3:
+ setAction(&scene->_action2, this);
+ break;
+ case 4: {
+ for (int idx = 100; idx >= 0; idx -= 5) {
+ _globals->_scenePalette.fade(adjustData, false, idx);
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+
+ scene->_hotspot4.postInit();
+ scene->_hotspot4.setVisage(4150);
+ scene->_hotspot4.setStrip(2);
+ scene->_hotspot4.setPosition(Common::Point(166, 157));
+
+ scene->_hotspot1.postInit();
+ scene->_hotspot1.setVisage(4156);
+ scene->_hotspot1.setStrip(1);
+ scene->_hotspot1.setFrame(1);
+
+ setDelay(120);
+ break;
+ }
+ case 5:
+ _globals->_scenePalette.loadPalette(4150);
+ _globals->_scenePalette.refresh();
+ setDelay(60);
+ break;
+ case 6:
+ scene->_stripManager.start(4522, this);
+ break;
+ case 7:
+ for (int idx = 100; idx >= 0; idx -= 5) {
+ _globals->_scenePalette.fade(adjustData, false, idx);
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+
+ scene->_hotspot4.remove();
+ scene->_hotspot1.setVisage(4157);
+ scene->_hotspot1.animate(ANIM_MODE_NONE, NULL);
+ scene->_hotspot1.setStrip(1);
+ scene->_hotspot1.setFrame(1);
+ scene->_hotspot1.show();
+
+ _globals->_player.setVisage(4200);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(3);
+ _globals->_player.setPosition(Common::Point(139, 166));
+ _globals->_player._moveDiff = Common::Point(7, 3);
+ _globals->_player.show();
+
+ setDelay(120);
+ break;
+ case 8:
+ _globals->_scenePalette.loadPalette(4150);
+ _globals->_scenePalette.refresh();
+ setDelay(30);
+ break;
+ case 9:
+ scene->_stripManager.start(4523, this);
+ break;
+ case 10:
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player._moveDiff = Common::Point(7, 4);
+ _globals->_player.setStrip(3);
+ _globals->_player.enableControl();
+
+ remove();
+ break;
+ }
+}
+
+void Scene4150::Action2::signal() {
+ Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_hotspot1.setVisage(4152);
+ scene->_hotspot1.setStrip(1);
+ scene->_hotspot1.setFrame(1);
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+
+ _globals->_player.animate(ANIM_MODE_5, NULL);
+ break;
+ case 2:
+ _globals->_player.hide();
+ scene->_hotspot1.setVisage(4153);
+ scene->_hotspot1.setStrip(1);
+ scene->_hotspot1.setFrame(1);
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ remove();
+ break;
+ }
+}
+
+void Scene4150::Action3::signal() {
+ Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(15);
+ break;
+ case 1:
+ _globals->_player.checkAngle(&scene->_hotspot3);
+
+ if (_globals->_inventory._rope._sceneNumber == 1) {
+ scene->_hotspot3.postInit();
+ scene->_hotspot3.setVisage(4150);
+ scene->_hotspot3.setPosition(Common::Point(175, 70));
+
+ _globals->_inventory._rope._sceneNumber = 4150;
+ _globals->_sceneItems.push_front(&scene->_hotspot3);
+ } else {
+ _globals->_inventory._rope._sceneNumber = 1;
+ scene->_hotspot3.remove();
+ }
+
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4150::HotspotGroup1::doAction(int action) {
+ Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4150, 0);
+ break;
+ case OBJECT_ROPE:
+ scene->setAction(&scene->_action3);
+ break;
+ }
+}
+
+void Scene4150::HotspotGroup3::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4150, _globals->getFlag(46) ? 9 : 8);
+ _globals->setFlag(46);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(4150, 30);
+ break;
+ }
+}
+
+void Scene4150::HotspotGroup6::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4150, _globals->getFlag(47) ? 16 : 15);
+ _globals->setFlag(47);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(4150, 31);
+ break;
+ }
+}
+
+void Scene4150::Hotspot3::doAction(int action) {
+ Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4150, 20);
+ break;
+ case CURSOR_USE:
+ scene->setAction(&scene->_action3);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4150::Scene4150() :
+ _hotspot1(0, CURSOR_LOOK, 4000, 17, CURSOR_USE, 4150, 21, CURSOR_TALK, 4150, 21,
+ OBJECT_SCANNER, 4150, 22, OBJECT_STUNNER, 4150, 23, LIST_END),
+ _hotspot2(0, CURSOR_LOOK, 4150, 4, CURSOR_USE, 4150, 24, LIST_END),
+ _hotspot7(0, CURSOR_LOOK, 4150, 1, CURSOR_USE, 4150, 25, OBJECT_ROPE, 4150, 26, LIST_END),
+ _hotspot8(0, CURSOR_LOOK, 4150, 1, CURSOR_USE, 4150, 25, OBJECT_ROPE, 4150, 26, LIST_END),
+ _hotspot9(0, CURSOR_LOOK, 4150, 2, CURSOR_USE, 4150, 27, OBJECT_SCANNER, 4150, 28,
+ OBJECT_STUNNER, 4150, 32, LIST_END),
+ _hotspot10(0, CURSOR_LOOK, 4150, 5, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot11(0, CURSOR_LOOK, 4150, 6, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot12(0, CURSOR_LOOK, 4150, 7, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot17(0, CURSOR_LOOK, 4150, 10, CURSOR_USE, 4150, 27, OBJECT_STUNNER, 4150, 32, LIST_END),
+ _hotspot18(0, CURSOR_LOOK, 4150, 11, CURSOR_USE, 4150, 32, OBJECT_STUNNER, 4150, 27, LIST_END),
+ _hotspot19(0, CURSOR_LOOK, 4150, 12, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot20(0, CURSOR_LOOK, 4150, 13, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot21(0, CURSOR_LOOK, 4150, 13, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot22(0, CURSOR_LOOK, 4150, 13, CURSOR_USE, 4150, 29, LIST_END),
+ _hotspot23(0, CURSOR_LOOK, 4150, 14, CURSOR_USE, 4150, 27, OBJECT_STUNNER, 4150, 32, LIST_END),
+ _hotspot24(0, CURSOR_LOOK, 4150, 14, CURSOR_USE, 4150, 27, OBJECT_STUNNER, 4150, 32, LIST_END)
+ {
+}
+
+void Scene4150::postInit(SceneObjectList *OwnerList) {
+ loadScene(4150);
+ Scene::postInit();
+ setZoomPercents(60, 85, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerCDL);
+ _stripManager.addSpeaker(&_speakerQText);
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(4171);
+ _hotspot2.animate(ANIM_MODE_2, NULL);
+ _hotspot2.setPriority2(100);
+ _hotspot2.setPosition(Common::Point(76, 147));
+
+ _hotspot1.postInit();
+ _hotspot1.setPosition(Common::Point(177, 201));
+
+ if (_globals->getFlag(44)) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(4200);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setStrip(2);
+ _globals->_player.setPosition(Common::Point(328, 160));
+ _globals->_player._moveDiff = Common::Point(7, 4);
+ _globals->_player.disableControl();
+
+ _sceneMode = 4151;
+ setAction(&_sequenceManager, this, 4151, &_globals->_player, NULL);
+
+ _hotspot1.setVisage(4157);
+ _hotspot1.setPosition(Common::Point(177, 201));
+ } else {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(4154);
+ _globals->_player._canWalk = false;
+ _globals->_player.setPosition(Common::Point(198, 202));
+ _globals->_player.disableControl();
+
+ _hotspot1.setVisage(4152);
+ setAction(&_action1);
+ _globals->setFlag(44);
+ }
+
+ if (_globals->_inventory._rope._sceneNumber == 4150) {
+ _hotspot3.postInit();
+ _hotspot3.setVisage(4150);
+ _hotspot3.setPosition(Common::Point(175, 70));
+
+ _globals->_sceneItems.push_back(&_hotspot3);
+ }
+
+ _globals->_sceneItems.push_back(&_hotspot1);
+
+ _hotspot5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot6.setBounds(Rect(28, 121, 80, 148));
+ _hotspot7.setBounds(Rect(27, 17, 127, 100));
+ _hotspot8.setBounds(Rect(62, 11, 117, 22));
+ _hotspot9.setBounds(Rect(48, 78, 104, 94));
+ _hotspot10.setBounds(Rect(32, 107, 58, 119));
+ _hotspot11.setBounds(Rect(1, 130, 17, 163));
+ _hotspot12.setBounds(Rect(1, 158, 78, 197));
+ _hotspot13.setBounds(Rect(253, 11, 274, 188));
+ _hotspot14.setBounds(Rect(4, 15, 29, 153));
+ _hotspot15.setBounds(Rect(127, 22, 146, 133));
+ _hotspot16.setBounds(Rect(165, 22, 181, 141));
+ _hotspot17.setBounds(Rect(186, 31, 217, 52));
+ _hotspot18.setBounds(Rect(200, 31, 251, 86));
+ _hotspot19.setBounds(Rect(183, 81, 234, 111));
+ _hotspot20.setBounds(Rect(188, 120, 219, 142));
+ _hotspot21.setBounds(Rect(235, 122, 249, 145));
+ _hotspot22.setBounds(Rect(283, 125, 320, 146));
+ _hotspot23.setBounds(Rect(284, 27, 306, 160));
+ _hotspot24.setBounds(Rect(257, 72, 284, 99));
+ _hotspot25.setBounds(Rect(183, 155, 316, 190));
+ _hotspot26.setBounds(Rect(98, 169, 238, 198));
+
+ _globals->_sceneItems.addItems(&_hotspot24, &_hotspot23, &_hotspot13, &_hotspot25,
+ &_hotspot26, &_hotspot19, &_hotspot22, &_hotspot20, &_hotspot17, &_hotspot16,
+ &_hotspot15, &_hotspot11, &_hotspot14, &_hotspot18, &_hotspot21, &_hotspot12,
+ &_hotspot10, &_hotspot9, &_hotspot8, &_hotspot7, &_hotspot6, &_hotspot2,
+ &_hotspot5, NULL);
+
+ _globals->_soundHandler.startSound(165);
+ _soundHandler.startSound(311);
+}
+
+void Scene4150::signal() {
+ if (_sceneMode == 4151)
+ _globals->_player.enableControl();
+ else if (_sceneMode == 4152)
+ _globals->_sceneManager.changeScene(4100);
+}
+
+void Scene4150::dispatch() {
+ Scene::dispatch();
+
+ if (!_action && (_globals->_player._position.x >= 316)) {
+ _globals->_soundHandler.proc1(NULL);
+ _globals->_player.disableControl();
+ _sceneMode = 4152;
+ setAction(&_sequenceManager, this, 4152, &_globals->_player, NULL);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4000 - Village
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4250::Action1::signal() {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ ADD_MOVER_NULL(_globals->_player, 6, 190);
+ ADD_MOVER_NULL(scene->_hotspot3, 9, 195);
+ ADD_MOVER(scene->_hotspot1, 12, 185);
+ break;
+ case 2:
+ setDelay(30);
+ break;
+ case 3:
+ scene->_stripManager.start(4450, this);
+ break;
+ case 4:
+ case 7:
+ setDelay(15);
+ break;
+ case 5:
+ ADD_PLAYER_MOVER(220, 175);
+ scene->_hotspot1.setPriority2(105);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot1, 197, 173);
+ break;
+ case 6:
+ scene->_stripManager.start(4470, this);
+ break;
+ case 8:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4250::Action2::signal() {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_PLAYER_MOVER(247, 182);
+ break;
+ case 1:
+ _globals->_player.setVisage(2670);
+ _globals->_player.changeZoom(50);
+ _globals->_player.setStrip(3);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ if ((_globals->_stripNum == 9000) || (_globals->_stripNum == 4300)) {
+ scene->_stripManager.start(4205, this);
+ } else {
+ scene->_stripManager.start(4490, this);
+ }
+ break;
+ case 3:
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 4:
+ _globals->_player.setVisage(2602);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.changeZoom(70);
+
+ if ((_globals->_stripNum == 9000) || (_globals->_stripNum == 4300)) {
+ _globals->_player.enableControl();
+ remove();
+ } else {
+ ADD_PLAYER_MOVER(6, 180);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot1, 12, 185);
+ }
+ break;
+ case 5:
+ ADD_PLAYER_MOVER(-16, 180);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot1, -12, 185);
+ scene->_hotspot3.setStrip2(2);
+ ADD_MOVER_NULL(scene->_hotspot5, -30, 195);
+ break;
+ case 6:
+ _globals->clearFlag(59);
+ _globals->clearFlag(70);
+ _globals->clearFlag(37);
+ _globals->clearFlag(114);
+ _globals->clearFlag(36);
+ _globals->clearFlag(43);
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ }
+}
+
+void Scene4250::Action3::signal() {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_stripManager.start(4480, this);
+ break;
+ case 2:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4250::Action4::signal() {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ _globals->_player.addMover(NULL);
+ scene->_stripManager.start((_globals->_inventory._helmet._sceneNumber == 4250) ? 4259 : 4256, this);
+ break;
+ case 2:
+ ADD_PLAYER_MOVER(_globals->_player._position.x + 5, _globals->_player._position.y);
+ break;
+ case 3:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene4250::Action5::signal() {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ scene->_hotspot4.setPriority2(195);
+ scene->_hotspot1.setPriority2(105);
+ ADD_MOVER_NULL(_globals->_player, 6, 185);
+ ADD_MOVER_NULL(scene->_hotspot4, 9, 190);
+ ADD_MOVER(scene->_hotspot1, 12, 180);
+ break;
+ case 2:
+ ADD_PLAYER_MOVER(252, 176);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot1, 197, 173);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot4, 239, 195);
+ break;
+ case 3:
+ scene->_hotspot4.setPriority2(-1);
+ scene->_hotspot1.setStrip(5);
+ scene->_hotspot4.setStrip(7);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4250::Hotspot1::doAction(int action) {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 19 : 14);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ if (!_globals->_sceneObjects->contains(&scene->_hotspot4)) {
+ scene->setAction(&scene->_action3);
+ } else {
+ scene->_sceneMode = 4260;
+ if (_globals->_inventory._helmet._sceneNumber == 4250) {
+ scene->_sceneMode = 4265;
+ scene->setAction(&scene->_sequenceManager, scene, 4265, this, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager, scene,
+ _globals->_sceneObjects->contains(&scene->_hotspot6) ? 4260 : 4262, this, NULL);
+ }
+ }
+ break;
+ case OBJECT_SCANNER:
+ if (_globals->_inventory._helmet._sceneNumber == 4250)
+ SceneItem::display2(4250, 21);
+ else
+ SceneHotspot::doAction(action);
+ break;
+ case OBJECT_STUNNER:
+ if (_globals->_inventory._helmet._sceneNumber == 4250)
+ SceneItem::display2(4250, 22);
+ else
+ SceneHotspot::doAction(action);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4250::Hotspot2::doAction(int action) {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ case CURSOR_USE:
+ SceneItem::display2(4250, 16);
+ break;
+ case OBJECT_SCANNER:
+ if ((_globals->_stripNum == 9000) || (_globals->_stripNum == 4300))
+ scene->setAction(&scene->_action2);
+ else if (_globals->getFlag(55))
+ SceneItem::display2(4250, 17);
+ else {
+ _globals->setFlag(55);
+ scene->setAction(&scene->_action2);
+ }
+ break;
+ case OBJECT_STASIS_NEGATOR:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 4252;
+ scene->setAction(&scene->_sequenceManager, scene, 4252, &_globals->_player, this, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4250::Hotspot4::doAction(int action) {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 18 : 5);
+ break;
+ case OBJECT_SCANNER:
+ if (_globals->_inventory._helmet._sceneNumber == 4250)
+ SceneItem::display2(4250, 21);
+ else
+ SceneHotspot::doAction(action);
+ break;
+ case OBJECT_STUNNER:
+ if (_globals->_inventory._helmet._sceneNumber == 4250)
+ SceneItem::display2(4250, 22);
+ else
+ SceneHotspot::doAction(action);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ if (!_globals->_sceneObjects->contains(&scene->_hotspot6)) {
+ scene->_sceneMode = 4254;
+ scene->setAction(&scene->_sequenceManager, scene, 4263, NULL);
+ } else {
+ scene->_sceneMode = 4254;
+
+ if (_globals->_inventory._helmet._sceneNumber == 4250) {
+ scene->_sceneMode = 4266;
+ scene->setAction(&scene->_sequenceManager, scene, 4266, this, NULL);
+ } else {
+ scene->setAction(&scene->_sequenceManager, scene,
+ (_globals->_inventory._concentrator._sceneNumber == 1) ? 4255 : 4254, NULL);
+ }
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4250::Hotspot6::doAction(int action) {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 7 : 6);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 1 : 2);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 20 : 3);
+ break;
+ case OBJECT_HELMET:
+ _globals->_soundHandler.startSound(354);
+ _globals->_player.disableControl();
+ _globals->_inventory._helmet._sceneNumber = 4250;
+
+ if (_globals->_inventory._concentrator._sceneNumber == 1) {
+ if (_globals->getFlag(115)) {
+ scene->_sceneMode = 4269;
+ scene->setAction(&scene->_sequenceManager, scene, 4269, this, NULL);
+ } else {
+ _globals->setFlag(115);
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->setAction(&scene->_sequenceManager, scene, 4256, this, NULL);
+ }
+ } else if (_globals->_inventory._keyDevice._sceneNumber == 1) {
+ scene->_sceneMode = 4267;
+ scene->setAction(&scene->_sequenceManager, scene, 4267, this, NULL);
+ } else if (_globals->_inventory._keyDevice._sceneNumber == 4300) {
+ scene->_sceneMode = 4268;
+ scene->setAction(&scene->_sequenceManager, scene, 4268, this, NULL);
+ } else {
+ _globals->_events.setCursor(CURSOR_WALK);
+ ADD_MOVER_NULL(scene->_hotspot1, 241, 169);
+ scene->_sceneMode = 4261;
+ scene->setAction(&scene->_sequenceManager, scene, 4261, &_globals->_player, this, NULL);
+ }
+ break;
+ case OBJECT_NULLIFIER:
+ if (_globals->_inventory._helmet._sceneNumber == 4250) {
+ _globals->_soundHandler.startSound(353);
+ _globals->_player.disableControl();
+ _globals->_inventory._helmet._sceneNumber = 1;
+
+ scene->_sceneMode = 4257;
+ scene->setAction(&scene->_sequenceManager, scene, 4257, &_globals->_player, this, NULL);
+ } else {
+ SceneItem::display2(4250, 4);
+ }
+ break;
+ case CURSOR_TALK:
+ if (_globals->_inventory._helmet._sceneNumber == 4250)
+ doAction(OBJECT_HELMET);
+ else {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 4264;
+ scene->setAction(&scene->_sequenceManager, scene, 4264, this, NULL);
+ }
+ break;
+ case CURSOR_USE:
+ if (_globals->_inventory._helmet._sceneNumber == 4250)
+ doAction(OBJECT_HELMET);
+ else {
+ _globals->_player.disableControl();
+ if ((_globals->_inventory._items._sceneNumber != 1) || (_globals->_inventory._concentrator._sceneNumber != 1)) {
+ scene->_sceneMode = 4258;
+ scene->setAction(&scene->_sequenceManager, scene, 4258, this, NULL);
+ } else {
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(4251);
+ scene->_hotspot2.setFrame(scene->_hotspot2.getFrameCount());
+ scene->_hotspot2.setPosition(Common::Point(267, 172));
+ scene->_hotspot2.hide();
+
+ scene->_sceneMode = 4259;
+ scene->setAction(&scene->_sequenceManager, scene, 4259, &_globals->_player, this, &scene->_hotspot2, NULL);
+ }
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4250::Hotspot8::doAction(int action) {
+ Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ case CURSOR_USE:
+ _globals->_sceneManager.changeScene(4300);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4250, 24);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4250, 25);
+ break;
+ case OBJECT_STASIS_NEGATOR:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 4270;
+ scene->setAction(&scene->_sequenceManager, scene,
+ (_globals->_inventory._helmet._sceneNumber == 4250) ? 4270 : 4271, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4250::Scene4250() :
+ _hotspot7(0, CURSOR_LOOK, 4250, 0, LIST_END) {
+}
+
+void Scene4250::postInit(tSage::SceneObjectList *OwnerList) {
+ loadScene(4250);
+ Scene::postInit();
+ setZoomPercents(160, 90, 185, 100);
+
+ _stripManager.addSpeaker(&_speakerSR);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerGameText);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerPText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerFLText);
+
+ _speakerSText.setTextPos(Common::Point(40, 40));
+ _speakerPText.setTextPos(Common::Point(40, 100));
+ _hotspot8._sceneRegionId = 16;
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2602);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(-13, 190));
+ _globals->_player.changeZoom(-1);
+ _globals->_player._moveDiff = Common::Point(4, 1);
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(2801);
+ _hotspot1.animate(ANIM_MODE_1, NULL);
+ _hotspot1.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot1.setPosition(Common::Point(-18, 185));
+ _hotspot1.changeZoom(-1);
+ _hotspot1._moveDiff = Common::Point(4, 1);
+ _globals->_sceneItems.push_back(&_hotspot1);
+
+ if (_globals->_sceneManager._previousScene == 4300) {
+ _hotspot5.postInit();
+ _hotspot5.setVisage(4250);
+ _hotspot5.setPosition(Common::Point(268, 168));
+ _hotspot5.setPriority2(1);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(2701);
+ _hotspot4.animate(ANIM_MODE_1, NULL);
+ _hotspot4.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot4.setPosition(Common::Point(272, 175));
+ _hotspot4.setStrip(2);
+ _hotspot4._moveDiff = Common::Point(4, 1);
+ _hotspot4.changeZoom(70);
+ _globals->_sceneItems.push_back(&_hotspot4);
+
+ _hotspot1.setPosition(Common::Point(197, 173));
+ _hotspot1.changeZoom(70);
+
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setPosition(Common::Point(252, 176));
+ _globals->_player.changeZoom(70);
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(4302);
+ _hotspot6.setStrip(4);
+ _hotspot6.setFrame(3);
+ _hotspot6.changeZoom(50);
+ _hotspot6.setPriority2(70);
+ _hotspot6.setPosition(Common::Point(261, 175));
+
+ if (_globals->_inventory._helmet._sceneNumber == 4250) {
+ _hotspot6.setStrip(6);
+ _hotspot6.setFrame(_hotspot6.getFrameCount());
+ }
+
+ if (_globals->getFlag(98)) {
+ _globals->_sceneItems.push_front(&_hotspot6);
+ } else {
+ _hotspot6.hide();
+ if ((_globals->_stripNum == 4300) || (_globals->_stripNum == 4301)) {
+ _globals->setFlag(98);
+ _globals->_player.setVisage(4302);
+ _globals->_player.setStrip(5);
+ _globals->_player.changeZoom(50);
+ _globals->_player.disableControl();
+
+ _hotspot4.setPosition(Common::Point(239, 195));
+ _sceneMode = 4253;
+ _globals->_sceneItems.push_front(&_hotspot6);
+
+ setAction(&_sequenceManager, this, 4253, &_globals->_player, NULL);
+ }
+ }
+ } else if (_globals->_stripNum == 9000) {
+ _hotspot4.postInit();
+ _hotspot4.setVisage(2701);
+ _hotspot4.animate(ANIM_MODE_1, NULL);
+ _hotspot4.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot4.setPosition(Common::Point(-15, 195));
+ _hotspot4._moveDiff = Common::Point(4, 1);
+ _globals->_sceneItems.push_back(&_hotspot4);
+
+ setAction(&_action5);
+ } else {
+ _hotspot3.postInit();
+ _hotspot3.setVisage(4006);
+ _hotspot3.animate(ANIM_MODE_1, NULL);
+ _hotspot3.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot3.setPosition(Common::Point(-15, 195));
+ _hotspot3.setStrip2(3);
+ _hotspot3._moveDiff = Common::Point(4, 1);
+
+ setAction(&_action1);
+ _globals->clearFlag(43);
+ _globals->clearFlag(114);
+ _globals->clearFlag(36);
+ }
+
+ if (_globals->getFlag(17)) {
+ _globals->_sceneItems.push_back(&_hotspot8);
+ } else {
+ _hotspot2.postInit();
+ _hotspot2.setVisage(4251);
+ _hotspot2.setStrip2(1);
+ _hotspot2.setPriority2(2);
+ _hotspot2.setFrame(1);
+ _hotspot2.setPosition(Common::Point(267, 172));
+
+ _globals->_sceneItems.push_back(&_hotspot2);
+ }
+
+ _hotspot7.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _globals->_sceneItems.push_back(&_hotspot7);
+ _globals->_soundHandler.startSound(185);
+}
+
+void Scene4250::signal() {
+ switch (_sceneMode) {
+ case 4252:
+ _globals->setFlag(17);
+ _globals->_sceneManager.changeScene(4301);
+ break;
+ case 4253:
+ if (_globals->_stripNum == 4301) {
+ ADD_MOVER_NULL(_hotspot1, 241, 169);
+ setAction(&_sequenceManager, this, 4261, &_globals->_player, &_hotspot6, NULL);
+ } else {
+ _globals->_player.enableControl();
+ }
+ break;
+ case 4254:
+ case 4256:
+ case 4257:
+ case 4258:
+ case 4260:
+ case 4264:
+ case 4265:
+ case 4266:
+ case 4267:
+ case 4268:
+ case 4269:
+ case 4270:
+ _globals->_player.enableControl();
+ break;
+ case 4255:
+ case 4262:
+ case 4263:
+ break;
+ case 4259:
+ _globals->_soundHandler.startSound(360);
+ _globals->_sceneManager.changeScene(9900);
+ break;
+ case 4261:
+ _globals->_inventory._keyDevice._sceneNumber = 1;
+ _globals->_player.enableControl();
+ break;
+ }
+}
+
+void Scene4250::dispatch() {
+ if (_globals->_player.getRegionIndex() == 8)
+ _globals->_player.changeZoom(90 - (_globals->_player._position.y - 153));
+ if (_globals->_player.getRegionIndex() == 12)
+ _globals->_player.changeZoom(70);
+ if (_globals->_player.getRegionIndex() == 15) {
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setPriority2(-1);
+ }
+
+ if (_hotspot1.getRegionIndex() == 8)
+ _hotspot1.changeZoom(90 - (_hotspot1._position.y - 153));
+ if (_hotspot1.getRegionIndex() == 12)
+ _hotspot1.changeZoom(70);
+ if (_hotspot1.getRegionIndex() == 15) {
+ _hotspot1.changeZoom(-1);
+ _hotspot1.setPriority2(-1);
+ }
+
+ if (_hotspot4.getRegionIndex() == 8)
+ _hotspot4.changeZoom(90 - (_hotspot4._position.y - 153));
+ if (_hotspot4.getRegionIndex() == 12)
+ _hotspot4.changeZoom(70);
+ if (_hotspot4.getRegionIndex() == 15) {
+ _hotspot4.changeZoom(-1);
+ _hotspot4.setPriority2(-1);
+ }
+
+ Scene::dispatch();
+
+ if (!_action) {
+ if (!_globals->getFlag(55) && (_globals->_player.getRegionIndex() == 12)) {
+ setAction(&_action4);
+ }
+
+ if (_globals->_sceneObjects->contains(&_hotspot6) && (_globals->_player.getRegionIndex() == 12))
+ setAction(&_action4);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4300 - Village - Slaver Ship
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4300::Action1::signal() {
+ Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->setFlag(56);
+ _globals->_scenePalette.addRotation(240, 254, -1);
+ scene->_hotspot7.animate(ANIM_MODE_6, this);
+ _globals->_soundHandler.startSound(164);
+ break;
+ case 1:
+ _globals->_soundHandler.startSound(340);
+ scene->_soundHandler1.startSound(341);
+ scene->_hotspot1.remove();
+ setDelay(3);
+ break;
+ case 2:
+ scene->_soundHandler1.startSound(341);
+ scene->_hotspot2.remove();
+ setDelay(6);
+ break;
+ case 3:
+ scene->_soundHandler1.startSound(341);
+ scene->_hotspot3.remove();
+ setDelay(6);
+ break;
+ case 4:
+ scene->_soundHandler1.startSound(341);
+ scene->_hotspot4.remove();
+ setDelay(12);
+ break;
+ case 5:
+ scene->_soundHandler1.startSound(341);
+ scene->_hotspot5.remove();
+ setDelay(12);
+ break;
+ case 6:
+ scene->_soundHandler1.startSound(341);
+ scene->_hotspot6.remove();
+ setDelay(60);
+ break;
+ case 7:
+ scene->_hotspot10.setPriority2(250);
+ scene->_hotspot10.animate(ANIM_MODE_5, this);
+ break;
+ case 8:
+ scene->_hotspot13.show();
+ scene->_stripManager.start(8015, this, scene);
+ break;
+ case 9:
+ _globals->_soundHandler.startSound(350);
+ _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL;
+ _globals->_events.setCursor(CURSOR_USE);
+ _globals->_player.enableControl();
+
+ remove();
+ break;
+ }
+}
+
+void Scene4300::Action2::signal() {
+ Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ scene->_stripManager.start(8016, this, scene);
+ break;
+ case 2:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4300::Hotspot8::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4300, 15);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(4300, 18);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4300, 14);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 19);
+ break;
+ case OBJECT_KEY_DEVICE:
+ _globals->_inventory._keyDevice._sceneNumber = 4300;
+ _globals->_scenePalette.addRotation(240, 254, -1);
+ animate(ANIM_MODE_5, NULL);
+
+ _globals->setFlag(99);
+ _globals->_sceneItems.push_back(this);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4300::Hotspot9::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) ||
+ (_globals->_inventory._concentrator._sceneNumber == 1))
+ SceneItem::display2(4300, 7);
+ else
+ SceneItem::display2(4300, 1);
+ break;
+ case CURSOR_USE:
+ if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) ||
+ (_globals->_inventory._concentrator._sceneNumber == 1))
+ SceneItem::display2(4300, 7);
+ else
+ SceneItem::display2(4300, 3);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 24);
+ break;
+ case OBJECT_SCANNER:
+ if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) ||
+ (_globals->_inventory._concentrator._sceneNumber != 1))
+ SceneItem::display2(4300, 22);
+ else
+ SceneItem::display2(4300, 23);
+ break;
+ default:
+ NamedHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4300::Hotspot10::doAction(int action) {
+ Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4300, 2);
+ break;
+ case CURSOR_TALK:
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action2);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4300, 20);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 21);
+ break;
+ case CURSOR_USE:
+ case OBJECT_HELMET:
+ _globals->_stripNum = (action == CURSOR_USE) ? 4300 : 4301;
+ _globals->_events.setCursor(CURSOR_NONE);
+ _globals->_sceneManager.changeScene(4250);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4300::Hotspot15::signal() {
+ Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
+
+ scene->_soundHandler2.startSound(345);
+
+ _strip = (_globals->_randomSource.getRandomNumber(6) < 2) ? 2 : 1;
+ if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) ||
+ (_globals->_inventory._concentrator._sceneNumber == 1)) {
+ setStrip(1);
+ setFrame(1);
+ animate(ANIM_MODE_NONE, NULL);
+ } else {
+ animate(ANIM_MODE_5, this);
+ }
+}
+
+void Scene4300::Hotspot16::doAction(int action) {
+ Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4300, 8);
+ break;
+ case CURSOR_USE:
+ if ((_globals->_inventory._stasisBox2._sceneNumber != 4300) &&
+ (_globals->_inventory._concentrator._sceneNumber != 4300)) {
+ SceneItem::display2(4300, 16);
+ } else {
+ scene->_sceneMode = 4302;
+ scene->setAction(&scene->_sequenceManager, scene, 4302, this, NULL);
+ }
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4300, 27);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 24);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene4300::Hotspot17::doAction(int action) {
+ Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4300, (_globals->_inventory._stasisBox2._sceneNumber == 4300) ? 17 : 11);
+ break;
+ case CURSOR_USE:
+ if (_globals->_inventory._stasisBox2._sceneNumber != 4300)
+ SceneItem::display2(4300, 13);
+ else {
+ _globals->_scenePalette.clearListeners();
+ remove();
+
+ SceneItem::display2(4300, 12);
+ _globals->_inventory._concentrator._sceneNumber = 1;
+ }
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4300, 25);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 26);
+ break;
+ case OBJECT_STASIS_BOX2:
+ scene->_soundHandler1.startSound(352);
+ _globals->_events.setCursor(CURSOR_USE);
+ scene->_sceneMode = 4303;
+
+ scene->setAction(&scene->_sequenceManager, scene, 4303, this, NULL);
+ break;
+ }
+}
+
+void Scene4300::Hotspot19::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4300, 9);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4300, 28);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 24);
+ break;
+ case CURSOR_USE:
+ if ((_globals->_inventory._stasisBox2._sceneNumber != 4300) &&
+ (_globals->_inventory._concentrator._sceneNumber != 4300))
+ SceneItem::display2(4300, 10);
+ else
+ SceneItem::display2(4300, 29);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene4300::Scene4300() :
+ _hotspot18(0, CURSOR_LOOK, 4300, 0, LIST_END) {
+}
+
+void Scene4300::postInit(SceneObjectList *OwnerList) {
+ loadScene(4300);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerFLText);
+
+ _hotspot11.setup(76, 97, 102, 127, 4300, 5, 6);
+
+ _hotspot7.postInit();
+ _hotspot7.setPosition(Common::Point(90, 128));
+ _hotspot7.setVisage(4303);
+ _hotspot7.setPriority2(250);
+ _globals->_sceneItems.push_back(&_hotspot7);
+
+ _hotspot9.setup(120, 49, 174, 91, 4300, -1, -1);
+
+ _hotspot15.postInit();
+ _hotspot15.setVisage(4300);
+ _hotspot15.setPosition(Common::Point(149, 79));
+ _hotspot15.signal();
+
+ if (!_globals->getFlag(99)) {
+ _hotspot8.postInit();
+ _hotspot8.setVisage(4300);
+ _hotspot8.setStrip(3);
+ _hotspot8.setPosition(Common::Point(196, 47));
+ _globals->_sceneItems.push_back(&_hotspot8);
+ }
+
+ if (_globals->_inventory._concentrator._sceneNumber == 4300) {
+ _hotspot17.postInit();
+ _hotspot17.setVisage(4300);
+ _hotspot17.setStrip(6);
+ _hotspot17.setPriority2(1);
+ _hotspot17.setPosition(Common::Point(200, 69));
+
+ if (_globals->_inventory._stasisBox2._sceneNumber == 4300)
+ _hotspot17.setFrame(_hotspot17.getFrameCount());
+
+ _globals->_sceneItems.push_back(&_hotspot17);
+ }
+
+ if (!_globals->getFlag(98)) {
+ _hotspot10.postInit();
+ _hotspot10.setVisage(4302);
+ _hotspot10.setPosition(Common::Point(244, 179));
+ _hotspot10.setPriority2(100);
+ _globals->_sceneItems.push_back(&_hotspot10);
+
+ _hotspot12.postInit();
+ _hotspot12.setVisage(4302);
+ _hotspot12.setStrip2(3);
+ _hotspot12.setPosition(Common::Point(231, 185));
+ _hotspot12.setPriority2(251);
+ _hotspot12.hide();
+
+ _hotspot13.postInit();
+ _hotspot13.hide();
+ _hotspot13.setVisage(4302);
+ _hotspot13.setStrip2(2);
+ _hotspot13.setPosition(Common::Point(256, 168));
+ _hotspot13.setPriority2(251);
+ _hotspot13._numFrames = 1;
+ _hotspot13.animate(ANIM_MODE_8, 0, NULL);
+ }
+
+ if (_globals->_inventory._items._sceneNumber == 4300) {
+ _hotspot16.postInit();
+ _hotspot16.setVisage(4300);
+ _hotspot16.setPosition(Common::Point(169, 141));
+ _hotspot16.setPriority2(1);
+ _hotspot16.setStrip(4);
+ _globals->_sceneItems.push_back(&_hotspot16);
+ }
+
+ if (_globals->_sceneManager._previousScene == 4301) {
+ _globals->_player.disableControl();
+ _hotspot7.setFrame(_hotspot7.getFrameCount());
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(4301);
+ _hotspot1.setPriority2(145);
+ _hotspot1.setPosition(Common::Point(160, 64));
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(4301);
+ _hotspot2.setStrip2(2);
+ _hotspot2.setPriority2(140);
+ _hotspot2.setPosition(Common::Point(166, 90));
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(4301);
+ _hotspot3.setStrip2(3);
+ _hotspot3.setPriority2(135);
+ _hotspot3.setPosition(Common::Point(173, 114));
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(4301);
+ _hotspot4.setStrip2(4);
+ _hotspot4.setPriority2(130);
+ _hotspot4.setPosition(Common::Point(187, 141));
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(4301);
+ _hotspot5.setStrip2(5);
+ _hotspot5.setPriority2(125);
+ _hotspot5.setPosition(Common::Point(201, 164));
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(4301);
+ _hotspot6.setStrip2(6);
+ _hotspot6.setPriority2(120);
+ _hotspot6.setPosition(Common::Point(219, 186));
+
+ setAction(&_action1);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 4304;
+ setAction(&_sequenceManager, this, 4304, NULL);
+ }
+
+ _hotspot10.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot19._sceneRegionId = 0;
+ _globals->_sceneItems.push_back(&_hotspot19);
+ _globals->_sceneItems.push_back(&_hotspot18);
+}
+
+void Scene4300::stripCallback(int v) {
+ switch (v) {
+ case 1:
+ _hotspot12.show();
+ _hotspot12.animate(ANIM_MODE_7, 0, NULL);
+ break;
+ case 2:
+ _hotspot12.hide();
+ break;
+ }
+}
+
+void Scene4300::remove() {
+ _globals->_scenePalette.clearListeners();
+ Scene::remove();
+}
+
+void Scene4300::signal() {
+ switch (_sceneMode) {
+ case 4302:
+ _globals->_inventory._items._sceneNumber = 1;
+ _hotspot16.remove();
+ _globals->_player.enableControl();
+ break;
+ case 4303:
+ _globals->_inventory._stasisBox2._sceneNumber = 4300;
+ _hotspot15.setStrip(1);
+ _hotspot15.setFrame(1);
+ _hotspot15.animate(ANIM_MODE_NONE, NULL);
+ break;
+ case 4304:
+ _hotspot14.postInit();
+ _hotspot14.setVisage(4300);
+ _hotspot14.setStrip(7);
+ _hotspot14.setPosition(Common::Point(60, 199));
+
+ _gfxButton.setText(EXIT_MSG);
+ _gfxButton._bounds.centre(60, 193);
+ _gfxButton.draw();
+ _gfxButton._bounds.expandPanes();
+
+ _globals->_player.enableControl();
+ _globals->_scenePalette.addRotation(240, 254, -1);
+ break;
+ }
+}
+
+void Scene4300::dispatch() {
+ if (_action)
+ _action->dispatch();
+}
+
+void Scene4300::process(Event &event) {
+ Scene::process(event);
+ if (_gfxButton.process(event))
+ _globals->_sceneManager.changeScene(4250);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 4301 - Village - Slaver Ship Keypad
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene4301::Action1::synchronise(Serialiser &s) {
+ Action::synchronise(s);
+ s.syncAsSint16LE(_field34E);
+ for (int idx = 0; idx < 6; ++idx)
+ s.syncAsSint16LE(_indexList[idx]);
+}
+
+void Scene4301::Action1::remove() {
+ Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene;
+ _globals->_player.enableControl();
+
+ for (_state = 0; _state < 6; ++_state)
+ _buttonList[_state].remove();
+
+ scene->_hotspot3.remove();
+ scene->_hotspot2.remove();
+
+ scene->_hotspot1.animate(ANIM_MODE_6, NULL);
+ Action::remove();
+}
+
+void Scene4301::Action1::signal() {
+ Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ scene->_soundHandler.startSound(164);
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 1:
+ _globals->_soundHandler.startSound(335);
+ _globals->_events.setCursor(CURSOR_USE);
+
+ scene->_hotspot2.postInit();
+ scene->_hotspot2.setVisage(4303);
+ scene->_hotspot2.setStrip(2);
+ scene->_hotspot2.setFrame(1);
+ scene->_hotspot2.setPosition(Common::Point(30, 15));
+ scene->_hotspot2.setPriority2(255);
+
+ scene->_hotspot3.postInit();
+ scene->_hotspot3.setVisage(4303);
+ scene->_hotspot3.setStrip(2);
+ scene->_hotspot3.setFrame(2);
+ scene->_hotspot3.setPosition(Common::Point(48, 29));
+ scene->_hotspot3.setPriority2(255);
+ scene->_hotspot3.hide();
+
+ _field34E = 0;
+ _state = 0;
+ _actionIndex = 2;
+ break;
+ case 10:
+ _globals->_events.setCursor(CURSOR_NONE);
+ scene->_soundHandler.startSound(337);
+ if (scene->_hotspot3._flags & OBJFLAG_HIDE)
+ scene->_hotspot3.show();
+ else
+ scene->_hotspot3.hide();
+ setDelay(20);
+
+ if (_state <= 8)
+ _actionIndex = 10;
+ ++_state;
+ break;
+ case 11:
+ for (_state = 0; _state < 6; ++_state)
+ _buttonList[_state].remove();
+
+ scene->_soundHandler.startSound(338);
+ scene->_hotspot3.hide();
+
+ _actionIndex = 2;
+ _state = 0;
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 20:
+ _globals->_player.disableControl();
+ scene->_soundHandler.startSound(339);
+ scene->_hotspot3._frame = 3;
+ if (scene->_hotspot3._flags & OBJFLAG_HIDE)
+ scene->_hotspot3.show();
+ else
+ scene->_hotspot3.hide();
+
+ if (_state <= 8)
+ _actionIndex = 20;
+ ++_state;
+
+ setDelay(20);
+ break;
+ case 21:
+ scene->_field68E = true;
+ remove();
+ break;
+ }
+}
+
+void Scene4301::Action1::process(Event &event) {
+ Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene;
+ Rect buttonsRect;
+
+ Action::process(event);
+ if (event.handled || (_actionIndex != 2))
+ return;
+
+ buttonsRect = Rect(14, 35, 112, 100);
+ buttonsRect.translate(30, 15);
+
+ if ((event.eventType == EVENT_BUTTON_DOWN) && buttonsRect.contains(event.mousePos)) {
+ event.handled = true;
+ scene->_soundHandler.startSound(336);
+
+ int buttonIndex = ((event.mousePos.y - buttonsRect.top) / 33) * 3 +
+ ((event.mousePos.x - buttonsRect.left) / 33);
+
+ _buttonList[_state].postInit();
+ _buttonList[_state].setVisage(4303);
+ _buttonList[_state].setStrip(buttonIndex + 3);
+ _buttonList[_state].setFrame(1);
+ _buttonList[_state].setPosition(Common::Point((_state % 3) * 25 + 55, (_state / 3) * 25 + 121));
+ _buttonList[_state].setPriority2(255);
+ _buttonList[_state]._numFrames = 25;
+ _buttonList[_state].animate(ANIM_MODE_5, NULL);
+
+ _indexList[_state++] = buttonIndex;
+
+ if (_state == 6) {
+ // Six buttons pressed
+ if ((_indexList[0] == 2) && (_indexList[1] == 3) && (_indexList[2] == 0) &&
+ (_indexList[3] == 4) && (_indexList[4] == 1) && (_indexList[5] == 5)) {
+ // Entered the correct full combination
+ _state = 0;
+ _actionIndex = 20;
+ } else {
+ // Incorrect combination entered
+ _state = 0;
+ _actionIndex = 10;
+ }
+
+ signal();
+ }
+ }
+
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ event.handled = true;
+ remove();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4301::Hotspot4::doAction(int action) {
+ Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_USE) {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action1);
+ } else {
+ NamedHotspot::doAction(action);
+ }
+}
+
+void Scene4301::Hotspot5::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(4300, 0);
+ break;
+ case CURSOR_USE:
+ SceneItem::display(4300, 30);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(4300, 31);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(4300, 32);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene4301::postInit(SceneObjectList *OwnerList) {
+ _globals->setFlag(50);
+ loadScene(4301);
+ Scene::postInit();
+ setZoomPercents(0, 100, 200, 100);
+
+ _field68E = false;
+ _globals->_inventory._stasisBox2._sceneNumber = 1;
+ _hotspot4.setup(76, 97, 102, 127, 4300, 5, 6);
+
+ _hotspot1.postInit();
+ _hotspot1.setPosition(Common::Point(90, 128));
+ _hotspot1.setVisage(4303);
+ _hotspot1._strip = 1;
+ _hotspot1._frame = 1;
+ _hotspot1.setPriority2(250);
+
+ _hotspot5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _globals->_sceneItems.push_back(&_hotspot5);
+
+ _globals->_player.enableControl();
+}
+
+void Scene4301::dispatch() {
+ if (_action) {
+ _action->dispatch();
+ } else if (_field68E) {
+ _field68E = 0;
+ _globals->clearFlag(50);
+ _globals->_sceneManager._fadeMode = FADEMODE_NONE;
+ _globals->_sceneManager.setNewScene(4300);
+ }
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes5.h b/engines/tsage/ringworld_scenes5.h
new file mode 100644
index 0000000000..0def49ebe6
--- /dev/null
+++ b/engines/tsage/ringworld_scenes5.h
@@ -0,0 +1,695 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES5_H
+#define TSAGE_RINGWORLD_SCENES5_H
+
+#include "common/scummsys.h"
+#include "tsage/core.h"
+#include "tsage/converse.h"
+#include "tsage/ringworld_logic.h"
+
+namespace tSage {
+
+class Scene4000 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action9 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action10 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action11 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action12 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action13 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot7 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ private:
+ int _ctr;
+ public:
+ virtual void synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ s.syncAsUint16LE(_ctr);
+ }
+ virtual void doAction(int action);
+ };
+ class Hotspot9 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot12 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot13 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot17 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot18 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot23 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3;
+ SoundHandler _soundHandler1, _soundHandler2;
+ SpeakerQR _speakerQR;
+ SpeakerML _speakerML;
+ SpeakerMR _speakerMR;
+ SpeakerSR _speakerSR;
+ SpeakerCHFL _speakerCHFL;
+ SpeakerPL _speakerPL;
+ SpeakerPText _speakerPText;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ SpeakerMText _speakerMText;
+ SpeakerCHFR _speakerCHFR;
+ SpeakerQL _speakerQL;
+ SpeakerCHFText _speakerCHFText;
+ SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5, _hotspot6;
+ Hotspot7 _hotspot7;
+ Hotspot8 _hotspot8;
+ Hotspot9 _hotspot9;
+ Hotspot10 _hotspot10;
+ DisplayHotspot _hotspot11;
+ Hotspot12 _hotspot12;
+ Hotspot13 _hotspot13;
+ Hotspot _hotspot14, _hotspot15, _hotspot16;
+ Hotspot17 _hotspot17;
+ Hotspot18 _hotspot18;
+ DisplayHotspot _hotspot19, _hotspot20, _hotspot21, _hotspot22;
+ Hotspot23 _hotspot23;
+ DisplayHotspot _hotspot24, _hotspot25, _hotspot26;
+ SceneObject _hotspot27;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ Action9 _action9;
+ Action10 _action10;
+ Action11 _action11;
+ Action12 _action12;
+ Action13 _action13;
+
+ Scene4000();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene4010 : public Scene {
+public:
+ SequenceManager _sequenceManager;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ SpeakerMText _speakerMText;
+ SceneObject _hotspot1, _hotspot2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene4025 : public Scene {
+ /* Custom classes */
+ class Peg;
+
+ class Hole : public SceneObject {
+ public:
+ Peg *_pegPtr;
+ int _armStrip;
+ Common::Point _newPosition;
+
+ virtual void synchronise(Serialiser &s);
+ virtual void doAction(int action);
+ };
+ class Peg : public SceneObject {
+ public:
+ int _field88;
+ int _armStrip;
+
+ Peg() : SceneObject() { _field88 = 0; _armStrip = 3; }
+ virtual void synchronise(Serialiser &s);
+ virtual void doAction(int action);
+ };
+
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ SequenceManager _sequenceManager;
+ GfxButton _gfxButton;
+ SceneObject _armHotspot;
+ Hole _hole1, _hole2, _hole3, _hole4, _hole5;
+ Peg _peg1, _peg2, _peg3, _peg4, _peg5;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Peg *_pegPtr, *_pegPtr2;
+ Hole *_holePtr;
+
+ Scene4025();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronise(Serialiser &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class Scene4045 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SequenceManager _sequenceManager;
+ SpeakerQR _speakerQR;
+ SpeakerML _speakerML;
+ SpeakerPR _speakerPR;
+ SpeakerPText _speakerPText;
+ SpeakerQText _speakerQText;
+ SpeakerQL _speakerQL;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ DisplayHotspot _hotspot3;
+ SceneObject _hotspot4, _hotspot5;
+ Hotspot6 _hotspot6;
+ DisplayHotspot _hotspot7, _hotspot8, _hotspot9, _hotspot10;
+ DisplayHotspot _hotspot11, _hotspot12, _hotspot13, _hotspot14;
+ Action1 _action1;
+ Action _action2;
+ Action _action3;
+
+ Scene4045();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void stripCallback(int v);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene4050 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot14 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot17 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SpeakerPText _speakerPText;
+ SpeakerQText _speakerQText;
+ SpeakerGameText _speakerGameText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ DisplayHotspot _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5;
+ DisplayHotspot _hotspot6, _hotspot7, _hotspot8, _hotspot9, _hotspot10;
+ DisplayHotspot _hotspot11, _hotspot12, _hotspot13;
+ Hotspot14 _hotspot14;
+ SceneObject _hotspot15, _hotspot16;
+ Hotspot17 _hotspot17;
+
+ Scene4050();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene4100 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot14 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SpeakerMText _speakerMText;
+ SpeakerML _speakerML;
+ SpeakerQText _speakerQText;
+ SpeakerQR _speakerQR;
+ SpeakerCHFText _speakerCHFText;
+ SpeakerCDRText _speakerCDRText;
+ SpeakerCDR _speakerCDR;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ DisplayHotspot _hotspot3, _hotspot4;
+ Hotspot5 _hotspot5;
+ Hotspot6 _hotspot6;
+ DisplayHotspot _hotspot7, _hotspot8, _hotspot9, _hotspot10;
+ DisplayHotspot _hotspot11, _hotspot12, _hotspot13;
+ Hotspot14 _hotspot14;
+
+ Scene4100();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene4150 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class HotspotGroup1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class HotspotGroup3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class HotspotGroup6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+ class Hotspot3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SequenceManager _sequenceManager;
+ SoundHandler _soundHandler;
+ SpeakerQText _speakerQText;
+ SpeakerQR _speakerQR;
+ SpeakerCDL _speakerCDL;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ DisplayHotspot _hotspot1, _hotspot2;
+ Hotspot3 _hotspot3;
+ SceneObject _hotspot4;
+ HotspotGroup1 _hotspot5, _hotspot6;
+ DisplayHotspot _hotspot7, _hotspot8, _hotspot9, _hotspot10, _hotspot11, _hotspot12;
+ HotspotGroup3 _hotspot13, _hotspot14, _hotspot15, _hotspot16;
+ DisplayHotspot _hotspot17, _hotspot18, _hotspot19, _hotspot20, _hotspot21;
+ DisplayHotspot _hotspot22, _hotspot23, _hotspot24;
+ HotspotGroup6 _hotspot25, _hotspot26;
+
+ Scene4150();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene4250 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SequenceManager _sequenceManager;
+ SoundHandler _soundHandler;
+ SpeakerSR _speakerSR;
+ SpeakerSL _speakerSL;
+ SpeakerSText _speakerSText;
+ SpeakerGameText _speakerGameText;
+ SpeakerQL _speakerQL;
+ SpeakerQR _speakerQR;
+ SpeakerQText _speakerQText;
+ SpeakerPText _speakerPText;
+ SpeakerMText _speakerMText;
+ SpeakerFLText _speakerFLText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ SceneObject _hotspot3;
+ Hotspot4 _hotspot4;
+ SceneObject _hotspot5;
+ Hotspot6 _hotspot6;
+ DisplayHotspot _hotspot7;
+ Hotspot8 _hotspot8;
+
+ Scene4250();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene4300 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot9 : public NamedHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot15 : public SceneObject {
+ public:
+ virtual void signal();
+ };
+ class Hotspot16 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot17 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot19 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler1, _soundHandler2;
+ SequenceManager _sequenceManager;
+ GfxButton _gfxButton;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ SpeakerMText _speakerMText;
+ SpeakerFLText _speakerFLText;
+
+ SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4;
+ SceneObject _hotspot5, _hotspot6, _hotspot7;
+ Hotspot8 _hotspot8;
+ Hotspot9 _hotspot9;
+ Hotspot10 _hotspot10;
+ NamedHotspot _hotspot11;
+ SceneObject _hotspot12, _hotspot13, _hotspot14;
+ Hotspot15 _hotspot15;
+ Hotspot16 _hotspot16;
+ Hotspot17 _hotspot17;
+ DisplayHotspot _hotspot18;
+ Hotspot19 _hotspot19;
+ Action1 _action1;
+ Action2 _action2;
+
+ Scene4300();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void stripCallback(int v);
+ virtual void remove();
+ virtual void signal();
+ virtual void dispatch();
+ virtual void process(Event &event);
+};
+
+class Scene4301 : public Scene {
+ /* Actions */
+ class Action1 : public ActionExt {
+ public:
+ SceneObject _buttonList[6];
+ int _field34E;
+ int _indexList[6];
+
+ virtual void synchronise(Serialiser &s);
+ virtual void remove();
+ virtual void signal();
+ virtual void process(Event &event);
+ };
+
+ /* Hotspots */
+ class Hotspot4 : public NamedHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot5 : public NamedHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ Common::List<int> _list1;
+ SequenceManager _sequenceManager;
+ SoundHandler _soundHandler;
+ Action1 _action1;
+ SceneObject _hotspot1, _hotspot2, _hotspot3;
+ Hotspot4 _hotspot4;
+ Hotspot5 _hotspot5;
+ bool _field68E;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void dispatch();
+ virtual void synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ s.syncAsSint16LE(_field68E);
+ }
+};
+
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes6.cpp b/engines/tsage/ringworld_scenes6.cpp
new file mode 100644
index 0000000000..3ea4d7b279
--- /dev/null
+++ b/engines/tsage/ringworld_scenes6.cpp
@@ -0,0 +1,2173 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/ringworld_scenes6.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 5000 - Caverns - Entrance
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene5000::Action1::signal() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_soundHandler.startSound(190);
+ scene->_soundHandler.proc5(true);
+ ADD_MOVER(scene->_hotspot1, 283, 12);
+ break;
+ case 2:
+ break;
+ case 3:
+ scene->_hotspot1._moveDiff.y = 1;
+ scene->_hotspot4.setPosition(Common::Point(scene->_hotspot1._position.x,
+ scene->_hotspot1._position.y + 15));
+ scene->_hotspot4.show();
+ setDelay(15);
+ break;
+ case 4:
+ scene->_soundHandler.proc4();
+ ADD_MOVER(scene->_hotspot1, 233, 80);
+ break;
+ case 5:
+ scene->_hotspot3.animate(ANIM_MODE_8, 0, NULL);
+ scene->_hotspot3.show();
+ ADD_MOVER(scene->_hotspot1, 233, 90);
+ break;
+ case 6:
+ scene->_hotspot3.remove();
+ scene->_hotspot2.setPosition(Common::Point(233, 76));
+ scene->_hotspot2.show();
+ scene->_hotspot2.animate(ANIM_MODE_5, this);
+
+ scene->_hotspot4.remove();
+ break;
+ case 7:
+ setDelay(60);
+ scene->_hotspot2.remove();
+ break;
+ case 8:
+ scene->_hotspot5.show();
+ scene->_hotspot5.animate(ANIM_MODE_5, this);
+ break;
+ case 9:
+ scene->setAction(&scene->_action2);
+ break;
+ }
+}
+
+void Scene5000::Action1::dispatch() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+ Action::dispatch();
+
+ if (_actionIndex == 3) {
+ if (scene->_hotspot1._percent % 2 == 0) {
+ ++scene->_hotspot1._position.y;
+ if (scene->_hotspot1._position.x > 233)
+ --scene->_hotspot1._position.x;
+ }
+
+ scene->_hotspot1.changeZoom(++scene->_hotspot1._percent);
+ scene->_hotspot1._flags |= OBJFLAG_PANES;
+
+ if (scene->_hotspot1._percent >= 100)
+ signal();
+ }
+
+ if ((_actionIndex == 5) || (_actionIndex == 6)) {
+ scene->_hotspot4.setPosition(Common::Point(scene->_hotspot1._position.x,
+ scene->_hotspot1._position.y + 15));
+ }
+}
+
+void Scene5000::Action2::signal() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.setPosition(Common::Point(217, 76));
+ setDelay(10);
+ break;
+ case 1:
+ _globals->_player.setStrip2(3);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ ADD_MOVER(_globals->_player, 214, 89);
+ break;
+ case 2:
+ if (!_globals->getFlag(59))
+ setAction(&scene->_action3, this);
+ _globals->_player.setPriority2(15);
+ ADD_MOVER(_globals->_player, 208, 100);
+ break;
+ case 3:
+ ADD_MOVER(_globals->_player, 213, 98);
+ break;
+ case 4:
+ ADD_MOVER(_globals->_player, 215, 115);
+ break;
+ case 5:
+ _globals->_player.changeZoom(47);
+ ADD_MOVER(_globals->_player, 220, 125);
+ break;
+ case 6:
+ ADD_MOVER(_globals->_player, 229, 115);
+ break;
+ case 7:
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setPriority2(35);
+ ADD_MOVER(_globals->_player, 201, 166);
+ break;
+ case 8:
+ _globals->_player.updateZoom();
+ ADD_MOVER(_globals->_player, 205, 146);
+ break;
+ case 9:
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setPriority2(50);
+ ADD_MOVER(_globals->_player, 220, 182);
+ break;
+ case 10:
+ _globals->_player.updateZoom();
+ ADD_MOVER(_globals->_player, 208, 163);
+ break;
+ case 11:
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setStrip2(-1);
+ _globals->_player.setPriority2(-1);
+ ADD_MOVER(_globals->_player, 208, 175);
+ break;
+ case 12:
+ _globals->_player.setStrip(8);
+ _globals->_player.setFrame(1);
+ setDelay(10);
+ break;
+ case 13:
+ if (!_globals->_sceneObjects->contains(&scene->_hotspot7))
+ setDelay(10);
+ break;
+ case 14:
+ setDelay(30);
+ break;
+ case 15:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene5000::Action3::signal() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(10);
+ break;
+ case 1:
+ scene->_hotspot7.postInit();
+ scene->_hotspot7.setVisage(2809);
+ scene->_hotspot7.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot7.setPosition(Common::Point(217, 76));
+ scene->_hotspot7.changeZoom(10);
+ scene->_hotspot7.setStrip2(3);
+ scene->_hotspot7.setPriority2(200);
+ scene->_hotspot7._moveDiff.y = 2;
+ scene->_hotspot7.animate(ANIM_MODE_1, NULL);
+ ADD_MOVER(scene->_hotspot7, 214, 89);
+
+ _globals->_sceneItems.push_front(&scene->_hotspot7);
+ break;
+ case 2:
+ scene->_hotspot7.changeZoom(-1);
+ scene->_hotspot7.setPriority2(14);
+ ADD_MOVER(scene->_hotspot7, 208, 100);
+ break;
+ case 3:
+ ADD_MOVER(scene->_hotspot7, 213, 98);
+ break;
+ case 4:
+ scene->_hotspot7.setPriority2(19);
+ ADD_MOVER(scene->_hotspot7, 213, 98);
+ break;
+ case 5:
+ scene->_hotspot7.changeZoom(46);
+ ADD_MOVER(scene->_hotspot7, 220, 125);
+ break;
+ case 6:
+ ADD_MOVER(scene->_hotspot7, 229, 115);
+ break;
+ case 7:
+ scene->_hotspot7.changeZoom(-1);
+ scene->_hotspot7.setPriority2(34);
+ ADD_MOVER(scene->_hotspot7, 201, 166);
+ break;
+ case 8:
+ scene->_hotspot7.updateZoom();
+ ADD_MOVER(scene->_hotspot7, 205, 146);
+ break;
+ case 9:
+ scene->_hotspot7.changeZoom(-1);
+ scene->_hotspot7.setPriority2(49);
+ ADD_MOVER(scene->_hotspot7, 210, 182);
+ break;
+ case 10:
+ scene->_hotspot7.updateZoom();
+ ADD_MOVER(scene->_hotspot7, 208, 163);
+ break;
+ case 11:
+ scene->_hotspot7.changeZoom(-1);
+ scene->_hotspot7.setStrip2(-1);
+ scene->_hotspot7.setPriority2(-1);
+ ADD_MOVER(scene->_hotspot7, 175, 166);
+ break;
+ case 12:
+ ADD_MOVER(scene->_hotspot7, 126, 146);
+ break;
+ case 13:
+ scene->_hotspot7.setStrip(2);
+ remove();
+ break;
+ }
+}
+
+void Scene5000::Action4::signal() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ break;
+ case 1:
+ _globals->_player.setPriority2(50);
+ _globals->_player.setStrip2(4);
+ ADD_MOVER(_globals->_player, 210, 182);
+ break;
+ case 2:
+ ADD_MOVER(_globals->_player, 205, 146);
+ break;
+ case 3:
+ _globals->_player.setPriority2(35);
+ ADD_MOVER(_globals->_player, 201, 166);
+ break;
+ case 4:
+ ADD_MOVER(_globals->_player, 229, 115);
+ break;
+ case 5:
+ _globals->_player.setPriority2(20);
+ _globals->_player.changeZoom(47);
+ ADD_MOVER(_globals->_player, 220, 125);
+ break;
+ case 6:
+ ADD_MOVER(_globals->_player, 215, 115);
+ break;
+ case 7:
+ _globals->_player.changeZoom(-1);
+ ADD_MOVER(_globals->_player, 213, 98);
+ break;
+ case 8:
+ _globals->_player.setPriority2(15);
+ ADD_MOVER(_globals->_player, 208, 100);
+ break;
+ case 9:
+ ADD_MOVER(_globals->_player, 214, 89);
+ break;
+ case 10:
+ ADD_MOVER(_globals->_player, 217, 76);
+ break;
+ case 11:
+ _globals->_player.hide();
+ setDelay(60);
+ break;
+ case 12:
+ if (!_globals->_sceneObjects->contains(&scene->_hotspot7))
+ _globals->_sceneManager.changeScene(2320);
+ remove();
+ break;
+ }
+}
+
+void Scene5000::Action5::signal() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_MOVER(_globals->_player, 91, 155);
+ break;
+ case 1:
+ _globals->_player.setVisage(2670);
+ _globals->_player._strip = 4;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ SceneItem::display2(5000, _globals->_sceneObjects->contains(&scene->_hotspot7) ? 17 : 13);
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ _globals->_player.setVisage(0);
+ _globals->_player._strip = 8;
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ _globals->_player.enableControl();
+ remove();
+ }
+}
+
+void Scene5000::Action6::signal() {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ _globals->_events.setCursor(CURSOR_WALK);
+ scene->_stripManager.start(2150, this);
+ break;
+ case 2:
+ _globals->_events.setCursor(CURSOR_NONE);
+ scene->setAction(&scene->_sequenceManager, this, 5001, &scene->_hotspot7, NULL);
+ break;
+ case 3:
+ ADD_PLAYER_MOVER(208, 163);
+ break;
+ case 4:
+ _globals->_player.setPriority2(50);
+ _globals->_player.setStrip2(4);
+ ADD_MOVER(_globals->_player, 210, 182);
+ break;
+ case 5:
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene5000::Hotspot7::doAction(int action) {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5000, 12);
+ break;
+ case CURSOR_TALK:
+ setAction(&scene->_action6);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5000::Hotspot8::doAction(int action) {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5000, 10);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(5000, 14);
+ break;
+ case OBJECT_SCANNER:
+ setAction(&scene->_action5);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5000::HotspotGroup1::doAction(int action) {
+ Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene;
+
+ if (_globals->_sceneObjects->contains(&scene->_hotspot7))
+ scene->setAction(&scene->_action6);
+ else
+ SceneItem::display2(5000, 11);
+}
+/*--------------------------------------------------------------------------*/
+
+Scene5000::Scene5000() :
+ _hotspot1(0, CURSOR_LOOK, 5000, 3, LIST_END),
+ _hotspot12(0, CURSOR_LOOK, 5000, 6, CURSOR_USE, 5000, 7, OBJECT_STUNNER, 5000, 14,
+ OBJECT_SCANNER, 5000, 16, LIST_END),
+ _hotspot13(0, CURSOR_LOOK, 5000, 8, CURSOR_USE, 5000, 9, OBJECT_STUNNER, 5000, 0,
+ OBJECT_SCANNER, 5000, 16, LIST_END),
+ _hotspot14(0, CURSOR_LOOK, 5000, 8, CURSOR_USE, 5000, 9, OBJECT_STUNNER, 5000, 0,
+ OBJECT_SCANNER, 5000, 16, LIST_END),
+ _hotspot15(0, CURSOR_LOOK, 5000, 2, OBJECT_STUNNER, 5000, 15, LIST_END),
+ _hotspot16(0, CURSOR_LOOK, 5000, 4, CURSOR_USE, 5000, 5, LIST_END),
+ _hotspot17(0, CURSOR_LOOK, 5000, 1, LIST_END),
+ _hotspot18(0, CURSOR_LOOK, 5000, 0, LIST_END) {
+}
+
+
+void Scene5000::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ loadScene(5000);
+
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerQText);
+
+ _globals->_player.postInit();
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player._moveDiff = Common::Point(4, 2);
+ _globals->_player.changeZoom(-1);
+ _globals->_player.disableControl();
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(5001);
+ _hotspot1.setFrame2(1);
+ _hotspot1._moveDiff = Common::Point(5, 5);
+ _hotspot1.setPriority2(10);
+ _hotspot1.changeZoom(10);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(5001);
+ _hotspot4.setStrip2(2);
+ _hotspot4._moveDiff = Common::Point(5, 1);
+ _hotspot4.setPriority2(10);
+ _hotspot4.changeZoom(100);
+ _hotspot4.animate(ANIM_MODE_8, 0, NULL);
+ _hotspot4.hide();
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(5001);
+ _hotspot2.setStrip2(3);
+ _hotspot2._numFrames = 5;
+ _hotspot2.hide();
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(5001);
+ _hotspot3.setStrip2(5);
+ _hotspot3._numFrames = 5;
+ _hotspot3.setPosition(Common::Point(233, 76));
+ _hotspot3.hide();
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(5001);
+ _hotspot5.setStrip2(4);
+ _hotspot5._numFrames = 5;
+ _hotspot5.setPriority2(15);
+ _hotspot5.setPosition(Common::Point(218, 76));
+ _hotspot5.hide();
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(5002);
+ _hotspot9.setPriority2(80);
+ _hotspot9.setPosition(Common::Point(71, 174));
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(5002);
+ _hotspot10.setStrip2(2);
+ _hotspot10.setPosition(Common::Point(87, 120));
+
+ _hotspot11.postInit();
+ _hotspot11.setVisage(5002);
+ _hotspot11.setStrip2(2);
+ _hotspot11.setFrame(3);
+ _hotspot10.setPosition(Common::Point(93, 118));
+
+ setZoomPercents(95, 10, 145, 100);
+
+ _hotspot8.setBounds(Rect(0, 73, 87, 144));
+ _hotspot18.setBounds(Rect(54, 0, 319, 85));
+ _hotspot17.setBounds(Rect(184, 0, 199, 79));
+ _hotspot13.setBounds(Rect(0, 164, 135, 200));
+ _hotspot14.setBounds(Rect(0, 0, 105, 140));
+ _hotspot15.setBounds(Rect(266, 70, 291, 85));
+ _hotspot16.setBounds(Rect(0, 86, 3219, 200));
+ _hotspot12.setBounds(Rect(230, 143, 244, 150));
+
+ _globals->_sceneItems.addItems(&_hotspot9, &_hotspot10, &_hotspot11, &_hotspot8, &_hotspot13,
+ &_hotspot14, &_hotspot12, &_hotspot15, &_hotspot17, &_hotspot18, &_hotspot16, NULL);
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 1000:
+ case 2100:
+ case 2320:
+ if (_globals->getFlag(59)) {
+ _hotspot1.setPosition(Common::Point(233, 90));
+ _hotspot1.changeZoom(100);
+ _hotspot1.show();
+
+ _hotspot5.setFrame(1);
+ _hotspot5.animate(ANIM_MODE_5, NULL);
+ _hotspot5.setPosition(Common::Point(218, 76));
+ _hotspot5.show();
+
+ _globals->_player.setPosition(Common::Point(217, -10));
+ _globals->_player.disableControl();
+
+ setAction(&_action2);
+ } else {
+ _globals->_player.setPosition(Common::Point(217, -10));
+ _hotspot1.setPosition(Common::Point(320, -10));
+ _globals->_player.disableControl();
+
+ setAction(&_action1);
+ }
+ break;
+ default:
+ _globals->_player.disableControl();
+ _globals->_player.setPosition(Common::Point(0, 146));
+
+ _hotspot1.changeZoom(100);
+ _hotspot1.setPosition(Common::Point(233, 90));
+ _hotspot1.show();
+
+ _hotspot5.setFrame(_hotspot5.getFrameCount());
+ _hotspot5.show();
+
+ _sceneMode = 5004;
+ setAction(&_sequenceManager, this, 5004, &_globals->_player, NULL);
+ break;
+ }
+
+ _globals->_soundHandler.startSound(190);
+}
+
+void Scene5000::signal() {
+ switch (_sceneMode) {
+ case 5002:
+ case 5003:
+ case 5004:
+ _globals->_player.enableControl();
+ break;
+ case 5005:
+ _globals->_sceneManager.changeScene(5100);
+ break;
+ }
+}
+
+void Scene5000::dispatch() {
+ Scene::dispatch();
+
+ if (!_action) {
+ if (!_globals->_sceneObjects->contains(&_hotspot7) && (_globals->_player.getRegionIndex() == 10)) {
+ _globals->_player.disableControl();
+ _sceneMode = 5005;
+ setAction(&_sequenceManager, this, 5005, &_globals->_player, NULL);
+ }
+
+ if (_globals->_player.getRegionIndex() == 8) {
+ _globals->_player.disableControl();
+
+ if (_globals->_sceneObjects->contains(&_hotspot7)) {
+ _sceneMode = 5003;
+ _globals->_player.addMover(NULL);
+ setAction(&_sequenceManager, this, 5003, &_globals->_player, NULL);
+ } else {
+ setAction(&_action4);
+ }
+ }
+
+ if (_globals->_sceneObjects->contains(&_hotspot7) && (_globals->_player.getRegionIndex() == 15)) {
+ _sceneMode = 5002;
+ _globals->_player.disableControl();
+ _globals->_player.addMover(NULL);
+ setAction(&_sequenceManager, this, 5002, &_globals->_player, NULL);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 5100 - Caverns
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene5100::Action1::signal() {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ ADD_MOVER(_globals->_player, 1111, 165);
+ break;
+ case 2:
+ _globals->_player.setStrip(6);
+ _globals->_player.setFrame(1);
+ setDelay(60);
+ break;
+ case 3:
+ if (_globals->getFlag(10)) {
+ _globals->_player.enableControl();
+ remove();
+ } else {
+ _globals->setFlag(10);
+ scene->_stripManager.start(5102, this);
+ }
+ break;
+ case 4:
+ scene->_soundHandler.startSound(206);
+
+ scene->_hotspot5.postInit();
+ scene->_hotspot5.setVisage(5362);
+ scene->_hotspot5.setPosition(Common::Point(1160, 34));
+ scene->_hotspot5.setStrip2(2);
+ scene->_hotspot5.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot5.setPriority2(10);
+
+ _globals->_sceneItems.push_front(&scene->_hotspot5);
+ ADD_MOVER(scene->_hotspot5, 999, 14);
+ break;
+ case 5:
+ scene->_hotspot5.setStrip2(4);
+ scene->_hotspot5._frame = 1;
+ scene->_hotspot5.animate(ANIM_MODE_5, this);
+ break;
+ case 6:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene5100::Action2::signal() {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(5);
+ break;
+ case 1:
+ if (scene->_hotspot8._visage == 2806)
+ setDelay(1);
+ else
+ scene->_hotspot8.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ if (scene->_hotspot8._visage != 2806) {
+ scene->_hotspot8.setVisage(2806);
+ scene->_hotspot8.setPosition(Common::Point(548, 193));
+ scene->_hotspot8.animate(ANIM_MODE_1, NULL);
+ scene->_hotspot8._angle = 325;
+ scene->_hotspot8.setObjectWrapper(new SceneObjectWrapper());
+ scene->_hotspot8.setStrip(8);
+ }
+
+ scene->_stripManager.start(5129, this);
+ break;
+ case 3:
+ if (_globals->_player._position.x >= 966) {
+ ADD_PLAYER_MOVER(1215, 155);
+ } else {
+ ADD_PLAYER_MOVER_THIS(scene->_hotspot8, 966, 185);
+ }
+
+ if (_globals->_player._position.x >= 966) {
+ setDelay(1);
+ } else {
+ ADD_PLAYER_MOVER(966, 190);
+ }
+ break;
+ case 4:
+ ADD_PLAYER_MOVER_THIS(scene->_hotspot8, 1215, 155);
+ ADD_PLAYER_MOVER(1215, 155);
+ break;
+ case 5:
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ }
+}
+
+void Scene5100::Action3::signal() {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->setFlag(62);
+ _globals->_player.disableControl();
+ _globals->_player.addMover(NULL);
+
+ scene->_hotspot2.addMover(NULL);
+ scene->_hotspot3.addMover(NULL);
+ _globals->_player.setVisage(2672);
+
+ if (static_cast<SceneObject *>(_owner)->_position.x >= _globals->_player._position.x)
+ _globals->_player._strip = 4;
+ else
+ _globals->_player._strip = 3;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 1:
+ _globals->_player.setVisage(2674);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ scene->_soundHandler.startSound(28);
+ if (static_cast<SceneObject *>(_owner)->_position.x < _globals->_player._position.x) {
+ scene->_hotspot2.setVisage(5130);
+ scene->_hotspot2._strip = 1;
+ scene->_hotspot2._frame = 1;
+ scene->_hotspot2.animate(ANIM_MODE_5, this);
+ scene->_hotspot2.setAction(NULL);
+
+ scene->_hotspot3.setStrip2(1);
+ ADD_PLAYER_MOVER_THIS(scene->_hotspot3, 1200, 100);
+ } else {
+ scene->_hotspot3.setVisage(5130);
+ scene->_hotspot3._strip = 1;
+ scene->_hotspot3._frame = 1;
+ scene->_hotspot3.animate(ANIM_MODE_5, this);
+ scene->_hotspot3.setAction(NULL);
+
+ scene->_hotspot2.setStrip2(2);
+ ADD_PLAYER_MOVER_NULL(scene->_hotspot2, 10, 140);
+
+ }
+
+ _globals->_player.setVisage(2672);
+ _globals->_player._frame = _globals->_player.getFrameCount();
+ _globals->_player.animate(ANIM_MODE_6, this);
+ break;
+ case 3:
+ break;
+ case 4:
+ SceneItem::display2(5100, 38);
+ _globals->_player.enableControl();
+
+ _globals->_player.setVisage(0);
+ _globals->_player._strip = 8;
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ remove();
+ break;
+ }
+}
+
+void Scene5100::Action4::signal() {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ _globals->_player.disableControl();
+ scene->_soundHandler.startSound(208);
+ SceneItem::display2(5100, 15);
+
+ ObjectMover3 *mover = new ObjectMover3();
+ scene->_hotspot2.addMover(mover, &_globals->_player, 20, this);
+ break;
+ }
+ case 1:
+ scene->_hotspot1.postInit();
+ scene->_hotspot1.setVisage(5120);
+ scene->_hotspot1.setPosition(Common::Point(795, 161));
+ scene->_hotspot1._strip = 4;
+ scene->_hotspot1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ setDelay(15);
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(5200);
+ break;
+ }
+}
+
+void Scene5100::Action5::signal() {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(60);
+ break;
+ case 1:
+ scene->_stripManager.start(5128, this);
+ break;
+ case 2:
+ setDelay(15);
+ break;
+ case 3:
+ scene->_sceneMode = 5106;
+ scene->setAction(&scene->_sequenceManager, scene, 5106, &_globals->_player, NULL);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene5100::HotspotGroup1::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, _globals->getFlag(62) ? 41 : 26);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(5100, 11);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(5100, 17);
+ break;
+ case OBJECT_STUNNER:
+ if (_globals->getFlag(62))
+ SceneItem::display2(5100, 42);
+ else
+ setAction(&scene->_action3);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::Hotspot4::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, 31);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5110;
+ scene->setAction(&scene->_sequenceManager, scene, 5110, &_globals->_player, this, &scene->_hotspot7, NULL);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display2(5100, 34);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(5100, 36);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(5100, 37);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::HotspotGroup2::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, _globals->getFlag(62) ? 47 : 23);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(5100, 29);
+ break;
+ case CURSOR_TALK:
+ if (_position.x >= 600)
+ SceneItem::display2(5100, 28);
+ else {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5114;
+ scene->setAction(&scene->_sequenceManager, scene, 5114, NULL);
+ }
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(5100, 43);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::Hotspot9::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, 32);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5117;
+ scene->setAction(&scene->_sequenceManager, scene, 5117, &_globals->_player, NULL);
+ break;
+ case OBJECT_STUNNER:
+ SceneItem::display2(5100, 35);
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(5100, 44);
+ break;
+ case OBJECT_BONE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5116;
+ scene->setAction(&scene->_sequenceManager, scene, 5116, &_globals->_player, &scene->_hotspot10,
+ &scene->_hotspot4, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::Hotspot17::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, 18);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(67))
+ SceneItem::display2(5100, 19);
+ else {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5101;
+ scene->setAction(&scene->_sequenceManager, scene, 5101, &_globals->_player, this, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::Hotspot18::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->_sceneManager._previousScene != 5000) {
+ SceneItem::display2(5100, 3);
+ } else {
+ switch (_index1) {
+ case 0:
+ SceneItem::display2(5100, 0);
+ ++_index1;
+ break;
+ case 1:
+ SceneItem::display2(5100, 1);
+ ++_index1;
+ break;
+ default:
+ SceneItem::display2(5100, 2);
+ break;
+ }
+ }
+ break;
+ case CURSOR_USE:
+ switch (_index2) {
+ case 0:
+ SceneItem::display2(5100, 8);
+ ++_index2;
+ break;
+ case 1:
+ SceneItem::display2(5100, 9);
+ ++_index2;
+ break;
+ default:
+ SceneItem::display2(5100, 10);
+ break;
+ }
+ break;
+
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::Hotspot19::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, _globals->_sceneObjects->contains(&scene->_hotspot14) ? 27 : 20);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5106;
+
+ if (_globals->getFlag(66))
+ scene->setAction(&scene->_sequenceManager, scene, 5113, &_globals->_player, NULL);
+ else {
+ _globals->setFlag(66);
+ scene->setAction(&scene->_sequenceManager, scene, 5106, &_globals->_player, &scene->_hotspot14, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5100::Hotspot20::doAction(int action) {
+ Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5100, 21);
+ break;
+ case CURSOR_USE:
+ _globals->_player.disableControl();
+
+ if (_globals->getFlag(67)) {
+ scene->_sceneMode = 5112;
+ scene->setAction(&scene->_sequenceManager, scene, 5112, &_globals->_player, NULL);
+ } else {
+ scene->_sceneMode = 5101;
+ scene->setAction(&scene->_sequenceManager, scene, 5106, &_globals->_player, &scene->_hotspot17, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene5100::Scene5100() :
+ _hotspot16(0, CURSOR_LOOK, 5100, 48, LIST_END),
+ _hotspot21(0, CURSOR_LOOK, 5100, 4, CURSOR_USE, 5100, 5, LIST_END) {
+}
+
+void Scene5100::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(50, 10, 200, 100);
+ _sceneMode = 0;
+
+ _stripManager.addSpeaker(&_speakerMText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerGameText);
+ _stripManager.addSpeaker(&_speakerBatText);
+ _speakerQText._npc = &_globals->_player;
+ _speakerMText._npc = &_globals->_player;
+ _speakerSText._npc = &_hotspot8;
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.disableControl();
+
+ if (!_globals->getFlag(66)) {
+ _hotspot14.postInit();
+ _hotspot14.setVisage(5101);
+ _hotspot14.setPosition(Common::Point(498, 147));
+ _hotspot14.setPriority2(200);
+ _hotspot14._moveDiff.y = 10;
+ }
+
+ _hotspot17.postInit();
+ _hotspot17.setVisage(5101);
+ _hotspot17._strip = 2;
+ _hotspot17.setPriority2(200);
+
+ if (_globals->getFlag(67))
+ _hotspot17.setPosition(Common::Point(554, 192));
+ else
+ _hotspot17.setPosition(Common::Point(539, 179));
+
+ _hotspot19.setBounds(Rect(488, 115, 508, 148));
+ _hotspot21.setBounds(Rect(1150, 85, 1173, 112));
+ _hotspot20.setBounds(Rect(517, 193, 562, 200));
+ _globals->_sceneItems.addItems(&_hotspot19, &_hotspot21, NULL);
+
+ if (_globals->getFlag(67)) {
+ _globals->_sceneItems.addItems(&_hotspot20, &_hotspot17, NULL);
+ } else {
+ _globals->_sceneItems.addItems(&_hotspot17, &_hotspot20, NULL);
+ }
+
+ if (!_globals->getFlag(105)) {
+ _hotspot4.postInit();
+ _hotspot4.setVisage(5363);
+ _hotspot4.setPosition(Common::Point(1025, 65));
+ _hotspot4.setStrip(4);
+ _hotspot4.animate(ANIM_MODE_7, 0, NULL);;
+ _globals->_sceneItems.push_back(&_hotspot4);
+
+ _hotspot9.postInit();
+ _hotspot9.setVisage(5363);
+ _hotspot9.setPosition(Common::Point(966, 120));
+ _globals->_sceneItems.push_back(&_hotspot9);
+
+ _hotspot10.postInit();
+ _hotspot10.setVisage(5363);
+ _hotspot10.setPosition(Common::Point(999, 68));
+ _hotspot10.setStrip(2);
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(5362);
+ _hotspot6.setPosition(Common::Point(1017, 34));
+ _hotspot6._strip = 4;
+ _hotspot6._frame = _hotspot6.getFrameCount();
+ _globals->_sceneItems.push_back(&_hotspot6);
+ }
+
+ _hotspot16._sceneRegionId = 15;
+ _globals->_sceneItems.push_back(&_hotspot16);
+
+ if (!_globals->getFlag(62)) {
+ _hotspot2.postInit();
+ _hotspot2.setVisage(5110);
+ _hotspot2.animate(ANIM_MODE_1, NULL);
+ _hotspot2._moveDiff.x = 4;
+ _globals->_sceneItems.push_back(&_hotspot2);
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(5110);
+ _hotspot3.animate(ANIM_MODE_1, NULL);
+ _hotspot3._moveDiff.x = 4;
+ _globals->_sceneItems.push_back(&_hotspot3);
+
+ if (_globals->getFlag(61)) {
+ _hotspot2.setPosition(Common::Point(483, 189));
+ _hotspot3.setPosition(Common::Point(811, 182));
+ } else {
+ _hotspot2.setPosition(Common::Point(610, 170));
+ _hotspot3.setPosition(Common::Point(600, 180));
+ }
+ }
+
+ if (_globals->getFlag(60) && (_globals->_inventory._stasisBox._sceneNumber == 1) &&
+ _globals->getFlag(107) && _globals->getFlag(67)) {
+ _hotspot8.postInit();
+ _hotspot8.setVisage(2806);
+ _hotspot8.setPosition(Common::Point(557, 178));
+ _hotspot8.animate(ANIM_MODE_1, NULL);
+ _hotspot8.setObjectWrapper(new SceneObjectWrapper());
+
+ _globals->clearFlag(59);
+ }
+
+ switch (_globals->_sceneManager._previousScene) {
+ case 5000:
+ default:
+ _globals->_player.setPosition(Common::Point(1184, 160));
+ setAction(&_action1);
+ break;
+ case 5200:
+ if (_globals->_stripNum == 5200) {
+ _globals->_player.setVisage(5101);
+ _globals->_player.setPriority2(200);
+ _globals->_player.setStrip(5);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(513, 199));
+
+ _sceneMode = 5108;
+ setAction(&_sequenceManager, this, 5108, &_globals->_player, NULL);
+ } else {
+ _globals->_player.setPosition(Common::Point(20, 175));
+
+ _hotspot13.postInit();
+ _hotspot13.setVisage(5110);
+ _hotspot13.setPosition(Common::Point(578, 192));
+ _hotspot13._strip = 2;
+
+ _hotspot11.postInit();
+ _hotspot11.setVisage(5110);
+ _hotspot11.setPosition(Common::Point(5, 162));
+ _hotspot11.setStrip2(1);
+ _hotspot11._moveDiff = Common::Point(4, 2);
+ _hotspot11.animate(ANIM_MODE_1, NULL);
+
+ ObjectMover2 *mover = new ObjectMover2();
+ _hotspot11.addMover(mover, 15, 20, &_globals->_player);
+
+ _hotspot12.postInit();
+ _hotspot12.setVisage(5110);
+ _hotspot12.setPosition(Common::Point(15, 164));
+ _hotspot12.setStrip2(1);
+ _hotspot12._moveDiff = Common::Point(4, 2);
+ _hotspot12.animate(ANIM_MODE_1, NULL);
+
+ ObjectMover2 *mover2 = new ObjectMover2();
+ _hotspot12.addMover(mover2, 25, 50, &_globals->_player);
+
+ _hotspot17.setPosition(Common::Point(554, 182));
+ _globals->_player.disableControl();
+
+ _sceneMode = 5105;
+ setAction(&_sequenceManager, this, 5105, &_globals->_player, NULL);
+ }
+ break;
+ case 5300:
+ switch (_globals->_stripNum) {
+ case 5300:
+ _sceneMode = 5111;
+
+ _globals->_player.setVisage(5101);
+ _globals->_player.setStrip(6);
+ _globals->_player.setPriority2(170);
+ _globals->_player.setPosition(Common::Point(1168, 110));
+
+ setAction(&_sequenceManager, this, 5111, &_globals->_player, NULL);
+ _hotspot8.setPosition(Common::Point(1107, 178));
+ break;
+ case 5302:
+ _globals->_player.setPosition(Common::Point(512, 190));
+
+ if (_globals->_sceneObjects->contains(&_hotspot8))
+ setAction(&_action2);
+ else
+ _globals->_player.enableControl();
+ break;
+ case 5303:
+ _hotspot8.setVisage(5102);
+ _hotspot8.setPosition(Common::Point(533, 172));
+ _globals->_player.setPosition(Common::Point(512, 190));
+ setAction(&_action2);
+ break;
+ }
+
+ if (_globals->getFlag(108)) {
+ _hotspot6.postInit();
+ _hotspot6.setVisage(5362);
+ _hotspot6.setPosition(Common::Point(542, 19));
+ _hotspot6.setStrip(6);
+ _hotspot6.setFrame(1);
+ _globals->_sceneItems.push_back(&_hotspot6);
+ } else if (_globals->_inventory._vial._sceneNumber != 5100) {
+ _hotspot6.postInit();
+ _hotspot6.setVisage(5362);
+ _hotspot6.setPosition(Common::Point(1152, 70));
+ _hotspot6.setPriority2(170);
+ _hotspot6.setStrip(6);
+ _hotspot6.setFrame(1);
+ _globals->_sceneItems.push_back(&_hotspot6);
+ }
+ break;
+ }
+
+ _hotspot18.setBounds(Rect(0, 0, 1280, 200));
+ _globals->_sceneItems.push_back(&_hotspot18);
+
+ _hotspot15.postInit();
+ _hotspot15.setVisage(5140);
+ _hotspot15.setStrip(3);
+ _hotspot15.setPosition(Common::Point(977, 173));
+ _hotspot15.setPriority2(1);
+
+ _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position);
+ loadScene(5100);
+ _globals->_soundHandler.startSound(205);
+}
+
+void Scene5100::signal() {
+ switch (_sceneMode) {
+ case 5101:
+ case 5112:
+ _globals->setFlag(67);
+ _globals->_sceneManager.changeScene(5300);
+ break;
+ case 5102:
+ case 5114:
+ _globals->_player.enableControl();
+ break;
+ case 5103:
+ if (_globals->getFlag(61)) {
+ SceneItem::display2(5100, 46);
+ _globals->_sceneManager.changeScene(5300);
+ } else {
+ SceneItem::display2(5100, 45);
+ _globals->_sceneManager.changeScene(5200);
+ }
+ break;
+ case 5105:
+ _globals->_sceneManager.changeScene(5300);
+ break;
+ case 5106:
+ _globals->_stripNum = 5111;
+ _globals->_sceneManager.changeScene(5200);
+ break;
+ case 5108:
+ if (!_globals->getFlag(60))
+ _globals->_player.enableControl();
+ else if (_globals->_inventory._stasisBox._sceneNumber == 1)
+ setAction(&_action2);
+ else
+ setAction(&_action5);
+ break;
+ case 5110:
+ SceneItem::display2(5100, 30);
+ _globals->_player._angle = 325;
+ _globals->_player.enableControl();
+ break;
+ case 5111:
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setVisage(6);
+ _globals->_player.setStrip(6);
+ _globals->_player.setPriority2(-1);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ if ((_globals->_inventory._vial._sceneNumber != 5100) && !_globals->getFlag(108)) {
+ _globals->setFlag(108);
+ _sceneMode = 5130;
+ _globals->_player.disableControl();
+
+ _speakerBatText.setTextPos(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + 20, 30));
+ setAction(&_sequenceManager, this, 5130, &_globals->_player, &_hotspot6, NULL);
+ } else if (_globals->_sceneObjects->contains(&_hotspot8)) {
+ setAction(&_action2);
+ } else {
+ _globals->_player.enableControl();
+ }
+ break;
+ case 5116:
+ _globals->setFlag(105);
+ _globals->_inventory._bone._sceneNumber = 0;
+
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setVisage(0);
+ _globals->_player.setStrip(6);
+ _globals->_player.setPriority2(-1);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ break;
+ case 5117:
+ _globals->_player.enableControl();
+ break;
+ case 5130:
+ _hotspot6.setVisage(5362);
+ _hotspot6.setPosition(Common::Point(542, 25));
+ _hotspot6.setStrip(6);
+ _hotspot6.setFrame(1);
+ _globals->_player.enableControl();
+ break;
+ case 5150:
+ _globals->clearFlag(60);
+ _globals->_sceneManager.changeScene(5300);
+ break;
+ }
+}
+
+void Scene5100::dispatch() {
+ if (_hotspot15._bounds.contains(_globals->_player._position) && !_globals->_player._visage) {
+ _globals->_player.disableControl();
+ _globals->_player.addMover(NULL);
+
+ _soundHandler.startSound(207);
+ _sceneMode = 5103;
+ setAction(&_sequenceManager, this, (_globals->_player._position.x >= 966) ? 5104 : 5103,
+ &_globals->_player, &_hotspot15, NULL);
+ }
+
+ if (_globals->getFlag(61) && !_globals->getFlag(62) &&
+ ((_globals->_player._position.x - _hotspot2._position.x) < 160) &&
+ (_globals->_sceneManager._previousScene != 5200) &&
+ (_globals->_sceneManager._previousScene != 5150)) {
+ setAction(NULL);
+ _sceneMode = 5150;
+ _soundHandler.startSound(208);
+
+ if (_globals->_inventory._vial._sceneNumber == 5100) {
+ _globals->_player.addMover(NULL);
+ _globals->_player.disableControl();
+ SceneItem::display2(5100, 39);
+ }
+
+ _hotspot2.setStrip2(1);
+ _hotspot3.setStrip2(2);
+
+ ObjectMover3 *mover1 = new ObjectMover3();
+ _hotspot2.addMover(mover1, 20, this);
+ ObjectMover3 *mover2 = new ObjectMover3();
+ _hotspot3.addMover(mover2, 20, this);
+ }
+
+ if (!_action) {
+ if (((_globals->_player._position.x - _hotspot2._position.x) < 130) && !_globals->getFlag(61)) {
+ _globals->_player._canWalk = false;
+ _globals->_player.addMover(NULL);
+
+ PlayerMover2 *mover = new PlayerMover2();
+ _hotspot3.addMover(mover, 20, 25, &_globals->_player);
+ setAction(&_action4);
+ }
+
+ if ((_globals->_sceneManager._scene->_backgroundBounds.right - 85) <= _globals->_player._position.x)
+ _globals->_sceneManager.changeScene(5000);
+
+ if (_globals->_player.getRegionIndex() == 8) {
+ _sceneMode = 5114;
+ setAction(&_sequenceManager, this, 5115, &_globals->_player, NULL);
+ }
+ }
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 5200 - Caverns - Throne Room
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene5200::Action1::signal() {
+ Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(59) + 120);
+ break;
+ case 1:
+ scene->_hotspot3.animate(ANIM_MODE_8, 1, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene5200::Action2::signal() {
+ Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ ADD_PLAYER_MOVER(92, 52);
+ break;
+ case 1:
+ _globals->_player.setVisage(5202);
+ _globals->_player._strip = 4;
+ _globals->_player._frame = 1;
+ _globals->_player.animate(ANIM_MODE_4, 3, 1, this);
+ break;
+ case 2:
+ scene->_soundHandler.proc3();
+ scene->_hotspot14.remove();
+
+ _globals->_inventory._stasisBox._sceneNumber = 1;
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ _globals->_player.setVisage(0);
+ _globals->_player._strip = 3;
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+
+ scene->_hotspot8.animate(ANIM_MODE_2, NULL);
+ ADD_MOVER(scene->_hotspot8, 141, 77);
+ break;
+ case 4:
+ scene->_soundHandler.startSound(303);
+
+ scene->_hotspot8._strip = 2;
+ scene->_hotspot8._frame = 1;
+ scene->_hotspot8.animate(ANIM_MODE_5, this);
+ break;
+ case 5:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene5200::Action3::signal() {
+ switch (_actionIndex++) {
+ _globals->_player.disableControl();
+ setDelay(5);
+ break;
+ case 1:
+ ADD_PLAYER_MOVER(285, 62);
+ break;
+ case 2:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene5200::Action4::signal() {
+ Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(120);
+ break;
+ case 1:
+ _globals->_soundHandler.startSound(209);
+ scene->_stripManager.start(5202, this, scene);
+ break;
+ case 2:
+ scene->_hotspot6.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ setDelay(10);
+ break;
+ case 4:
+ scene->_stripManager.start(5204, this, scene);
+ break;
+ case 5:
+ setDelay(60);
+ break;
+ case 6:
+ _globals->_sceneManager.changeScene(5100);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene5200::Hotspot9::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (!_state) {
+ ++_state;
+ SceneItem::display2(5200, 5);
+ } else {
+ SceneItem::display2(5200, 6);
+ }
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(5200, 14);
+ break;
+ default:
+ SceneItem::doAction(action);
+ break;
+ }
+}
+
+void Scene5200::Hotspot10::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (!_state) {
+ ++_state;
+ SceneItem::display2(5200, 7);
+ } else {
+ SceneItem::display2(5200, 8);
+ }
+ break;
+ default:
+ SceneItem::doAction(action);
+ break;
+ }
+}
+
+void Scene5200::Hotspot14::doAction(int action) {
+ Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5200, 4);
+ break;
+ case CURSOR_USE:
+ scene->setAction(&scene->_action2);
+ break;
+ default:
+ SceneItem::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene5200::Scene5200() :
+ _hotspot11(0, CURSOR_LOOK, 5200, 0, CURSOR_USE, 5200, 13, LIST_END),
+ _hotspot12(10, CURSOR_LOOK, 5200, 9, LIST_END),
+ _hotspot13(8, CURSOR_LOOK, 5200, 0, CURSOR_USE, 5200, 13, LIST_END) {
+}
+
+
+void Scene5200::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(0, 150, 199, 150);
+ _fieldA = 5600;
+ _fieldE = 5100;
+
+ _hotspot9._state = 0;
+ _hotspot10._state = 0;
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerGameText);
+ _stripManager.addSpeaker(&_speakerFLText);
+ _stripManager.addSpeaker(&_speakerFLL);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.setCallback(this);
+
+ _speakerFLText._textPos.x = 160;
+ _speakerQText._textPos.x = 20;
+
+ if (_globals->_inventory._stasisBox._sceneNumber == 5200) {
+ _soundHandler.startSound(216);
+ _soundHandler.proc5(true);
+
+ _hotspot14.postInit();
+ _hotspot14.setVisage(5202);
+ _hotspot14._strip = 3;
+ _hotspot14.setPosition(Common::Point(105, 52));
+ _hotspot14.setPriority2(90);
+
+ _hotspot8.postInit();
+ _hotspot8.setVisage(5202);
+ _hotspot8._strip = 1;
+ _hotspot8.setPosition(Common::Point(96, 53));
+ _hotspot8.setPriority2(90);
+ _globals->_sceneItems.push_back(&_hotspot14);
+ }
+
+ if (_globals->_stripNum == 1111) {
+ _globals->_soundHandler.startSound(205);
+ _globals->_player.disableControl();
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.changeZoom(75);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(3);
+ _globals->_player.setPosition(Common::Point(307, 62));
+
+ setAction(&_action3);
+ } else {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2640);
+ _globals->_player._strip = 1;
+ _globals->_player._frame = 4;
+ _globals->_player.setPosition(Common::Point(105, 199));
+
+ _hotspot5.postInit();
+ _hotspot5.setVisage(5210);
+ _hotspot5._frame = 2;
+ _hotspot5.setPosition(Common::Point(189, 167));
+
+ _hotspot6.postInit();
+ _hotspot6.setVisage(5210);
+ _hotspot6._frame = 1;
+ _hotspot6._strip = 2;
+ _hotspot6.setPosition(Common::Point(159, 137));
+
+ _hotspot7.postInit();
+ _hotspot7.setVisage(5210);
+ _hotspot7._frame = 1;
+ _hotspot7._strip = 4;
+ _hotspot7.setPriority2(168);
+ _hotspot7.setPosition(Common::Point(186, 106));
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(5212);
+ _hotspot1._frame = 1;
+ _hotspot1.setPosition(Common::Point(62, 132));
+
+ _hotspot2.postInit();
+ _hotspot2.setVisage(5212);
+ _hotspot2._strip = 3;
+ _hotspot2.setPosition(Common::Point(148, 141));
+ _hotspot2.setPriority2(90);
+
+ _hotspot3.postInit();
+ _hotspot3.setVisage(5212);
+ _hotspot3._strip = 2;
+ _hotspot3.setPosition(Common::Point(62, 109));
+ _hotspot3.setPriority2(138);
+ _hotspot3.setAction(&_action1);
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(5212);
+ _hotspot4._strip = 4;
+ _hotspot4.setPosition(Common::Point(146, 110));
+ _hotspot4.setPriority2(90);
+
+ _globals->_player.disableControl();
+ _globals->setFlag(61);
+
+ setAction(&_action4);
+ }
+
+ _hotspot11.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot9._sceneRegionId = 11;
+ _hotspot10._sceneRegionId = 9;
+
+ _globals->_sceneItems.addItems(&_hotspot12, &_hotspot13, &_hotspot9, &_hotspot10, &_hotspot11, NULL);
+ _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position);
+ loadScene(5200);
+}
+
+void Scene5200::stripCallback(int v) {
+ switch (v) {
+ case 1:
+ _hotspot7.animate(ANIM_MODE_2, NULL);
+ break;
+ case 2:
+ _hotspot7.animate(ANIM_MODE_NONE, NULL);
+ break;
+ }
+}
+
+void Scene5200::dispatch() {
+ Scene::dispatch();
+
+ if (!_action && (_globals->_player.getRegionIndex() == 12)) {
+ _globals->_stripNum = 5200;
+ _globals->_sceneManager.changeScene(5100);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 5300 - Caverns - Pit
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene5300::Action1::signal() {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ scene->_hotspot2._numFrames = 4;
+ scene->_hotspot2.animate(ANIM_MODE_8, 1, NULL);
+ setDelay(120);
+ break;
+ case 2:
+ scene->_hotspot2.animate(ANIM_MODE_NONE, NULL);
+
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.setStrip2(-1);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ ADD_MOVER(_globals->_player, 85, 170);
+ break;
+ case 3:
+ scene->_hotspot2.setPriority2(-1);
+ _globals->_player.checkAngle(&scene->_hotspot2);
+ setAction(&scene->_sequenceManager, this, 5305, &scene->_hotspot2, NULL);
+ break;
+ case 4:
+ scene->_stripManager.start(5316, this);
+ break;
+ case 5:
+ if (!_globals->getFlag(106) || !_globals->getFlag(107) || (_globals->_inventory._stasisBox._sceneNumber != 1)) {
+ _globals->_player.enableControl();
+ remove();
+ } else {
+ _globals->getFlag(60);
+
+ if (_globals->getFlag(67)) {
+ scene->_sceneMode = 5310;
+ scene->setAction(&scene->_sequenceManager, scene, 5310, &_globals->_player, &scene->_hotspot2, NULL);
+ } else {
+ scene->_sceneMode = 5347;
+ scene->setAction(&scene->_sequenceManager, scene, 5347, NULL);
+ }
+ }
+ break;
+ }
+}
+
+void Scene5300::Action2::signal() {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(60);
+ break;
+ case 1:
+ _globals->setFlag(60);
+ scene->_stripManager.start(5328, this);
+ break;
+ case 2:
+ if (_globals->_inventory._stasisBox._sceneNumber == 1) {
+ _globals->_stripNum = 5303;
+ setDelay(5);
+ } else {
+ _globals->_stripNum = 5302;
+ scene->_stripManager.start(5329, this);
+ }
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(5100);
+ remove();
+ break;
+ }
+}
+
+void Scene5300::Action3::signal() {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(30);
+ break;
+ case 1:
+ scene->_stripManager.start(_globals->_stripNum, this);
+ break;
+ case 2:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene5300::Hotspot1::doAction(int action) {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5300, 24);
+ break;
+ case CURSOR_TALK:
+ _globals->_stripNum = 5312;
+ scene->setAction(&scene->_action3);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5300::Hotspot2::doAction(int action) {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5300, 23);
+ break;
+ case CURSOR_USE:
+ if (!_globals->getFlag(106)) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5302;
+ scene->setAction(&scene->_sequenceManager, scene, 5302, &_globals->_player, NULL);
+ } else {
+ SceneItem::display2(5300, _globals->getFlag(107) ? 25 : 20);
+ }
+ break;
+ case CURSOR_TALK:
+ if (!_globals->getFlag(106)) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5302;
+ scene->setAction(&scene->_sequenceManager, scene, 5302, &_globals->_player, NULL);
+ } else if (!_globals->getFlag(107)) {
+ SceneItem::display2(5300, 11);
+ } else {
+ _globals->_player.disableControl();
+
+ if (_globals->_inventory._stasisBox._sceneNumber != 1) {
+ scene->setAction(&scene->_sequenceManager, scene, 5316, NULL);
+ } else {
+ _globals->setFlag(60);
+ scene->_sceneMode = _globals->getFlag(67) ? 5315 : 5347;
+ scene->setAction(&scene->_sequenceManager, scene, 5315, this);
+ }
+ }
+ break;
+ case OBJECT_SCANNER:
+ SceneItem::display2(5300, _globals->getFlag(107) ? 10 : 9);
+ break;
+ case OBJECT_MEDKIT:
+ if (_globals->getFlag(106))
+ SceneItem::display2(5300, 7);
+ else {
+ _globals->setFlag(106);
+ _globals->_player.disableControl();
+
+ scene->_sceneMode = 5303;
+ scene->setAction(&scene->_sequenceManager, scene, 5303, &_globals->_player, NULL);
+ }
+ break;
+ case OBJECT_VIAL:
+ if (_globals->getFlag(107)) {
+ SceneItem::display2(5300, 8);
+ } else {
+ _globals->_inventory._vial._sceneNumber = 5300;
+ _globals->setFlag(107);
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5304;
+
+ scene->setAction(&scene->_sequenceManager, scene, 5304, &_globals->_player, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5300::Hotspot5::doAction(int action) {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5300, 27);
+ break;
+ case CURSOR_USE:
+ _globals->_inventory._bone._sceneNumber = 1;
+ _globals->_player.disableControl();
+
+ scene->_sceneMode = 5309;
+ scene->setAction(&scene->_sequenceManager, scene, 5309, &_globals->_player, this, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5300::Hotspot6::doAction(int action) {
+ Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (!_globals->getFlag(105) || (_globals->_inventory._vial._sceneNumber == 1))
+ SceneItem::display2(5300, 4);
+ else
+ SceneItem::display2(5300, 26);
+ break;
+ case CURSOR_USE:
+ if (!_globals->getFlag(105) || (_globals->_inventory._vial._sceneNumber != 5100)) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5301;
+ scene->setAction(&scene->_sequenceManager, scene, 5301, &_globals->_player, NULL);
+ } else {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 5307;
+ _globals->_inventory._vial._sceneNumber = 1;
+
+ scene->setAction(&scene->_sequenceManager, scene, 5307, &scene->_hotspot1, &_globals->_player,
+ &scene->_hotspot4, NULL);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5300::Hotspot7::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(63))
+ SceneItem::display2(5300, 2);
+ else {
+ _globals->setFlag(63);
+ SceneItem::display2(5300, 0);
+ SceneItem::display2(5300, 1);
+ }
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(64))
+ SceneItem::display2(5300, 15);
+ else {
+ _globals->setFlag(64);
+ SceneItem::display2(5300, 14);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene5300::Hotspot8::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display2(5300, _globals->getFlag(65) ? 6 : 5);
+ break;
+ case CURSOR_USE:
+ SceneItem::display2(5300, 18);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene5300::Scene5300() :
+ _hotspot3(0, CURSOR_LOOK, 5300, 3, CURSOR_USE, 5300, 16, LIST_END) {
+}
+
+void Scene5300::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ loadScene(5300);
+ setZoomPercents(0, 100, 199, 100);
+
+ _stripManager.addSpeaker(&_speakerQR);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerBatR);
+ _stripManager.addSpeaker(&_speakerSR);
+ _stripManager.addSpeaker(&_speakerSL);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerBatText);
+ _stripManager.addSpeaker(&_speakerSText);
+ _stripManager.addSpeaker(&_speakerGameText);
+
+ if (_globals->getFlag(106) && _globals->getFlag(107)) {
+ _hotspot2.postInit();
+ _hotspot2.setVisage(2806);
+ _hotspot2.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot2.setPosition(Common::Point(63, 170));
+ _hotspot2.animate(ANIM_MODE_1, NULL);
+ } else {
+ _hotspot2.postInit();
+ _hotspot2.setVisage(5310);
+ _hotspot2.setPosition(Common::Point(63, 170));
+ _hotspot2.animate(ANIM_MODE_1, NULL);
+ _hotspot2.setPriority2(98);
+ }
+
+ _hotspot1.postInit();
+ _hotspot1.setVisage(5362);
+ _hotspot1.setStrip2(3);
+ _hotspot1.setFrame2(5);
+ _hotspot1.setPosition(Common::Point(76, 48));
+
+ _hotspot4.postInit();
+ _hotspot4.setVisage(5316);
+ _hotspot4.setStrip(2);
+ _hotspot4.setPosition(Common::Point(89, 65));
+ _hotspot4.animate(ANIM_MODE_2, NULL);
+ _hotspot4.hide();
+
+ if (_globals->getFlag(67)) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(5316);
+ _globals->_player.setPosition(Common::Point(191, 27));
+ _globals->_player.disableControl();
+
+ if (_globals->getFlag(107) && _globals->getFlag(106)) {
+ _hotspot2.postInit();
+ _hotspot2.setObjectWrapper(new SceneObjectWrapper());
+ _hotspot2.animate(ANIM_MODE_1, NULL);
+
+ setAction(&_action2);
+ } else {
+ _globals->_player.setVisage(5315);
+ _globals->_player.setPosition(Common::Point(204, 86));
+ _globals->_player.animate(ANIM_MODE_2, NULL);
+ _globals->_player.setStrip2(1);
+ _globals->_player._moveDiff.y = 12;
+
+ _sceneMode = 5308;
+ setAction(&_sequenceManager, this, 5308, &_globals->_player, NULL);
+ }
+ } else {
+ _hotspot3.postInit();
+ _hotspot3.setVisage(5301);
+ _hotspot3.setPosition(Common::Point(172, 32));
+ _hotspot3.setPriority2(1);
+ _hotspot3.animate(ANIM_MODE_NONE, NULL);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(5315);
+ _globals->_player.setPosition(Common::Point(204, 86));
+ _globals->_player.animate(ANIM_MODE_2, NULL);
+ _globals->_player.setStrip2(1);
+ _globals->_player._moveDiff.y = 12;
+ _globals->_player.disableControl();
+
+ _sceneMode = 5306;
+ setAction(&_sequenceManager, this, 5306, &_globals->_player, &_hotspot3, NULL);
+ }
+
+ _field1B0A = 1;
+ if (_globals->_inventory._bone._sceneNumber == 5300) {
+ _hotspot5.postInit();
+ _hotspot5.setVisage(5301);
+ _hotspot5.setStrip(2);
+ _hotspot5.setPosition(Common::Point(190, 147));
+ _globals->_sceneItems.push_back(&_hotspot5);
+ }
+
+ _hotspot6.setBounds(Rect(74, 51, 114, 69));
+ _hotspot7.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _hotspot8._sceneRegionId = 8;
+
+ _globals->_sceneItems.addItems(&_hotspot8, &_hotspot2, &_hotspot6, &_hotspot3, &_hotspot7, NULL);
+ _globals->_soundHandler.startSound(212);
+}
+
+void Scene5300::signal() {
+ switch (_sceneMode) {
+ case 5301:
+ _globals->_stripNum = 5300;
+ _globals->_sceneManager.changeScene(5100);
+ break;
+ case 5302:
+ case 5308:
+ case 5316:
+ case 5347:
+ _globals->_player.setStrip2(-1);
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.enableControl();
+ break;
+ case 5303:
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.enableControl();
+
+ if (_globals->getFlag(107))
+ setAction(&_action1);
+ else
+ SceneItem::display2(5300, 28);
+ break;
+ case 5304:
+ _globals->_player.animate(ANIM_MODE_1, NULL);
+ _globals->_player.enableControl();
+
+ if (_globals->getFlag(106))
+ setAction(&_action1);
+ else
+ SceneItem::display2(5300, 28);
+ break;
+ case 5306:
+ _globals->clearFlag(67);
+ _globals->_player.setStrip2(-1);
+
+ if ((_globals->_inventory._vial._sceneNumber == 1) || (_globals->_inventory._vial._sceneNumber == 5300))
+ _stripManager.start(5303, this);
+ else
+ _stripManager.start(5302, this);
+ _sceneMode = 5302;
+ break;
+ case 5307:
+ _soundHandler.proc1(NULL);
+ break;
+ case 5309:
+ _hotspot5.remove();
+ _globals->_player.enableControl();
+ break;
+ case 5310:
+ _hotspot2.setPriority2(41);
+ _sceneMode = 5315;
+
+ setAction(&_sequenceManager, this, 5315, &_hotspot2, NULL);
+ break;
+ case 5315:
+ _globals->_stripNum = 5315;
+ _globals->_sceneManager.changeScene(5100);
+ break;
+ }
+}
+
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes6.h b/engines/tsage/ringworld_scenes6.h
new file mode 100644
index 0000000000..272aea4fe9
--- /dev/null
+++ b/engines/tsage/ringworld_scenes6.h
@@ -0,0 +1,333 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES6_H
+#define TSAGE_RINGWORLD_SCENES6_H
+
+#include "common/scummsys.h"
+#include "tsage/ringworld_logic.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+class Scene5000 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ virtual void dispatch();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot7 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class HotspotGroup1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SoundHandler _soundHandler;
+ SpeakerSText _speakerSText;
+ SpeakerQText _speakerQText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ DisplayHotspot _hotspot1;
+ SceneObject _hotspot2, _hotspot3, _hotspot4, _hotspot5, _hotspot6;
+ Hotspot7 _hotspot7;
+ Hotspot8 _hotspot8;
+ HotspotGroup1 _hotspot9, _hotspot10, _hotspot11;
+ DisplayHotspot _hotspot12, _hotspot13, _hotspot14, _hotspot15;
+ DisplayHotspot _hotspot16, _hotspot17, _hotspot18;
+
+ Scene5000();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene5100 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class HotspotGroup1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class HotspotGroup2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot4 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot9 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot17 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot18 : public SceneHotspot {
+ public:
+ int _index1;
+ int _index2;
+
+ virtual void doAction(int action);
+ };
+ class Hotspot19 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot20 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SequenceManager _sequenceManager;
+ SoundHandler _soundHandler;
+ SpeakerMText _speakerMText;
+ SpeakerQText _speakerQText;
+ SpeakerSText _speakerSText;
+ SpeakerBatText _speakerBatText;
+ SpeakerGameText _speakerGameText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ HotspotGroup1 _hotspot1, _hotspot2, _hotspot3;
+ Hotspot4 _hotspot4;
+ HotspotGroup2 _hotspot5, _hotspot6, _hotspot7;
+ SceneObject _hotspot8;
+ Hotspot9 _hotspot9;
+ SceneObject _hotspot10, _hotspot11, _hotspot12, _hotspot13, _hotspot14, _hotspot15;
+ DisplayHotspot _hotspot16;
+ Hotspot17 _hotspot17;
+ Hotspot18 _hotspot18;
+ Hotspot19 _hotspot19;
+ Hotspot20 _hotspot20;
+ DisplayHotspot _hotspot21;
+
+ Scene5100();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene5200 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot9 : public SceneItemExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot10 : public SceneItemExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot14 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler;
+ SpeakerFLL _speakerFLL;
+ SpeakerFLText _speakerFLText;
+ SpeakerQL _speakerQL;
+ SpeakerQText _speakerQText;
+ SpeakerGameText _speakerGameText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+
+ SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5, _hotspot6, _hotspot7;
+ SceneObject _hotspot8;
+ Hotspot9 _hotspot9;
+ Hotspot10 _hotspot10;
+ DisplayHotspot _hotspot11, _hotspot12, _hotspot13;
+ Hotspot14 _hotspot14;
+
+ Scene5200();
+ virtual void stripCallback(int v);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void dispatch();
+};
+
+class Scene5300 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Hotspots */
+ class Hotspot1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot2 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot5 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot6 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot7 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Hotspot8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager;
+ SpeakerQR _speakerQR;
+ SpeakerQL _speakerQL;
+ SpeakerQText _speakerQText;
+ SpeakerBatR _speakerBatR;
+ SpeakerBatText _speakerBatText;
+ SpeakerSR _speakerSR;
+ SpeakerSL _speakerSL;
+ SpeakerSText _speakerSText;
+ SpeakerGameText _speakerGameText;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Hotspot1 _hotspot1;
+ Hotspot2 _hotspot2;
+ DisplayHotspot _hotspot3;
+ SceneObject _hotspot4;
+ Hotspot5 _hotspot5;
+ Hotspot6 _hotspot6;
+ Hotspot7 _hotspot7;
+ Hotspot8 _hotspot8;
+ int _field1B0A;
+
+ Scene5300();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void synchronise(Serialiser &s) {
+ Scene::synchronise(s);
+ s.syncAsSint16LE(_field1B0A);
+ }
+};
+
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/ringworld_scenes8.cpp b/engines/tsage/ringworld_scenes8.cpp
new file mode 100644
index 0000000000..416b7fe0fd
--- /dev/null
+++ b/engines/tsage/ringworld_scenes8.cpp
@@ -0,0 +1,2508 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "graphics/cursorman.h"
+#include "tsage/ringworld_scenes8.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+/*--------------------------------------------------------------------------
+ * Scene 7000
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene7000::Action1::signal() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ setAction(&scene->_action6, this);
+ break;
+ case 2:
+ scene->_soundHandler.startSound(252, 0, 127);
+ scene->_object8.remove();
+ scene->_object1.postInit();
+ scene->_object1.setVisage(7003);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ scene->_object1.setPosition(Common::Point(151, 182), 0);
+ scene->_object1.setPriority2(205);
+ _globals->_sceneItems.push_front(&scene->_object1);
+ break;
+ case 3:
+ scene->_object1.setStrip(4);
+ scene->_object1.animate(ANIM_MODE_8, 0, 0);
+ scene->_stripManager.start(7005, this);
+ break;
+ case 4:
+ scene->_object1.animate(ANIM_MODE_2, 0);
+ setDelay(3);
+ break;
+ case 5:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action2::signal() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ _globals->_player.addMover(0, 0);
+ _globals->_player.setVisage(7006);
+ _globals->_player.setStrip(1);
+ _globals->_player.setFrame(1);
+ _globals->_player.setPosition(Common::Point(_globals->_player._position.x, _globals->_player._position.y + 13));
+ _globals->_player.changeZoom(68);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ scene->_object1.remove();
+ break;
+ case 2:
+ _globals->_sceneManager.changeScene(7100);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action3::dispatch() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ Action::dispatch();
+ if (_actionIndex == 4)
+ scene->_object4.setPosition(Common::Point(scene->_object3._position.x, scene->_object3._position.y));
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action3::signal() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ scene->setZoomPercents(10, 10, 62, 100);
+ scene->_object4.postInit();
+ scene->_object4.setVisage(5001);
+ scene->_object4.setStrip2(2);
+ scene->_object4.animate(ANIM_MODE_8, 0, 0);
+ scene->_object4.setPosition(Common::Point(10, 18), 0);
+ scene->_object4.setPriority2(10);
+ scene->_object4.changeZoom(100);
+ scene->_object4.hide();
+ break;
+ case 1: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(107, 65);
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ scene->_object3.setPriority2(10);
+ scene->_object4.setPosition(Common::Point(scene->_object3._position.x, scene->_object3._position.y + 15), 0);
+ scene->_object4.show();
+ setDelay(30);
+ break;
+ case 3: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(107, 92);
+ scene->_object3.addMover(mover, &pt, this);
+ break;
+ }
+ case 4:
+ scene->_object4.remove();
+ _globals->_sceneManager.changeScene(2100);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action4::signal() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 1:
+ scene->_object1.hide();
+ setDelay(300);
+ break;
+ case 2:
+ _globals->_soundHandler.startSound(252, 0, 127);
+ scene->_object1.show();
+ scene->_object1.setStrip(3);
+ scene->_object1.setFrame(1);
+ scene->_object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ scene->_object1.setStrip(1);
+ scene->_object1.animate(ANIM_MODE_8, 0, 0);
+ _globals->setFlag(81);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action5::signal() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0: {
+ NpcMover *playerMover = new NpcMover();
+ Common::Point pt(88, 121);
+ _globals->_player.addMover(playerMover, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_player.checkAngle(&scene->_object1);
+ _globals->_soundHandler.startSound(252, 0, 127);
+ scene->_object1.setStrip(2);
+ scene->_stripManager.start(7015, this);
+ break;
+ case 2:
+ scene->_object1.setStrip(1);
+ scene->_object1.setFrame(4);
+ scene->_object1.animate(ANIM_MODE_6, this);
+ break;
+ case 3: {
+ scene->_object1.remove();
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(31, 94);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(11, 94);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ _globals->_player.setPriority2(10);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(11, 89);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(41, 89);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 7:
+ _globals->clearFlag(36);
+ _globals->clearFlag(37);
+ _globals->clearFlag(72);
+ _globals->clearFlag(13);
+ _globals->_sceneManager.changeScene(2100);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action6::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(12, 91);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(8, 91);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(31, 96);
+ _globals->_player.addMover(mover, &pt, this);
+ _globals->_player.setPriority2(-1);
+ break;
+ }
+ case 4: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(83, 117);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(95, 121);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6:
+ _globals->_player.setStrip(3);
+ _globals->_player.setFrame(1);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Action7::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ _globals->_player.disableControl();
+ setDelay(3);
+ break;
+ case 1:
+ setDelay(3);
+ break;
+ case 2: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(31, 94);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(11, 94);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ _globals->_player.setPriority2(10);
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(11, 89);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(41, 89);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 6:
+ if (_globals->getFlag(13))
+ _globals->_sceneManager.changeScene(2280);
+ else
+ _globals->_sceneManager.changeScene(2320);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::SceneItem1::doAction(int action) {
+ if (action == CURSOR_LOOK)
+ SceneItem::display(7000, 2, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+
+ SceneItem::doAction(action);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::Object1::doAction(int action) {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_TRANSLATOR:
+ _globals->_player.disableControl();
+ _globals->_inventory._translator._sceneNumber = 7000;
+ if (_globals->_inventory._waldos._sceneNumber == 7000) {
+ if (_globals->_inventory._jar._sceneNumber == 7000) {
+ scene->_sceneMode = 7012;
+ scene->setAction(&scene->_sequenceManager, scene, 7010, &_globals->_player, &scene->_object1, 0, 0);
+ } else {
+ scene->_sceneMode = 7015;
+ scene->setAction(&scene->_sequenceManager, scene, 7017, &_globals->_player, 0, 0);
+ }
+ } else {
+ if (_globals->_inventory._jar._sceneNumber == 7000) {
+ scene->_sceneMode = 7011;
+ scene->setAction(&scene->_sequenceManager, scene, 7010, &_globals->_player, &scene->_object1, 0, 0);
+ } else {
+ scene->_sceneMode = 7004;
+ scene->setAction(&scene->_sequenceManager, scene, 7004, &_globals->_player, this, 0, 0);
+ }
+ }
+ break;
+ case OBJECT_WALDOS:
+ _globals->_player.disableControl();
+ _globals->_inventory._waldos._sceneNumber = 7000;
+ if (_globals->_inventory._translator._sceneNumber == 7000) {
+ if (_globals->_inventory._jar._sceneNumber == 7000) {
+ scene->_sceneMode = 7015;
+ scene->setAction(&scene->_sequenceManager, scene, 7015, &_globals->_player, 0, 0);
+ } else {
+ scene->_sceneMode = 7006;
+ scene->setAction(&scene->_sequenceManager, scene, 7006, &_globals->_player, 0, 0);
+ }
+ } else {
+ scene->_sceneMode = 7009;
+ scene->setAction(&scene->_sequenceManager, scene, 7009, &_globals->_player, 0, 0);
+ }
+ break;
+ case OBJECT_JAR:
+ _globals->_player.disableControl();
+ _globals->_inventory._jar._sceneNumber = 7000;
+ if (_globals->_inventory._translator._sceneNumber == 7000) {
+ if (_globals->_inventory._waldos._sceneNumber == 7000) {
+ scene->_sceneMode = 7007;
+ scene->setAction(&scene->_sequenceManager, scene, 7007, &_globals->_player, &scene->_object1, 0, 0);
+ } else {
+ scene->_sceneMode = 7015;
+ scene->setAction(&scene->_sequenceManager, scene, 7016, &_globals->_player, 0, 0);
+ }
+ } else {
+ scene->_sceneMode = 7008;
+ scene->setAction(&scene->_sequenceManager, scene, 7008, &_globals->_player, 0, 0);
+ }
+ break;
+ case CURSOR_LOOK:
+ if (_globals->getFlag(81))
+ SceneItem::display(7000, 1, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneItem::display(7000, 0, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(81)) {
+ _globals->_inventory._stasisBox._sceneNumber = 1;
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action5);
+ } else {
+ SceneItem::display(7000, 5, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+ break;
+ case CURSOR_TALK:
+ if (_globals->getFlag(81)) {
+ _globals->_inventory._stasisBox._sceneNumber = 1;
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action5);
+ } else if (_globals->getFlag(52)) {
+ scene->_sceneMode = 7005;
+ scene->setAction(&scene->_sequenceManager, scene, 7013, 0, 0);
+ } else if (_globals->getFlag(13)) {
+ _globals->_sceneManager._sceneNumber = 7002;
+ scene->setAction(&scene->_sequenceManager, scene, 7014, 0, 0);
+ } else {
+ _globals->_sceneManager._sceneNumber = 7002;
+ scene->setAction(&scene->_sequenceManager, scene, 7002, 0, 0);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::dispatch() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+
+ if (!_action) {
+ if (_globals->_sceneRegions.indexOf(_globals->_player._position) == 8) {
+ if (!_globals->getFlag(13)) {
+ _globals->_player.disableControl();
+ _globals->_player.addMover(0);
+ SceneItem::display(7000, 3, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ _sceneMode = 7001;
+ setAction(&scene->_sequenceManager, this, 7001, &_globals->_player, NULL);
+ } else if (!_globals->getFlag(52)) {
+ setAction(&_action2);
+ } else {
+ _globals->_player.disableControl();
+ _sceneMode = 7003;
+ setAction(&scene->_sequenceManager, this, 7003, &_globals->_player, 0);
+ }
+ }
+ if (_globals->_sceneRegions.indexOf(_globals->_player._position) == 9)
+ scene->setAction(&scene->_action7);
+ }
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::postInit(SceneObjectList *OwnerList) {
+ loadScene(7000);
+ Scene::postInit();
+ setZoomPercents(93, 25, 119, 55);
+ _stripManager.addSpeaker(&_speakerSKText);
+ _stripManager.addSpeaker(&_speakerSKL);
+ _stripManager.addSpeaker(&_speakerQText);
+ _stripManager.addSpeaker(&_speakerQL);
+ _stripManager.addSpeaker(&_speakerQR);
+
+ _speakerSKText._npc = &_object1;
+ _speakerQText._npc = &_globals->_player;
+
+ _object5.postInit();
+ _object5.setVisage(7001);
+ _object5.setStrip2(1);
+ _object5.animate(ANIM_MODE_2, 0);
+ _object5.setPosition(Common::Point(49, 147), 0);
+ _object5.setPriority2(1);
+
+ _object6.postInit();
+ _object6.setVisage(7001);
+ _object6.setStrip2(2);
+ _object6.animate(ANIM_MODE_2, 0);
+ _object6.setPosition(Common::Point(160, 139), 0);
+ _object6.setPriority2(1);
+
+ _object7.postInit();
+ _object7.setVisage(7001);
+ _object7.setStrip2(3);
+ _object7.animate(ANIM_MODE_2, 0);
+ _object7.setPosition(Common::Point(272, 129), 0);
+ _object7.setPriority2(1);
+
+ _object8.postInit();
+ _object8.setVisage(7001);
+ _object8.setStrip2(4);
+ _object8.animate(ANIM_MODE_2, 0);
+ _object8.setPosition(Common::Point(176, 175), 0);
+ _object8.setPriority2(1);
+
+ if (_globals->getFlag(72)) {
+ _object3.postInit();
+ _object3.setVisage(5001);
+ _object3.setStrip2(1);
+ _object3.animate(ANIM_MODE_2, 0);
+ _object3.setPosition(Common::Point(107, 92), 0);
+ _object3.changeZoom(100);
+ _object3.setPriority2(10);
+
+ _object1.postInit();
+ _object1.setVisage(7003);
+ if (_globals->getFlag(81))
+ _object1.setStrip(4);
+ else
+ _object1.setStrip(2);
+ _object1.setPosition(Common::Point(87, 129), 0);
+ _object1._numFrames = 4;
+ _object1.changeZoom(45);
+ _object1.animate(ANIM_MODE_8, 0, 0);
+ _globals->_sceneItems.addItems(&_object1, 0);
+ }
+ _soundHandler.startSound(251, 0, 127);
+ if (_globals->_sceneManager._previousScene == 2100) {
+ if (_globals->getFlag(72)) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ SceneObjectWrapper *wrapper = new SceneObjectWrapper();
+ _globals->_player.setObjectWrapper(wrapper);
+ _globals->_player.setPosition(Common::Point(57, 94), 0);
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setPriority2(10);
+ if (_globals->getFlag(81)) {
+ setAction(&_action4);
+ } else {
+ _object1.setPosition(Common::Point(151, 182), 0);
+ setAction(&_action1);
+ }
+ } else {
+ _globals->_soundHandler.startSound(250, 0, 127);
+ _globals->setFlag(72);
+
+ _object3.postInit();
+ _object3.setVisage(5001);
+ _object3.setStrip2(1);
+ _object3.animate(ANIM_MODE_1, 0);
+ _object3.setPosition(Common::Point(307, 0), 0);
+ _object3.changeZoom(-1);
+ setAction(&_action3);
+ }
+ } else if (_globals->_sceneManager._previousScene == 2280) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2170);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ SceneObjectWrapper *wrapper = new SceneObjectWrapper();
+ _globals->_player.setObjectWrapper(wrapper);
+ _globals->_player.setPosition(Common::Point(57, 94), 0);
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setPriority2(10);
+ _globals->_player.disableControl();
+ _sceneMode = 7001;
+ setAction(&_action6, this);
+ if (!_globals->getFlag(81)) {
+ _object1.setPosition(Common::Point(151, 182), 0);
+ _object1.changeZoom(100);
+ }
+ _object8.remove();
+ _object9.remove();
+ } else if (_globals->_sceneManager._previousScene == 2320) {
+ _globals->_player.postInit();
+ _globals->_player.setVisage(0);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ SceneObjectWrapper *wrapper = new SceneObjectWrapper();
+ _globals->_player.setObjectWrapper(wrapper);
+ _globals->_player.setPosition(Common::Point(57, 94), 0);
+ _globals->_player.changeZoom(-1);
+ _globals->_player.setPriority2(10);
+ _sceneMode = 7001;
+ setAction(&_action6, this);
+ } else {
+ _globals->setFlag(72);
+
+ _object3.postInit();
+ _object3.setVisage(5001);
+ _object3.setStrip2(1);
+ _object3.setPosition(Common::Point(307, 0), 0);
+ _soundHandler.startSound(151, 0, 127);
+ _soundHandler.proc5(1);
+ _globals->_soundHandler.startSound(250, 0, 127);
+ setAction(&_action3);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7000::signal() {
+ Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene;
+ switch (_sceneMode) {
+ case 7001:
+ case 7002:
+ case 7004:
+ case 7009:
+ _globals->_player.enableControl();
+ break;
+ case 7003:
+ _sceneMode = 7001;
+ setAction(&scene->_sequenceManager, this, 7001, &_globals->_player, NULL);
+ break;
+ case 7011:
+ _sceneMode = 7005;
+ setAction(&scene->_sequenceManager, this, 7005, &_globals->_player, NULL);
+ break;
+ case 7012:
+ _sceneMode = 7005;
+ setAction(&scene->_sequenceManager, this, 7012, &_globals->_player, NULL);
+ break;
+ case 7015:
+ setAction(&_action4);
+ break;
+ }
+}
+
+
+/*--------------------------------------------------------------------------
+ * Scene 7100
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene7100::Action3::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ break;
+ case 1: {
+ Common::Point pt(433, 308);
+ NpcMover *mover = new NpcMover();
+ scene->_object4.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ scene->_object4.remove();
+ remove();
+ break;
+ }
+}
+
+void Scene7100::Action4::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(1) + 1);
+ break;
+ case 1: {
+ scene->_object5.setStrip(3);
+ Common::Point pt(85, 52);
+ NpcMover *mover = new NpcMover();
+ scene->_object5.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_object5.setStrip(4);
+ Common::Point pt(20, 52);
+ NpcMover *mover = new NpcMover();
+ scene->_object5.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _actionIndex = 0;
+ setDelay(1);
+ break;
+ }
+}
+
+void Scene7100::Action5::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ break;
+ case 1: {
+ Common::Point pt(59, 151);
+ NpcMover *mover = new NpcMover();
+ scene->_object9.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_object9.setStrip2(1);
+ Common::Point pt(127, 144);
+ NpcMover *mover = new NpcMover();
+ scene->_object9.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ scene->_object9.setStrip2(2);
+ scene->_object9.setPriority2(180);
+ Common::Point pt(8, 181);
+ NpcMover *mover = new NpcMover();
+ scene->_object9.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ scene->_object9.remove();
+ remove();
+ }
+ }
+}
+
+void Scene7100::Action6::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ scene->_object10.setPriority2(8);
+ scene->_object10.setPosition(Common::Point(155, 187), 0);
+
+ scene->_object11.setPriority2(8);
+ scene->_object11.setPosition(Common::Point(155, 190), 0);
+
+ scene->_object12.setPriority2(8);
+ scene->_object12.setPosition(Common::Point(151, 193), 0);
+ break;
+ case 1: {
+ Common::Point pt1(167, 187);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object10.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(165, 185);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object11.addMover(mover2, &pt2, 0);
+
+ Common::Point pt3(163, 183);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object12.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 2: {
+ scene->_object10.setStrip2(6);
+ Common::Point pt1(91, 187);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object10.addMover(mover1, &pt1, this);
+
+ scene->_object11.setStrip2(6);
+ scene->_object11.setPriority2(50);
+ Common::Point pt2(89, 185);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object11.addMover(mover2, &pt2, 0);
+
+ scene->_object12.setStrip2(6);
+ scene->_object12.setPriority2(50);
+ Common::Point pt3(87, 183);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object12.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 3:
+ _actionIndex = 0;
+ setDelay(1);
+ break;
+ }
+}
+
+void Scene7100::Action7::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ break;
+ case 1: {
+ scene->_object13.setStrip2(8);
+ Common::Point pt(324, 87);
+ NpcMover *mover = new NpcMover();
+ scene->_object13.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_object13.setStrip2(2);
+ Common::Point pt(524, 104);
+ NpcMover *mover = new NpcMover();
+ scene->_object13.addMover(mover, &pt, 0);
+ break;
+ }
+ case 3:
+ _actionIndex = 0;
+ setDelay(1);
+ break;
+ }
+}
+
+void Scene7100::Action8::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ break;
+ case 1: {
+ scene->_object17.setStrip2(4);
+ scene->_object18.setStrip2(4);
+ scene->_object19.setStrip2(4);
+
+ Common::Point pt1(482, 153);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object17.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(480, 146);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object18.addMover(mover2, &pt2, 0);
+
+ Common::Point pt3(470, 153);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object19.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 2: {
+ scene->_object17.setStrip2(3);
+ scene->_object18.setStrip2(3);
+ scene->_object19.setStrip2(3);
+
+ Common::Point pt1(506, 186);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object17.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(502, 179);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object18.addMover(mover2, &pt2, 0);
+
+ Common::Point pt3(495, 184);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object19.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 3: {
+ scene->_object17.setStrip2(4);
+ scene->_object18.setStrip2(4);
+ scene->_object19.setStrip2(4);
+
+ Common::Point pt1(386, 167);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object17.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(379, 161);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object18.addMover(mover2, &pt2, 0);
+
+ Common::Point pt3(373, 167);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object19.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 4: {
+ scene->_object17.setStrip2(3);
+ scene->_object18.setStrip2(3);
+ scene->_object19.setStrip2(3);
+
+ Common::Point pt1(479, 193);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object17.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(473, 187);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object18.addMover(mover2, &pt2, 0);
+
+ Common::Point pt3(466, 192);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object19.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 5: {
+ Common::Point pt1(552, 183);
+ NpcMover *mover1 = new NpcMover();
+ scene->_object17.addMover(mover1, &pt1, this);
+
+ Common::Point pt2(552, 178);
+ NpcMover *mover2 = new NpcMover();
+ scene->_object18.addMover(mover2, &pt2, 0);
+
+ Common::Point pt3(541, 183);
+ NpcMover *mover3 = new NpcMover();
+ scene->_object19.addMover(mover3, &pt3, 0);
+
+ _actionIndex = 0;
+ break;
+ }
+ }
+}
+
+void Scene7100::Action9::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1);
+ break;
+ case 1: {
+ scene->_object24.setStrip2(1);
+ Common::Point pt(64, 159);
+ NpcMover *mover = new NpcMover();
+ scene->_object24.addMover(mover, &pt, this);
+ break;
+ }
+ case 2: {
+ scene->_object24.setStrip2(2);
+ scene->_object24.setPriority2(160);
+ Common::Point pt(34, 159);
+ NpcMover *mover = new NpcMover();
+ scene->_object24.addMover(mover, &pt, this);
+ break;
+ }
+ case 3: {
+ scene->_object24.setStrip2(1);
+ Common::Point pt(64, 159);
+ NpcMover *mover = new NpcMover();
+ scene->_object24.addMover(mover, &pt, this);
+ break;
+ }
+ case 4: {
+ scene->_object24.setStrip2(2);
+ scene->_object24.setPriority2(180);
+ Common::Point pt(-12, 182);
+ NpcMover *mover = new NpcMover();
+ scene->_object24.addMover(mover, &pt, this);
+ break;
+ }
+ case 5: {
+ _actionIndex = 0;
+ setDelay(1);
+ break;
+ }
+ }
+}
+
+void Scene7100::Action10::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(1000);
+ break;
+ case 1: {
+ Common::Point pt(610, -60);
+ NpcMover *mover = new NpcMover();
+ scene->_object25.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ scene->_object25.remove();
+ remove();
+ break;
+ }
+}
+
+void Scene7100::Action11::signal() {
+ Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1: {
+ Common::Point pt(154, 175);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ ObjectMover2 *mover2 = new ObjectMover2();
+ scene->_object1.addMover(mover2, 25, 35, &_globals->_player);
+ break;
+ }
+ case 2: {
+ Common::Point pt(700, 155);
+ NpcMover *mover = new NpcMover();
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 3:
+ _globals->_sceneManager.changeScene(7200);
+ remove();
+ break;
+ }
+}
+
+void Scene7100::postInit(SceneObjectList *OwnerList) {
+ loadScene(7100);
+ Scene::postInit();
+ setZoomPercents(60, 85, 200, 100);
+
+ _object2.postInit();
+ _object2.setVisage(7161);
+ _object2.animate(ANIM_MODE_2, 0);
+ _object2.setPosition(Common::Point(10, 140), 0);
+ _object2._numFrames = 1;
+ _object2.setPriority2(180);
+ _object2.setAction(&_action1, 0);
+
+ _object3.postInit();
+ _object3.setVisage(7161);
+ _object3.animate(ANIM_MODE_2, 0);
+ _object3.setPosition(Common::Point(34, 115), 0);
+ _object3._numFrames = 1;
+ _object3.setPriority2(180);
+ _object3.setAction(&_action2, 0);
+
+ _object4.postInit();
+ _object4.setVisage(7164);
+ _object4.animate(ANIM_MODE_2, 0);
+ _object4.setPosition(Common::Point(-10, 159), 0);
+ _object4._numFrames = 2;
+ _object4.setPriority2(250);
+ _object4.setAction(&_action3, 0);
+
+ _object5.postInit();
+ _object5.setVisage(7162);
+ _object5.setStrip(3);
+ _object5.animate(ANIM_MODE_2, 0);
+ _object5.setPosition(Common::Point(20, 52), 0);
+ _object5.setAction(&_action4, 0);
+
+ _object9.postInit();
+ _object9.setVisage(7160);
+ _object5.setStrip(2);
+ _object9.animate(ANIM_MODE_2, 0);
+ _object9.setPosition(Common::Point(110, 168), 0);
+ _object9._numFrames = 2;
+ _object9.setPriority2(16);
+ _object9.setAction(&_action5, 0);
+
+ _object13.postInit();
+ _object13.setVisage(7161);
+ _object13.setStrip(8);
+ _object13.animate(ANIM_MODE_2, 0);
+ _object13.setPosition(Common::Point(524, 104), 0);
+ _object13._numFrames = 5;
+ _object13.setPriority2(250);
+ _object13.setAction(&_action7, 0);
+
+ _object17.postInit();
+ _object17.setVisage(7160);
+ _object17.setStrip(3);
+ _object17.animate(ANIM_MODE_2, 0);
+ _object17.setPosition(Common::Point(552, 183), 0);
+ _object17._numFrames = 4;
+ _object17._moveDiff.x = 12;
+ _object17._moveDiff.y = 12;
+ _object17.setAction(&_action8, 0);
+
+ _object18.postInit();
+ _object18.setVisage(7160);
+ _object18.setStrip(3);
+ _object18.animate(ANIM_MODE_2, 0);
+ _object18.setPosition(Common::Point(552, 178), 0);
+ _object18._numFrames = 4;
+ _object18._moveDiff.x = 12;
+ _object18._moveDiff.y = 12;
+
+ _object19.postInit();
+ _object19.setVisage(7160);
+ _object19.setStrip(3);
+ _object19.animate(ANIM_MODE_2, 0);
+ _object19.setPosition(Common::Point(541, 183), 0);
+ _object19._numFrames = 4;
+ _object19._moveDiff.x = 12;
+ _object19._moveDiff.y = 12;
+
+ _object24.postInit();
+ _object24.setVisage(7162);
+ _object24.setStrip(1);
+ _object24.animate(ANIM_MODE_2, 0);
+ _object24.setPosition(Common::Point(-12, 182), 0);
+ _object24._numFrames = 4;
+ _object24.setPriority2(180);
+ _object24.setAction(&_action9, 0);
+
+ _object25.postInit();
+ _object25.setVisage(7163);
+ _object25.animate(ANIM_MODE_2, 0);
+ _object25.setPosition(Common::Point(551, 145), 0);
+ _object25._numFrames = 5;
+ _object25.setPriority2(160);
+ _object25.setAction(&_action10, 0);
+
+ // Swimmer 1
+ _globals->_player.postInit();
+ _globals->_player.setVisage(7101);
+ _globals->_player.animate(ANIM_MODE_2, 0);
+ _globals->_player._moveDiff.x = 4;
+ _globals->_player._moveDiff.y = 2;
+ _globals->_player.setPosition(Common::Point(135, 135), 0);
+ _globals->_player.setPriority2(200);
+ _globals->_player.disableControl();
+
+ // Swimmer 2
+ _object1.postInit();
+ _object1.setVisage(7110);
+ _object1.animate(ANIM_MODE_1, 0);
+ _object1._moveDiff.x = 4;
+ _object1._moveDiff.y = 2;
+ _object1.setPosition(Common::Point(100, 100), 0);
+
+ setAction(&_action11);
+ _soundHandler1.startSound(270, 0, 127);
+ _soundHandler2.startSound(275, 0, 127);
+ _globals->_soundHandler.startSound(270, 0, 127);
+}
+/*--------------------------------------------------------------------------
+ * Scene 7200
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene7200::Action1::signal() {
+ Scene7200 *scene = (Scene7200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(15);
+ break;
+ case 1: {
+ PlayerMover *mover1 = new PlayerMover();
+ Common::Point pt1(165, 147);
+ scene->_swimmer.addMover(mover1, &pt1, this);
+ Common::Point pt2(207, 138);
+ PlayerMover *mover2 = new PlayerMover();
+ _globals->_player.addMover(mover2, &pt2, this);
+ break;
+ }
+ case 2:
+ break;
+ case 3:
+ _globals->_sceneManager.changeScene(7300);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7200::Action2::signal() {
+ Scene7200 *scene = (Scene7200 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(3);
+ break;
+ case 1: {
+ scene->_object2.setPriority2(25);
+ scene->_object3.setPriority2(25);
+ scene->_object4.setPriority2(25);
+ scene->_object2.setStrip(1);
+ scene->_object3.setStrip(1);
+ scene->_object4.setStrip(1);
+ NpcMover *mover1 = new NpcMover();
+ Common::Point pt1(54, 90);
+ scene->_object2.addMover(mover1, &pt1, this);
+ NpcMover *mover2 = new NpcMover();
+ Common::Point pt2(56, 85);
+ scene->_object3.addMover(mover2, &pt2, 0);
+ NpcMover *mover3 = new NpcMover();
+ Common::Point pt3(54, 80);
+ scene->_object4.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 2: {
+ scene->_object2.setPriority2(160);
+ scene->_object3.setPriority2(160);
+ scene->_object4.setPriority2(160);
+ scene->_object2.setStrip(2);
+ scene->_object3.setStrip(2);
+ scene->_object4.setStrip(2);
+ NpcMover *mover1 = new NpcMover();
+ Common::Point pt1(10, 89);
+ scene->_object2.addMover(mover1, &pt1, this);
+ NpcMover *mover2 = new NpcMover();
+ Common::Point pt2(12, 84);
+ scene->_object3.addMover(mover2, &pt2, 0);
+ NpcMover *mover3 = new NpcMover();
+ Common::Point pt3(10, 79);
+ scene->_object4.addMover(mover3, &pt3, 0);
+ break;
+ }
+ case 3:
+ _actionIndex = 0;
+ setDelay(1);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7200::postInit(SceneObjectList *OwnerList) {
+ loadScene(7200);
+ Scene::postInit();
+ _object2.postInit();
+ _object2.setVisage(7160);
+ _object2.animate(ANIM_MODE_2, 0);
+ _object2.setZoom(10);
+ _object2.setPosition(Common::Point(53, 88), 0);
+ _object2.setAction(&_action2);
+
+ _object3.postInit();
+ _object3.setVisage(7160);
+ _object3.animate(ANIM_MODE_2, 0);
+ _object3.setZoom(10);
+ _object3.setPosition(Common::Point(55, 83), 0);
+
+ _object4.postInit();
+ _object4.setVisage(7160);
+ _object4.animate(ANIM_MODE_2, 0);
+ _object4.setZoom(10);
+ _object4.setPosition(Common::Point(57, 78), 0);
+
+ _object5.postInit();
+ _object5.setVisage(7201);
+ _object5.setPosition(Common::Point(300, 172), 0);
+ _object5.setPriority(172);
+ _object5.animate(ANIM_MODE_2, 0);
+ _object5._numFrames = 3;
+
+ _object6.postInit();
+ _object6.setVisage(7201);
+ _object6.setStrip2(3);
+ _object6.setPosition(Common::Point(144, 97), 0);
+ _object6.setPriority(199);
+ _object6.animate(ANIM_MODE_2, 0);
+ _object6._numFrames = 3;
+
+ _object7.postInit();
+ _object7.setVisage(7201);
+ _object7.setStrip2(4);
+ _object7.setPosition(Common::Point(115, 123), 0);
+ _object7.setPriority(199);
+ _object7.animate(ANIM_MODE_2, 0);
+ _object7._numFrames = 3;
+
+ _object8.postInit();
+ _object8.setVisage(7201);
+ _object8.setStrip2(6);
+ _object8.setPosition(Common::Point(140, 173), 0);
+ _object8.setPriority(199);
+ _object8.animate(ANIM_MODE_2, 0);
+ _object8._numFrames = 3;
+
+ _object9.postInit();
+ _object9.setVisage(7201);
+ _object9.setStrip2(7);
+ _object9.setPosition(Common::Point(215, 196), 0);
+ _object9.setPriority(199);
+ _object9.animate(ANIM_MODE_2, 0);
+ _object9._numFrames = 3;
+
+ // Orange swimmer
+ _globals->_player.postInit();
+ _globals->_player.setVisage(7110);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setZoom(50);
+ _globals->_player.setPosition(Common::Point(-18, 16), 0);
+ _globals->_player.disableControl();
+
+ _swimmer.postInit();
+ _swimmer.setVisage(7101);
+ _swimmer.animate(ANIM_MODE_1, 0);
+ _swimmer.setObjectWrapper(new SceneObjectWrapper());
+ _swimmer.setZoom(50);
+ _swimmer.setPosition(Common::Point(-8, 16), 0);
+
+ setAction(&_action1);
+ _soundHandler.startSound(271, 0, 127);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 7300
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene7300::Action1::signal() {
+ Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ case 1:
+ case 3:
+ setDelay(30);
+ break;
+ case 2:
+ scene->_stripManager.start(7300, this);
+ break;
+ case 4: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(102, 122);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 5:
+ _globals->_player.setStrip(2);
+ _globals->_player.setFrame(1);
+ _globals->_player.animate(ANIM_MODE_5, this);
+ break;
+ case 6:
+ _globals->_player.setStrip(3);
+ _globals->_player._numFrames = 5;
+ _globals->_player.animate(ANIM_MODE_2, this);
+ if (_globals->_inventory._translator._sceneNumber == 1)
+ scene->_stripManager.start(7310, this);
+ else
+ scene->_stripManager.start(7305, this);
+ break;
+ case 7:
+ setDelay(3);
+ _globals->_soundHandler.proc1(0);
+ break;
+ case 8:
+ _globals->_sceneManager.changeScene(2280);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7300::Action2::signal() {
+ Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ NpcMover *mover1 = new NpcMover();
+ Common::Point pt(_globals->_randomSource.getRandomNumber(203), _globals->_randomSource.getRandomNumber(96));
+ scene->_object3.addMover(mover1, &pt, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7300::Action3::signal() {
+ Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ NpcMover *mover1 = new NpcMover();
+ Common::Point pt(_globals->_randomSource.getRandomNumber(76), _globals->_randomSource.getRandomNumber(78));
+ scene->_object1.addMover(mover1, &pt, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7300::Action4::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1:
+ _actionIndex = 0;
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7300::dispatch() {
+ Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene;
+ scene->_object4.setPosition(Common::Point(scene->_object3._position.x + 15, scene->_object3._position.y + 61));
+ scene->_object2.setPosition(Common::Point(scene->_object1._position.x + 1, scene->_object1._position.y - 31));
+
+ Scene::dispatch();
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7300::postInit(SceneObjectList *OwnerList) {
+ loadScene(7300);
+
+ Scene::postInit();
+ setZoomPercents(60, 85, 200, 100);
+
+ _globals->setFlag(52);
+ _globals->setFlag(24);
+ _globals->setFlag(109);
+
+ _stripManager.addSpeaker(&_speakerPOR);
+ _stripManager.addSpeaker(&_speakerPOText);
+ _stripManager.addSpeaker(&_speakerSKText);
+ _stripManager.addSpeaker(&_speakerQU);
+
+ _speakerSKText.setTextPos(Common::Point(100, 20));
+ _speakerPOText.setTextPos(Common::Point(100, 160));
+
+ _object4.postInit();
+ _object4.setVisage(7311);
+ _object4.setStrip(1);
+ _object4.setFrame(1);
+ _object4.setPosition(Common::Point(218, 157), 0);
+
+ _object3.postInit();
+ _object3.setVisage(7311);
+ _object3.setStrip(2);
+ _object3.setFrame(1);
+ _object3.setPosition(Common::Point(203, 96), 0);
+ _object3._numFrames = 2;
+ _object3._moveDiff = Common::Point(1, 1);
+ _object3.animate(ANIM_MODE_8, 0, 0);
+ _object3._field7A = 2;
+ _object3.setAction(&_action2);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(7305);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ _globals->_player.setPosition(Common::Point(-100, 100), 0);
+ _globals->_player.disableControl();
+
+ _object1.postInit();
+ _object1.setVisage(7312);
+ _object1.animate(ANIM_MODE_1, 0);
+ _object1._moveDiff = Common::Point(1, 1);
+ _object1.setPosition(Common::Point(76, 78), 0);
+ _object1._field7A = 1;
+ _object1.setAction(&_action3);
+
+ _object2.postInit();
+ _object2.setVisage(7312);
+ _object2.setStrip(2);
+ _object2.animate(ANIM_MODE_2, 0);
+ _object2.setPosition(Common::Point(77, 47), 0);
+ _object2.setPriority2(190);
+
+ _object5.postInit();
+ _object5.setVisage(7300);
+ _object5.setPosition(Common::Point(106, 45), 0);
+ _object5.animate(ANIM_MODE_2, 0);
+ _object5._numFrames = 5;
+
+ _object6.postInit();
+ _object6.setVisage(7300);
+ _object6.setStrip2(2);
+ _object6.setPosition(Common::Point(283, 193), 0);
+ _object6.animate(ANIM_MODE_2, 0);
+ _object6._numFrames = 3;
+
+ _object7.postInit();
+ _object7.setVisage(7300);
+ _object7.setStrip(4);
+ _object7.setPosition(Common::Point(295, 77), 0);
+ _object7.animate(ANIM_MODE_2, 0);
+ _object7._numFrames = 3;
+
+ _object8.postInit();
+ _object8.setVisage(7300);
+ _object8.setStrip(5);
+ _object8.setPosition(Common::Point(1, 147), 0);
+ _object8.animate(ANIM_MODE_2, 0);
+ _object8._numFrames = 2;
+
+ setAction(&_action1);
+ _globals->_soundHandler.startSound(272, 0, 127);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 7600
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene7600::Action1::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(120);
+ break;
+ case 1: {
+ PlayerMover *mover = new PlayerMover();
+ Common::Point pt(389, 57);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_sceneManager.changeScene(7700);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7600::Action2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1: {
+ NpcMover *mover = new NpcMover();
+ Common::Point pt(-30, 195);
+ _globals->_player.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _globals->_sceneManager.changeScene(2320);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene7600::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ setZoomPercents(100, 0, 200, 100);
+
+ _object2.postInit();
+ _object2.setVisage(7601);
+ _object2.setStrip(1);
+ _object2.animate(ANIM_MODE_2, 0);
+ _object2.setPosition(Common::Point(48, 135));
+ _object2.setPriority2(1);
+
+ _object3.postInit();
+ _object3.setVisage(7601);
+ _object3.setStrip(2);
+ _object3.animate(ANIM_MODE_2, 0);
+ _object3.setPosition(Common::Point(158, 136));
+ _object3.setPriority2(1);
+
+ _object4.postInit();
+ _object4.setVisage(7601);
+ _object4.setStrip(3);
+ _object4.animate(ANIM_MODE_2, 0);
+ _object4.setPosition(Common::Point(293, 141));
+ _object4.setPriority2(1);
+
+ _object5.postInit();
+ _object5.setVisage(7601);
+ _object5.setStrip(4);
+ _object5.animate(ANIM_MODE_2, 0);
+ _object5.setPosition(Common::Point(405, 143));
+ _object5.setPriority2(1);
+
+ _object6.postInit();
+ _object6.setVisage(7601);
+ _object6.setStrip(5);
+ _object6.animate(ANIM_MODE_2, 0);
+ _object6.setPosition(Common::Point(379, 191));
+ _object6.setPriority2(1);
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(2333);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ _globals->_player.setObjectWrapper(new SceneObjectWrapper());
+ _globals->_player.setStrip(1);
+ _globals->_player._moveDiff = Common::Point(16, 16);
+ _globals->_player.changeZoom(-1);
+ _globals->_player.disableControl();
+
+ if (_globals->_sceneManager._previousScene == 7700) {
+ _globals->_player.setPosition(Common::Point(389, 57));
+ setAction(&_action2);
+ } else {
+ _globals->_player.setPosition(Common::Point(-50, 195));
+ setAction(&_action1);
+ }
+ _sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y);
+ loadScene(7600);
+ _soundHandler2.startSound(255);
+ _soundHandler1.startSound(251);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 7700
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene7700::Action1::signal() {
+ SceneObject *fmtObj = (SceneObject *) _fmt;
+ switch (_actionIndex++) {
+ case 0: {
+ PlayerMover *mover1 = new PlayerMover();
+ Common::Point pt = Common::Point(fmtObj->_position.x, fmtObj->_position.y + 30);
+ _globals->_player.addMover(mover1, &pt, this);
+ break;
+ }
+ case 1:
+ _globals->_player.checkAngle(fmtObj);
+ if (_globals->_player._field8C == 0)
+ fmtObj->animate(ANIM_MODE_5, this);
+ else
+ fmtObj->animate(ANIM_MODE_6, this);
+ break;
+ case 2:
+ remove();
+ break;
+ }
+}
+
+void Scene7700::Action2::signal() {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+ switch (_actionIndex++) {
+ case 0:
+ case 2:
+ setDelay(_globals->_randomSource.getRandomNumber(60) + 60);
+ break;
+ case 1:
+ scene->_prof.animate(ANIM_MODE_7, 0, 0);
+ setDelay(20);
+ break;
+ case 3:
+ scene->_prof.animate(ANIM_MODE_6, this);
+ _actionIndex = 0;
+ break;
+ }
+}
+
+void Scene7700::Action3::signal() {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+ switch (_actionIndex++) {
+ case 0:
+ scene->_object15.animate(ANIM_MODE_5, this);
+ break;
+ case 1:
+ scene->_sceneItem10.remove();
+ scene->_object15.remove();
+ scene->_sceneHotspot8.remove();
+ scene->_sceneHotspot9.remove();
+ scene->_object19.remove();
+ setDelay(60);
+ // No break on purpose!
+ case 2:
+ scene->_soundHandler.startSound(260, 0, 127);
+ scene->_object8.setVisage(7703);
+ scene->_object8.setPosition(Common::Point(177, 97), 0);
+ scene->_object8.setStrip2(3);
+ scene->_object8.animate(ANIM_MODE_5, this);
+ scene->_object8._numFrames = 3;
+ break;
+ case 3:
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene7700::Action4::signal() {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+ switch (_actionIndex++) {
+ case 2:
+ scene->_object13.remove();
+ // No break on purpose!
+ case 0:
+ setDelay(3);
+ break;
+ case 1:
+ CursorMan.showMouse(false);
+ scene->_object13.postInit();
+ scene->_object13.setVisage(7700);
+ scene->_object13.setStrip2(7);
+ scene->_object13.setPosition(Common::Point(151, 33), 0);
+ scene->_object13.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ CursorMan.showMouse(true);
+ SceneItem::display(7700, 11, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ _globals->_player.enableControl();
+ remove();
+ break;
+ }
+}
+
+void Scene7700::Action5::signal() {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(_globals->_randomSource.getRandomNumber(240));
+ break;
+ case 1: {
+ scene->_cloud.setFrame(_globals->_randomSource.getRandomNumber(1) + 1);
+ scene->_cloud.setPosition(Common::Point(133, 145 + _globals->_randomSource.getRandomNumber(54)), 0);
+
+ Common::Point pt(360, scene->_cloud._position.y);
+ NpcMover *mover = new NpcMover();
+ scene->_cloud.addMover(mover, &pt, this);
+ _actionIndex = 0;
+ break;
+ }
+ }
+}
+
+void Scene7700::Action6::signal() {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(5);
+ break;
+ case 1: {
+ Common::Point pt(2, 66);
+ NpcMover *mover = new NpcMover();
+ scene->_easterEgg1.addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ scene->_easterEgg1.setStrip(2);
+ scene->_easterEgg1.setPosition(Common::Point(43, 65), 0);
+
+ scene->_easterEgg2.postInit();
+ scene->_easterEgg2.setVisage(7708);
+ scene->_easterEgg2.setStrip(3);
+ scene->_easterEgg2.setPosition(Common::Point(116, 54), 0);
+ scene->_easterEgg2.animate(ANIM_MODE_2, 0);
+
+ setDelay(120);
+ break;
+ case 3:
+ scene->_easterEgg1.remove();
+ scene->_easterEgg2.remove();
+ remove();
+ break;
+ }
+}
+
+void Scene7700::SceneHotspot1::doAction(int action) {
+ if (action == CURSOR_LOOK)
+ SceneItem::display(7700, 4, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneHotspot::doAction(action);
+}
+
+void Scene7700::SceneHotspot2::doAction(int action) {
+ if (action == CURSOR_LOOK)
+ SceneItem::display(7700, 6, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneHotspot::doAction(action);
+}
+
+void Scene7700::SceneHotspot3::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_KEY:
+ SceneItem::display(7702, 3, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ _globals->_inventory._key._sceneNumber = 7700;
+ break;
+ case CURSOR_LOOK:
+ if (_globals->_inventory._key._sceneNumber == 7700)
+ scene->setAction(&scene->_action4, 0);
+ else
+ SceneItem::display(7700, 53, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (!_globals->getFlag(78)) {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7715, 0);
+ } else if (_globals->_inventory._key._sceneNumber == 7700) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 7705;
+ scene->setAction(&scene->_sequenceManager, scene, 7705, &_globals->_player, 0);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::SceneHotspot4::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, 12, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (!_globals->getFlag(78)) {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7715, 0);
+ } else {
+ SceneItem::display(7700, 12, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::SceneHotspot5::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, 28, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(78)) {
+ if (_globals->_inventory._paper._sceneNumber == 7700) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 7708;
+ scene->setAction(&scene->_sequenceManager, scene, 7708, &_globals->_player, 0);
+ }
+ } else {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7715, 0);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::SceneHotspot6::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, 43, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ SceneItem::display(7700, 56, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::SceneItem7::doAction(int action) {
+ if (action == CURSOR_LOOK)
+ SceneItem::display(7700, 51, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+}
+
+void Scene7700::SceneHotspot8::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, 48, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ scene->_sceneMode = 7709;
+ scene->_soundHandler.startSound(259, 0, 127);
+ scene->_object15.setFrame(scene->_object15.getFrameCount());
+ scene->_object15.animate(ANIM_MODE_6, scene);
+ if ((scene->_field977 == 2) && (scene->_field97B == 0)) {
+ scene->_field979++;
+ } else {
+ scene->_field97B = 0;
+ scene->_field979 = 0;
+ scene->_field977 = 0;
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::SceneHotspot9::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, 48, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ scene->_sceneMode = 7709;
+ scene->_soundHandler.startSound(259, 0, 127);
+ scene->_object15.setFrame(1);
+ scene->_object15.animate(ANIM_MODE_5, scene);
+ if (scene->_field977 > 2) {
+ scene->_field97B = 0;
+ scene->_field979 = 0;
+ scene->_field977 = 0;
+ }
+
+ if (scene->_field979 != 0) {
+ if (scene->_field979 != 4) {
+ scene->_field97B = 0;
+ scene->_field979 = 0;
+ scene->_field977 = 0;
+ } else {
+ scene->_field97B++;
+ if (scene->_field97B == 3) {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action3);
+ }
+ }
+ } else {
+ scene->_field977++;
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::SceneItem10::doAction(int action) {
+}
+
+void Scene7700::Object1::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display(7700, _lookLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else if (action == CURSOR_USE) {
+ if (_globals->getFlag(78)) {
+ _globals->_player.disableControl();
+ scene->setAction(&scene->_action1, this);
+ } else {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7715, 0);
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::SceneHotspot11::doAction(int action) {
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, _lookLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ SceneItem::display(7701, _useLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::Object1::signal() {
+ if (_state == 0) {
+ _state = 1;
+ SceneItem::display(7701, _defltLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ _state = 0;
+ }
+ _globals->_player.enableControl();
+}
+
+void Scene7700::Object3::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display(7700, 34, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else if (action == CURSOR_USE) {
+ if (_globals->getFlag(78)) {
+ if (scene->_object3._frame == 1) {
+ _globals->_player.disableControl();
+ scene->_sceneMode = 7707;
+ scene->setAction(&scene->_sequenceManager, scene, 7707, &_globals->_player, this, 0);
+ } else {
+ SceneItem::display(7700, 60, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ }
+ } else {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7715, 0);
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::Object7::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ if (_globals->getFlag(78))
+ SceneItem::display(7700, 45, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneItem::display(7700, 44, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (_globals->getFlag(78)) {
+ SceneItem::display(7701, 41, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7714, 0);
+ }
+ break;
+ case CURSOR_TALK:
+ if (_globals->getFlag(78)) {
+ SceneItem::display(7702, 1, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ _globals->_player.disableControl();
+ if (_state == 0) {
+ _state = 1;
+ scene->_sceneMode = 7703;
+ scene->setAction(&scene->_sequenceManager, scene, 7703, 0);
+ } else {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7712, 0);
+ }
+ }
+ break;
+ case OBJECT_STUNNER:
+ if (!_globals->getFlag(78)) {
+ _globals->_soundHandler.proc3();
+ _globals->setFlag(78);
+ setAction(0);
+ _globals->_player.disableControl();
+ scene->_sceneMode = 7704;
+ scene->setAction(&scene->_sequenceManager, scene, 7704, &_globals->_player, this, 0);
+ }
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ break;
+ }
+}
+
+void Scene7700::Object8::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ if ((action == CURSOR_LOOK) || (action == CURSOR_USE)) {
+ if (_strip == 3) {
+ scene->_object9.postInit();
+ scene->_object9.setVisage(7701);
+ scene->_object9.setStrip2(3);
+ scene->_object9.setPosition(Common::Point(91, 166), 0);
+ scene->_object9.setPriority2(200);
+
+ scene->_object14.postInit();
+ scene->_object14.setVisage(7701);
+ scene->_object14.setStrip(2);
+ scene->_object14.setPriority2(250);
+ scene->_object14.setPosition(Common::Point(139, 151), 0);
+
+ scene->_gfxButton.setText(EXIT_MSG);
+ scene->_gfxButton._bounds.centre(140, 189);
+ scene->_gfxButton.draw();
+ scene->_gfxButton._bounds.expandPanes();
+
+ _globals->_sceneItems.push_front(&scene->_object10);
+ _globals->_sceneItems.push_front(&scene->_object9);
+ _globals->_player._canWalk = false;
+ } else {
+ scene->_object15.postInit();
+ scene->_object15.setVisage(7701);
+ scene->_object15.setPosition(Common::Point(140, 165), 0);
+ scene->_object15.setPriority2(200);
+
+ scene->_gfxButton.setText(EXIT_MSG);
+ scene->_gfxButton._bounds.centre(140, 186);
+ scene->_gfxButton.draw();
+ scene->_gfxButton._bounds.expandPanes();
+
+ scene->_object19.postInit();
+ scene->_object19.setVisage(7700);
+ scene->_object19.setStrip(6);
+ scene->_object19.setPosition(Common::Point(140, 192), 0);
+
+ _globals->_sceneItems.push_front(&scene->_object10);
+ _globals->_sceneItems.push_front(&scene->_object8);
+ _globals->_sceneItems.push_front(&scene->_object9);
+ _globals->_events.setCursor(CURSOR_WALK);
+ _globals->_player._canWalk = false;
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::Object9::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case CURSOR_LOOK:
+ SceneItem::display(7700, 49, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ SceneItem::display(7701, 42, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_TALK:
+ SceneItem::display(7702, 4, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case OBJECT_KEY:
+ if (_frame == 1) {
+ if (!_globals->getFlag(80)) {
+ scene->_object10.postInit();
+ scene->_object10.setVisage(7701);
+ scene->_object10.setStrip(4);
+ scene->_object10.setPosition(Common::Point(159, 136));
+ _globals->_sceneItems.push_front(&scene->_object10);
+ scene->_object10.setPriority2(240);
+ }
+ scene->_soundHandler.startSound(262, 0, 127);
+ scene->_object14.animate(ANIM_MODE_5, 0);
+ }
+ _globals->_events.setCursor(CURSOR_WALK);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::Object10::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display(7700, 50, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else if (action == CURSOR_USE) {
+ _globals->setFlag(80);
+ scene->_sceneItem10.remove();
+ scene->_gfxButton._bounds.expandPanes();
+ scene->_object14.remove();
+ scene->_object9.remove();
+ remove();
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::Object11::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ switch (action) {
+ case OBJECT_SCANNER:
+ if (_frame != 1)
+ SceneItem::display(7701, 44, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneItem::doAction(action);
+ break;
+ case CURSOR_LOOK:
+ if (_frame != 1)
+ SceneItem::display(7700, 9, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ else
+ SceneItem::display(7700, 52, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case CURSOR_USE:
+ if (_frame != 1) {
+ SceneItem::display(7701, 8, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else {
+ _globals->setFlag(49);
+ _globals->_player.disableControl();
+ scene->_sceneMode = 7706;
+ scene->setAction(&scene->_sequenceManager, scene, 7706, &_globals->_player, this, NULL);
+ }
+ break;
+ case OBJECT_EMPTY_JAR:
+ _globals->_inventory._emptyJar._sceneNumber = 0;
+ _globals->_inventory._jar._sceneNumber = 1;
+ _globals->_player.disableControl();
+ scene->_sceneMode = 7710;
+ scene->setAction(&scene->_sequenceManager, scene, 7710, &_globals->_player, NULL);
+ break;
+ default:
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::Object12::doAction(int action) {
+ Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene;
+
+ if (action == CURSOR_LOOK) {
+ SceneItem::display(7700, 15, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ } else if (action == CURSOR_USE) {
+ if (_globals->getFlag(78)) {
+ scene->_sceneMode = 7713;
+ scene->setAction(&scene->_sequenceManager, scene, 7713, &_globals->_player, NULL);
+ } else {
+ scene->_sceneMode = 7712;
+ scene->setAction(&scene->_sequenceManager, scene, 7715, NULL);
+ }
+ } else {
+ SceneHotspot::doAction(action);
+ }
+}
+
+void Scene7700::signal() {
+ switch (_sceneMode) {
+ case 7701:
+ _globals->_player.setPriority2(-1);
+ _globals->_player.setStrip2(-1);
+ if (_globals->getFlag(78)) {
+ _globals->_player.enableControl();
+ } else {
+ _sceneMode = 7711;
+ setAction(&_sequenceManager, this, 7711, 0);
+ }
+ break;
+ case 7702:
+ _soundHandler.proc1(0);
+ _globals->_sceneManager.changeScene(7600);
+ break;
+ case 7703:
+ case 7706:
+ case 7707:
+ case 7711:
+ case 7712:
+ _globals->_player.enableControl();
+ break;
+ case 7704:
+ _globals->_soundHandler.startSound(256, 0, 127);
+ _prof.setStrip2(4);
+ _prof.setFrame2(1);
+ _prof.setPosition(Common::Point(159, 87), 0);
+ _globals->_player.enableControl();
+ break;
+ case 7705:
+ case 7708:
+ _globals->_inventory._key._sceneNumber = 1;
+ _globals->_player.enableControl();
+ break;
+ case 7709:
+ _globals->_events.setCursor(CURSOR_USE);
+ break;
+ case 7710:
+ _globals->_player.enableControl();
+ SceneItem::display(7700, 62, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END);
+ break;
+ case 7713:
+ _emptyJar.remove();
+ _globals->_inventory._emptyJar._sceneNumber = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene7700::process(Event &event) {
+ Scene::process(event);
+
+ if (contains<SceneItem *>(_globals->_sceneItems, &_sceneItem10)) {
+ if (_gfxButton.process(event)) {
+ _sceneItem10.remove();
+ _sceneHotspot15.remove();
+ _sceneHotspot9.remove();
+ if (_globals->_sceneObjects->contains(&_object10))
+ _object10.remove();
+ if (_globals->_sceneObjects->contains(&_object14))
+ _object14.remove();
+ _object19.remove();
+ _gfxButton._bounds.expandPanes();
+ _globals->_player._canWalk = true;
+ }
+ }
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_p)) {
+ event.handled = true;
+ if (!_globals->_sceneObjects->contains(&_easterEgg1)) {
+ _easterEgg1.postInit();
+ _easterEgg1.setVisage(7708);
+ _easterEgg1.setPosition(Common::Point(163, 50), 0);
+ _easterEgg1.setPriority2(1);
+ _easterEgg1.animate(ANIM_MODE_2, 0);
+ _easterEgg1.setAction(&_action6);
+ }
+ }
+}
+
+void Scene7700::dispatch() {
+ if ((_globals->_sceneRegions.indexOf(_globals->_player._position) == 6) || (_globals->_player._position.x < 10))
+ _globals->_player.changeZoom(100 - ((_globals->_player._position.y - 68) / 2));
+ else
+ _globals->_player.changeZoom(-1);
+
+ if ((_action == 0) && (_globals->_sceneRegions.indexOf(_globals->_player._position) == 30)) {
+ _globals->_player.disableControl();
+ _sceneMode = 7702;
+ setAction(&_sequenceManager, this, 7702, &_globals->_player, 0);
+ }
+ Scene::dispatch();
+}
+
+void Scene7700::postInit(SceneObjectList *OwnerList) {
+ loadScene(7700);
+ Scene::postInit();
+ setZoomPercents(100, 80, 200, 100);
+ _globals->setFlag(53);
+ _field97B = 0;
+ _field979 = 0;
+ _field977 = 0;
+
+ _stripManager.addSpeaker(&_speakerEText);
+ _stripManager.addSpeaker(&_speakerQText);
+ _speakerQText._npc = &_globals->_player;
+ _speakerEText._npc = &_prof;
+
+ _globals->_player.postInit();
+ _globals->_player.setVisage(4201);
+ _globals->_player.animate(ANIM_MODE_1, 0);
+ SceneObjectWrapper *wrapper = new SceneObjectWrapper();
+ _globals->_player.setObjectWrapper(wrapper);
+ _globals->_player.setPosition(Common::Point(-19, 68), 0);
+ _globals->_player.setStrip2(7);
+ _globals->_player.setPriority2(95);
+ _globals->_player.changeZoom(80);
+ _globals->_player._moveDiff.x = 6;
+ _globals->_player._moveDiff.y = 3;
+ _globals->_player.disableControl();
+
+ _prof.postInit();
+ _prof.setVisage(7706);
+
+ if (_globals->getFlag(78)) {
+ _prof.setStrip2(4);
+ _prof.setPriority2(80);
+ _prof.setPosition(Common::Point(159, 87), 0);
+ } else {
+ _prof.setPosition(Common::Point(203, 87), 0);
+ _prof.setStrip2(2);
+ _prof._numFrames = 6;
+ _prof.setAction(&_action2);
+ }
+
+ _cloud.postInit();
+ _cloud.setVisage(7700);
+ _cloud.setStrip2(5);
+ _cloud.setPriority2(1);
+ _cloud.setPosition(Common::Point(133, 160), 0);
+ _cloud._moveDiff.x = 1;
+ _cloud._field7A = 7;
+ _cloud.setAction(&_action5);
+
+ _object1.postInit();
+ _object1.setVisage(7700);
+ _object1.setPosition(Common::Point(184, 61), 0);
+ _object1._lookLineNum = 18;
+ _object1._defltLineNum = 16;
+
+ _object2.postInit();
+ _object2.setVisage(7700);
+ _object2.setPosition(Common::Point(184, 70), 0);
+ _object2.setPriority2(60);
+ _object2._lookLineNum = 19;
+ _object2._defltLineNum = 17;
+
+ _object3.postInit();
+ _object3.setVisage(7703);
+ _object3.setPosition(Common::Point(288, 36), 0);
+ _object3.setStrip(2);
+
+ _object4.postInit();
+ _object4.setVisage(7700);
+ _object4.setPosition(Common::Point(268, 59), 0);
+ _object4.setStrip(2);
+ _object4._lookLineNum = 37;
+ _object4._defltLineNum = 35;
+
+ _object5.postInit();
+ _object5.setVisage(7700);
+ _object5.setPosition(Common::Point(268, 67), 0);
+ _object5.setPriority2(58);
+ _object5.setStrip2(3);
+ _object5._lookLineNum = 38;
+ _object5._defltLineNum = 36;
+
+ _object6.postInit();
+ _object6.setVisage(7700);
+ _object6.setPosition(Common::Point(268, 75), 0);
+ _object6.setPriority2(57);
+ _object6.setStrip2(4);
+ _object6._lookLineNum = 40;
+ _object6._defltLineNum = 43;
+
+ _object8.postInit();
+ _object8.setVisage(7703);
+ _object8.setPosition(Common::Point(203, 91), 0);
+ _object8.setStrip2(4);
+ _object8.setPriority2(86);
+
+ _sceneHotspot8.setBounds(82, 141, 161, 92);
+ _sceneHotspot9.setBounds(82, 187, 161, 141);
+
+ _cork.postInit();
+ _cork.setVisage(7703);
+ _cork.setPosition(Common::Point(32, 128), 0);
+
+ if (_globals->getFlag(49))
+ _cork.setFrame(_cork.getFrameCount());
+
+ if (_globals->_inventory._emptyJar._sceneNumber == 7700) {
+ _emptyJar.postInit();
+ _emptyJar.setVisage(7700);
+ _emptyJar.setStrip(8);
+ _emptyJar.setPosition(Common::Point(189, 48), 0);
+ _globals->_sceneItems.addItems(&_emptyJar, NULL);
+ }
+ _sceneHotspot1._sceneRegionId = 28;
+ _sceneHotspot2._sceneRegionId = 6;
+ _sceneHotspot3._sceneRegionId = 10;
+ _sceneHotspot4._sceneRegionId = 11;
+ _sceneHotspot5._sceneRegionId = 9;
+ _sceneHotspot6._sceneRegionId = 7;
+
+ _sceneItem7.setBounds(0, 320, 200, 0);
+ _sceneItem10.setBounds(0, 320, 200, 0);
+
+ _sceneHotspot11._sceneRegionId = 57;
+ _sceneHotspot11._useLineNum = 0;
+ _sceneHotspot11._lookLineNum = 0;
+ _sceneHotspot12._sceneRegionId = 2;
+ _sceneHotspot12._useLineNum = 2;
+ _sceneHotspot12._lookLineNum = 2;
+ _sceneHotspot13._sceneRegionId = 12;
+ _sceneHotspot13._useLineNum = 3;
+ _sceneHotspot13._lookLineNum = 3;
+ _sceneHotspot14._sceneRegionId = 18;
+ _sceneHotspot14._useLineNum = 4;
+ _sceneHotspot14._lookLineNum = 5;
+ _sceneHotspot15.setBounds(0, 55, 50, 8);
+ _sceneHotspot15._useLineNum = 6;
+ _sceneHotspot15._lookLineNum = 7;
+ _sceneHotspot16.setBounds(0, 130, 34, 103);
+ _sceneHotspot16._useLineNum = 8;
+ _sceneHotspot16._lookLineNum = 9;
+ _sceneHotspot17.setBounds(41, 180, 46, 170);
+ _sceneHotspot17._useLineNum = 11;
+ _sceneHotspot17._lookLineNum = 13;
+ _sceneHotspot18.setBounds(38, 187, 46, 180);
+ _sceneHotspot18._useLineNum = 12;
+ _sceneHotspot18._lookLineNum = 14;
+ _sceneHotspot19._sceneRegionId = 3;
+ _sceneHotspot19._useLineNum = 14;
+ _sceneHotspot19._lookLineNum = 16;
+ _sceneHotspot20._sceneRegionId = 14;
+ _sceneHotspot20._useLineNum = 15;
+ _sceneHotspot20._lookLineNum = 17;
+ _sceneHotspot21.setBounds(9, 215, 26, 210);
+ _sceneHotspot21._useLineNum = 18;
+ _sceneHotspot21._lookLineNum = 20;
+ _sceneHotspot22.setBounds(10, 221, 26, 215);
+ _sceneHotspot22._useLineNum = 19;
+ _sceneHotspot22._lookLineNum = 21;
+ _sceneHotspot23.setBounds(6, 230, 26, 225);
+ _sceneHotspot23._useLineNum = 20;
+ _sceneHotspot23._lookLineNum = 22;
+ _sceneHotspot24._sceneRegionId = 13;
+ _sceneHotspot24._useLineNum = 21;
+ _sceneHotspot24._lookLineNum = 23;
+ _sceneHotspot25._sceneRegionId = 21;
+ _sceneHotspot25._useLineNum = 22;
+ _sceneHotspot25._lookLineNum = 24;
+ _sceneHotspot26._sceneRegionId = 19;
+ _sceneHotspot26._useLineNum = 23;
+ _sceneHotspot26._lookLineNum = 25;
+ _sceneHotspot27._sceneRegionId = 27;
+ _sceneHotspot27._useLineNum = 24;
+ _sceneHotspot27._lookLineNum = 26;
+ _sceneHotspot28._sceneRegionId = 15;
+ _sceneHotspot28._useLineNum = 25;
+ _sceneHotspot28._lookLineNum = 27;
+ _sceneHotspot29._sceneRegionId = 26;
+ _sceneHotspot29._useLineNum = 27;
+ _sceneHotspot29._lookLineNum = 29;
+ _sceneHotspot30.setBounds(0, 317, 34, 310);
+ _sceneHotspot30._useLineNum = 28;
+ _sceneHotspot30._lookLineNum = 30;
+ _sceneHotspot31._sceneRegionId = 17;
+ _sceneHotspot31._useLineNum = 29;
+ _sceneHotspot31._lookLineNum = 31;
+ _sceneHotspot32._sceneRegionId = 25;
+ _sceneHotspot32._useLineNum = 30;
+ _sceneHotspot32._lookLineNum = 32;
+ _sceneHotspot33._sceneRegionId = 5;
+ _sceneHotspot33._useLineNum = 31;
+ _sceneHotspot33._lookLineNum = 33;
+ _sceneHotspot34.setBounds(42, 292, 48, 281);
+ _sceneHotspot34._useLineNum = 32;
+ _sceneHotspot34._lookLineNum = 35;
+ _sceneHotspot35._sceneRegionId = 24;
+ _sceneHotspot35._useLineNum = 38;
+ _sceneHotspot35._lookLineNum = 41;
+ _sceneHotspot36._sceneRegionId = 1;
+ _sceneHotspot36._useLineNum = 39;
+ _sceneHotspot36._lookLineNum = 42;
+
+ _globals->_sceneItems.addItems(&_prof, &_sceneHotspot35, &_object8, &_sceneHotspot34, &_sceneHotspot33, &_sceneHotspot32, NULL);
+ _globals->_sceneItems.addItems(&_sceneHotspot31, &_sceneHotspot30, &_sceneHotspot29, &_sceneHotspot5, &_sceneHotspot28, &_sceneHotspot27, NULL);
+ _globals->_sceneItems.addItems(&_sceneHotspot26, &_sceneHotspot25, &_sceneHotspot24, &_sceneHotspot23, &_sceneHotspot22, &_sceneHotspot21, NULL);
+ _globals->_sceneItems.addItems(&_sceneHotspot20, &_sceneHotspot19, &_sceneHotspot18, &_sceneHotspot17, &_sceneHotspot4, &_sceneHotspot3, NULL);
+ _globals->_sceneItems.addItems(&_sceneHotspot16, &_sceneHotspot15, &_sceneHotspot2, &_sceneHotspot14, &_cork, &_sceneHotspot1, NULL);
+ _globals->_sceneItems.addItems(&_sceneHotspot13, &_sceneHotspot12, &_sceneHotspot11, &_object2, &_object1, &_object3, NULL);
+ _globals->_sceneItems.addItems(&_object6, &_object5, &_object4, &_sceneHotspot6, &_sceneHotspot36, &_sceneItem7, NULL);
+
+ _sceneMode = 7701;
+ setAction(&_sequenceManager, this, 7701, &_globals->_player, 0);
+ _soundHandler.startSound(256, 0, 127);
+}
+
+Scene7700::Scene7700() {
+ _object1._state = 0;
+ _object2._state = 0;
+ _object4._state = 0;
+ _object5._state = 0;
+ _object6._state = 0;
+ _prof._state = 0;
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/ringworld_scenes8.h b/engines/tsage/ringworld_scenes8.h
new file mode 100644
index 0000000000..0c39920614
--- /dev/null
+++ b/engines/tsage/ringworld_scenes8.h
@@ -0,0 +1,495 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_RINGWORLD_SCENES8_H
+#define TSAGE_RINGWORLD_SCENES8_H
+
+#include "common/scummsys.h"
+#include "tsage/ringworld_logic.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+class NamedHotspotMult : public SceneHotspot {
+public:
+ int _useLineNum, _lookLineNum;
+ NamedHotspotMult() : SceneHotspot() {}
+
+ virtual Common::String getClassName() { return "NamedHotspotMult"; }
+};
+
+class SceneObject7700 : public SceneObjectExt {
+public:
+ int _lookLineNum, _defltLineNum;
+
+ virtual void synchronise(Serialiser &s) {
+ SceneObject::synchronise(s);
+ s.syncAsSint16LE(_lookLineNum);
+ s.syncAsSint16LE(_defltLineNum);
+ }
+ virtual Common::String getClassName() { return "SceneObject7700"; }
+};
+
+class Scene7000 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void dispatch();
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Objects */
+ class Object1 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+ /* Items */
+ class SceneItem1 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager;
+ SpeakerSKText _speakerSKText;
+ SpeakerSKL _speakerSKL;
+ SpeakerQL _speakerQL;
+ SpeakerQR _speakerQR;
+ SpeakerQText _speakerQText;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SceneObject _object7;
+ SceneObject _object8;
+ SceneObject _object9;
+ SceneObject _object10;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ SceneItem1 _sceneItem1;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void dispatch();
+};
+
+class Scene7100 : public Scene {
+ /* Actions */
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action7 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action8 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action9 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action10 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action11 : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SoundHandler _soundHandler1;
+ SoundHandler _soundHandler2;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SceneObject _object7;
+ SceneObject _object8;
+ SceneObject _object9;
+ SceneObject _object10;
+ SceneObject _object11;
+ SceneObject _object12;
+ SceneObject _object13;
+ SceneObject _object14;
+ SceneObject _object15;
+ SceneObject _object16;
+ SceneObject _object17;
+ SceneObject _object18;
+ SceneObject _object19;
+ SceneObject _object20;
+ SceneObject _object21;
+ SceneObject _object22;
+ SceneObject _object23;
+ SceneObject _object24;
+ SceneObject _object25;
+ Action _action1;
+ Action _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ Action7 _action7;
+ Action8 _action8;
+ Action9 _action9;
+ Action10 _action10;
+ Action11 _action11;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene7200 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ Action1 _action1;
+ Action2 _action2;
+ SceneObject _swimmer;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SceneObject _object7;
+ SceneObject _object8;
+ SceneObject _object9;
+ SoundHandler _soundHandler;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene7300 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ SpeakerPOR _speakerPOR;
+ SpeakerPOText _speakerPOText;
+ SpeakerSKText _speakerSKText;
+ SpeakerQU _speakerQU;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SceneObject _object7;
+ SceneObject _object8;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void dispatch();
+};
+
+class Scene7600 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+
+public:
+ Action1 _action1;
+ Action2 _action2;
+ SceneObject _object1;
+ SceneObject _object2;
+ SceneObject _object3;
+ SceneObject _object4;
+ SceneObject _object5;
+ SceneObject _object6;
+ SoundHandler _soundHandler1;
+ SoundHandler _soundHandler2;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene7700 : public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action4 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action5 : public Action {
+ public:
+ virtual void signal();
+ };
+ class Action6 : public Action {
+ public:
+ virtual void signal();
+ };
+
+ class Object1 : public SceneObject7700 {
+ public:
+ virtual void signal();
+ virtual void doAction(int action);
+ };
+ class Object3 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object7 : public SceneObjectExt {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object8 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object9 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object10 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object11 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+ class Object12 : public SceneObject {
+ public:
+ virtual void doAction(int action);
+ };
+
+ /* Items */
+ class SceneHotspot1 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot2 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot3 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot4 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot5 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot6 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneItem7 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot8 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot9 : public SceneHotspot {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneItem10 : public SceneItem {
+ public:
+ virtual void doAction(int action);
+ };
+ class SceneHotspot11 : public NamedHotspotMult {
+ public:
+ virtual void doAction(int action);
+ };
+public:
+ SoundHandler _soundHandler;
+ SequenceManager _sequenceManager;
+ GfxButton _gfxButton;
+ SpeakerEText _speakerEText;
+ SpeakerQText _speakerQText;
+ Object1 _object1;
+ Object1 _object2;
+ Object3 _object3;
+ Object1 _object4;
+ Object1 _object5;
+ Object1 _object6;
+ Object7 _prof;
+ Object8 _object8;
+ Object9 _object9;
+ Object10 _object10;
+ Object11 _cork;
+ Object12 _emptyJar;
+ SceneObject _object13;
+ SceneObject _object14;
+ SceneObject _object15;
+ SceneObject _cloud;
+ SceneObject _easterEgg1;
+ SceneObject _easterEgg2;
+ SceneObject _object19;
+ Action1 _action1;
+ Action2 _action2;
+ Action3 _action3;
+ Action4 _action4;
+ Action5 _action5;
+ Action6 _action6;
+ SceneHotspot1 _sceneHotspot1;
+ SceneHotspot2 _sceneHotspot2;
+ SceneHotspot3 _sceneHotspot3;
+ SceneHotspot4 _sceneHotspot4;
+ SceneHotspot5 _sceneHotspot5;
+ SceneHotspot6 _sceneHotspot6;
+ SceneItem7 _sceneItem7;
+ SceneHotspot8 _sceneHotspot8;
+ SceneHotspot9 _sceneHotspot9;
+ SceneItem10 _sceneItem10;
+ SceneHotspot11 _sceneHotspot11;
+ SceneHotspot11 _sceneHotspot12;
+ SceneHotspot11 _sceneHotspot13;
+ SceneHotspot11 _sceneHotspot14;
+ SceneHotspot11 _sceneHotspot15;
+ SceneHotspot11 _sceneHotspot16;
+ SceneHotspot11 _sceneHotspot17;
+ SceneHotspot11 _sceneHotspot18;
+ SceneHotspot11 _sceneHotspot19;
+ SceneHotspot11 _sceneHotspot20;
+ SceneHotspot11 _sceneHotspot21;
+ SceneHotspot11 _sceneHotspot22;
+ SceneHotspot11 _sceneHotspot23;
+ SceneHotspot11 _sceneHotspot24;
+ SceneHotspot11 _sceneHotspot25;
+ SceneHotspot11 _sceneHotspot26;
+ SceneHotspot11 _sceneHotspot27;
+ SceneHotspot11 _sceneHotspot28;
+ SceneHotspot11 _sceneHotspot29;
+ SceneHotspot11 _sceneHotspot30;
+ SceneHotspot11 _sceneHotspot31;
+ SceneHotspot11 _sceneHotspot32;
+ SceneHotspot11 _sceneHotspot33;
+ SceneHotspot11 _sceneHotspot34;
+ SceneHotspot11 _sceneHotspot35;
+ SceneHotspot11 _sceneHotspot36;
+ int _field977, _field979, _field97B;
+
+ Scene7700();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
new file mode 100644
index 0000000000..7983e2a34c
--- /dev/null
+++ b/engines/tsage/saveload.cpp
@@ -0,0 +1,387 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/savefile.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+#include "tsage/globals.h"
+#include "tsage/saveload.h"
+#include "tsage/tsage.h"
+
+namespace tSage {
+
+Saver *_saver;
+
+SavedObject::SavedObject() {
+ _saver->addObject(this);
+}
+
+SavedObject::~SavedObject() {
+ _saver->removeObject(this);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Saver::Saver() {
+ _macroSaveFlag = false;
+ _macroRestoreFlag = false;
+}
+
+Saver::~Saver() {
+ // Internal validation that no saved object is still present
+ int totalLost = 0;
+ for (SynchronisedList<SavedObject *>::iterator i = _saver->_objList.begin(); i != _saver->_objList.end(); ++i) {
+ SavedObject *so = *i;
+ if (so)
+ ++totalLost;
+ }
+
+ if (totalLost)
+ warning("Saved object not destroyed");
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Serialiser::syncPointer(SavedObject **ptr, Common::Serializer::Version minVersion,
+ Common::Serializer::Version maxVersion) {
+ int idx;
+ assert(ptr);
+
+ if (isSaving()) {
+ // Get the object index for the given pointer and write it out
+ if (!*ptr) {
+ idx = 0;
+ } else {
+ idx = _saver->blockIndexOf(*ptr);
+ assert(idx > 0);
+ }
+ syncAsUint32LE(idx);
+ } else {
+ // Load in the object index and add it into the unresolved pointer list
+ syncAsUint32LE(idx);
+ *ptr = NULL;
+ if (idx > 0)
+ // For non-zero (null) pointers, create a record for later resolving it to an address
+ _saver->addSavedObjectPtr(ptr, idx);
+ }
+}
+
+void Serialiser::validate(const Common::String &s, Common::Serializer::Version minVersion,
+ Common::Serializer::Version maxVersion) {
+ Common::String tempStr = s;
+ syncString(tempStr, minVersion, maxVersion);
+
+ if (isLoading() && (tempStr != s))
+ error("Savegame is corrupt");
+}
+
+void Serialiser::validate(int v, Common::Serializer::Version minVersion,
+ Common::Serializer::Version maxVersion) {
+ int tempVal = v;
+ syncAsUint32LE(tempVal, minVersion, maxVersion);
+ if (isLoading() && (tempVal != v))
+ error("Savegame is corrupt");
+}
+
+/*--------------------------------------------------------------------------*/
+
+Common::Error Saver::save(int slot, const Common::String &saveName) {
+ assert(!getMacroRestoreFlag());
+
+ // Signal any objects registered for notification
+ _saveNotifiers.notify(false);
+
+ // Set fields
+ _macroSaveFlag = true;
+ _saveSlot = slot;
+
+ // Set up the serialiser
+ Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(_vm->generateSaveName(slot));
+ Serialiser serialiser(NULL, saveFile);
+
+ // Write out the savegame header
+ tSageSavegameHeader header;
+ header.saveName = saveName;
+ header.version = TSAGE_SAVEGAME_VERSION;
+ writeSavegameHeader(saveFile, header);
+
+ // Save out objects that need to come at the start of the savegame
+ for (SynchronisedList<SaveListener *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) {
+ (*i)->listenerSynchronise(serialiser);
+ }
+
+ // Save each registered SaveObject descendant object into the savegame file
+ for (SynchronisedList<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) {
+ serialiser.validate((*i)->getClassName());
+ (*i)->synchronise(serialiser);
+ }
+
+ // Save file complete
+ saveFile->writeString("END");
+ saveFile->finalize();
+ delete saveFile;
+
+ // Final post-save notification
+ _macroSaveFlag = false;
+ _saveNotifiers.notify(true);
+
+ return Common::kNoError;
+}
+
+Common::Error Saver::restore(int slot) {
+ assert(!getMacroSaveFlag());
+
+ // Signal any objects registered for notification
+ _loadNotifiers.notify(false);
+
+ // Set fields
+ _macroSaveFlag = true;
+ _saveSlot = slot;
+ _unresolvedPtrs.clear();
+
+ // Set up the serialiser
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(_vm->generateSaveName(slot));
+ Serialiser serialiser(saveFile, NULL);
+
+ // Read in the savegame header
+ tSageSavegameHeader header;
+ readSavegameHeader(saveFile, header);
+ delete header.thumbnail;
+
+ // Load in data for objects that need to come at the start of the savegame
+ for (Common::List<SaveListener *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) {
+ (*i)->listenerSynchronise(serialiser);
+ }
+
+ // Loop through each registered object to load in the data
+ for (SynchronisedList<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) {
+ serialiser.validate((*i)->getClassName());
+ (*i)->synchronise(serialiser);
+ }
+
+ // Loop through the remaining data of the file, instantiating new objects.
+ // Note: I don't store pointers to instantiated objects here, because it's not necessary - the mere act
+ // of instantiating a saved object registers it with the saver, and will then be resolved to whatever
+ // object originally had a pointer to it as part of the post-processing step
+ Common::String className;
+ serialiser.syncString(className);
+ while (className != "END") {
+ SavedObject *savedObject;
+ if (!_factoryPtr || ((savedObject = _factoryPtr(className)) == NULL))
+ error("Unknown class name '%s' encountered trying to restore savegame", className.c_str());
+
+ // Populate the contents of the object
+ savedObject->synchronise(serialiser);
+
+ // Move to next object
+ serialiser.syncString(className);
+ }
+
+ // Post-process any unresolved pointers to get the correct pointer
+ resolveLoadPointers();
+
+ delete saveFile;
+
+ // Final post-restore notifications
+ _macroRestoreFlag = false;
+ _loadNotifiers.notify(false);
+
+ return Common::kNoError;
+}
+
+const char *SAVEGAME_STR = "SCUMMVM_TSAGE";
+#define SAVEGAME_STR_SIZE 13
+
+bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header) {
+ char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
+ header.thumbnail = NULL;
+
+ // Validate the header Id
+ in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
+ if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE))
+ return false;
+
+ header.version = in->readByte();
+ if (header.version != TSAGE_SAVEGAME_VERSION)
+ return false;
+
+ // Read in the string
+ header.saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0') header.saveName += ch;
+
+ // Get the thumbnail
+ header.thumbnail = new Graphics::Surface();
+ if (!Graphics::loadThumbnail(*in, *header.thumbnail)) {
+ delete header.thumbnail;
+ header.thumbnail = NULL;
+ return false;
+ }
+
+ // Read in save date/time
+ header.saveYear = in->readSint16LE();
+ header.saveMonth = in->readSint16LE();
+ header.saveDay = in->readSint16LE();
+ header.saveHour = in->readSint16LE();
+ header.saveMinutes = in->readSint16LE();
+ header.totalFrames = in->readUint32LE();
+
+ return true;
+}
+
+void Saver::writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header) {
+ // Write out a savegame header
+ out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
+
+ out->writeByte(TSAGE_SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->write(header.saveName.c_str(), header.saveName.size() + 1);
+
+ // Get the active palette
+ uint32 workPal[256];
+ uint8 thumbPalette[256 * 3];
+ const byte *srcP = (const byte *)&workPal[0];
+ byte *destP = &thumbPalette[0];
+ g_system->getPaletteManager()->grabPalette((byte *)workPal, 0, 256);
+ for (int idx = 0; idx < 256; ++idx, ++srcP) {
+ *destP++ = *srcP++;
+ *destP++ = *srcP++;
+ *destP++ = *srcP++;
+ }
+
+ // Create a thumbnail and save it
+ Graphics::Surface *thumb = new Graphics::Surface();
+ Graphics::Surface s = _globals->_screenSurface.lockSurface();
+ ::createThumbnail(thumb, (const byte *)s.pixels, SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette);
+ Graphics::saveThumbnail(*out, *thumb);
+ _globals->_screenSurface.unlockSurface();
+ delete thumb;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ out->writeSint16LE(td.tm_year + 1900);
+ out->writeSint16LE(td.tm_mon + 1);
+ out->writeSint16LE(td.tm_mday);
+ out->writeSint16LE(td.tm_hour);
+ out->writeSint16LE(td.tm_min);
+ out->writeUint32LE(_globals->_events.getFrameNumber());
+}
+
+/**
+ * Adds a serialisable object that should be saved/restored before any other objects
+ */
+void Saver::addListener(SaveListener *obj) {
+ _listeners.push_back(obj);
+}
+
+/**
+ * Adds a listener to be notified before the saving starts
+ */
+void Saver::addSaveNotifier(SaveNotifierFn fn) {
+ _saveNotifiers.push_back(fn);
+}
+
+/**
+ * Adds a listener to be notified before the saving starts
+ */
+void Saver::addLoadNotifier(SaveNotifierFn fn) {
+ _loadNotifiers.push_back(fn);
+}
+
+/**
+ * Registers a SavedObject descendant object for being saved in savegame files
+ */
+void Saver::addObject(SavedObject *obj) {
+ _objList.push_back(obj);
+}
+
+/**
+ * Removes a SavedObject descendant object from the save object list
+ */
+void Saver::removeObject(SavedObject *obj) {
+ _objList.remove(obj);
+}
+
+/**
+ * Returns true if any savegames exist
+ */
+bool Saver::savegamesExist() const {
+ Common::String slot1Name = _vm->generateSaveName(1);
+
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slot1Name);
+ bool result = saveFile != NULL;
+ delete saveFile;
+ return result;
+}
+
+/**
+ * Returns the index of the saved block associated with the given saved object pointer
+ */
+int Saver::blockIndexOf(SavedObject *p) {
+ int objIndex = 1;
+ SynchronisedList<SavedObject *>::iterator iObj;
+
+ for (iObj = _objList.begin(); iObj != _objList.end(); ++iObj, ++objIndex) {
+ SavedObject *iObjP = *iObj;
+ if (iObjP == p)
+ return objIndex;
+ }
+
+ return 0;
+}
+
+/**
+ * Returns the pointer associated with the specified object index
+ */
+void Saver::resolveLoadPointers() {
+ if (_unresolvedPtrs.size() == 0)
+ // Nothing to resolve
+ return;
+
+ // Outer loop through the main object list
+ int objIndex = 1;
+ for (SynchronisedList<SavedObject *>::iterator iObj = _objList.begin(); iObj != _objList.end(); ++iObj, ++objIndex) {
+ Common::List<SavedObjectRef>::iterator iPtr;
+
+ for (iPtr = _unresolvedPtrs.begin(); iPtr != _unresolvedPtrs.end(); ) {
+ SavedObjectRef &r = *iPtr;
+ if (r._objIndex == objIndex) {
+ // Found an unresolved pointer to this object
+ *r._savedObject = *iObj;
+ iPtr = _unresolvedPtrs.erase(iPtr);
+ } else {
+ ++iPtr;
+ }
+ }
+ }
+
+ // At this point, all the unresolved pointers should have been resolved and removed
+ if (_unresolvedPtrs.size() > 0)
+ error("Could not resolve savegame block pointers");
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
new file mode 100644
index 0000000000..83661b8f15
--- /dev/null
+++ b/engines/tsage/saveload.h
@@ -0,0 +1,215 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_SAVELOAD_H
+#define TSAGE_SAVELOAD_H
+
+#include "common/scummsys.h"
+#include "common/list.h"
+#include "common/memstream.h"
+#include "common/savefile.h"
+#include "common/serializer.h"
+
+namespace tSage {
+
+typedef void (*SaveNotifierFn)(bool postFlag);
+
+#define TSAGE_SAVEGAME_VERSION 1
+
+class SavedObject;
+
+struct tSageSavegameHeader {
+ uint8 version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+ int saveYear, saveMonth, saveDay;
+ int saveHour, saveMinutes;
+ int totalFrames;
+};
+
+/*--------------------------------------------------------------------------*/
+
+#define SYNC_POINTER(x) s.syncPointer((SavedObject **)&x)
+#define SYNC_ENUM(FIELD, TYPE) int v_##FIELD = (int)FIELD; s.syncAsUint16LE(v_##FIELD); \
+ if (s.isLoading()) FIELD = (TYPE)v_##FIELD;
+
+/**
+ * Derived serialiser class with extra synchronisation types
+ */
+class Serialiser : public Common::Serializer {
+public:
+ Serialiser(Common::SeekableReadStream *in, Common::WriteStream *out) : Common::Serializer(in, out) {}
+
+ void syncPointer(SavedObject **ptr, Common::Serializer::Version minVersion = 0,
+ Common::Serializer::Version maxVersion = kLastVersion);
+ void validate(const Common::String &s, Common::Serializer::Version minVersion = 0,
+ Common::Serializer::Version maxVersion = kLastVersion);
+ void validate(int v, Common::Serializer::Version minVersion = 0,
+ Common::Serializer::Version maxVersion = kLastVersion);
+};
+
+/*--------------------------------------------------------------------------*/
+
+class Serialisable {
+public:
+ virtual ~Serialisable() {}
+ virtual void synchronise(Serialiser &s) = 0;
+};
+
+class SaveListener {
+public:
+ virtual ~SaveListener() {}
+ virtual void listenerSynchronise(Serialiser &s) = 0;
+};
+
+/*--------------------------------------------------------------------------*/
+
+class SavedObject : public Serialisable {
+public:
+ SavedObject();
+ virtual ~SavedObject();
+
+ virtual Common::String getClassName() { return "SavedObject"; }
+ virtual void synchronise(Serialiser &s) {}
+
+ static SavedObject *createInstance(const Common::String &className);
+};
+
+/*--------------------------------------------------------------------------*/
+
+/**
+ * Derived list class with extra functionality
+ */
+template<typename T>
+class SynchronisedList : public Common::List<T> {
+public:
+ void synchronise(Serialiser &s) {
+ int entryCount;
+
+ if (s.isLoading()) {
+ this->clear();
+ s.syncAsUint32LE(entryCount);
+
+ for (int idx = 0; idx < entryCount; ++idx) {
+ this->push_back(static_cast<T>((T)NULL));
+ T &obj = Common::List<T>::back();
+ s.syncPointer((SavedObject **)&obj);
+ }
+ } else {
+ // Get the list size
+ entryCount = this->size();
+
+ // Write out list
+ s.syncAsUint32LE(entryCount);
+ for (typename Common::List<T>::iterator i = this->begin(); i != this->end(); ++i) {
+ s.syncPointer((SavedObject **)&*i);
+ }
+ }
+ }
+};
+
+/**
+ * Search whether an element is contained in a list.
+ *
+ * @param l List to search.
+ * @param v Element to search for.
+ * @return True in case the element is contained, false otherwise.
+ */
+template<typename T>
+inline bool contains(const Common::List<T> &l, const T &v) {
+ return (Common::find(l.begin(), l.end(), v) != l.end());
+}
+
+/**
+ * Derived list class for holding function pointers
+ */
+template<typename T>
+class FunctionList : public Common::List<void (*)(T)> {
+public:
+ void notify(T v) {
+ for (typename Common::List<void (*)(T)>::iterator i = this->begin(); i != this->end(); ++i) {
+ (*i)(v);
+ }
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+class SavedObjectRef {
+public:
+ SavedObject **_savedObject;
+ int _objIndex;
+
+ SavedObjectRef() : _savedObject(NULL), _objIndex(-1) {}
+ SavedObjectRef(SavedObject **so, int objIndex) : _savedObject(so), _objIndex(objIndex) {}
+};
+
+typedef SavedObject *(*SavedObjectFactory)(const Common::String &className);
+
+class Saver {
+private:
+ SynchronisedList<SavedObject *> _objList;
+ FunctionList<bool> _saveNotifiers;
+ FunctionList<bool> _loadNotifiers;
+ Common::List<SaveListener *> _listeners;
+
+ Common::List<SavedObjectRef> _unresolvedPtrs;
+ SavedObjectFactory _factoryPtr;
+
+ bool _macroSaveFlag;
+ bool _macroRestoreFlag;
+ int _saveSlot;
+
+ void resolveLoadPointers();
+public:
+ Saver();
+ ~Saver();
+
+ Common::Error save(int slot, const Common::String &saveName);
+ Common::Error restore(int slot);
+ static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header);
+ static void writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header);
+
+ void addListener(SaveListener *obj);
+ void addSaveNotifier(SaveNotifierFn fn);
+ void addLoadNotifier(SaveNotifierFn fn);
+ void addObject(SavedObject *obj);
+ void removeObject(SavedObject *obj);
+ void addFactory(SavedObjectFactory fn) { _factoryPtr = fn; }
+ void addSavedObjectPtr(SavedObject **ptr, int objIndex) {
+ _unresolvedPtrs.push_back(SavedObjectRef(ptr, objIndex));
+ }
+
+ bool savegamesExist() const;
+ bool getMacroSaveFlag() const { return _macroSaveFlag; }
+ bool getMacroRestoreFlag() const { return _macroRestoreFlag; }
+ int blockIndexOf(SavedObject *p);
+};
+
+extern Saver *_saver;
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
new file mode 100644
index 0000000000..68320066d7
--- /dev/null
+++ b/engines/tsage/scenes.cpp
@@ -0,0 +1,471 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/ringworld_logic.h"
+#include "tsage/tsage.h"
+
+namespace tSage {
+
+SceneManager::SceneManager() {
+ _scene = NULL;
+ _hasPalette = false;
+ _sceneNumber = -1;
+ _nextSceneNumber = -1;
+ _previousScene = 0;
+ _fadeMode = FADEMODE_GRADUAL;
+ _scrollerRect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ _saver->addListener(this);
+}
+
+SceneManager::~SceneManager() {
+ delete _scene;
+}
+
+void SceneManager::setNewScene(int sceneNumber) {
+ _nextSceneNumber = sceneNumber;
+}
+
+void SceneManager::checkScene() {
+ if (_nextSceneNumber != -1) {
+ sceneChange();
+ _nextSceneNumber = -1;
+ }
+
+ Common::for_each(_globals->_sceneListeners.begin(), _globals->_sceneListeners.end(), SceneHandler::dispatchObject);
+}
+
+void SceneManager::sceneChange() {
+ // Handle removing the scene
+ if (_scene)
+ _scene->remove();
+
+ // Clear the scene objects
+ SynchronisedList<SceneObject *>::iterator io = _globals->_sceneObjects->begin();
+ while (io != _globals->_sceneObjects->end()) {
+ SceneObject *sceneObj = *io;
+ ++io;
+ sceneObj->removeObject();
+ }
+
+ // Clear the secondary scene object list
+ io = _globals->_sceneManager._altSceneObjects.begin();
+ while (io != _globals->_sceneManager._altSceneObjects.end()) {
+ SceneObject *sceneObj = *io;
+ ++io;
+ sceneObj->removeObject();
+ }
+
+ // Clear the hotspot list
+ SynchronisedList<SceneItem *>::iterator ii = _globals->_sceneItems.begin();
+ while (ii != _globals->_sceneItems.end()) {
+ SceneItem *sceneItem = *ii;
+ ++ii;
+ sceneItem->remove();
+ }
+
+ // TODO: Clear _list_45BAA list
+
+ // If there is an active scene, deactivate it
+ if (_scene) {
+ _previousScene = _sceneNumber;
+
+ delete _scene;
+ _scene = NULL;
+ _sceneNumber = -1;
+ }
+
+ // Set the next scene to be active
+ _sceneNumber = _nextSceneNumber;
+
+ // TODO: Unknown check of word_45CD3 / call to saver method
+
+ // Free any regions
+ disposeRegions();
+
+ // Instantiate and set the new scene
+ _scene = getNewScene();
+ _scene->postInit();
+}
+
+Scene *SceneManager::getNewScene() {
+ return SceneFactory::createScene(_nextSceneNumber);
+}
+
+void SceneManager::fadeInIfNecessary() {
+ if (_hasPalette) {
+ uint32 adjustData = 0;
+ for (int percent = 0; percent < 100; percent += 5) {
+ if (_globals->_sceneManager._fadeMode == FADEMODE_IMMEDIATE)
+ percent = 100;
+
+ _globals->_scenePalette.fade((const byte *)&adjustData, false, percent);
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+
+ _globals->_scenePalette.refresh();
+ _hasPalette = false;
+ }
+}
+
+void SceneManager::changeScene(int newSceneNumber) {
+ // Fade out the scene
+ ScenePalette scenePalette;
+ uint32 adjustData = 0;
+ _globals->_scenePalette.clearListeners();
+ scenePalette.getPalette();
+
+ for (int percent = 100; percent >= 0; percent -= 5) {
+ scenePalette.fade((byte *)&adjustData, false, percent);
+ g_system->delayMillis(10);
+ }
+
+ // Stop any objects that were animating
+ SynchronisedList<SceneObject *>::iterator i;
+ for (i = _globals->_sceneObjects->begin(); i != _globals->_sceneObjects->end(); ++i) {
+ SceneObject *sceneObj = *i;
+ Common::Point pt(0, 0);
+ sceneObj->addMover(NULL, &pt);
+ sceneObj->setObjectWrapper(NULL);
+ sceneObj->animate(ANIM_MODE_NONE, 0);
+
+ sceneObj->_flags &= !OBJFLAG_PANES;
+ }
+
+ // Blank out the screen
+ _globals->_screenSurface.fillRect(_globals->_screenSurface.getBounds(), 0);
+
+ // Set the new scene to be loaded
+ setNewScene(newSceneNumber);
+}
+
+void SceneManager::setup() {
+ _saver->addLoadNotifier(SceneManager::loadNotifier);
+ setBackSurface();
+}
+
+void SceneManager::setBackSurface() {
+ int size = _globals->_sceneManager._scene->_backgroundBounds.width() *
+ _globals->_sceneManager._scene->_backgroundBounds.height();
+
+ if (size > 96000) {
+ if (_globals->_sceneManager._scene->_backgroundBounds.width() <= SCREEN_WIDTH) {
+ // Standard size creation
+ _globals->_sceneManager._scene->_backSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT * 3 / 2);
+ _globals->_sceneManager._scrollerRect = Rect(0, 30, SCREEN_WIDTH, SCREEN_HEIGHT - 30);
+ } else {
+ // Wide screen needs extra space to allow for scrolling
+ _globals->_sceneManager._scene->_backSurface.create(SCREEN_WIDTH * 3 / 2, SCREEN_HEIGHT);
+ _globals->_sceneManager._scrollerRect = Rect(80, 0, SCREEN_WIDTH - 80, SCREEN_HEIGHT);
+ }
+ } else {
+ _globals->_sceneManager._scene->_backSurface.create(
+ _globals->_sceneManager._scene->_backgroundBounds.width(),
+ _globals->_sceneManager._scene->_backgroundBounds.height()
+ );
+ _globals->_sceneManager._scrollerRect = Rect(80, 20, SCREEN_WIDTH - 80, SCREEN_HEIGHT - 20);
+ }
+}
+
+void SceneManager::saveListener(int saveMode) {
+ warning("TODO: SceneManager::saveLIstener");
+}
+
+void SceneManager::loadNotifier(bool postFlag) {
+ if (postFlag) {
+ if (_globals->_sceneManager._scene->_activeScreenNumber != -1)
+ _globals->_sceneManager._scene->loadSceneData(_globals->_sceneManager._scene->_activeScreenNumber);
+ _globals->_sceneManager._hasPalette = true;
+ }
+}
+
+void SceneManager::setBgOffset(const Common::Point &pt, int loadCount) {
+ _sceneBgOffset = pt;
+ _sceneLoadCount = loadCount;
+}
+
+void SceneManager::listenerSynchronise(Serialiser &s) {
+ s.validate("SceneManager");
+ _altSceneObjects.synchronise(s);
+
+ s.syncAsSint32LE(_sceneNumber);
+ if (s.isLoading()) {
+ changeScene(_sceneNumber);
+ checkScene();
+ }
+
+ s.syncAsUint16LE(_globals->_sceneManager._scene->_activeScreenNumber);
+ _globals->_sceneManager._scrollerRect.synchronise(s);
+ SYNC_POINTER(_globals->_scrollFollower);
+ s.syncAsSint16LE(_loadMode);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
+ _backgroundBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) {
+ _sceneMode = 0;
+ _oldSceneBounds = Rect(4000, 4000, 4100, 4100);
+}
+
+Scene::~Scene() {
+}
+
+void Scene::synchronise(Serialiser &s) {
+ s.syncAsSint32LE(_field12);
+ s.syncAsSint32LE(_sceneNumber);
+ s.syncAsSint32LE(_activeScreenNumber);
+ s.syncAsSint32LE(_sceneMode);
+ _backgroundBounds.synchronise(s);
+ _sceneBounds.synchronise(s);
+ _oldSceneBounds.synchronise(s);
+ s.syncAsSint16LE(_fieldA);
+ s.syncAsSint16LE(_fieldE);
+
+ for (int i = 0; i < 256; ++i)
+ s.syncAsUint16LE(_enabledSections[i]);
+ for (int i = 0; i < 256; ++i)
+ s.syncAsSint16LE(_zoomPercents[i]);
+}
+
+void Scene::postInit(SceneObjectList *OwnerList) {
+ _action = NULL;
+ _field12 = 0;
+ _sceneMode = 0;
+}
+
+void Scene::process(Event &event) {
+ if (_action)
+ _action->process(event);
+}
+
+void Scene::dispatch() {
+ if (_action)
+ _action->dispatch();
+}
+
+void Scene::loadScene(int sceneNum) {
+ _sceneNumber = sceneNum;
+ if (_globals->_scenePalette.loadPalette(sceneNum))
+ _globals->_sceneManager._hasPalette = true;
+
+ loadSceneData(sceneNum);
+}
+
+void Scene::loadSceneData(int sceneNum) {
+ _globals->_sceneManager._scene->_activeScreenNumber = sceneNum;
+
+ // Get the basic scene size
+ byte *data = _vm->_dataManager->getResource(RES_BITMAP, sceneNum, 9999);
+ _backgroundBounds = Rect(0, 0, READ_LE_UINT16(data), READ_LE_UINT16(data + 2));
+ _globals->_sceneManager._scene->_sceneBounds.contain(_backgroundBounds);
+ DEALLOCATE(data);
+
+ // Set up a surface for storing the scene background
+ SceneManager::setBackSurface();
+
+ // Load the data lists for the scene
+ _globals->_walkRegions.load(sceneNum);
+
+ // Load the item regions of the scene
+ _globals->_sceneRegions.load(sceneNum);
+
+ // Load the priority regions
+ _priorities.load(sceneNum);
+
+ // Initialise the section enabled list
+ Common::set_to(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff);
+
+ _globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160;
+ _globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100;
+ _globals->_paneRefreshFlag[0] = 1;
+ _globals->_paneRefreshFlag[1] = 1;
+ _globals->_sceneManager._loadMode = 1;
+ _globals->_sceneManager._sceneLoadCount = 0;
+ _globals->_sceneManager._sceneBgOffset = Common::Point(0, 0);
+
+ // Load the background for the scene
+ loadBackground(0, 0);
+}
+
+void Scene::loadBackground(int xAmount, int yAmount) {
+ // Adjust the scene bounds by the passed scroll amounts
+ _sceneBounds.translate(xAmount, yAmount);
+ _sceneBounds.contain(_backgroundBounds);
+ _sceneBounds.left &= ~3;
+ _sceneBounds.right &= ~3;
+ _globals->_sceneOffset.x &= ~3;
+
+ if ((_sceneBounds.top != _oldSceneBounds.top) || (_sceneBounds.left != _oldSceneBounds.left)) {
+ if (_globals->_sceneManager._loadMode == 0) {
+ _globals->_paneRefreshFlag[0] = 2;
+ _globals->_paneRefreshFlag[1] = 2;
+ _globals->_sceneManager._loadMode = 2;
+ }
+ _oldSceneBounds = _sceneBounds;
+ }
+
+ _globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160;
+ _globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100;
+
+ if ((_backgroundBounds.width() / 160) == 3)
+ _globals->_sceneOffset.x = 0;
+ if ((_backgroundBounds.height() / 100) == 3)
+ _globals->_sceneOffset.y = 0;
+
+ if ((_globals->_sceneOffset.x != _globals->_prevSceneOffset.x) ||
+ (_globals->_sceneOffset.y != _globals->_prevSceneOffset.y)) {
+ // Change has happend, so refresh background
+ _globals->_prevSceneOffset = _globals->_sceneOffset;
+ refreshBackground(xAmount, yAmount);
+ }
+}
+
+void Scene::refreshBackground(int xAmount, int yAmount) {
+ if (_globals->_sceneManager._scene->_activeScreenNumber == -1)
+ return;
+
+ // Set the quadrant ranges
+ int xHalfCount = MIN(_backSurface.getBounds().width() / 160, _backgroundBounds.width() / 160);
+ int yHalfCount = MIN(_backSurface.getBounds().height() / 100, _backgroundBounds.height() / 100);
+ int xHalfOffset = (_backgroundBounds.width() / 160) == 3 ? 0 : _sceneBounds.left / 160;
+ int yHalfOffset = (_backgroundBounds.height() / 100) == 3 ? 0 : _sceneBounds.top / 100;
+
+ // Set the limits and increment amounts
+ int xInc = (xAmount < 0) ? -1 : 1;
+ int xSectionStart = (xAmount < 0) ? 15 : 0;
+ int xSectionEnd = (xAmount < 0) ? -1 : 16;
+ int yInc = (yAmount < 0) ? -1 : 1;
+ int ySectionStart = (yAmount < 0) ? 15 : 0;
+ int ySectionEnd = (yAmount < 0) ? -1 : 16;
+ bool changedFlag = false;
+
+ for (int yp = ySectionStart; yp != ySectionEnd; yp += yInc) {
+ for (int xp = xSectionStart; xp != xSectionEnd; xp += xInc) {
+ if ((yp < yHalfOffset) || (yp >= (yHalfOffset + yHalfCount)) ||
+ (xp < xHalfOffset) || (xp >= (xHalfOffset + xHalfCount))) {
+ // Flag section as enabled
+ _enabledSections[xp * 16 + yp] = 0xffff;
+ } else {
+ // Check if the section is already loaded
+ if ((_enabledSections[xp * 16 + yp] == 0xffff) || ((xAmount == 0) && (yAmount == 0))) {
+ // Chunk isn't loaded, so load it in
+ Graphics::Surface s = _backSurface.lockSurface();
+ GfxSurface::loadScreenSection(s, xp - xHalfOffset, yp - yHalfOffset, xp, yp);
+ _backSurface.unlockSurface();
+ changedFlag = true;
+ } else {
+ int yv = (_enabledSections[xp * 16 + yp] == ((xp - xHalfOffset) << 4)) ? 0 : 1;
+ if (yv | (yp - yHalfOffset)) {
+ // Copy an existing 160x100 screen section previously loaded
+ int xSectionDest = xp - xHalfOffset;
+ int ySectionDest = yp - yHalfOffset;
+ int xSectionSrc = _enabledSections[xp * 16 + yp] >> 4;
+ int ySectionSrc = _enabledSections[xp * 16 + yp] & 0xf;
+
+ Rect srcBounds(xSectionSrc * 160, ySectionSrc * 100,
+ (xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100);
+ Rect destBounds(xSectionDest * 160, ySectionDest * 100,
+ (xSectionDest + 1) * 160, (ySectionDest + 1) * 100);
+
+ _backSurface.copyFrom(_backSurface, srcBounds, destBounds);
+ }
+ }
+
+ _enabledSections[xp * 16 + yp] =
+ ((xp - xHalfOffset) << 4) | (yp - yHalfOffset);
+ }
+ }
+ }
+
+ if (changedFlag) {
+ drawAltObjects();
+ }
+}
+
+void Scene::drawAltObjects() {
+ Common::Array<SceneObject *> objList;
+
+ // Initial loop to set the priority for entries in the list
+ for (SynchronisedList<SceneObject *>::iterator i = _globals->_sceneManager._altSceneObjects.begin();
+ i != _globals->_sceneManager._altSceneObjects.end(); ++i) {
+ SceneObject *obj = *i;
+ objList.push_back(obj);
+
+ // Handle updating object priority
+ if (!(obj->_flags & OBJFLAG_FIXED_PRIORITY)) {
+ obj->_priority = MIN((int)obj->_position.y - 1,
+ (int)_globals->_sceneManager._scene->_backgroundBounds.bottom);
+ }
+ }
+
+ // Sort the list by priority
+ _globals->_sceneManager._altSceneObjects.sortList(objList);
+
+ // Drawing loop
+ for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
+ SceneObject *obj = objList[objIndex];
+
+ obj->reposition();
+ obj->draw();
+ }
+}
+
+void Scene::setZoomPercents(int yStart, int minPercent, int yEnd, int maxPercent) {
+ int var_6 = 0;
+ int v = 0;
+ while (v < yStart)
+ _zoomPercents[v++] = minPercent;
+
+ int diff1 = ABS(maxPercent - minPercent);
+ int diff2 = ABS(yEnd - yStart);
+ int var_8 = MAX(diff1, diff2);
+
+ while (var_8-- != 0) {
+ _zoomPercents[v] = minPercent;
+ if (diff2 <= diff1) {
+ ++minPercent;
+ var_6 += diff2;
+ if (var_6 >= diff1) {
+ var_6 -= diff1;
+ ++v;
+ }
+ } else {
+ ++v;
+ var_6 += diff1;
+ if (var_6 >= diff2) {
+ var_6 -= diff2;
+ ++minPercent;
+ }
+ }
+ }
+
+ while (yEnd < 256)
+ _zoomPercents[yEnd++] = minPercent;
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/scenes.h b/engines/tsage/scenes.h
new file mode 100644
index 0000000000..1a6f92745d
--- /dev/null
+++ b/engines/tsage/scenes.h
@@ -0,0 +1,115 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_SCENES_H
+#define TSAGE_SCENES_H
+
+#include "common/scummsys.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/saveload.h"
+
+namespace tSage {
+
+class Scene : public StripCallback {
+private:
+ void drawAltObjects();
+public:
+ int _field12;
+ int _sceneNumber;
+ int _activeScreenNumber;
+ int _sceneMode;
+ StripManager _stripManager;
+
+ Rect _backgroundBounds;
+ GfxSurface _backSurface;
+ Rect _sceneBounds;
+ Rect _oldSceneBounds;
+ int _enabledSections[256];
+ int _zoomPercents[256];
+ ScenePriorities _priorities;
+
+ int _fieldA;
+ int _fieldE;
+public:
+ Scene();
+ virtual ~Scene();
+
+ virtual Common::String getClassName() { return "Scene"; }
+ virtual void synchronise(Serialiser &s);
+ virtual void stripCallback(int v) {}
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void loadScene(int sceneNum);
+
+ void setZoomPercents(int yStart, int minPercent, int yEnd, int maxPercent);
+ void loadBackground(int xAmount, int yAmount);
+ void refreshBackground(int xAmount, int yAmount);
+ void loadSceneData(int sceneNum);
+};
+
+class SceneManager : public GameHandler, public SaveListener {
+private:
+ void disposeRegions() { warning("TODO: disposeRegions()"); }
+ Scene *getNewScene();
+public:
+ Scene *_scene;
+ bool _hasPalette;
+ int _loadMode;
+ int _sceneNumber;
+ int _previousScene;
+ int _nextSceneNumber;
+ FadeMode _fadeMode;
+ Common::Point _sceneBgOffset;
+ int _sceneLoadCount;
+ Rect _scrollerRect;
+ SceneObjectList _altSceneObjects;
+public:
+ SceneManager();
+ virtual ~SceneManager();
+
+ virtual void listenerSynchronise(Serialiser &s);
+ void setNewScene(int sceneNumber);
+ void checkScene();
+ void sceneChange();
+ void fadeInIfNecessary();
+ void changeScene(int newSceneNumber);
+ void setBgOffset(const Common::Point &pt, int loadCount);
+
+ void removeAction(Action *action) {
+ // Not currently implemented because addAction method doesn't seem to have any callers
+ }
+
+ static void setup();
+ static void setBackSurface();
+ static void saveListener(int saveMode);
+ static void loadNotifier(bool postFlag);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
new file mode 100644
index 0000000000..7c8325d53e
--- /dev/null
+++ b/engines/tsage/sound.cpp
@@ -0,0 +1,62 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/endian.h"
+#include "tsage/core.h"
+#include "tsage/globals.h"
+#include "tsage/debugger.h"
+#include "tsage/graphics.h"
+
+namespace tSage {
+
+void SoundManager::postInit() {
+ _saver->addSaveNotifier(&SoundManager::saveNotifier);
+ _saver->addLoadNotifier(&SoundManager::loadNotifier);
+ _saver->addListener(this);
+}
+
+void SoundManager::saveNotifier(bool postFlag) {
+ _globals->_soundManager.saveNotifierProc(postFlag);
+}
+
+void SoundManager::saveNotifierProc(bool postFlag) {
+ warning("TODO: SoundManager::saveNotifierProc");
+}
+
+void SoundManager::loadNotifier(bool postFlag) {
+ _globals->_soundManager.loadNotifierProc(postFlag);
+}
+
+void SoundManager::loadNotifierProc(bool postFlag) {
+ warning("TODO: SoundManager::loadNotifierProc");
+}
+
+void SoundManager::listenerSynchronise(Serialiser &s) {
+ s.validate("SoundManager");
+ warning("TODO: SoundManager listenerSynchronise");
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
new file mode 100644
index 0000000000..a495344038
--- /dev/null
+++ b/engines/tsage/sound.h
@@ -0,0 +1,49 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_SOUND_H
+#define TSAGE_SOUND_H
+
+#include "common/scummsys.h"
+#include "tsage/saveload.h"
+
+namespace tSage {
+
+class SoundManager : public SaveListener {
+public:
+ void dispatch() {}
+ virtual void listenerSynchronise(Serialiser &s);
+ virtual void postInit();
+
+ void proc2() {}
+ static void saveNotifier(bool postFlag);
+ void saveNotifierProc(bool postFlag);
+ static void loadNotifier(bool postFlag);
+ void loadNotifierProc(bool postFlag);
+};
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
new file mode 100644
index 0000000000..46b75e30ea
--- /dev/null
+++ b/engines/tsage/staticres.cpp
@@ -0,0 +1,117 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "tsage/staticres.h"
+
+namespace tSage {
+
+const byte CURSOR_ARROW_DATA[] = {
+ 15, 0, 15, 0, 0, 0, 0, 0, 9, 0,
+ 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09
+};
+
+const byte CURSOR_WALK_DATA[] = {
+ 15, 0, 15, 0, 7, 0, 7, 0, 9, 0,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x09, 0x09, 0x09, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09
+};
+
+const char *LOOK_SCENE_HOTSPOT = "You see nothing special.";
+const char *USE_SCENE_HOTSPOT = "That accomplishes nothing.";
+const char *TALK_SCENE_HOTSPOT = "Yak, yak.";
+const char *SPECIAL_SCENE_HOTSPOT = "That is a unique use for that.";
+const char *DEFAULT_SCENE_HOTSPOT = "That accomplishes nothing.";
+const char *SAVE_ERROR_MSG = "Error occurred saving game. Please do not try to restore this game!";
+const char *SAVING_NOT_ALLOWED_MSG = "Saving is not allowed at this time.";
+const char *RESTORING_NOT_ALLOWED_MSG = "Restoring is not allowed at this time.";
+const char *RESTART_CONFIRM_MSG = "Do you want to restart your game?";
+const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
+const char *INV_EMPTY_MSG = "You have nothing in your possesion.";
+
+const char *HELP_MSG = "Ringworld\rRevenge of the Patriarch\x14\rScummVM Version\r\r\
+\x01 Keyboard shortcuts...\rF2 - Sound options\rF3 - Quit\r\
+F4 - Restart\rF5 - Save game\rF7 - Restore Game\rF10 - Pause game";
+const char *QUIT_CONFIRM_MSG = "Do you want to quit playing this game?";
+const char *RESTART_MSG = "Do you want to restart this game?";
+const char *GAME_PAUSED_MSG = "Game is paused.";
+const char *OPTIONS_MSG = "\x01Options...";
+const char *OK_BTN_STRING = " Ok ";
+const char *CANCEL_BTN_STRING = "Cancel";
+const char *QUIT_BTN_STRING = " Quit ";
+const char *RESTART_BTN_STRING = "Restart";
+const char *SAVE_BTN_STRING = "Save";
+const char *RESTORE_BTN_STRING = "Restore";
+const char *SOUND_BTN_STRING = "Sound";
+const char *RESUME_BTN_STRING = " Resume \rplay";
+const char *LOOK_BTN_STRING = "Look";
+const char *PICK_BTN_STRING = "Pick";
+const char *START_PLAY_BTN_STRING = " Start Play ";
+const char *INTRODUCTION_BTN_STRING = "Introduction";
+
+const char *EXIT_MSG = " EXIT ";
+const char *SCENE6100_CAREFUL = "Be careful! The probe cannot handle too much of that.";
+const char *SCENE6100_TOUGHER = "Hey! This is tougher than it looks!";
+const char *SCENE6100_ONE_MORE_HIT = "You had better be more careful. One more hit like that \
+and the probe may be destroyed.";
+const char *SCENE6100_DOING_BEST = "I'm doing the best I can. I just hope it holds together!";
+const char *SCENE6100_REPAIR = "\r\rQuinn and Seeker repair the probe....";
+const char *SCENE6100_ROCKY_AREA = "The rocky area should be directly ahead of you. Do you see it?";
+const char *SCENE6100_REPLY = "Yes. Now if I can just avoid those sunbeams.";
+const char *SCENE6100_TAKE_CONTROLS = "You had better take the controls Seeker. My hands are sweating.";
+const char *SCENE6100_SURPRISE = "You surprise me Quinn. I would have thought you of hardier stock.";
+const char *SCENE6100_SWEAT = "Humans sweat, Kzin twitch their tail. What's the difference?";
+const char *SCENE6100_VERY_WELL = "Very well. I will retrieve the stasis box and return the probe. \
+Wait for it's return in the lander bay.";
+
+} // End of namespace tSage
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
new file mode 100644
index 0000000000..cb62272735
--- /dev/null
+++ b/engines/tsage/staticres.h
@@ -0,0 +1,84 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_STATICRES_H
+#define TSAGE_STATICRES_H
+
+#include "common/scummsys.h"
+
+namespace tSage {
+
+extern const byte CURSOR_ARROW_DATA[];
+
+extern const byte CURSOR_WALK_DATA[];
+
+extern const char *LOOK_SCENE_HOTSPOT;
+extern const char *USE_SCENE_HOTSPOT;
+extern const char *TALK_SCENE_HOTSPOT;
+extern const char *SPECIAL_SCENE_HOTSPOT;
+extern const char *DEFAULT_SCENE_HOTSPOT;
+extern const char *SAVE_ERROR_MSG;
+extern const char *SAVING_NOT_ALLOWED_MSG;
+extern const char *RESTORING_NOT_ALLOWED_MSG;
+extern const char *RESTART_CONFIRM_MSG;
+extern const char *WATCH_INTRO_MSG;
+
+// Dialogs
+extern const char *HELP_MSG;
+extern const char *QUIT_CONFIRM_MSG;
+extern const char *RESTART_MSG;
+extern const char *GAME_PAUSED_MSG;
+extern const char *OPTIONS_MSG;
+extern const char *OK_BTN_STRING;
+extern const char *CANCEL_BTN_STRING;
+extern const char *QUIT_BTN_STRING;
+extern const char *RESTART_BTN_STRING;
+extern const char *SAVE_BTN_STRING;
+extern const char *RESTORE_BTN_STRING;
+extern const char *SOUND_BTN_STRING;
+extern const char *RESUME_BTN_STRING;
+extern const char *LOOK_BTN_STRING;
+extern const char *PICK_BTN_STRING;
+extern const char *INV_EMPTY_MSG;
+extern const char *START_PLAY_BTN_STRING;
+extern const char *INTRODUCTION_BTN_STRING;
+
+// Scene specific resources
+extern const char *EXIT_MSG;
+extern const char *SCENE6100_CAREFUL;
+extern const char *SCENE6100_TOUGHER;
+extern const char *SCENE6100_ONE_MORE_HIT;
+extern const char *SCENE6100_DOING_BEST;
+extern const char *SCENE6100_REPAIR;
+extern const char *SCENE6100_ROCKY_AREA;
+extern const char *SCENE6100_REPLY;
+extern const char *SCENE6100_TAKE_CONTROLS;
+extern const char *SCENE6100_SURPRISE;
+extern const char *SCENE6100_SWEAT;
+extern const char *SCENE6100_VERY_WELL;
+
+} // End of namespace tSage
+
+#endif
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
new file mode 100644
index 0000000000..1f6442f2ff
--- /dev/null
+++ b/engines/tsage/tsage.cpp
@@ -0,0 +1,136 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/system.h"
+#include "common/savefile.h"
+#include "engines/util.h"
+
+#include "tsage/tsage.h"
+#include "tsage/core.h"
+#include "tsage/dialogs.h"
+#include "tsage/events.h"
+#include "tsage/resources.h"
+#include "tsage/globals.h"
+
+namespace tSage {
+
+TSageEngine *_vm = NULL;
+
+TSageEngine::TSageEngine(OSystem *system, const tSageGameDescription *gameDesc) : Engine(system),
+ _gameDescription(gameDesc) {
+ _vm = this;
+ DebugMan.addDebugChannel(kRingDebugScripts, "scripts", "Scripts debugging");
+ _debugger = new Debugger();
+ _dataManager = NULL;
+}
+
+Common::Error TSageEngine::init() {
+ initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, false);
+
+ return Common::kNoError;
+}
+
+TSageEngine::~TSageEngine() {
+ // Remove all of our debug levels here
+ DebugMan.clearAllDebugChannels();
+ delete _debugger;
+}
+
+bool TSageEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+void TSageEngine::initialise() {
+ _tSageManager = new RlbManager(_memoryManager, "tsage.rlb");
+ _dataManager = new RlbManager(_memoryManager, "ring.rlb");
+
+ _saver = new Saver();
+ _globals = new Globals();
+ _globals->gfxManager().setDefaults();
+}
+
+void TSageEngine::deinitialise() {
+ delete _globals;
+ delete _saver;
+ delete _tSageManager;
+ delete _dataManager;
+}
+
+Common::Error TSageEngine::run() {
+ // Basic initialisation
+ initialise();
+
+ _globals->_events.showCursor();
+
+ _globals->_sceneHandler.registerHandler();
+ _globals->_game.execute();
+
+ deinitialise();
+ return Common::kNoError;
+}
+
+/**
+ * Returns true if it is currently okay to restore a game
+ */
+bool TSageEngine::canLoadGameStateCurrently() {
+ return _globals->getFlag(50) == 0;
+}
+
+/**
+ * Returns true if it is currently okay to save the game
+ */
+bool TSageEngine::canSaveGameStateCurrently() {
+ return _globals->getFlag(50) == 0;
+}
+
+/**
+ * Load the savegame at the specified slot index
+ */
+Common::Error TSageEngine::loadGameState(int slot) {
+ return _saver->restore(slot);
+}
+
+/**
+ * Save the game to the given slot index, and with the given name
+ */
+Common::Error TSageEngine::saveGameState(int slot, const char *desc) {
+ return _saver->save(slot, desc);
+}
+
+/**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+Common::String TSageEngine::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+} // End of namespace tSage
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
new file mode 100644
index 0000000000..2a627d80bc
--- /dev/null
+++ b/engines/tsage/tsage.h
@@ -0,0 +1,104 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef TSAGE_H
+#define TSAGE_H
+
+#include "engines/advancedDetector.h"
+#include "engines/engine.h"
+#include "common/rect.h"
+#include "audio/mixer.h"
+#include "common/file.h"
+
+#include "tsage/core.h"
+#include "tsage/resources.h"
+#include "tsage/debugger.h"
+#include "tsage/events.h"
+#include "tsage/graphics.h"
+#include "tsage/resources.h"
+
+
+namespace tSage {
+
+enum {
+ GType_Ringworld = 0,
+ GType_BlueForce = 1
+};
+
+enum {
+ GF_DEMO = 1 << 0,
+ GF_CD = 1 << 1,
+ GF_FLOPPY = 1 << 2
+};
+
+enum {
+ kRingDebugScripts = 1 << 0
+};
+
+struct tSageGameDescription;
+
+#define SCREEN_WIDTH 320
+#define SCREEN_HEIGHT 200
+#define SCREEN_CENTRE_X 160
+#define SCREEN_CENTRE_Y 100
+
+class TSageEngine : public Engine {
+private:
+ const tSageGameDescription *_gameDescription;
+public:
+ TSageEngine(OSystem *system, const tSageGameDescription *gameDesc);
+ ~TSageEngine();
+ virtual bool hasFeature(EngineFeature f) const;
+
+ MemoryManager _memoryManager;
+ Debugger *_debugger;
+ RlbManager *_tSageManager;
+ RlbManager *_dataManager;
+
+ const char *getGameId() const;
+ uint32 getGameID() const;
+ uint32 getFeatures() const;
+
+ virtual Common::Error init();
+ virtual Common::Error run();
+ virtual bool canLoadGameStateCurrently();
+ virtual bool canSaveGameStateCurrently();
+ virtual Common::Error loadGameState(int slot);
+ virtual Common::Error saveGameState(int slot, const char *desc);
+ Common::String generateSaveName(int slot);
+
+ void initialise();
+ void deinitialise();
+};
+
+extern TSageEngine *_vm;
+
+#define ALLOCATE_HANDLE(x) _vm->_memoryManager.allocate(x)
+#define ALLOCATE(x) _vm->_memoryManager.allocate2(x)
+#define DEALLOCATE(x) _vm->_memoryManager.deallocate(x)
+
+} // End of namespace tSage
+
+#endif