aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/advancedDetector.cpp2
-rw-r--r--engines/advancedDetector.h3
-rw-r--r--engines/agi/detection_tables.h1
-rw-r--r--engines/agos/agos.h24
-rw-r--r--engines/agos/saveload.cpp99
-rw-r--r--engines/agos/script_pn.cpp14
-rw-r--r--engines/configure.engines1
-rw-r--r--engines/drascula/actors.cpp16
-rw-r--r--engines/drascula/animation.cpp18
-rw-r--r--engines/drascula/console.cpp2
-rw-r--r--engines/drascula/converse.cpp16
-rw-r--r--engines/drascula/drascula.cpp93
-rw-r--r--engines/drascula/drascula.h14
-rw-r--r--engines/drascula/graphics.cpp14
-rw-r--r--engines/drascula/interface.cpp8
-rw-r--r--engines/drascula/objects.cpp74
-rw-r--r--engines/drascula/rooms.cpp60
-rw-r--r--engines/drascula/saveload.cpp24
-rw-r--r--engines/drascula/sound.cpp16
-rw-r--r--engines/drascula/talk.cpp54
-rw-r--r--engines/engines.mk5
-rw-r--r--engines/fullpipe/behavior.cpp315
-rw-r--r--engines/fullpipe/behavior.h84
-rw-r--r--engines/fullpipe/constants.h179
-rw-r--r--engines/fullpipe/detection.cpp112
-rw-r--r--engines/fullpipe/fullpipe.cpp441
-rw-r--r--engines/fullpipe/fullpipe.h241
-rw-r--r--engines/fullpipe/gameloader.cpp493
-rw-r--r--engines/fullpipe/gameloader.h117
-rw-r--r--engines/fullpipe/gfx.cpp1238
-rw-r--r--engines/fullpipe/gfx.h216
-rw-r--r--engines/fullpipe/init.cpp247
-rw-r--r--engines/fullpipe/input.cpp215
-rw-r--r--engines/fullpipe/input.h77
-rw-r--r--engines/fullpipe/interaction.cpp517
-rw-r--r--engines/fullpipe/interaction.h96
-rw-r--r--engines/fullpipe/inventory.cpp420
-rw-r--r--engines/fullpipe/inventory.h130
-rw-r--r--engines/fullpipe/lift.cpp67
-rw-r--r--engines/fullpipe/messages.cpp727
-rw-r--r--engines/fullpipe/messages.h175
-rw-r--r--engines/fullpipe/modal.cpp106
-rw-r--r--engines/fullpipe/modal.h59
-rw-r--r--engines/fullpipe/module.mk31
-rw-r--r--engines/fullpipe/motion.cpp280
-rw-r--r--engines/fullpipe/motion.h186
-rw-r--r--engines/fullpipe/ngiarchive.cpp156
-rw-r--r--engines/fullpipe/ngiarchive.h69
-rw-r--r--engines/fullpipe/objectnames.h250
-rw-r--r--engines/fullpipe/objects.h97
-rw-r--r--engines/fullpipe/scene.cpp690
-rw-r--r--engines/fullpipe/scene.h108
-rw-r--r--engines/fullpipe/scenes.cpp1508
-rw-r--r--engines/fullpipe/scenes.h53
-rw-r--r--engines/fullpipe/sound.cpp140
-rw-r--r--engines/fullpipe/sound.h61
-rw-r--r--engines/fullpipe/stateloader.cpp339
-rw-r--r--engines/fullpipe/statics.cpp1720
-rw-r--r--engines/fullpipe/statics.h247
-rw-r--r--engines/fullpipe/utils.cpp484
-rw-r--r--engines/fullpipe/utils.h154
-rw-r--r--engines/kyra/text_rpg.cpp2
-rw-r--r--engines/lastexpress/data/scene.h14
-rw-r--r--engines/lastexpress/debug.cpp8
-rw-r--r--engines/lastexpress/game/scenes.cpp4
-rw-r--r--engines/lastexpress/game/state.h1
-rw-r--r--engines/lastexpress/lastexpress.cpp4
-rw-r--r--engines/mohawk/myst.cpp1
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp1
-rw-r--r--engines/mortevielle/actions.cpp289
-rw-r--r--engines/mortevielle/detection.cpp24
-rw-r--r--engines/mortevielle/detection_tables.h120
-rw-r--r--engines/mortevielle/dialogs.cpp63
-rw-r--r--engines/mortevielle/dialogs.h4
-rw-r--r--engines/mortevielle/graphics.cpp21
-rw-r--r--engines/mortevielle/menu.cpp473
-rw-r--r--engines/mortevielle/menu.h77
-rw-r--r--engines/mortevielle/mortevielle.cpp51
-rw-r--r--engines/mortevielle/mortevielle.h54
-rw-r--r--engines/mortevielle/mouse.cpp22
-rw-r--r--engines/mortevielle/outtext.cpp26
-rw-r--r--engines/mortevielle/saveload.cpp28
-rw-r--r--engines/mortevielle/saveload.h2
-rw-r--r--engines/mortevielle/sound.cpp15
-rw-r--r--engines/mortevielle/sound.h1
-rw-r--r--engines/mortevielle/utils.cpp497
-rw-r--r--engines/plugins_table.h3
-rw-r--r--engines/sci/detection.cpp5
-rw-r--r--engines/sci/detection_tables.h8
-rw-r--r--engines/sci/engine/features.cpp6
-rw-r--r--engines/sci/engine/script_patches.cpp24
-rw-r--r--engines/sci/engine/vm_types.cpp32
-rw-r--r--engines/sci/engine/vm_types.h2
-rw-r--r--engines/sci/engine/workarounds.cpp10
-rw-r--r--engines/sci/graphics/picture.cpp16
-rw-r--r--engines/sci/sci.h1
-rw-r--r--engines/scumm/actor.cpp2
-rw-r--r--engines/scumm/detection_tables.h7
-rw-r--r--engines/scumm/gfx.cpp13
-rw-r--r--engines/scumm/he/script_v100he.cpp2
-rw-r--r--engines/scumm/he/script_v70he.cpp2
-rw-r--r--engines/scumm/he/script_v72he.cpp4
-rw-r--r--engines/scumm/insane/insane_enemy.cpp1
-rw-r--r--engines/scumm/module.mk1
-rw-r--r--engines/scumm/player_ad.cpp959
-rw-r--r--engines/scumm/player_ad.h190
-rw-r--r--engines/scumm/saveload.h2
-rw-r--r--engines/scumm/script_v6.cpp2
-rw-r--r--engines/scumm/scumm-md5.h3
-rw-r--r--engines/scumm/scumm.cpp10
-rw-r--r--engines/scumm/scumm.h1
-rw-r--r--engines/scumm/sound.cpp16
-rw-r--r--engines/scumm/vars.cpp6
-rw-r--r--engines/sword25/gfx/microtiles.cpp3
-rw-r--r--engines/testbed/graphics.cpp22
-rw-r--r--engines/tinsel/detection_tables.h20
-rw-r--r--engines/toltecs/detection.cpp14
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp1
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.cpp2
-rw-r--r--engines/tsage/converse.cpp15
-rw-r--r--engines/tsage/core.cpp19
-rw-r--r--engines/tsage/events.cpp2
-rw-r--r--engines/tsage/globals.cpp84
-rw-r--r--engines/tsage/globals.h21
-rw-r--r--engines/tsage/graphics.cpp18
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.cpp14
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp118
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h13
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp624
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h73
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp2608
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h270
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp759
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.h76
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp80
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp125
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.h16
-rw-r--r--engines/tsage/staticres.cpp6
-rw-r--r--engines/tsage/staticres.h6
-rw-r--r--engines/tsage/user_interface.cpp13
-rw-r--r--engines/tsage/user_interface.h2
-rw-r--r--engines/wintermute/ad/ad_region.cpp2
-rw-r--r--engines/wintermute/ad/ad_rot_level.cpp2
-rw-r--r--engines/wintermute/ad/ad_scale_level.cpp2
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.cpp2
-rw-r--r--engines/wintermute/base/base_game.cpp4
-rw-r--r--engines/wintermute/base/base_object.cpp20
-rw-r--r--engines/wintermute/base/base_persistence_manager.cpp69
-rw-r--r--engines/wintermute/base/base_persistence_manager.h4
-rw-r--r--engines/wintermute/base/base_region.cpp2
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp6
-rw-r--r--engines/wintermute/base/gfx/base_renderer.h2
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp43
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h39
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp90
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h4
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp17
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.h13
-rw-r--r--engines/wintermute/base/particles/part_emitter.cpp20
-rw-r--r--engines/wintermute/base/particles/part_particle.cpp10
-rw-r--r--engines/wintermute/base/scriptables/script_engine.cpp9
-rw-r--r--engines/wintermute/base/scriptables/script_value.cpp11
-rw-r--r--engines/wintermute/dcgf.h2
-rw-r--r--engines/wintermute/detection_tables.h86
-rw-r--r--engines/wintermute/graphics/transparent_surface.cpp173
-rw-r--r--engines/wintermute/graphics/transparent_surface.h13
-rw-r--r--engines/wintermute/utils/string_util.cpp23
-rw-r--r--engines/wintermute/video/video_theora_player.cpp2
-rw-r--r--engines/wintermute/wintermute.cpp2
173 files changed, 18563 insertions, 3678 deletions
diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp
index fd0c8dc2da..40783a2407 100644
--- a/engines/advancedDetector.cpp
+++ b/engines/advancedDetector.cpp
@@ -78,7 +78,7 @@ static Common::String generatePreferredTarget(const Common::String &id, const AD
res = res + "-cd";
}
- if (desc->platform != Common::kPlatformDOS && desc->platform != Common::kPlatformUnknown) {
+ if (desc->platform != Common::kPlatformDOS && desc->platform != Common::kPlatformUnknown && !(desc->flags & ADGF_DROPPLATFORM)) {
res = res + "-" + getPlatformAbbrev(desc->platform);
}
diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h
index 71d2c4a446..376a59e471 100644
--- a/engines/advancedDetector.h
+++ b/engines/advancedDetector.h
@@ -87,7 +87,8 @@ enum ADGameFlags {
ADGF_ADDENGLISH = (1 << 24), ///< always add English as language option
ADGF_MACRESFORK = (1 << 25), ///< the md5 for this entry will be calculated from the resource fork
ADGF_USEEXTRAASTITLE = (1 << 26), ///< Extra field value will be used as main game title, not gameid
- ADGF_DROPLANGUAGE = (1 << 28), ///< don't add language to gameid
+ ADGF_DROPLANGUAGE = (1 << 27), ///< don't add language to gameid
+ ADGF_DROPPLATFORM = (1 << 28), ///< don't add platform to gameid
ADGF_CD = (1 << 29), ///< add "-cd" to gameid
ADGF_DEMO = (1 << 30) ///< add "-demo" to gameid
};
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 0c2c3ed3be..f1bb079ffc 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -642,6 +642,7 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("AGI Piano (v1.0)", "8778b3d89eb93c1d50a70ef06ef10310"),
FANMADE("AGI Quest (v1.46-TJ0)", "1cf1a5307c1a0a405f5039354f679814"),
GAME("tetris", "", "7a874e2db2162e7a4ce31c9130248d8a", 0x2917, GID_FANMADE),
+ FANMADE("AGI Tetris (1998)", "1afcbc25bfafded2d5fb82de9da0bd9a"),
FANMADE_V("AGI Trek (Demo)", "c02882b8a8245b629c91caf7eb78eafe", 0x2440),
FANMADE_F("AGI256 Demo", "79261ac143b2e2773b2753674733b0d5", GF_AGI256),
FANMADE_F("AGI256-2 Demo", "3cad9b3aff1467cebf0c5c5b110985c5", GF_AGI256_2),
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 65f8dd1420..87a1228c6a 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -1272,7 +1272,7 @@ protected:
Item *getNextItemPtrStrange();
- virtual bool loadGame(const char *filename, bool restartMode = false);
+ virtual bool loadGame(const Common::String &filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
void openTextWindow();
@@ -1311,7 +1311,7 @@ protected:
int countSaveGames();
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_PN : public AGOSEngine {
@@ -1517,8 +1517,8 @@ protected:
virtual void windowPutChar(WindowBlock *window, byte c, byte b = 0);
bool badload(int8 errorNum);
- int loadFile(char *name);
- int saveFile(char *name);
+ int loadFile(const Common::String &name);
+ int saveFile(const Common::String &name);
void getFilename();
void sysftodb();
void dbtosysf();
@@ -1640,7 +1640,7 @@ protected:
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Elvira2 : public AGOSEngine_Elvira1 {
@@ -1709,7 +1709,7 @@ protected:
virtual void readItemChildren(Common::SeekableReadStream *in, Item *item, uint tmp);
- virtual bool loadGame(const char *filename, bool restartMode = false);
+ virtual bool loadGame(const Common::String &filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
virtual void addArrows(WindowBlock *window, uint8 num);
@@ -1735,7 +1735,7 @@ protected:
virtual void userGame(bool load);
virtual int userGameGetKey(bool *b, char *buf, uint maxChar);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Waxworks : public AGOSEngine_Elvira2 {
@@ -1802,7 +1802,7 @@ protected:
virtual bool confirmOverWrite(WindowBlock *window);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Simon1 : public AGOSEngine_Waxworks {
@@ -1873,7 +1873,7 @@ protected:
virtual void vcStopAnimation(uint16 zone, uint16 sprite);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Simon2 : public AGOSEngine_Simon1 {
@@ -1919,7 +1919,7 @@ protected:
virtual void playSpeech(uint16 speechId, uint16 vgaSpriteId);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
#ifdef ENABLE_AGOS2
@@ -2059,7 +2059,7 @@ protected:
void saveUserGame(int slot);
void windowBackSpace(WindowBlock *window);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
virtual void quickLoadOrSave();
};
@@ -2139,7 +2139,7 @@ protected:
void printInfoText(const char *itemText);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 48671390f0..8eb7f066b3 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -33,32 +33,35 @@
namespace AGOS {
+
+// FIXME: This code counts savegames, but callers in many cases assume
+// that the return value + 1 indicates an empty slot.
int AGOSEngine::countSaveGames() {
Common::InSaveFile *f = NULL;
Common::StringArray filenames;
uint i = 1;
- char slot[4];
int slotNum;
bool marks[256];
- char *prefix = genSaveName(998);
- prefix[strlen(prefix)-3] = '*';
- prefix[strlen(prefix)-2] = '\0';
+ // Get the name of (possibly non-existent) savegame slot 998, and replace
+ // the extension by * to get a pattern.
+ Common::String tmp = genSaveName(998);
+ assert(tmp.size() >= 4 && tmp[tmp.size()-4] == '.');
+ Common::String prefix = Common::String(tmp.c_str(), tmp.size()-3) + "*";
+
memset(marks, false, 256 * sizeof(bool)); //assume no savegames for this title
filenames = _saveFileMan->listSavefiles(prefix);
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file){
//Obtain the last 3 digits of the filename, since they correspond to the save slot
- slot[0] = file->c_str()[file->size()-3];
- slot[1] = file->c_str()[file->size()-2];
- slot[2] = file->c_str()[file->size()-1];
- slot[3] = '\0';
-
- slotNum = atoi(slot);
+ assert(file->size() >= 4);
+ slotNum = atoi(file->c_str() + file->size() - 3);
if (slotNum >= 0 && slotNum < 256)
marks[slotNum] = true; //mark this slot as valid
}
+ // FIXME: Why does this already try to actually open the savegames?
+ // Historical accident?
while (i < 256) {
if (marks[i] &&
(f = _saveFileMan->openForLoading(genSaveName(i)))) {
@@ -72,68 +75,46 @@ int AGOSEngine::countSaveGames() {
}
#ifdef ENABLE_AGOS2
-char *AGOSEngine_PuzzlePack::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_PuzzlePack::genSaveName(int slot) const {
if (getGameId() == GID_DIMP)
- sprintf(buf, "dimp.sav");
+ return "dimp.sav";
else
- sprintf(buf, "swampy.sav");
-
- return buf;
+ return "swampy.sav";
}
-char *AGOSEngine_Feeble::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "feeble.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Feeble::genSaveName(int slot) const {
+ return Common::String::format("feeble.%.3d", slot);
}
#endif
-char *AGOSEngine_Simon2::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon2.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon2::genSaveName(int slot) const {
+ return Common::String::format("simon2.%.3d", slot);
}
-char *AGOSEngine_Simon1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon1::genSaveName(int slot) const {
+ return Common::String::format("simon1.%.3d", slot);
}
-char *AGOSEngine_Waxworks::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Waxworks::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "waxworks-pc.%.3d", slot);
+ return Common::String::format("waxworks-pc.%.3d", slot);
else
- sprintf(buf, "waxworks.%.3d", slot);
-
- return buf;
+ return Common::String::format("waxworks.%.3d", slot);
}
-char *AGOSEngine_Elvira2::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Elvira2::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "elvira2-pc.%.3d", slot);
+ return Common::String::format("elvira2-pc.%.3d", slot);
else
- sprintf(buf, "elvira2.%.3d", slot);
-
- return buf;
+ return Common::String::format("elvira2.%.3d", slot);
}
-char *AGOSEngine_Elvira1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "elvira1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Elvira1::genSaveName(int slot) const {
+ return Common::String::format("elvira1.%.3d", slot);
}
-char *AGOSEngine::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "pn.%.3d", slot);
- return buf;
+Common::String AGOSEngine::genSaveName(int slot) const {
+ return Common::String::format("pn.%.3d", slot);
}
#ifdef ENABLE_AGOS2
@@ -177,12 +158,12 @@ void AGOSEngine::quickLoadOrSave() {
waitForSync(1122);
}
- char *filename = genSaveName(_saveLoadSlot);
+ Common::String filename = genSaveName(_saveLoadSlot);
if (_saveLoadType == 2) {
Subroutine *sub;
success = loadGame(genSaveName(_saveLoadSlot));
if (!success) {
- buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename.c_str());
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
drawIconArray(2, me(), 0, 0);
setBitFlag(97, true);
@@ -217,7 +198,7 @@ void AGOSEngine::quickLoadOrSave() {
} else {
success = saveGame(_saveLoadSlot, _saveLoadName);
if (!success)
- buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename.c_str());
}
if (!success) {
@@ -225,7 +206,7 @@ void AGOSEngine::quickLoadOrSave() {
dialog.runModal();
} else if (_saveLoadType == 1) {
- buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename);
+ buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename.c_str());
GUI::TimedMessageDialog dialog(buf, 1500);
dialog.runModal();
@@ -1041,7 +1022,7 @@ void writeItemID(Common::WriteStream *f, uint16 val) {
f->writeUint32BE(val - 1);
}
-bool AGOSEngine::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i;
@@ -1215,7 +1196,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
return result;
}
-bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i, j;
@@ -1633,7 +1614,7 @@ void AGOSEngine_PN::getFilename() {
}
}
-int AGOSEngine_PN::loadFile(char *name) {
+int AGOSEngine_PN::loadFile(const Common::String &name) {
Common::InSaveFile *f;
haltAnimation();
@@ -1666,7 +1647,7 @@ int AGOSEngine_PN::loadFile(char *name) {
return 0;
}
-int AGOSEngine_PN::saveFile(char *name) {
+int AGOSEngine_PN::saveFile(const Common::String &name) {
Common::OutSaveFile *f;
sysftodb();
haltAnimation();
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 60a1376f25..e98cd2795a 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -370,7 +370,7 @@ void AGOSEngine_PN::opn_opcode30() {
void AGOSEngine_PN::opn_opcode31() {
int a, slot = 0;
- char bf[60];
+ Common::String bf;
if ((a = varval()) > 2) {
setScriptReturn(false);
@@ -381,10 +381,10 @@ void AGOSEngine_PN::opn_opcode31() {
case 0:
getFilename();
slot = matchSaveGame(_saveFile, countSaveGames());
- strcpy(bf, genSaveName(slot));
+ bf = genSaveName(slot);
break;
case 1:
- strcpy(bf, "pn.sav");
+ bf = "pn.sav";
break;
case 2:
// NOTE: Is this case ever used?
@@ -404,7 +404,7 @@ void AGOSEngine_PN::opn_opcode31() {
}
void AGOSEngine_PN::opn_opcode32() {
- char bf[60];
+ Common::String bf;
int a, slot;
a = varval();
@@ -419,12 +419,12 @@ void AGOSEngine_PN::opn_opcode32() {
getFilename();
slot = matchSaveGame(_saveFile, curSlot);
if (slot != -1)
- strcpy(bf, genSaveName(slot));
+ bf = genSaveName(slot);
else
- strcpy(bf, genSaveName(curSlot));
+ bf = genSaveName(curSlot);
break;
case 1:
- strcpy(bf, "pn.sav");
+ bf = "pn.sav";
break;
case 2:
// NOTE: Is this case ever used?
diff --git a/engines/configure.engines b/engines/configure.engines
index 963b9f774f..195cdda6c7 100644
--- a/engines/configure.engines
+++ b/engines/configure.engines
@@ -13,6 +13,7 @@ add_engine cruise "Cinematique evo 2" yes
add_engine draci "Dragon History" yes
add_engine drascula "Drascula: The Vampire Strikes Back" yes
add_engine dreamweb "Dreamweb" yes
+add_engine fullpipe "Full Pipe" yes
add_engine gob "Gobli*ns" yes
add_engine groovie "Groovie" yes "groovie2" "7th Guest"
add_engine groovie2 "Groovie 2 games" no
diff --git a/engines/drascula/actors.cpp b/engines/drascula/actors.cpp
index 9d5d6550fa..e0983809fa 100644
--- a/engines/drascula/actors.cpp
+++ b/engines/drascula/actors.cpp
@@ -135,7 +135,7 @@ void DrasculaEngine::startWalking() {
else
characterMoved = 0;
}
- startTime = getTime();
+ _startTime = getTime();
}
void DrasculaEngine::moveCharacters() {
@@ -239,7 +239,7 @@ void DrasculaEngine::moveCharacters() {
factor_red[curY + curHeight], frontSurface, screenSurface);
}
} else if (characterMoved == 1) {
- curPos[0] = _frameX[num_frame];
+ curPos[0] = _frameX[_characterFrame];
curPos[1] = frame_y + DIF_MASK_HARE;
curPos[2] = curX;
curPos[3] = curY;
@@ -369,13 +369,11 @@ void DrasculaEngine::quadrant_4() {
}
void DrasculaEngine::increaseFrameNum() {
- timeDiff = getTime() - startTime;
-
- if (timeDiff >= 6) {
- startTime = getTime();
- num_frame++;
- if (num_frame == 6)
- num_frame = 0;
+ if (getTime() - _startTime >= 6) {
+ _startTime = getTime();
+ _characterFrame++;
+ if (_characterFrame == 6)
+ _characterFrame = 0;
if (curDirection == kDirectionUp) {
curX -= stepX;
diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 52cab6cd32..1145c8c3ff 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -426,7 +426,7 @@ void DrasculaEngine::animation_2_1() {
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
- roomNumber = 16;
+ _roomNumber = 16;
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
@@ -512,7 +512,7 @@ void DrasculaEngine::animation_2_1() {
// room number to -1 for the same purpose
// Also check animation_9_6(), where the same hack was used by
// the original
- roomNumber = -1;
+ _roomNumber = -1;
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
pause(8);
@@ -734,7 +734,7 @@ void DrasculaEngine::animation_14_2() {
void DrasculaEngine::asco() {
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
black();
updateRoom();
updateScreen();
@@ -1661,7 +1661,7 @@ void DrasculaEngine::animation_9_6() {
// We set the room number to -1 for the same purpose.
// Also check animation_2_1(), where the same hack was used
// by the original
- roomNumber = -2;
+ _roomNumber = -2;
loadPic("nota2.alg", bgSurface, HALF_PAL);
black();
trackProtagonist = 1;
@@ -2176,9 +2176,9 @@ void DrasculaEngine::animation_5_4(){
void DrasculaEngine::animation_6_4() {
debug(4, "animation_6_4()");
- int prevRoom = roomNumber;
+ int prevRoom = _roomNumber;
- roomNumber = 26;
+ _roomNumber = 26;
clearRoom();
loadPic(26, bgSurface, HALF_PAL);
loadPic("aux26.alg", drawSurface3);
@@ -2191,11 +2191,11 @@ void DrasculaEngine::animation_6_4() {
updateScreen();
pause(40);
talk_igor(26, kIgorFront);
- roomNumber = prevRoom;
+ _roomNumber = prevRoom;
clearRoom();
loadPic(96, frontSurface);
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
selectVerb(kVerbNone);
updateRoom();
}
@@ -2224,7 +2224,7 @@ void DrasculaEngine::activatePendulum() {
flags[1] = 2;
hare_se_ve = 0;
- roomNumber = 102;
+ _roomNumber = 102;
loadPic(102, bgSurface, HALF_PAL);
loadPic("an_p1.alg", drawSurface3);
loadPic("an_p2.alg", extraSurface);
diff --git a/engines/drascula/console.cpp b/engines/drascula/console.cpp
index 426b2ade67..c0d2748ec3 100644
--- a/engines/drascula/console.cpp
+++ b/engines/drascula/console.cpp
@@ -41,7 +41,7 @@ bool Console::Cmd_Room(int argc, const char **argv) {
int roomNum = atoi(argv[1]);
- _vm->loadedDifferentChapter = 0;
+ _vm->_loadedDifferentChapter = false;
_vm->enterRoom(roomNum);
_vm->selectVerb(kVerbNone);
_vm->clearRoom();
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index d045d683fc..95a5f7d87f 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -216,7 +216,7 @@ void DrasculaEngine::converse(int index) {
phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3);
phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected);
- if (mouseY > 0 && mouseY < phrase1_bottom) {
+ if (_mouseY > 0 && _mouseY < phrase1_bottom) {
if (game1 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game1 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -224,13 +224,13 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase1, 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game1 = kDialogOptionClicked;
talk(phrase1, sound1);
response(answer1);
}
- } else if (mouseY > phrase1_bottom && mouseY < phrase2_bottom) {
+ } else if (_mouseY > phrase1_bottom && _mouseY < phrase2_bottom) {
if (game2 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game2 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -238,13 +238,13 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game2 = kDialogOptionClicked;
talk(phrase2, sound2);
response(answer2);
}
- } else if (mouseY > phrase2_bottom && mouseY < phrase3_bottom) {
+ } else if (_mouseY > phrase2_bottom && _mouseY < phrase3_bottom) {
if (game3 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game3 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -252,16 +252,16 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game3 = kDialogOptionClicked;
talk(phrase3, sound3);
response(answer3);
}
- } else if (mouseY > phrase3_bottom && mouseY < phrase4_bottom) {
+ } else if (_mouseY > phrase3_bottom && _mouseY < phrase4_bottom) {
print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
talk(phrase4, sound4);
breakOut = 1;
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index 804881cf9a..cde00baa32 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -91,10 +91,10 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
_color = 0;
blinking = 0;
- mouseX = 0;
- mouseY = 0;
- leftMouseButton = 0;
- rightMouseButton = 0;
+ _mouseX = 0;
+ _mouseY = 0;
+ _leftMouseButton = 0;
+ _rightMouseButton = 0;
*textName = 0;
_rnd = new Common::RandomSource("drascula");
@@ -197,7 +197,7 @@ Common::Error DrasculaEngine::run() {
syncSoundSettings();
currentChapter = 1; // values from 1 to 6 will start each part of game
- loadedDifferentChapter = 0;
+ _loadedDifferentChapter = false;
setTotalPlayTime(0);
// Check if a save is loaded from the launcher
@@ -218,7 +218,7 @@ Common::Error DrasculaEngine::run() {
curX = -1;
characterMoved = 0;
trackProtagonist = 3;
- num_frame = 0;
+ _characterFrame = 0;
hare_se_ve = 1;
checkFlags = 1;
doBreak = 0;
@@ -231,9 +231,6 @@ Common::Error DrasculaEngine::run() {
curWidth = CHARACTER_WIDTH;
feetHeight = FEET_HEIGHT;
- talkHeight = TALK_HEIGHT;
- talkWidth = TALK_WIDTH;
-
hasAnswer = 0;
savedTime = 0;
breakOut = 0;
@@ -246,7 +243,7 @@ Common::Error DrasculaEngine::run() {
globalSpeed = 0;
curExcuseLook = 0;
curExcuseAction = 0;
- roomNumber = 0;
+ _roomNumber = 0;
for (i = 0; i < 8; i++)
actorFrames[i] = 0;
@@ -268,7 +265,7 @@ Common::Error DrasculaEngine::run() {
loadPic("aux13.alg", bgSurface, COMPLETE_PAL);
loadPic(96, frontSurface);
} else if (currentChapter == 4) {
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
animation_castle();
loadPic(96, frontSurface);
clearRoom();
@@ -330,7 +327,7 @@ void DrasculaEngine::endChapter() {
bool DrasculaEngine::runCurrentChapter() {
int n;
- rightMouseButton = 0;
+ _rightMouseButton = 0;
previousMusic = -1;
@@ -360,14 +357,14 @@ bool DrasculaEngine::runCurrentChapter() {
if (currentChapter == 1) {
pickObject(28);
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
animation_1_1();
selectVerb(kVerbNone);
loadPic("2aux62.alg", drawSurface2);
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter != 0) {
+ if (_loadedDifferentChapter) {
if (!loadGame(_currentSaveSlot)) {
return true;
}
@@ -383,7 +380,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemPhone);
trackProtagonist = 3;
objExit = 162;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(14);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -401,7 +398,7 @@ bool DrasculaEngine::runCurrentChapter() {
flags[1] = 1;
trackProtagonist = 1;
objExit = 99;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(20);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -415,7 +412,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemReefer2);
addObject(kItemOneCoin2);
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(21);
trackProtagonist = 0;
curX = 235;
@@ -437,7 +434,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(20);
trackProtagonist = 1;
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(45);
} else {
if (!loadGame(_currentSaveSlot)) {
@@ -450,7 +447,7 @@ bool DrasculaEngine::runCurrentChapter() {
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(58);
animation_1_6();
} else {
@@ -480,13 +477,13 @@ bool DrasculaEngine::runCurrentChapter() {
// lead to an incorrect setting of the protagonist's tracking flag (above). This
// made the character start walking off screen, as his actual position was
// different than the displayed one
- if (roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
+ if (_roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
gotoObject(178, 121);
gotoObject(169, 135);
- } else if (roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
+ } else if (_roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
walkToObject = 1;
gotoObject(190, 130);
- } else if (roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
+ } else if (_roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
walkToObject = 1;
gotoObject(190, 130);
}
@@ -518,12 +515,12 @@ bool DrasculaEngine::runCurrentChapter() {
checkObjects();
#ifdef _WIN32_WCE
- if (rightMouseButton) {
+ if (_rightMouseButton) {
if (_menuScreen) {
#else
- if (rightMouseButton == 1 && _menuScreen) {
+ if (_rightMouseButton == 1 && _menuScreen) {
#endif
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
if (currentChapter == 2) {
loadPic(menuBackground, cursorSurface);
@@ -549,10 +546,10 @@ bool DrasculaEngine::runCurrentChapter() {
// Do not show the inventory screen in chapter 5, if the right mouse button is clicked
// while the plug (object 16) is held
// Fixes bug #2059621 - "DRASCULA: Plug bug"
- if (rightMouseButton == 1 && !_menuScreen &&
+ if (_rightMouseButton == 1 && !_menuScreen &&
!(currentChapter == 5 && pickedObject == 16)) {
#endif
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
characterMoved = 0;
if (trackProtagonist == 2)
@@ -580,19 +577,19 @@ bool DrasculaEngine::runCurrentChapter() {
}
#endif
- if (leftMouseButton == 1 && _menuBar) {
+ if (_leftMouseButton == 1 && _menuBar) {
delay(100);
selectVerbFromBar();
- } else if (leftMouseButton == 1 && takeObject == 0) {
+ } else if (_leftMouseButton == 1 && takeObject == 0) {
delay(100);
if (verify1())
return true;
- } else if (leftMouseButton == 1 && takeObject == 1) {
+ } else if (_leftMouseButton == 1 && takeObject == 1) {
if (verify2())
return true;
}
- _menuBar = (mouseY < 24 && !_menuScreen) ? true : false;
+ _menuBar = (_mouseY < 24 && !_menuScreen) ? true : false;
Common::KeyCode key = getScan();
if (key == Common::KEYCODE_F1 && !_menuScreen) {
@@ -644,11 +641,11 @@ bool DrasculaEngine::runCurrentChapter() {
} else if (key == Common::KEYCODE_TILDE || key == Common::KEYCODE_BACKQUOTE) {
_console->attach();
_console->onFrame();
- } else if (currentChapter == 6 && key == Common::KEYCODE_0 && roomNumber == 61) {
+ } else if (currentChapter == 6 && key == Common::KEYCODE_0 && _roomNumber == 61) {
loadPic("alcbar.alg", bgSurface, 255);
}
- if (leftMouseButton != 0 || rightMouseButton != 0 || key != 0)
+ if (_leftMouseButton != 0 || _rightMouseButton != 0 || key != 0)
framesWithoutAction = 0;
if (framesWithoutAction == 15000) {
@@ -670,8 +667,8 @@ bool DrasculaEngine::verify1() {
removeObject();
else {
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX >= _objectX1[l] && mouseY >= _objectY1[l]
- && mouseX <= _objectX2[l] && mouseY <= _objectY2[l] && doBreak == 0) {
+ if (_mouseX >= _objectX1[l] && _mouseY >= _objectY1[l]
+ && _mouseX <= _objectX2[l] && _mouseY <= _objectY2[l] && doBreak == 0) {
if (exitRoom(l))
return true;
if (doBreak == 1)
@@ -679,13 +676,13 @@ bool DrasculaEngine::verify1() {
}
}
- if (mouseX > curX && mouseY > curY
- && mouseX < curX + curWidth && mouseY < curY + curHeight)
+ if (_mouseX > curX && _mouseY > curY
+ && _mouseX < curX + curWidth && _mouseY < curY + curHeight)
doBreak = 1;
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l] && doBreak == 0) {
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l] && doBreak == 0) {
roomX = roomObjX[l];
roomY = roomObjY[l];
trackFinal = trackObj[l];
@@ -696,8 +693,8 @@ bool DrasculaEngine::verify1() {
}
if (doBreak == 0) {
- roomX = CLIP(mouseX, floorX1, floorX2);
- roomY = CLIP(mouseY, floorY1 + feetHeight, floorY2);
+ roomX = CLIP(_mouseX, floorX1, floorX2);
+ roomY = CLIP(_mouseY, floorY1 + feetHeight, floorY2);
startWalking();
}
doBreak = 0;
@@ -718,8 +715,8 @@ bool DrasculaEngine::verify2() {
return true;
} else {
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l] && visible[l] == 1) {
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l] && visible[l] == 1) {
trackFinal = trackObj[l];
walkToObject = 1;
gotoObject(roomObjX[l], roomObjY[l]);
@@ -779,20 +776,20 @@ void DrasculaEngine::updateEvents() {
case Common::EVENT_KEYUP:
break;
case Common::EVENT_MOUSEMOVE:
- mouseX = event.mouse.x;
- mouseY = event.mouse.y;
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
break;
case Common::EVENT_LBUTTONDOWN:
- leftMouseButton = 1;
+ _leftMouseButton = 1;
break;
case Common::EVENT_LBUTTONUP:
- leftMouseButton = 0;
+ _leftMouseButton = 0;
break;
case Common::EVENT_RBUTTONDOWN:
// We changed semantic and react only on button up event
break;
case Common::EVENT_RBUTTONUP:
- rightMouseButton = 1;
+ _rightMouseButton = 1;
break;
default:
break;
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index c4d1c4c761..944191b5fb 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -403,7 +403,7 @@ public:
int actorFrames[8];
int previousMusic, roomMusic;
- int roomNumber;
+ int _roomNumber;
char roomDisk[20];
char currentData[20];
int numRoomObjs;
@@ -428,18 +428,17 @@ public:
int flags[NUM_FLAGS];
int frame_y;
- int curX, curY, characterMoved, curDirection, trackProtagonist, num_frame;
+ int curX, curY, characterMoved, curDirection, trackProtagonist, _characterFrame;
int hare_se_ve; // TODO: what is this for?
int roomX, roomY, checkFlags;
int doBreak;
int stepX, stepY;
int curHeight, curWidth, feetHeight;
- int talkHeight, talkWidth;
int floorX1, floorY1, floorX2, floorY2;
int lowerLimit, upperLimit;
int trackFinal, walkToObject;
int objExit;
- int timeDiff, startTime;
+ int _startTime;
int hasAnswer;
int savedTime;
int breakOut;
@@ -454,14 +453,11 @@ public:
int framesWithoutAction;
int term_int;
int currentChapter;
- int loadedDifferentChapter;
+ bool _loadedDifferentChapter;
int _currentSaveSlot;
int _color;
int musicStopped;
- int mouseX;
- int mouseY;
- int leftMouseButton;
- int rightMouseButton;
+ int _mouseX, _mouseY, _leftMouseButton, _rightMouseButton;
Common::KeyState _keyBuffer[KEYBUFSIZE];
int _keyBufferHead;
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 31d03a94a7..b28de669b6 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -82,7 +82,7 @@ void DrasculaEngine::moveCursor() {
} else if (!_menuScreen && _color != kColorLightGreen)
color_abc(kColorLightGreen);
if (_hasName && !_menuScreen)
- centerText(textName, mouseX, mouseY);
+ centerText(textName, _mouseX, _mouseY);
if (_menuScreen)
showMenu();
else if (_menuBar)
@@ -417,8 +417,8 @@ void DrasculaEngine::screenSaver() {
delete stream;
updateEvents();
- xr = mouseX;
- yr = mouseY;
+ xr = _mouseX;
+ yr = _mouseY;
while (!shouldQuit()) {
// efecto(bgSurface);
@@ -480,18 +480,18 @@ void DrasculaEngine::screenSaver() {
// end of efecto()
updateEvents();
- if (rightMouseButton == 1 || leftMouseButton == 1)
+ if (_rightMouseButton == 1 || _leftMouseButton == 1)
break;
- if (mouseX != xr)
+ if (_mouseX != xr)
break;
- if (mouseY != yr)
+ if (_mouseY != yr)
break;
}
// fin_ghost();
free(copia);
free(ghost);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
showCursor();
}
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index fca8040f59..f0b6d12027 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -51,7 +51,7 @@ bool DrasculaEngine::isCursorVisible() {
void DrasculaEngine::selectVerbFromBar() {
for (int n = 0; n < 7; n++) {
- if (mouseX > _verbBarX[n] && mouseX < _verbBarX[n + 1] && n > 0) {
+ if (_mouseX > _verbBarX[n] && _mouseX < _verbBarX[n + 1] && n > 0) {
selectVerb(n);
return;
}
@@ -143,7 +143,7 @@ void DrasculaEngine::clearMenu() {
int n, verbActivated = 1;
for (n = 0; n < 7; n++) {
- if (mouseX > _verbBarX[n] && mouseX < _verbBarX[n + 1])
+ if (_mouseX > _verbBarX[n] && _mouseX < _verbBarX[n + 1])
verbActivated = 0;
copyRect(OBJWIDTH * n, OBJHEIGHT * verbActivated, _verbBarX[n], 2,
OBJWIDTH, OBJHEIGHT, cursorSurface, screenSurface);
@@ -165,8 +165,8 @@ void DrasculaEngine::showMap() {
_hasName = false;
for (int l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l]
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l]
&& visible[l] == 1) {
strcpy(textName, objName[l]);
_hasName = true;
diff --git a/engines/drascula/objects.cpp b/engines/drascula/objects.cpp
index f9f68c3317..35dfd3162a 100644
--- a/engines/drascula/objects.cpp
+++ b/engines/drascula/objects.cpp
@@ -91,8 +91,8 @@ void DrasculaEngine::gotoObject(int pointX, int pointY) {
updateRoom();
updateScreen();
- // roomNumber -2 is end credits. Do not show cursor there
- if (cursorVisible && roomNumber != -2)
+ // _roomNumber -2 is end credits. Do not show cursor there
+ if (cursorVisible && _roomNumber != -2)
showCursor();
}
@@ -100,8 +100,8 @@ void DrasculaEngine::checkObjects() {
int l, veo = 0;
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l]
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l]
&& visible[l] == 1 && isDoor[l] == 0) {
strcpy(textName, objName[l]);
_hasName = true;
@@ -109,8 +109,8 @@ void DrasculaEngine::checkObjects() {
}
}
- if (mouseX > curX + 2 && mouseY > curY + 2
- && mouseX < curX + curWidth - 2 && mouseY < curY + curHeight - 2) {
+ if (_mouseX > curX + 2 && _mouseY > curY + 2
+ && _mouseX < curX + curWidth - 2 && _mouseY < curY + curHeight - 2) {
if (currentChapter == 2 || veo == 0) {
strcpy(textName, "hacker");
_hasName = true;
@@ -223,9 +223,9 @@ int DrasculaEngine::whichObject() {
int n;
for (n = 1; n < ARRAYSIZE(inventoryObjects); n++) {
- if (mouseX > _itemLocations[n].x && mouseY > _itemLocations[n].y &&
- mouseX < _itemLocations[n].x + OBJWIDTH &&
- mouseY < _itemLocations[n].y + OBJHEIGHT) {
+ if (_mouseX > _itemLocations[n].x && _mouseY > _itemLocations[n].y &&
+ _mouseX < _itemLocations[n].x + OBJWIDTH &&
+ _mouseY < _itemLocations[n].y + OBJHEIGHT) {
return n;
}
}
@@ -237,69 +237,69 @@ void DrasculaEngine::updateVisible() {
if (currentChapter == 1) {
// nothing
} else if (currentChapter == 2) {
- if (roomNumber == 2 && flags[40] == 0)
+ if (_roomNumber == 2 && flags[40] == 0)
visible[3] = 0;
- else if (roomNumber == 3 && flags[3] == 1)
+ else if (_roomNumber == 3 && flags[3] == 1)
visible[8] = 0;
- else if (roomNumber == 6 && flags[1] == 1 && flags[10] == 0) {
+ else if (_roomNumber == 6 && flags[1] == 1 && flags[10] == 0) {
visible[2] = 0;
visible[4] = 1;
- } else if (roomNumber == 7 && flags[35] == 1)
+ } else if (_roomNumber == 7 && flags[35] == 1)
visible[3] = 0;
- else if (roomNumber == 14 && flags[5] == 1)
+ else if (_roomNumber == 14 && flags[5] == 1)
visible[4] = 0;
- else if (roomNumber == 18 && flags[28] == 1)
+ else if (_roomNumber == 18 && flags[28] == 1)
visible[2] = 0;
} else if (currentChapter == 3) {
// nothing
} else if (currentChapter == 4) {
- if (roomNumber == 23 && flags[0] == 0 && flags[11] == 0)
+ if (_roomNumber == 23 && flags[0] == 0 && flags[11] == 0)
visible[2] = 1;
- if (roomNumber == 23 && flags[0] == 1 && flags[11] == 0)
+ if (_roomNumber == 23 && flags[0] == 1 && flags[11] == 0)
visible[2] = 0;
- if (roomNumber == 21 && flags[10] == 1)
+ if (_roomNumber == 21 && flags[10] == 1)
visible[2] = 0;
- if (roomNumber == 22 && flags[26] == 1) {
+ if (_roomNumber == 22 && flags[26] == 1) {
visible[2] = 0;
visible[1] = 1;
}
- if (roomNumber == 22 && flags[27] == 1)
+ if (_roomNumber == 22 && flags[27] == 1)
visible[3] = 0;
- if (roomNumber == 26 && flags[21] == 0)
+ if (_roomNumber == 26 && flags[21] == 0)
strcpy(objName[2], _textmisc[0]);
- if (roomNumber == 26 && flags[18] == 1)
+ if (_roomNumber == 26 && flags[18] == 1)
visible[2] = 0;
- if (roomNumber == 26 && flags[12] == 1)
+ if (_roomNumber == 26 && flags[12] == 1)
visible[1] = 0;
- if (roomNumber == 35 && flags[14] == 1)
+ if (_roomNumber == 35 && flags[14] == 1)
visible[2] = 0;
- if (roomNumber == 35 && flags[17] == 1)
+ if (_roomNumber == 35 && flags[17] == 1)
visible[3] = 1;
- if (roomNumber == 35 && flags[15] == 1)
+ if (_roomNumber == 35 && flags[15] == 1)
visible[1] = 0;
} else if (currentChapter == 5) {
- if (roomNumber == 49 && flags[6] == 1)
+ if (_roomNumber == 49 && flags[6] == 1)
visible[2] = 0;
- if (roomNumber == 49 && flags[6] == 0)
+ if (_roomNumber == 49 && flags[6] == 0)
visible[1] = 0;
- if (roomNumber == 49 && flags[6] == 1)
+ if (_roomNumber == 49 && flags[6] == 1)
visible[1] = 1;
- if (roomNumber == 45 && flags[6] == 1)
+ if (_roomNumber == 45 && flags[6] == 1)
visible[3] = 1;
- if (roomNumber == 53 && flags[2] == 1)
+ if (_roomNumber == 53 && flags[2] == 1)
visible[3] = 0;
- if (roomNumber == 54 && flags[13] == 1)
+ if (_roomNumber == 54 && flags[13] == 1)
visible[3] = 0;
- if (roomNumber == 55 && flags[8] == 1)
+ if (_roomNumber == 55 && flags[8] == 1)
visible[1] = 0;
} else if (currentChapter == 6) {
- if (roomNumber == 58 && flags[8] == 0)
+ if (_roomNumber == 58 && flags[8] == 0)
isDoor[1] = 0;
- if (roomNumber == 58 && flags[8] == 1)
+ if (_roomNumber == 58 && flags[8] == 1)
isDoor[1] = 1;
- if (roomNumber == 59)
+ if (_roomNumber == 59)
isDoor[1] = 0;
- if (roomNumber == 60) {
+ if (_roomNumber == 60) {
trackDrascula = 0;
drasculaX = 155;
drasculaY = 69;
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 9f707eaa07..25f3da0080 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1087,7 +1087,7 @@ bool DrasculaEngine::room_102(int fl) {
void DrasculaEngine::updateRefresh() {
// Check generic updaters
for (int i = 0; i < _roomUpdatesSize; i++) {
- if (_roomUpdates[i].roomNum == roomNumber) {
+ if (_roomUpdates[i].roomNum == _roomNumber) {
if (_roomUpdates[i].flag < 0 ||
flags[_roomUpdates[i].flag] == _roomUpdates[i].flagValue) {
if (_roomUpdates[i].type == 0) {
@@ -1107,25 +1107,25 @@ void DrasculaEngine::updateRefresh() {
// Call room-specific updater
char rm[20];
- sprintf(rm, "update_%d", roomNumber);
+ sprintf(rm, "update_%d", _roomNumber);
for (uint i = 0; i < _roomHandlers->roomUpdaters.size(); i++) {
if (!strcmp(rm, _roomHandlers->roomUpdaters[i]->desc)) {
- debug(8, "Calling room updater %d", roomNumber);
+ debug(8, "Calling room updater %d", _roomNumber);
(this->*(_roomHandlers->roomUpdaters[i]->proc))();
break;
}
}
- if (roomNumber == 10)
+ if (_roomNumber == 10)
showMap();
- else if (roomNumber == 45)
+ else if (_roomNumber == 45)
showMap();
}
void DrasculaEngine::updateRefresh_pre() {
// Check generic preupdaters
for (int i = 0; i < _roomPreUpdatesSize; i++) {
- if (_roomPreUpdates[i].roomNum == roomNumber) {
+ if (_roomPreUpdates[i].roomNum == _roomNumber) {
if (_roomPreUpdates[i].flag < 0 ||
flags[_roomPreUpdates[i].flag] == _roomPreUpdates[i].flagValue) {
if (_roomPreUpdates[i].type == 0) {
@@ -1145,16 +1145,16 @@ void DrasculaEngine::updateRefresh_pre() {
// Call room-specific preupdater
char rm[20];
- sprintf(rm, "update_%d_pre", roomNumber);
+ sprintf(rm, "update_%d_pre", _roomNumber);
for (uint i = 0; i < _roomHandlers->roomPreupdaters.size(); i++) {
if (!strcmp(rm, _roomHandlers->roomPreupdaters[i]->desc)) {
- debug(8, "Calling room preupdater %d", roomNumber);
+ debug(8, "Calling room preupdater %d", _roomNumber);
(this->*(_roomHandlers->roomPreupdaters[i]->proc))();
break;
}
}
- if (currentChapter == 1 && roomNumber == 16)
+ if (currentChapter == 1 && _roomNumber == 16)
placeBJ();
}
@@ -1577,12 +1577,12 @@ bool DrasculaEngine::checkAction(int fl) {
hasAnswer = 0;
} else if (currentChapter == 2) {
// Note: the original check was strcmp(num_room, "18.alg")
- if (pickedObject == 11 && fl == 50 && flags[22] == 0 && roomNumber != 18)
+ if (pickedObject == 11 && fl == 50 && flags[22] == 0 && _roomNumber != 18)
talk(315);
else
hasAnswer = 0;
} else if (currentChapter == 3) {
- if (roomNumber == 13) {
+ if (_roomNumber == 13) {
if (room(13, fl)) {
showCursor();
return true;
@@ -1590,13 +1590,13 @@ bool DrasculaEngine::checkAction(int fl) {
} else
hasAnswer = 0;
} else if (currentChapter == 4) {
- if (roomNumber == 28)
+ if (_roomNumber == 28)
talk(178);
else if (pickedObject == 8 && fl == 50 && flags[18] == 0)
talk(481);
else if (pickedObject == 12 && fl == 50 && flags[18] == 0)
talk(487);
- else if (roomNumber == 21) {
+ else if (_roomNumber == 21) {
if (room(21, fl)) {
showCursor();
return true;
@@ -1604,7 +1604,7 @@ bool DrasculaEngine::checkAction(int fl) {
} else
hasAnswer = 0;
} else if (currentChapter == 5) {
- if (roomNumber == 56) {
+ if (_roomNumber == 56) {
if (room(56, fl)) {
showCursor();
return true;
@@ -1616,9 +1616,9 @@ bool DrasculaEngine::checkAction(int fl) {
talk(308);
else if (pickedObject == kVerbLook && fl == 50 && flags[0] == 0)
talk(310);
- else if (roomNumber == 102)
+ else if (_roomNumber == 102)
room(102, fl);
- else if (roomNumber == 60) {
+ else if (_roomNumber == 60) {
if (room(60, fl)) {
showCursor();
return true;
@@ -1632,7 +1632,7 @@ bool DrasculaEngine::checkAction(int fl) {
if (hasAnswer == 0) {
hasAnswer = 1;
- room(roomNumber, fl);
+ room(_roomNumber, fl);
}
if (hasAnswer == 0 && (_hasName || _menuScreen))
@@ -1684,7 +1684,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
TextResourceParser p(stream, DisposeAfterUse::YES);
- p.parseInt(roomNumber);
+ p.parseInt(_roomNumber);
p.parseInt(roomMusic);
p.parseString(roomDisk);
p.parseInt(palLevel);
@@ -1778,7 +1778,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
copyBackground(0, 171, 0, 0, OBJWIDTH, OBJHEIGHT, backSurface, drawSurface3);
@@ -1808,14 +1808,14 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
}
- if (roomNumber == 24) {
+ if (_roomNumber == 24) {
for (l = floorY1 - 1; l > 74; l--) {
factor_red[l] = (int)(upperLimit - pequegnez);
pequegnez = pequegnez + chiquez;
}
}
- if (currentChapter == 5 && roomNumber == 54) {
+ if (currentChapter == 5 && _roomNumber == 54) {
for (l = floorY1 - 1; l > 84; l--) {
factor_red[l] = (int)(upperLimit - pequegnez);
pequegnez = pequegnez + chiquez;
@@ -1853,13 +1853,13 @@ void DrasculaEngine::enterRoom(int roomIndex) {
isDoor[7] = 0;
if (currentChapter == 2) {
- if (roomNumber == 14 && flags[39] == 1)
+ if (_roomNumber == 14 && flags[39] == 1)
roomMusic = 16;
- else if (roomNumber == 15 && flags[39] == 1)
+ else if (_roomNumber == 15 && flags[39] == 1)
roomMusic = 16;
- if (roomNumber == 14 && flags[5] == 1)
+ if (_roomNumber == 14 && flags[5] == 1)
roomMusic = 0;
- else if (roomNumber == 15 && flags[5] == 1)
+ else if (_roomNumber == 15 && flags[5] == 1)
roomMusic = 0;
if (previousMusic != roomMusic && roomMusic != 0)
@@ -1872,21 +1872,21 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
if (currentChapter == 2) {
- if (roomNumber == 9 || roomNumber == 2 || roomNumber == 14 || roomNumber == 18)
+ if (_roomNumber == 9 || _roomNumber == 2 || _roomNumber == 14 || _roomNumber == 18)
savedTime = getTime();
}
if (currentChapter == 4) {
- if (roomNumber == 26)
+ if (_roomNumber == 26)
savedTime = getTime();
}
- if (currentChapter == 4 && roomNumber == 24 && flags[29] == 1)
+ if (currentChapter == 4 && _roomNumber == 24 && flags[29] == 1)
animation_7_4();
if (currentChapter == 5) {
- if (roomNumber == 45)
+ if (_roomNumber == 45)
hare_se_ve = 0;
- if (roomNumber == 49 && flags[7] == 0) {
+ if (_roomNumber == 49 && flags[7] == 0) {
playTalkSequence(4); // sequence 4, chapter 5
}
}
diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp
index 996c9d3f03..61d6f0b4af 100644
--- a/engines/drascula/saveload.cpp
+++ b/engines/drascula/saveload.cpp
@@ -263,7 +263,7 @@ bool DrasculaEngine::loadGame(int slot) {
if (savedChapter != currentChapter) {
_currentSaveSlot = slot;
currentChapter = savedChapter - 1;
- loadedDifferentChapter = 1;
+ _loadedDifferentChapter = true;
delete in;
return false;
}
@@ -283,7 +283,7 @@ bool DrasculaEngine::loadGame(int slot) {
takeObject = in->readSint32LE();
pickedObject = in->readSint32LE();
- loadedDifferentChapter = 0;
+ _loadedDifferentChapter = false;
if (!sscanf(currentData, "%d.ald", &roomNum)) {
error("Bad save format");
}
@@ -383,10 +383,10 @@ bool DrasculaEngine::saveLoadScreen() {
updateScreen();
updateEvents();
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
// Check if the user has clicked on a save slot
for (n = 0; n < NUM_SAVES; n++) {
- if (mouseX > 115 && mouseY > 27 + (9 * n) && mouseX < 115 + 175 && mouseY < 27 + 10 + (9 * n)) {
+ if (_mouseX > 115 && _mouseY > 27 + (9 * n) && _mouseX < 115 + 175 && _mouseY < 27 + 10 + (9 * n)) {
selectedSlot = n;
selectedName = _saveNames[selectedSlot];
if (selectedName.empty()) {
@@ -399,14 +399,14 @@ bool DrasculaEngine::saveLoadScreen() {
}
// Check if the user has clicked in the text area above the save slots
- if (mouseX > 117 && mouseY > 15 && mouseX < 295 && mouseY < 24 && !selectedName.empty()) {
+ if (_mouseX > 117 && _mouseY > 15 && _mouseX < 295 && _mouseY < 24 && !selectedName.empty()) {
selectedName = enterName(selectedName);
if (!selectedName.empty())
_saveNames[selectedSlot] = selectedName; // update save name
}
// Check if the user has clicked a button
- if (mouseX > 208 && mouseY > 123 && mouseX < 282 && mouseY < 149) {
+ if (_mouseX > 208 && _mouseY > 123 && _mouseX < 282 && _mouseY < 149) {
// "Save" button
if (selectedName.empty()) {
print_abc("Please select a slot", 117, 15);
@@ -415,14 +415,14 @@ bool DrasculaEngine::saveLoadScreen() {
} else {
selectVerb(kVerbNone);
clearRoom();
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
updateRoom();
updateScreen();
saveGame(selectedSlot + 1, _saveNames[selectedSlot]);
return true;
}
- } else if (mouseX > 125 && mouseY > 123 && mouseX < 199 && mouseY < 149) {
+ } else if (_mouseX > 125 && _mouseY > 123 && _mouseX < 199 && _mouseY < 149) {
// "Load" button
if (selectedName.empty()) {
print_abc("Please select a slot", 117, 15);
@@ -431,19 +431,19 @@ bool DrasculaEngine::saveLoadScreen() {
} else {
return loadGame(selectedSlot + 1);
}
- } else if (mouseX > 168 && mouseY > 154 && mouseX < 242 && mouseY < 180) {
+ } else if (_mouseX > 168 && _mouseY > 154 && _mouseX < 242 && _mouseY < 180) {
// "Play" button
break;
}
- } // if (leftMouseButton == 1)
+ } // if (_leftMouseButton == 1)
- leftMouseButton = 0;
+ _leftMouseButton = 0;
delay(10);
}
selectVerb(kVerbNone);
clearRoom();
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
return true;
}
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 112f6fd06c..59b5e1d237 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -36,9 +36,9 @@ namespace Drascula {
void DrasculaEngine::updateVolume(Audio::Mixer::SoundType soundType, int prevVolume) {
int vol = _mixer->getVolumeForSoundType(soundType) / 16;
- if (mouseY < prevVolume && vol < 15)
+ if (_mouseY < prevVolume && vol < 15)
vol++;
- if (mouseY > prevVolume && vol > 0)
+ if (_mouseY > prevVolume && vol > 0)
vol--;
_mixer->setVolumeForSoundType(soundType, vol * 16);
}
@@ -78,23 +78,23 @@ void DrasculaEngine::volumeControls() {
while (getScan())
;
- if (rightMouseButton == 1) {
+ if (_rightMouseButton == 1) {
// Clear this to avoid going straight to the inventory
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
break;
}
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
- if (mouseX > 80 && mouseX < 121) {
+ if (_mouseX > 80 && _mouseX < 121) {
updateVolume(Audio::Mixer::kPlainSoundType, masterVolumeY);
}
- if (mouseX > 136 && mouseX < 178) {
+ if (_mouseX > 136 && _mouseX < 178) {
updateVolume(Audio::Mixer::kSpeechSoundType, voiceVolumeY);
}
- if (mouseX > 192 && mouseX < 233) {
+ if (_mouseX > 192 && _mouseX < 233) {
updateVolume(Audio::Mixer::kMusicSoundType, musicVolumeY);
}
}
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index a326852e96..6aabd91c6a 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -381,11 +381,11 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
int face;
if (currentChapter == 6) {
- if (flags[0] == 0 && roomNumber == 102) {
+ if (flags[0] == 0 && _roomNumber == 102) {
talk_pen(said, filename, 0);
return;
}
- if (flags[0] == 0 && roomNumber == 58) {
+ if (flags[0] == 0 && _roomNumber == 58) {
talk_pen(said, filename, 1);
return;
}
@@ -397,7 +397,7 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
}
if (currentChapter == 4) {
- if (roomNumber == 24 || flags[29] == 0) {
+ if (_roomNumber == 24 || flags[29] == 0) {
color_abc(kColorYellow);
}
} else {
@@ -413,59 +413,59 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
updateRefresh_pre();
if (currentChapter == 2)
- copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, TALK_HEIGHT - 1, screenSurface, drawSurface3);
else
copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
screenSurface, drawSurface3);
moveCharacters();
if (currentChapter == 2) {
if (!strcmp(menuBackground, "99.alg") || !strcmp(menuBackground, "994.alg"))
- copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, TALK_HEIGHT - 1, drawSurface3, screenSurface);
} else {
copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
drawSurface3, screenSurface);
}
if (trackProtagonist == 0) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight,
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
talkOffset + curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, talkWidth, talkHeight,
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
talkOffset + curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth,talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH,TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
}
@@ -827,47 +827,47 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
updateRefresh_pre();
if (currentChapter == 2)
- copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, TALK_HEIGHT - 1, screenSurface, drawSurface3);
else
copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]), screenSurface, drawSurface3);
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[curY + curHeight]), screenSurface, drawSurface3);
moveCharacters();
if (currentChapter == 2) {
if (curHeight != 56)
- copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, TALK_HEIGHT - 1, drawSurface3, screenSurface);
} else
copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]), drawSurface3, screenSurface);
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[curY + curHeight]), drawSurface3, screenSurface);
if (trackProtagonist == 0) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight, extraSurface, screenSurface);
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT, extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk, (int)(curX + (8.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight, extraSurface, screenSurface);
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT, extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk, (int)(curX + (12.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight, frontSurface, screenSurface);
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT, frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
(int)(talkOffset + curX + (12.0f / 100) * factor_red[curY + curHeight]), curY,
- talkWidth, talkHeight, factor_red[curY + curHeight], frontSurface, screenSurface);
+ TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, talkWidth, talkHeight, frontSurface, screenSurface);
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT, frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
(int)(talkOffset + curX + (8.0f / 100) * factor_red[curY + curHeight]), curY,
- talkWidth, talkHeight, factor_red[curY + curHeight], frontSurface, screenSurface);
+ TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], frontSurface, screenSurface);
updateRefresh();
}
diff --git a/engines/engines.mk b/engines/engines.mk
index f58dba0d6d..5b3eeea61c 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -61,6 +61,11 @@ DEFINES += -DENABLE_DREAMWEB=$(ENABLE_DREAMWEB)
MODULES += engines/dreamweb
endif
+ifdef ENABLE_FULLPIPE
+DEFINES += -DENABLE_FULLPIPE=$(ENABLE_FULLPIPE)
+MODULES += engines/fullpipe
+endif
+
ifdef ENABLE_GOB
DEFINES += -DENABLE_GOB=$(ENABLE_GOB)
MODULES += engines/gob
diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
new file mode 100644
index 0000000000..6bfb400c24
--- /dev/null
+++ b/engines/fullpipe/behavior.cpp
@@ -0,0 +1,315 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+
+namespace Fullpipe {
+
+BehaviorManager::BehaviorManager() {
+ _scene = 0;
+ _isActive = 1;
+}
+
+BehaviorManager::~BehaviorManager() {
+ clear();
+}
+
+void BehaviorManager::clear() {
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ for (int j = 0; j < _behaviors[i]->_itemsCount; j++)
+ delete _behaviors[i]->_bheItems[j];
+
+ delete _behaviors[i];
+ }
+ _behaviors.clear();
+}
+
+void BehaviorManager::initBehavior(Scene *sc, CGameVar *var) {
+ clear();
+ _scene = sc;
+
+ BehaviorInfo *behinfo;
+
+ CGameVar *behvar = var->getSubVarByName("BEHAVIOR");
+ if (!behvar)
+ return;
+
+ for (CGameVar *subvar = behvar->_subVars; subvar; subvar = subvar->_nextVarObj) {
+ if (!strcmp(subvar->_varName, "AMBIENT")) {
+ behinfo = new BehaviorInfo;
+ behinfo->initAmbientBehavior(subvar, sc);
+
+ _behaviors.push_back(behinfo);
+ } else {
+ StaticANIObject *ani = sc->getStaticANIObject1ByName(subvar->_varName, -1);
+ if (ani)
+ for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++)
+ if (((StaticANIObject *)sc->_staticANIObjectList1[i])->_id == ani->_id) {
+ behinfo = new BehaviorInfo;
+ behinfo->initObjectBehavior(subvar, sc, ani);
+ behinfo->_ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+
+ _behaviors.push_back(behinfo);
+ }
+ }
+ }
+}
+
+void BehaviorManager::updateBehaviors() {
+ if (!_isActive)
+ return;
+
+ debug(0, "BehaviorManager::updateBehaviors()");
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ BehaviorInfo *beh = _behaviors[i];
+
+ if (!beh->_ani) {
+ beh->_counter++;
+ if (beh->_counter >= beh->_counterMax)
+ updateBehavior(beh, beh->_bheItems[0]);
+
+ continue;
+ }
+
+ if (beh->_ani->_movement || !(beh->_ani->_flags & 4) || (beh->_ani->_flags & 2)) {
+ beh->_staticsId = 0;
+ continue;
+ }
+
+ if (beh->_ani->_statics->_staticsId == beh->_staticsId) {
+ beh->_counter++;
+ if (beh->_counter >= beh->_counterMax) {
+ if (beh->_subIndex >= 0 && !(beh->_flags & 1) && beh->_ani->_messageQueueId <= 0)
+ updateStaticAniBehavior(beh->_ani, beh->_counter, beh->_bheItems[beh->_subIndex]);
+ }
+ } else {
+ beh->_staticsId = beh->_ani->_statics->_staticsId;
+ beh->_counter = 0;
+ beh->_subIndex = -1;
+
+ for (int j = 0; j < beh->_itemsCount; j++)
+ if (beh->_bheItems[j]->_staticsId == beh->_staticsId) {
+ beh->_subIndex = j;
+ break;
+ }
+
+ }
+ }
+}
+
+void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry) {
+ debug(0, "BehaviorManager::updateBehavior() %d", entry->_itemsCount);
+ for (int i = 0; i < entry->_itemsCount; i++) {
+ BehaviorEntryInfo *bhi = entry->_items[i];
+ if (!(bhi->_flags & 1)) {
+ if (bhi->_flags & 2) {
+ MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
+
+ mq->sendNextCommand();
+
+ bhi->_flags &= 0xFFFFFFFD;
+ } else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fullpipe->_rnd->getRandomNumber(32767) <= entry->_items[i]->_percent) {
+ MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
+
+ mq->sendNextCommand();
+
+ behaviorInfo->_counter = 0;
+ }
+ }
+ }
+}
+
+void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *bhe) {
+ debug(0, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName));
+
+ MessageQueue *mq = 0;
+
+ if (bhe->_flags & 1) {
+ uint rnd = g_fullpipe->_rnd->getRandomNumber(32767);
+ uint runPercent = 0;
+ for (int i = 0; i < bhe->_itemsCount; i++) {
+ if (!(bhe->_items[i]->_flags & 1) && bhe->_items[i]->_percent) {
+ if ((rnd >= runPercent && rnd <= runPercent + bhe->_items[i]->_percent) || i == bhe->_itemsCount - 1) {
+ mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1);
+ break;
+ }
+ runPercent += bhe->_items[i]->_percent;
+ }
+ }
+ } else {
+ for (int i = 0; i < bhe->_itemsCount; i++) {
+ if (!(bhe->_items[i]->_flags & 1) && delay >= bhe->_items[i]->_delay) {
+ if (bhe->_items[i]->_percent) {
+ if (g_fullpipe->_rnd->getRandomNumber(32767) <= bhe->_items[i]->_percent) {
+ mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (mq) {
+ mq->replaceKeyCode(-1, ani->_okeyCode);
+ mq->chain(ani);
+ }
+}
+
+void BehaviorInfo::clear() {
+ _ani = 0;
+ _staticsId = 0;
+ _counter = 0;
+ _counterMax = 0;
+ _flags = 0;
+ _subIndex = 0;
+ _itemsCount = 0;
+
+ _bheItems.clear();
+}
+
+void BehaviorInfo::initAmbientBehavior(CGameVar *var, Scene *sc) {
+ debug(0, "BehaviorInfo::initAmbientBehavior(%s)", transCyrillic((byte *)var->_varName));
+
+ clear();
+ _itemsCount = 1;
+ _counterMax = -1;
+
+ BehaviorEntry *bi = new BehaviorEntry();
+
+ _bheItems.push_back(bi);
+
+ bi->_itemsCount = var->getSubVarsCount();
+
+ bi->_items = (BehaviorEntryInfo**)calloc(bi->_itemsCount, sizeof(BehaviorEntryInfo *));
+
+ for (int i = 0; i < bi->_itemsCount; i++) {
+ int delay;
+ bi->_items[i] = new BehaviorEntryInfo(var->getSubVarByIndex(i), sc, &delay);
+
+ if (bi->_items[i]->_delay <_counterMax)
+ _counterMax = bi->_items[i]->_delay;
+ }
+}
+
+void BehaviorInfo::initObjectBehavior(CGameVar *var, Scene *sc, StaticANIObject *ani) {
+ debug(0, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName));
+
+ clear();
+
+ _itemsCount = var->getSubVarsCount();
+ _counterMax = -1;
+
+ while (var->_varType == 2) {
+ if (strcmp(var->_value.stringValue, "ROOT"))
+ break;
+
+ CGameVar *v1 = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("BEHAVIOR")->getSubVarByName(ani->getName());
+ if (v1 == var)
+ return;
+
+ sc = g_fullpipe->accessScene(ani->_sceneId);
+ clear();
+ var = v1;
+ _itemsCount = var->getSubVarsCount();
+ _counterMax = -1;
+ }
+
+ for (int i = 0; i < _itemsCount; i++) {
+ int maxDelay;
+
+ _bheItems.push_back(new BehaviorEntry(var->getSubVarByIndex(i), sc, ani, &maxDelay));
+
+ if (maxDelay < _counterMax)
+ _counterMax = maxDelay;
+ }
+}
+
+BehaviorEntry::BehaviorEntry() {
+ _staticsId = 0;
+ _itemsCount = 0;
+ _flags = 0;
+ _items = 0;
+}
+
+BehaviorEntry::BehaviorEntry(CGameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay) {
+ _staticsId = 0;
+ _itemsCount = 0;
+
+ *minDelay = 100000000;
+
+ int totalPercent = 0;
+ _flags = 0;
+ _items = 0;
+
+ Statics *st = ani->getStaticsByName(var->_varName);
+ if (st)
+ _staticsId = st->_staticsId;
+
+ _itemsCount = var->getSubVarsCount();
+ if (_itemsCount) {
+ _items = (BehaviorEntryInfo**)calloc(_itemsCount, sizeof(BehaviorEntryInfo *));
+
+ for (int i = 0; i < _itemsCount; i++) {
+ CGameVar *subvar = var->getSubVarByIndex(i);
+ int delay;
+
+ _items[i] = new BehaviorEntryInfo(subvar, sc, &delay);
+ totalPercent += delay;
+
+ if (_items[i]->_delay < *minDelay)
+ *minDelay = _items[i]->_delay;
+ }
+
+ if (!*minDelay && totalPercent == 1000)
+ _flags |= 1;
+ }
+}
+
+BehaviorEntryInfo::BehaviorEntryInfo(CGameVar *subvar, Scene *sc, int *delay) {
+ _messageQueue = 0;
+ _delay = 0;
+ _percent = 0;
+ _flags = 0;
+ _messageQueue = sc->getMessageQueueByName(subvar->_varName);
+
+ CGameVar *vart = subvar->getSubVarByName("dwDelay");
+ if (vart)
+ _delay = vart->_value.intValue;
+
+ *delay = 0;
+ vart = subvar->getSubVarByName("dwPercent");
+ if (vart) {
+ _percent = 0x7FFF * vart->_value.intValue / 1000;
+ *delay = vart->_value.intValue;
+ }
+
+ vart = subvar->getSubVarByName("dwFlags");
+ if (vart && vart->_varType == 2 && strstr(vart->_value.stringValue, "QDESC_AUTOSTART"))
+ _flags |= 2;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/behavior.h b/engines/fullpipe/behavior.h
new file mode 100644
index 0000000000..d9375d4d01
--- /dev/null
+++ b/engines/fullpipe/behavior.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.
+ *
+ */
+
+#ifndef FULLPIPE_BEHAVIOR_H
+#define FULLPIPE_BEHAVIOR_H
+
+namespace Fullpipe {
+
+struct BehaviorEntryInfo {
+ MessageQueue *_messageQueue;
+ int _delay;
+ uint32 _percent;
+ int _flags;
+
+ BehaviorEntryInfo(CGameVar *subvar, Scene *sc, int *delay);
+};
+
+struct BehaviorEntry {
+ int _staticsId;
+ int _itemsCount;
+ int _flags;
+ BehaviorEntryInfo **_items;
+
+ BehaviorEntry();
+ BehaviorEntry(CGameVar *var, Scene *sc, StaticANIObject *ani, int *minDelay);
+};
+
+struct BehaviorInfo {
+ StaticANIObject *_ani;
+ int _staticsId;
+ int _counter;
+ int _counterMax;
+ int _flags;
+ int _subIndex;
+ int _itemsCount;
+ Common::Array<BehaviorEntry *> _bheItems;
+
+ BehaviorInfo() { clear(); }
+
+ void clear();
+ void initAmbientBehavior(CGameVar *var, Scene *sc);
+ void initObjectBehavior(CGameVar *var, Scene *sc, StaticANIObject *ani);
+};
+
+class BehaviorManager : public CObject {
+ Common::Array<BehaviorInfo *> _behaviors;
+ Scene *_scene;
+ bool _isActive;
+
+ public:
+ BehaviorManager();
+ ~BehaviorManager();
+
+ void clear();
+
+ void initBehavior(Scene *scene, CGameVar *var);
+
+ void updateBehaviors();
+ void updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry);
+ void updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *beh);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_BEHAVIOR_H */
diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h
new file mode 100644
index 0000000000..4f389f80a8
--- /dev/null
+++ b/engines/fullpipe/constants.h
@@ -0,0 +1,179 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_CONSTANTS_H
+#define FULLPIPE_CONSTANTS_H
+
+namespace Fullpipe {
+
+#define ANI_BOOT_1 4231
+#define ANI_IN1MAN 5110
+#define ANI_INV_MAP 5321
+#define ANI_LIFTBUTTON 2751
+#define ANI_MAN 322
+#define MSG_DISABLESAVES 5201
+#define MSG_ENABLESAVES 5202
+#define MSG_HMRKICK_METAL 4764
+#define MSG_HMRKICK_STUCCO 4765
+#define MSG_MANSHADOWSOFF 5196
+#define MSG_MANSHADOWSON 5197
+#define MSG_RESTARTGAME 4767
+#define MSG_SC1_SHOWOSK 1019
+#define MSG_SC1_SHOWOSK2 468
+#define MSG_SC1_UTRUBACLICK 1100
+#define MV_MAN_GOLADDER 451
+#define MV_MAN_GOLADDER2 2844
+#define MV_MAN_LOOKUP 4773
+#define MV_MAN_STARTLADDER 452
+#define MV_MAN_STARTLADDER2 2842
+#define MV_MAN_STOPLADDER 454
+#define MV_MAN_STOPLADDER2 2845
+#define MV_MAN_TOLADDER 448
+#define MV_MAN_TOLADDER2 2841
+#define MV_MAN_TURN_LU 486
+#define PIC_CMN_EVAL 3468
+#define PIC_CSR_DEFAULT 4891
+#define PIC_CSR_DEFAULT_INV 4892
+#define PIC_CSR_ITN 4893
+#define PIC_CSR_ITN_INV 4894
+#define PIC_CSR_GOFAR_L 4895
+#define PIC_CSR_GOFAR_R 4896
+#define PIC_CSR_ARCADE1 4901
+#define PIC_CSR_ARCADE2 4902
+#define PIC_CSR_ARCADE2_D 4903
+#define PIC_CSR_ARCADE3 4904
+#define PIC_CSR_ARCADE4 4905
+#define PIC_CSR_ARCADE5 4906
+#define PIC_CSR_ARCADE6 4907
+#define PIC_CSR_ARCADE6_D 4908
+#define PIC_CSR_ARCADE7 4909
+#define PIC_CSR_ARCADE7_D 4910
+#define PIC_CSR_ARCADE8 4911
+#define PIC_CSR_DEFAULT 4891
+#define PIC_CSR_DEFAULT_INV 4892
+#define PIC_CSR_GOD 4900
+#define PIC_CSR_GOFAR_L 4895
+#define PIC_CSR_GOFAR_R 4896
+#define PIC_CSR_GOL 4897
+#define PIC_CSR_GOR 4898
+#define PIC_CSR_GOU 4899
+#define PIC_CSR_HELPERBGR 5331
+#define PIC_CSR_ITN 4893
+#define PIC_CSR_ITN_GREEN 5330
+#define PIC_CSR_ITN_INV 4894
+#define PIC_CSR_ITN_RED 5329
+#define PIC_CSR_LIFT 5176
+#define PIC_CSR_MAP 5339
+#define PIC_IN1_PIPETITLE 5167
+#define PIC_INV_MENU 991
+#define PIC_MAP_A13 5275
+#define PIC_MAP_S01 5223
+#define PIC_SC1_KUCHKA 1321
+#define PIC_SC1_LADDER 1091
+#define PIC_SC1_OSK 1018
+#define PIC_SC1_OSK2 2932
+#define PIC_SCD_SEL 734
+#define SC_1 301
+#define SC_10 653
+#define SC_11 654
+#define SC_12 655
+#define SC_13 1137
+#define SC_14 1138
+#define SC_15 1139
+#define SC_16 1140
+#define SC_17 1141
+#define SC_18 1142
+#define SC_19 1143
+#define SC_2 302
+#define SC_20 1144
+#define SC_21 1546
+#define SC_22 1547
+#define SC_23 1548
+#define SC_24 1549
+#define SC_25 1550
+#define SC_26 1551
+#define SC_27 1552
+#define SC_28 2062
+#define SC_29 2063
+#define SC_3 303
+#define SC_30 2064
+#define SC_31 2065
+#define SC_32 2066
+#define SC_33 2067
+#define SC_34 2068
+#define SC_35 2069
+#define SC_36 2070
+#define SC_37 2071
+#define SC_38 2072
+#define SC_4 304
+#define SC_5 305
+#define SC_6 649
+#define SC_7 650
+#define SC_8 651
+#define SC_9 652
+#define SC_COMMON 321
+#define SC_DBGMENU 726
+#define SC_FINAL1 4999
+#define SC_FINAL2 5000
+#define SC_FINAL3 5001
+#define SC_FINAL4 2460
+#define SC_INTRO1 3896
+#define SC_INTRO2 3907
+#define SC_INV 858
+#define SC_LDR 635
+#define SC_MAINMENU 4620
+#define SC_MAP 5222
+#define SC_TEST 903
+#define SC_TITLES 5166
+#define SND_CMN_031 3516
+#define SND_CMN_070 5199
+#define ST_LBN_0N 2832
+#define ST_LBN_0P 2833
+#define ST_LBN_1N 2753
+#define ST_LBN_1P 2754
+#define ST_LBN_2N 2756
+#define ST_LBN_2P 2757
+#define ST_LBN_3N 2759
+#define ST_LBN_3P 2760
+#define ST_LBN_4N 2762
+#define ST_LBN_4P 2763
+#define ST_LBN_5N 2765
+#define ST_LBN_5P 2766
+#define ST_LBN_6N 2768
+#define ST_LBN_6P 2769
+#define ST_LBN_7N 2771
+#define ST_LBN_7P 2772
+#define ST_LBN_8N 2774
+#define ST_LBN_8P 2775
+#define ST_LBN_9N 2777
+#define ST_LBN_9P 2778
+#define ST_MAN_EMPTY 476
+#define ST_MAN_RIGHT 325
+#define TrubaDown 697
+#define TrubaLeft 474
+#define TrubaRight 696
+#define TrubaUp 680
+#define rMV_MAN_LOOKUP 4775
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_CONSTANTS_H */
diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp
new file mode 100644
index 0000000000..8c4a422333
--- /dev/null
+++ b/engines/fullpipe/detection.cpp
@@ -0,0 +1,112 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "engines/advancedDetector.h"
+#include "common/file.h"
+
+#include "fullpipe/fullpipe.h"
+
+
+namespace Fullpipe {
+
+const char *FullpipeEngine::getGameId() const {
+ return _gameDescription->gameid;
+}
+
+}
+
+static const PlainGameDescriptor fullpipeGames[] = {
+ {"fullpipe", "Full Pipe"},
+ {0, 0}
+};
+
+namespace Fullpipe {
+
+static const ADGameDescription gameDescriptions[] = {
+
+ // Fullpipe Russian version
+ {
+ "fullpipe",
+ 0,
+ AD_ENTRY1s("0654.sc2", "099f54f86d33ad2395f3b854b7e05058", 2272),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
+
+ // Fullpipe German version
+ {
+ "fullpipe",
+ 0,
+ AD_ENTRY1s("0654.sc2", "d8743351fc53d205f42d91f6d791e51b", 2272),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
+
+ AD_TABLE_END_MARKER
+};
+
+} // End of namespace Fullpipe
+
+class FullpipeMetaEngine : public AdvancedMetaEngine {
+public:
+ FullpipeMetaEngine() : AdvancedMetaEngine(Fullpipe::gameDescriptions, sizeof(ADGameDescription), fullpipeGames) {
+ _singleid = "fullpipe";
+ }
+
+ virtual const char *getName() const {
+ return "Fullpipe Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Fullpipe Engine (C) Pipe Studio";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+};
+
+bool FullpipeMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return false;
+}
+
+bool Fullpipe::FullpipeEngine::hasFeature(EngineFeature f) const {
+ return false;
+}
+
+bool FullpipeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new Fullpipe::FullpipeEngine(syst, desc);
+ }
+ return desc != 0;
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(FULLPIPE)
+ REGISTER_PLUGIN_DYNAMIC(FULLPIPE, PLUGIN_TYPE_ENGINE, FullpipeMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(FULLPIPE, PLUGIN_TYPE_ENGINE, FullpipeMetaEngine);
+#endif
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
new file mode 100644
index 0000000000..11808e95c2
--- /dev/null
+++ b/engines/fullpipe/fullpipe.cpp
@@ -0,0 +1,441 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "common/archive.h"
+#include "common/config-manager.h"
+
+#include "engines/util.h"
+
+#include "fullpipe/fullpipe.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/input.h"
+#include "fullpipe/scenes.h"
+
+namespace Fullpipe {
+
+FullpipeEngine *g_fullpipe = 0;
+Vars *g_vars = 0;
+
+FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+ // Setup mixer
+ if (!_mixer->isReady()) {
+ warning("Sound initialization failed.");
+ }
+
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
+ _rnd = new Common::RandomSource("fullpipe");
+
+ _gameProjectVersion = 0;
+ _pictureScale = 8;
+ _scrollSpeed = 0;
+ _currSoundListCount = 0;
+ _globalPalette = 0;
+
+ _updateTicks = 0;
+ _lastInputTicks = 0;
+ _lastButtonUpTicks = 0;
+
+ _currArchive = 0;
+
+ _soundEnabled = true;
+ _flgSoundList = true;
+
+ _sfxVolume = 0;
+
+ _inputController = 0;
+ _inputDisabled = false;
+
+ _modalObject = 0;
+
+ _gameContinue = true;
+ _needRestart = false;
+ _flgPlayIntro = false;
+ _gamePaused = false;
+ _inputArFlag = false;
+ _recordEvents = false;
+
+ _flgGameIsRunning = true;
+
+ _isProcessingMessages = false;
+
+ _musicAllowed = -1;
+
+ _aniMan = 0;
+ _aniMan2 = 0;
+ _currentScene = 0;
+ _scene2 = 0;
+ _movTable = 0;
+
+ _globalMessageQueueList = 0;
+ _messageHandlers = 0;
+
+ _updateScreenCallback = 0;
+ _updateCursorCallback = 0;
+
+ _msgX = 0;
+ _msgY = 0;
+ _msgObjectId2 = 0;
+ _msgId = 0;
+ _mouseVirtX = 0;
+ _mouseVirtY = 0;
+
+ _currSelectedInventoryItemId = 0;
+
+ _behaviorManager = 0;
+
+ _cursorId = 0;
+
+ _keyState = Common::KEYCODE_INVALID;
+ _buttonState = 0;
+
+ _gameLoader = 0;
+ _gameProject = 0;
+
+ _updateFlag = true;
+ _flgCanOpenMap = true;
+
+ _sceneWidth = 1;
+ _sceneHeight = 1;
+
+ for (int i = 0; i < 11; i++)
+ _currSoundList1[i] = 0;
+
+ for (int i = 0; i < 200; i++)
+ _mapTable[i] = 0;
+
+ _inventoryScene = 0;
+ _inventory = 0;
+
+ _minCursorId = 0xffff;
+ _maxCursorId = 0;
+ _objectAtCursor = 0;
+ _objectIdAtCursor = 0;
+
+ _isSaveAllowed = true;
+
+ g_fullpipe = this;
+ g_vars = new Vars;
+}
+
+FullpipeEngine::~FullpipeEngine() {
+ delete _rnd;
+ delete _globalMessageQueueList;
+}
+
+void FullpipeEngine::initialize() {
+ _globalMessageQueueList = new GlobalMessageQueueList;
+ _behaviorManager = new BehaviorManager;
+
+ _sceneRect.left = 0;
+ _sceneRect.top = 0;
+ _sceneRect.right = 799;
+ _sceneRect.bottom = 599;
+}
+
+Common::Error FullpipeEngine::run() {
+ const Graphics::PixelFormat format(2, 5, 6, 5, 0, 11, 5, 0, 0);
+ // Initialize backend
+ initGraphics(800, 600, true, &format);
+
+ _backgroundSurface.create(800, 600, format);
+
+ initialize();
+
+ _isSaveAllowed = false;
+
+ int scene = 0;
+ if (ConfMan.hasKey("boot_param"))
+ scene = ConfMan.getInt("boot_param");
+
+ if (!loadGam("fullpipe.gam", scene))
+ return Common::kNoGameDataFoundError;
+
+#if 0
+ loadAllScenes();
+#endif
+
+ _gameContinue = true;
+
+ while (_gameContinue) {
+ updateEvents();
+
+ updateScreen();
+
+ if (_needRestart) {
+ if (_modalObject) {
+ delete _modalObject;
+ _modalObject = 0;
+ }
+
+ freeGameLoader();
+ _currentScene = 0;
+ _updateTicks = 0;
+
+ loadGam("fullpipe.gam");
+ _needRestart = false;
+ }
+
+ _system->delayMillis(10);
+ _system->updateScreen();
+ }
+
+ freeGameLoader();
+
+ cleanup();
+
+ return Common::kNoError;
+}
+
+void FullpipeEngine::updateEvents() {
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ ExCommand *ex;
+
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ _keyState = event.kbd.keycode;
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_SPACE:
+ if (_gamePaused) {
+ if (_modalObject) {
+ if (_modalObject->init(42)) {
+ _modalObject->update();
+ } else {
+ _modalObject->saveload();
+ CBaseModalObject *obj = _modalObject->_parentObj;
+ if (obj)
+ delete _modalObject;
+ _modalObject = obj;
+ }
+ } else {
+ _gameLoader->updateSystems(42);
+ }
+ return;
+ }
+
+ ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = 32;
+ ex->_excFlags |= 3;
+ ex->handle();
+ break;
+ case Common::KEYCODE_s:
+ if (_gamePaused) {
+ _gamePaused = 0;
+ _flgGameIsRunning = true;
+ return;
+ }
+
+ ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = 83;
+ ex->_excFlags |= 3;
+ ex->handle();
+ break;
+ case Common::KEYCODE_q:
+ return;
+ break;
+ default:
+ ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = event.kbd.keycode;
+ ex->_excFlags |= 3;
+ ex->handle();
+ break;
+ }
+ break;
+ case Common::EVENT_KEYUP:
+ if (!_inputArFlag) {
+ ex = new ExCommand(0, 17, 37, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->handle();
+ }
+ _keyState = Common::KEYCODE_INVALID;
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ if (_recordEvents) {
+ ex = new ExCommand(0, 17, 31, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->handle();
+ }
+
+ _mouseScreenPos = event.mouse;
+ break;
+ case Common::EVENT_QUIT:
+ _gameContinue = false;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) {
+ ex = new ExCommand(0, 17, 107, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ _lastInputTicks = _updateTicks;
+ ex->handle();
+ }
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) {
+ ex = new ExCommand(0, 17, 29, event.mouse.x, event.mouse.y, 0, 1, 0, 0, 0);
+
+ ex->_sceneClickX = _sceneRect.left + ex->_x;
+ ex->_sceneClickY = _sceneRect.top + ex->_y;
+ ex->_keyCode = getGameLoaderInventory()->getSelectedItemId();
+ ex->_excFlags |= 3;
+ _lastInputTicks = _updateTicks;
+ ex->handle();
+ }
+ break;
+ case Common::EVENT_LBUTTONUP:
+ if (!_inputArFlag && (_updateTicks - _lastButtonUpTicks) >= 2) {
+ ex = new ExCommand(0, 17, 30, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ _lastButtonUpTicks = _updateTicks;
+ ex->handle();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+
+#if 0
+ warning("STUB: FullpipeEngine::updateEvents() <mainWindowProc>");
+ if (Msg == MSG_SC11_SHOWSWING && _modalObject) {
+ _modalObject->method14();
+ }
+#endif
+}
+
+void FullpipeEngine::freeGameLoader() {
+ warning("STUB: FullpipeEngine::freeGameLoader()");
+}
+
+void FullpipeEngine::cleanup() {
+ warning("STUB: FullpipeEngine::cleanup()");
+}
+
+void FullpipeEngine::updateScreen() {
+ debug(4, "FullpipeEngine::updateScreen()");
+
+ _mouseVirtX = _mouseScreenPos.x + _sceneRect.left;
+ _mouseVirtY = _mouseScreenPos.y + _sceneRect.top;
+
+ //if (inputArFlag)
+ // updateGame_inputArFlag();
+
+ if (_modalObject || (_flgGameIsRunning && (_gameLoader->updateSystems(42), _modalObject != 0))) {
+ if (_flgGameIsRunning) {
+ if (_modalObject->init(42)) {
+ _modalObject->update();
+ } else {
+ _modalObject->saveload();
+ CBaseModalObject *tmp = _modalObject->_parentObj;
+
+ delete _modalObject;
+
+ _modalObject = tmp;
+ }
+ }
+ } else if (_currentScene) {
+ _currentScene->draw();
+
+ if (_inventoryScene)
+ _inventory->draw();
+
+ if (_updateScreenCallback)
+ _updateScreenCallback();
+
+ //if (inputArFlag && _currentScene) {
+ // vrtTextOut(*(_DWORD *)g_vrtHandle, smallNftData, "DEMO", 4, 380, 580);
+ // vrtTextOut(*(_DWORD *)g_vrtHandle, smallNftData, "Alt+F4 - exit", 14, 695, 580);
+ //}
+ } else {
+ //vrtRectangle(*(_DWORD *)g_vrtHandle, 0, 0, 0, 800, 600);
+ }
+ _inputController->drawCursor(_mouseScreenPos.x, _mouseScreenPos.y);
+
+ ++_updateTicks;
+}
+
+int FullpipeEngine::getObjectEnumState(const char *name, const char *state) {
+ CGameVar *var = _gameLoader->_gameVar->getSubVarByName("OBJSTATES");
+
+ if (!var) {
+ var = _gameLoader->_gameVar->addSubVarAsInt("OBJSTATES", 0);
+ }
+
+ var = var->getSubVarByName(name);
+ if (var) {
+ var = var->getSubVarByName("ENUMSTATES");
+ if (var)
+ return var->getSubVarAsInt(state);
+ }
+
+ return 0;
+}
+
+int FullpipeEngine::getObjectState(const char *objname) {
+ CGameVar *var = _gameLoader->_gameVar->getSubVarByName("OBJSTATES");
+
+ if (var)
+ return var->getSubVarAsInt(objname);
+
+ return 0;
+}
+
+void FullpipeEngine::setObjectState(const char *name, int state) {
+ CGameVar *var = _gameLoader->_gameVar->getSubVarByName("OBJSTATES");
+
+ if (!var) {
+ var = _gameLoader->_gameVar->addSubVarAsInt("OBJSTATES", 0);
+ }
+
+ var->setSubVarAsInt(name, state);
+}
+
+void FullpipeEngine::updateMapPiece(int mapId, int update) {
+ for (int i = 0; i < 200; i++) {
+ int hiWord = (_mapTable[i] >> 16) & 0xffff;
+
+ if (hiWord == mapId) {
+ _mapTable[i] |= update;
+ return;
+ }
+ if (!hiWord) {
+ _mapTable[i] = (mapId << 16) | update;
+ return;
+ }
+ }
+}
+
+void FullpipeEngine::disableSaves(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::disableSaves()");
+}
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
new file mode 100644
index 0000000000..f688151267
--- /dev/null
+++ b/engines/fullpipe/fullpipe.h
@@ -0,0 +1,241 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_FULLPIPE_H
+#define FULLPIPE_FULLPIPE_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/random.h"
+#include "common/savefile.h"
+#include "common/system.h"
+
+#include "audio/mixer.h"
+
+#include "graphics/surface.h"
+
+#include "engines/engine.h"
+
+struct ADGameDescription;
+
+namespace Fullpipe {
+
+enum FullpipeGameFeatures {
+};
+
+class BehaviorManager;
+class CBaseModalObject;
+class CGameLoader;
+class CGameVar;
+class CInputController;
+class CInventory2;
+struct CursorInfo;
+struct EntranceInfo;
+class ExCommand;
+class GameProject;
+class GameObject;
+class GlobalMessageQueueList;
+struct MessageHandler;
+struct MovTable;
+class NGIArchive;
+class Scene;
+class SoundList;
+class StaticANIObject;
+class Vars;
+
+int global_messageHandler1(ExCommand *cmd);
+int global_messageHandler2(ExCommand *cmd);
+int global_messageHandler3(ExCommand *cmd);
+int global_messageHandler4(ExCommand *cmd);
+void global_messageHandler_handleSound(ExCommand *cmd);
+
+
+class FullpipeEngine : public ::Engine {
+protected:
+
+ Common::Error run();
+
+public:
+ FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc);
+ virtual ~FullpipeEngine();
+
+ void initialize();
+
+ void setMusicAllowed(int val) { _musicAllowed = val; }
+
+ // Detection related functions
+ const ADGameDescription *_gameDescription;
+ const char *getGameId() const;
+ Common::Platform getPlatform() const;
+ bool hasFeature(EngineFeature f) const;
+
+ Common::RandomSource *_rnd;
+
+ Common::KeyCode _keyState;
+ uint16 _buttonState;
+
+ void updateEvents();
+
+ Graphics::Surface _backgroundSurface;
+
+ CGameLoader *_gameLoader;
+ GameProject *_gameProject;
+ bool loadGam(const char *fname, int scene = 0);
+
+ CGameVar *getGameLoaderGameVar();
+ CInputController *getGameLoaderInputController();
+
+ int _gameProjectVersion;
+ int _pictureScale;
+ int _scrollSpeed;
+ bool _updateFlag;
+ bool _flgCanOpenMap;
+ bool _gamePaused;
+ bool _flgGameIsRunning;
+ bool _inputArFlag;
+ bool _recordEvents;
+
+ Common::Rect _sceneRect;
+ int _sceneWidth;
+ int _sceneHeight;
+ Scene *_currentScene;
+ Scene *_scene2;
+ StaticANIObject *_aniMan;
+ StaticANIObject *_aniMan2;
+ byte *_globalPalette;
+
+ CInputController *_inputController;
+ bool _inputDisabled;
+
+ void defHandleKeyDown(int key);
+
+ SoundList *_currSoundList1[11];
+ int _currSoundListCount;
+ bool _soundEnabled;
+ bool _flgSoundList;
+
+ void stopAllSounds();
+ void toggleMute();
+ void playSound(int id, int flag);
+ void startSceneTrack();
+
+ int _sfxVolume;
+
+ GlobalMessageQueueList *_globalMessageQueueList;
+ MessageHandler *_messageHandlers;
+
+ int _msgX;
+ int _msgY;
+ int _msgObjectId2;
+ int _msgId;
+
+ Common::List<ExCommand *> _exCommandList;
+ bool _isProcessingMessages;
+
+ int _mouseVirtX;
+ int _mouseVirtY;
+ Common::Point _mouseScreenPos;
+
+ BehaviorManager *_behaviorManager;
+
+ MovTable *_movTable;
+
+ void initMap();
+ void updateMapPiece(int mapId, int update);
+ void updateScreen();
+
+ void freeGameLoader();
+ void cleanup();
+
+ bool _gameContinue;
+ bool _needRestart;
+ bool _flgPlayIntro;
+ int _musicAllowed;
+
+ void enableSaves() { _isSaveAllowed = true; }
+ void disableSaves(ExCommand *ex);
+
+ void initObjectStates();
+ void setLevelStates();
+ void setSwallowedEggsState();
+ void loadAllScenes();
+
+ void initCursors();
+ void addCursor(CursorInfo *cursorInfo, Scene *inv, int pictureId, int hotspotX, int hotspotY, int itemPictureOffsX, int itemPictureOffsY);
+
+ int32 _mapTable[200];
+
+ Scene *_inventoryScene;
+ CInventory2 *_inventory;
+ int _currSelectedInventoryItemId;
+
+ int32 _updateTicks;
+ int32 _lastInputTicks;
+ int32 _lastButtonUpTicks;
+
+ CBaseModalObject *_modalObject;
+
+ int (*_updateScreenCallback)();
+ int (*_updateCursorCallback)();
+
+ int _cursorId;
+ int _minCursorId;
+ int _maxCursorId;
+ Common::Array<int> _objectIdCursors;
+ GameObject *_objectAtCursor;
+ int _objectIdAtCursor;
+
+ void setCursor(int id);
+ void updateCursorsCommon();
+
+ int getObjectState(const char *objname);
+ void setObjectState(const char *name, int state);
+ int getObjectEnumState(const char *name, const char *state);
+
+ bool sceneSwitcher(EntranceInfo *entrance);
+ Scene *accessScene(int sceneId);
+ void setSceneMusicParameters(CGameVar *var);
+
+ NGIArchive *_currArchive;
+
+ void openMap();
+ void openHelp();
+ void openMainMenu();
+
+ int lift_getButtonIdP(int objid);
+
+public:
+
+ bool _isSaveAllowed;
+
+ bool canLoadGameStateCurrently() { return _isSaveAllowed; }
+ bool canSaveGameStateCurrently() { return _isSaveAllowed; }
+
+};
+
+extern FullpipeEngine *g_fullpipe;
+extern Vars *g_vars;
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_FULLPIPE_H */
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
new file mode 100644
index 0000000000..fa8eddf7f1
--- /dev/null
+++ b/engines/fullpipe/gameloader.cpp
@@ -0,0 +1,493 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/input.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/motion.h"
+
+namespace Fullpipe {
+
+CInventory2 *getGameLoaderInventory() {
+ return &g_fullpipe->_gameLoader->_inventory;
+}
+
+CMctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId) {
+ for (uint i = 0; i < g_fullpipe->_gameLoader->_sc2array.size(); i++)
+ if (g_fullpipe->_gameLoader->_sc2array[i]._sceneId == sceneId)
+ return (CMctlCompound *)g_fullpipe->_gameLoader->_sc2array[i]._motionController;
+
+ return 0;
+}
+
+CInteractionController *getGameLoaderInteractionController() {
+ return g_fullpipe->_gameLoader->_interactionController;
+}
+
+CGameLoader::CGameLoader() {
+ _interactionController = new CInteractionController();
+ _inputController = new CInputController();
+
+ _gameProject = 0;
+ _gameName = 0;
+
+ addMessageHandlerByIndex(global_messageHandler2, 0, 0);
+ insertMessageHandler(global_messageHandler3, 0, 128);
+ insertMessageHandler(global_messageHandler4, 0, 1);
+
+ _field_FA = 0;
+ _field_F8 = 0;
+ _sceneSwitcher = 0;
+ _preloadCallback = 0;
+ _readSavegameCallback = 0;
+ _gameVar = 0;
+ _preloadSceneId = 0;
+ _preloadEntranceId = 0;
+ _updateCounter = 0;
+
+ g_fullpipe->_msgX = 0;
+ g_fullpipe->_msgY = 0;
+ g_fullpipe->_msgObjectId2 = 0;
+ g_fullpipe->_msgId = 0;
+}
+
+CGameLoader::~CGameLoader() {
+ free(_gameName);
+ delete _gameProject;
+ delete _interactionController;
+ delete _inputController;
+}
+
+bool CGameLoader::load(MfcArchive &file) {
+ debug(5, "CGameLoader::load()");
+
+ _gameName = file.readPascalString();
+ debug(6, "_gameName: %s", _gameName);
+
+ _gameProject = new GameProject();
+
+ _gameProject->load(file);
+
+ g_fullpipe->_gameProject = _gameProject;
+
+ if (g_fullpipe->_gameProjectVersion < 12) {
+ error("Old gameProjectVersion: %d", g_fullpipe->_gameProjectVersion);
+ }
+
+ _gameName = file.readPascalString();
+ debug(6, "_gameName: %s", _gameName);
+
+ _inventory.load(file);
+
+ _interactionController->load(file);
+
+ debug(6, "sceneTag count: %d", _gameProject->_sceneTagList->size());
+
+ _sc2array.resize(_gameProject->_sceneTagList->size());
+
+ int i = 0;
+ for (SceneTagList::const_iterator it = _gameProject->_sceneTagList->begin(); it != _gameProject->_sceneTagList->end(); ++it, i++) {
+ char tmp[12];
+
+ snprintf(tmp, 11, "%04d.sc2", it->_sceneId);
+
+ debug(2, "sc: %s", tmp);
+
+ _sc2array[i].loadFile((const char *)tmp);
+ }
+
+ _preloadItems.load(file);
+
+ _field_FA = file.readUint16LE();
+ _field_F8 = file.readUint16LE();
+
+ _gameVar = (CGameVar *)file.readClass();
+
+ return true;
+}
+
+bool CGameLoader::loadScene(int sceneId) {
+ SceneTag *st;
+
+ int idx = getSceneTagBySceneId(sceneId, &st);
+
+ if (idx < 0)
+ return false;
+
+ if (!st->_scene)
+ st->loadScene();
+
+ if (st->_scene) {
+ st->_scene->init();
+
+ applyPicAniInfos(st->_scene, _sc2array[idx]._defPicAniInfos, _sc2array[idx]._defPicAniInfosCount);
+ applyPicAniInfos(st->_scene, _sc2array[idx]._picAniInfos, _sc2array[idx]._picAniInfosCount);
+
+ _sc2array[idx]._scene = st->_scene;
+ _sc2array[idx]._isLoaded = 1;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool CGameLoader::gotoScene(int sceneId, int entranceId) {
+ SceneTag *st;
+
+ int sc2idx = getSceneTagBySceneId(sceneId, &st);
+
+ if (sc2idx < 0)
+ return false;
+
+ if (!_sc2array[sc2idx]._isLoaded)
+ return false;
+
+ if (_sc2array[sc2idx]._entranceDataCount < 1) {
+ g_fullpipe->_currentScene = st->_scene;
+ return true;
+ }
+
+ if (_sc2array[sc2idx]._entranceDataCount <= 0)
+ return false;
+
+ int entranceIdx = 0;
+ if (sceneId != 726) // WORKAROUND
+ for (entranceIdx = 0; _sc2array[sc2idx]._entranceData[entranceIdx]->_field_4 != entranceId; entranceIdx++) {
+ if (entranceIdx >= _sc2array[sc2idx]._entranceDataCount)
+ return false;
+ }
+
+ CGameVar *sg = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
+
+ if (sg || (sg = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0)) != 0)
+ sg->setSubVarAsInt("Entrance", entranceId);
+
+ if (!g_fullpipe->sceneSwitcher(_sc2array[sc2idx]._entranceData[entranceIdx]))
+ return false;
+
+ g_fullpipe->_msgObjectId2 = 0;
+ g_fullpipe->_msgY = -1;
+ g_fullpipe->_msgX = -1;
+
+ g_fullpipe->_currentScene = st->_scene;
+
+ MessageQueue *mq1 = g_fullpipe->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]->_messageQueueId);
+ if (mq1) {
+ MessageQueue *mq = new MessageQueue(mq1, 0, 0);
+
+ StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1);
+ if (stobj) {
+ stobj->_flags &= 0x100;
+
+ ExCommand *ex = new ExCommand(stobj->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_14 = 256;
+ ex->_messageNum = 0;
+ ex->_excFlags |= 3;
+
+ mq->_exCommands.push_back(ex);
+ }
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ if (!mq->chain(0)) {
+ delete mq;
+
+ return false;
+ }
+ } else {
+ StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1);
+ if (stobj)
+ stobj->_flags &= 0xfeff;
+ }
+
+ return true;
+}
+
+bool preloadCallback(const PreloadItem &pre, int flag) {
+ warning("STUB: preloadCallback");
+
+ return true;
+}
+
+bool CGameLoader::preloadScene(int sceneId, int entranceId) {
+ debug(0, "preloadScene(%d, %d), ", sceneId, entranceId);
+
+ if (_preloadSceneId != sceneId || _preloadEntranceId != entranceId) {
+ _preloadSceneId = sceneId;
+ _preloadEntranceId = entranceId;
+ return true;
+ }
+
+ int idx = -1;
+
+ for (uint i = 0; i < _preloadItems.size(); i++)
+ if (_preloadItems[i].preloadId1 == sceneId && _preloadItems[i].preloadId2 == entranceId) {
+ idx = i;
+ break;
+ }
+
+ if (idx == -1) {
+ _preloadSceneId = 0;
+ _preloadEntranceId = 0;
+ return false;
+ }
+
+ if (_preloadCallback) {
+ if (!_preloadCallback(_preloadItems[idx], 0))
+ return false;
+ }
+
+ if (g_fullpipe->_currentScene && g_fullpipe->_currentScene->_sceneId == sceneId)
+ g_fullpipe->_currentScene = 0;
+
+ saveScenePicAniInfos(sceneId);
+ clearGlobalMessageQueueList1();
+ unloadScene(sceneId);
+
+ if (_preloadCallback)
+ _preloadCallback(_preloadItems[idx], 50);
+
+ loadScene(_preloadItems[idx].sceneId);
+
+ ExCommand *ex = new ExCommand(_preloadItems[idx].sceneId, 17, 62, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+ ex->_keyCode = _preloadItems[idx].keyCode;
+
+ _preloadSceneId = 0;
+ _preloadEntranceId = 0;
+
+ if (_preloadCallback)
+ _preloadCallback(_preloadItems[idx], 100);
+
+ ex->postMessage();
+
+ return true;
+}
+
+bool CGameLoader::unloadScene(int sceneId) {
+ SceneTag *tag;
+ int sceneTag = getSceneTagBySceneId(sceneId, &tag);
+
+ if (sceneTag < 0)
+ return false;
+
+ if (_sc2array[sceneTag]._isLoaded)
+ saveScenePicAniInfos(sceneId);
+
+ _sc2array[sceneTag]._motionController->freeItems();
+
+ delete tag->_scene;
+ tag->_scene = 0;
+
+ _sc2array[sceneTag]._isLoaded = 0;
+ _sc2array[sceneTag]._scene = 0;
+
+ return true;
+}
+
+int CGameLoader::getSceneTagBySceneId(int sceneId, SceneTag **st) {
+ if (_sc2array.size() > 0 && _gameProject->_sceneTagList->size() > 0) {
+ for (uint i = 0; i < _sc2array.size(); i++) {
+ if (_sc2array[i]._sceneId == sceneId) {
+ int num = 0;
+ for (SceneTagList::iterator s = _gameProject->_sceneTagList->begin(); s != _gameProject->_sceneTagList->end(); ++s, num++) {
+ if (s->_sceneId == sceneId) {
+ *st = &(*s);
+ return num;
+ }
+ }
+ }
+ }
+ }
+
+ *st = 0;
+ return -1;
+}
+
+void CGameLoader::applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount) {
+ if (picAniInfoCount <= 0)
+ return;
+
+ debug(0, "CGameLoader::applyPicAniInfos(sc, ptr, %d)", picAniInfoCount);
+
+ PictureObject *pict;
+ StaticANIObject *ani;
+
+ for (int i = 0; i < picAniInfoCount; i++) {
+ debug(7, "PicAniInfo: id: %d type: %d", picAniInfo[i]->objectId, picAniInfo[i]->type);
+ if (picAniInfo[i]->type & 2) {
+ pict = sc->getPictureObjectById(picAniInfo[i]->objectId, picAniInfo[i]->field_8);
+ if (pict) {
+ pict->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+ pict = sc->getPictureObjectById(picAniInfo[i]->objectId, 0);
+ if (pict) {
+ PictureObject *pictNew = new PictureObject(pict);
+
+ sc->_picObjList.push_back(pictNew);
+ pictNew->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+ } else {
+ if (!(picAniInfo[i]->type & 1))
+ continue;
+
+ Scene *scNew = g_fullpipe->accessScene(picAniInfo[i]->sceneId);
+ if (!scNew)
+ continue;
+
+ ani = sc->getStaticANIObject1ById(picAniInfo[i]->objectId, picAniInfo[i]->field_8);
+ if (ani) {
+ ani->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+
+ ani = scNew->getStaticANIObject1ById(picAniInfo[i]->objectId, 0);
+ if (ani) {
+ StaticANIObject *aniNew = new StaticANIObject(ani);
+
+ sc->addStaticANIObject(aniNew, 1);
+
+ aniNew->setPicAniInfo(picAniInfo[i]);
+ continue;
+ }
+ }
+ }
+}
+
+void CGameLoader::saveScenePicAniInfos(int sceneId) {
+ warning("STUB: CGameLoader::saveScenePicAniInfos(%d)", sceneId);
+}
+
+void CGameLoader::updateSystems(int counterdiff) {
+ if (g_fullpipe->_currentScene) {
+ g_fullpipe->_currentScene->update(counterdiff);
+
+ _exCommand._messageKind = 17;
+ _updateCounter++;
+ _exCommand._messageNum = 33;
+ _exCommand._excFlags = 0;
+ _exCommand.postMessage();
+ }
+
+ processMessages();
+
+ if (_preloadSceneId) {
+ processMessages();
+ preloadScene(_preloadSceneId, _preloadEntranceId);
+ }
+}
+
+Sc2::Sc2() {
+ _sceneId = 0;
+ _field_2 = 0;
+ _scene = 0;
+ _motionController = 0;
+ _data1 = 0;
+ _count1 = 0;
+ _defPicAniInfos = 0;
+ _defPicAniInfosCount = 0;
+ _picAniInfos = 0;
+ _picAniInfosCount = 0;
+ _isLoaded = 0;
+ _entranceData = 0;
+ _entranceDataCount = 0;
+}
+
+bool Sc2::load(MfcArchive &file) {
+ debug(5, "Sc2::load()");
+
+ _sceneId = file.readUint16LE();
+
+ _motionController = (CMotionController *)file.readClass();
+
+ _count1 = file.readUint32LE();
+ debug(4, "count1: %d", _count1);
+ if (_count1 > 0) {
+ _data1 = (int32 *)malloc(_count1 * sizeof(int32));
+
+ for (int i = 0; i < _count1; i++) {
+ _data1[i] = file.readUint32LE();
+ }
+ } else {
+ _data1 = 0;
+ }
+
+ _defPicAniInfosCount = file.readUint32LE();
+ debug(4, "defPicAniInfos: %d", _defPicAniInfosCount);
+ if (_defPicAniInfosCount > 0) {
+ _defPicAniInfos = (PicAniInfo **)malloc(_defPicAniInfosCount * sizeof(PicAniInfo *));
+
+ for (int i = 0; i < _defPicAniInfosCount; i++) {
+ _defPicAniInfos[i] = new PicAniInfo();
+
+ _defPicAniInfos[i]->load(file);
+ }
+ } else {
+ _defPicAniInfos = 0;
+ }
+
+ _picAniInfos = 0;
+ _picAniInfosCount = 0;
+
+ _entranceDataCount = file.readUint32LE();
+ debug(4, "_entranceData: %d", _entranceDataCount);
+
+ if (_entranceDataCount > 0) {
+ _entranceData = (EntranceInfo **)malloc(_entranceDataCount * sizeof(EntranceInfo *));
+
+ for (int i = 0; i < _entranceDataCount; i++) {
+ _entranceData[i] = new EntranceInfo();
+ _entranceData[i]->load(file);
+ }
+ } else {
+ _entranceData = 0;
+ }
+
+ if (file.size() - file.pos() > 0)
+ error("Sc2::load(): (%d bytes left)", file.size() - file.pos());
+
+ return true;
+}
+
+CGameVar *FullpipeEngine::getGameLoaderGameVar() {
+ if (_gameLoader)
+ return _gameLoader->_gameVar;
+ else
+ return 0;
+}
+
+CInputController *FullpipeEngine::getGameLoaderInputController() {
+ if (_gameLoader)
+ return _gameLoader->_inputController;
+ else
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
new file mode 100644
index 0000000000..87cd1f1a35
--- /dev/null
+++ b/engines/fullpipe/gameloader.h
@@ -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.
+ *
+ */
+
+#ifndef FULLPIPE_GAMELOADER_H
+#define FULLPIPE_GAMELOADER_H
+
+#include "fullpipe/objects.h"
+#include "fullpipe/inventory.h"
+#include "fullpipe/messages.h"
+
+namespace Fullpipe {
+
+class SceneTag;
+class CMctlCompound;
+class CInputController;
+class CInteractionController;
+class CMotionController;
+
+class Sc2 : public CObject {
+ public:
+ int16 _sceneId;
+ int16 _field_2;
+ Scene *_scene;
+ CMotionController *_motionController;
+ int32 *_data1; // FIXME, could be a struct
+ int _count1;
+ PicAniInfo **_defPicAniInfos;
+ int _defPicAniInfosCount;
+ PicAniInfo **_picAniInfos;
+ int _picAniInfosCount;
+ int _isLoaded;
+ EntranceInfo **_entranceData;
+ int _entranceDataCount;
+
+ public:
+ Sc2();
+ virtual bool load(MfcArchive &file);
+};
+
+typedef Common::Array<Sc2> Sc2Array;
+
+struct PreloadItem {
+ int preloadId1;
+ int preloadId2;
+ int sceneId;
+ int keyCode;
+};
+
+bool preloadCallback(const PreloadItem &pre, int flag);
+
+class PreloadItems : public Common::Array<PreloadItem>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class CGameLoader : public CObject {
+ public:
+ CGameLoader();
+ virtual ~CGameLoader();
+
+ virtual bool load(MfcArchive &file);
+ bool loadScene(int sceneId);
+ bool gotoScene(int sceneId, int entranceId);
+ bool preloadScene(int sceneId, int entranceId);
+ bool unloadScene(int sceneId);
+
+ void updateSystems(int counterdiff);
+
+ int getSceneTagBySceneId(int sceneId, SceneTag **st);
+ void applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount);
+ void saveScenePicAniInfos(int sceneId);
+
+ GameProject *_gameProject;
+ CInteractionController *_interactionController;
+ CInputController *_inputController;
+ CInventory2 _inventory;
+ Sc2Array _sc2array;
+ void *_sceneSwitcher;
+ bool (*_preloadCallback)(const PreloadItem &pre, int flag);
+ void *_readSavegameCallback;
+ int16 _field_F8;
+ int16 _field_FA;
+ PreloadItems _preloadItems;
+ CGameVar *_gameVar;
+ char *_gameName;
+ ExCommand _exCommand;
+ int _updateCounter;
+ int _preloadSceneId;
+ int _preloadEntranceId;
+};
+
+CInventory2 *getGameLoaderInventory();
+CInteractionController *getGameLoaderInteractionController();
+CMctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId);
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_GAMELOADER_H */
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
new file mode 100644
index 0000000000..2ab038b74d
--- /dev/null
+++ b/engines/fullpipe/gfx.cpp
@@ -0,0 +1,1238 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
+
+#include "common/memstream.h"
+
+namespace Fullpipe {
+
+Bitmap::Bitmap() {
+ _x = 0;
+ _y = 0;
+ _width = 0;
+ _height = 0;
+ _pixels = 0;
+ _type = 0;
+ _dataSize = 0;
+ _flags = 0;
+}
+
+Bitmap::Bitmap(Bitmap *src) {
+ _x = src->_x;
+ _y = src->_y;
+ _flags = src->_flags;
+ _dataSize = src->_dataSize;
+ _type = src->_type;
+ _width = src->_width;
+ _height = src->_height;
+ _pixels = src->_pixels;
+}
+
+Bitmap::~Bitmap() {
+ if (_pixels)
+ free(_pixels);
+}
+
+void Bitmap::load(Common::ReadStream *s) {
+ debug(5, "Bitmap::load()");
+
+ _x = s->readUint32LE();
+ _y = s->readUint32LE();
+ _width = s->readUint32LE();
+ _height = s->readUint32LE();
+ s->readUint32LE(); // pixels
+ _type = s->readUint32LE();
+ _dataSize = s->readUint32LE();
+ _flags = s->readUint32LE();
+
+ debug(8, "Bitmap: x: %d y: %d w: %d h: %d dataSize: 0x%x", _x, _y, _width, _height, _dataSize);
+ debug(8, "Bitmap: type: %s (0x%04x) flags: 0x%x", Common::tag2string(_type).c_str(), _type, _flags);
+}
+
+Background::Background() {
+ _x = 0;
+ _y = 0;
+ _messageQueueId = 0;
+ _bigPictureArray1Count = 0;
+ _bigPictureArray2Count = 0;
+ _bigPictureArray = 0;
+ _bgname = 0;
+ _palette = 0;
+}
+
+bool Background::load(MfcArchive &file) {
+ debug(5, "Background::load()");
+ _bgname = file.readPascalString();
+
+ int count = file.readUint16LE();
+
+ for (int i = 0; i < count; i++) {
+ PictureObject *pct = new PictureObject();
+
+ pct->load(file, i == 0);
+ addPictureObject(pct);
+ }
+
+ assert(g_fullpipe->_gameProjectVersion >= 4);
+
+ _bigPictureArray1Count = file.readUint32LE();
+
+ assert(g_fullpipe->_gameProjectVersion >= 5);
+
+ _bigPictureArray2Count = file.readUint32LE();
+
+ _bigPictureArray = (BigPicture ***)calloc(_bigPictureArray1Count, sizeof(BigPicture **));
+
+ debug(6, "bigPictureArray[%d][%d]", _bigPictureArray1Count, _bigPictureArray2Count);
+
+ for (int i = 0; i < _bigPictureArray1Count; i++) {
+ _bigPictureArray[i] = (BigPicture **)calloc(_bigPictureArray2Count, sizeof(BigPicture *));
+ for (int j = 0; j < _bigPictureArray2Count; j++) {
+ _bigPictureArray[i][j] = new BigPicture();
+
+ _bigPictureArray[i][j]->load(file);
+ }
+ }
+
+ return true;
+}
+
+void Background::addPictureObject(PictureObject *pct) {
+ if (pct->_okeyCode)
+ pct->renumPictures(&_picObjList);
+
+ bool inserted = false;
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i])->_priority == pct->_priority) {
+ _picObjList.insert_at(i, pct);
+ inserted = true;
+ break;
+ }
+ }
+
+ if (!inserted) {
+ _picObjList.push_back(pct);
+ }
+}
+
+PictureObject::PictureObject() {
+ _ox = 0;
+ _oy = 0;
+ _picture = 0;
+ _ox2 = 0;
+ _oy2 = 0;
+ _pictureObject2List = 0;
+ _objtype = kObjTypePictureObject;
+}
+
+PictureObject::PictureObject(PictureObject *src) : GameObject(src) {
+ _picture = src->_picture;
+ _ox2 = _ox;
+ _oy2 = _oy;
+ _pictureObject2List = src->_pictureObject2List;
+ _objtype = kObjTypePictureObject;
+}
+
+bool PictureObject::load(MfcArchive &file, bool bigPicture) {
+ debug(5, "PictureObject::load()");
+ GameObject::load(file);
+
+ if (bigPicture)
+ _picture = new BigPicture();
+ else
+ _picture = new Picture();
+
+ _picture->load(file);
+
+ _pictureObject2List = new CPtrList();
+
+ int count = file.readUint16LE();
+
+ if (count > 0) {
+ GameObject *o = new GameObject();
+
+ o->load(file);
+ _pictureObject2List->push_back(o);
+ }
+
+ _ox2 = _ox;
+ _oy2 = _oy;
+
+#if 0
+ _picture->displayPicture();
+#endif
+
+ return true;
+}
+
+Common::Point *PictureObject::getDimensions(Common::Point *p) {
+ _picture->getDimensions(p);
+
+ return p;
+}
+
+void PictureObject::draw() {
+ if (_flags & 1)
+ _picture->draw(_ox, _oy, 2, 0);
+ else
+ _picture->draw(_ox, _oy, 0, 0);
+}
+
+void PictureObject::drawAt(int x, int y) {
+ if (x == -1)
+ x = _ox;
+ if (y == -1)
+ y = _oy;
+
+ _picture->_x = x;
+ _picture->_y = y;
+
+ if (_flags & 1)
+ _picture->draw(x, y, 2, 0);
+ else
+ _picture->draw(x, y, 0, 0);
+}
+
+bool PictureObject::setPicAniInfo(PicAniInfo *picAniInfo) {
+ if (!(picAniInfo->type & 2) || (picAniInfo->type & 1)) {
+ error("Picture::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
+
+ return false;
+ }
+
+ if (picAniInfo->type & 2) {
+ setOXY(picAniInfo->ox, picAniInfo->oy);
+ _priority = picAniInfo->priority;
+ _okeyCode = picAniInfo->field_8;
+ setFlags(picAniInfo->flags);
+ _field_8 = picAniInfo->field_24;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool PictureObject::isPointInside(int x, int y) {
+ bool res;
+ int oldx = _picture->_x;
+ int oldy = _picture->_y;
+
+ _picture->_x = _ox;
+ _picture->_y = _oy;
+
+ res = _picture->isPointInside(x, y);
+
+ _picture->_x = oldx;
+ _picture->_y = oldy;
+
+ return res;
+}
+
+bool PictureObject::isPixelHitAtPos(int x, int y) {
+ int oldx = _picture->_x;
+ int oldy = _picture->_y;
+
+ _picture->_x = _ox;
+ _picture->_y = _oy;
+ bool res = _picture->isPixelHitAtPos(x, y);
+ _picture->_x = oldx;
+ _picture->_y = oldy;
+
+ return res;
+}
+
+GameObject::GameObject() {
+ _okeyCode = 0;
+ _flags = 0;
+ _id = 0;
+ _ox = 0;
+ _oy = 0;
+ _priority = 0;
+ _field_20 = 0;
+ _field_8 = 0;
+ _objectName = 0;
+}
+
+GameObject::GameObject(GameObject *src) {
+ _okeyCode = 1;
+ _flags = 0;
+ _id = src->_id;
+
+ _objectName = (char *)calloc(strlen(src->_objectName) + 1, 1);
+ strncpy(_objectName, src->_objectName, strlen(src->_objectName));
+
+ _ox = src->_ox;
+ _oy = src->_oy;
+ _priority = src->_priority;
+ _field_20 = 1;
+ _field_8 = src->_field_8;
+}
+
+GameObject::~GameObject() {
+ free(_objectName);
+}
+
+bool GameObject::load(MfcArchive &file) {
+ debug(5, "GameObject::load()");
+ _okeyCode = 0;
+ _flags = 0;
+ _field_20 = 0;
+
+ _id = file.readUint16LE();
+
+ _objectName = file.readPascalString();
+ _ox = file.readUint32LE();
+ _oy = file.readUint32LE();
+ _priority = file.readUint16LE();
+
+ if (g_fullpipe->_gameProjectVersion >= 11) {
+ _field_8 = file.readUint32LE();
+ }
+
+ return true;
+}
+
+void GameObject::setOXY(int x, int y) {
+ _ox = x;
+ _oy = y;
+}
+
+void GameObject::renumPictures(CPtrList *lst) {
+ int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
+
+ for (uint i = 0; i < lst->size(); i++) {
+ if (_id == ((PictureObject *)((*lst)[i]))->_id)
+ buf[((PictureObject *)((*lst)[i]))->_okeyCode] = 1;
+ }
+
+ if (buf[_okeyCode]) {
+ uint count;
+ for (count = 1; buf[count] && count < lst->size() + 2; count++)
+ ;
+ _okeyCode = count;
+ }
+
+ free(buf);
+}
+
+bool GameObject::getPicAniInfo(PicAniInfo *info) {
+ if (_objtype == kObjTypePictureObject) {
+ info->type = 2;
+ info->objectId = _id;
+ info->sceneId = 0;
+ info->field_8 = _okeyCode;
+ info->flags = _flags;
+ info->field_24 = _field_8;
+ info->ox = _ox;
+ info->oy = _oy;
+ info->priority = _priority;
+
+ return true;
+ }
+
+ if (_objtype == kObjTypeStaticANIObject) {
+ StaticANIObject *ani = (StaticANIObject *)this;
+
+ info->type = (ani->_messageQueueId << 16) | 1;
+ info->objectId = ani->_id;
+ info->field_8 = ani->_okeyCode;
+ info->sceneId = ani->_sceneId;
+ info->flags = ani->_flags;
+ info->field_24 = ani->_field_8;
+ if (ani->_movement) {
+ info->ox = ani->_movement->_ox;
+ info->oy = ani->_movement->_oy;
+ } else {
+ info->ox = ani->_ox;
+ info->oy = ani->_oy;
+ }
+ info->priority = ani->_priority;
+
+ if (ani->_statics)
+ info->staticsId = ani->_statics->_staticsId;
+
+ if (ani->_movement) {
+ info->movementId = ani->_movement->_id;
+ info->dynamicPhaseIndex = ani->_movement->_currDynamicPhaseIndex;
+ }
+
+ info->someDynamicPhaseIndex = ani->_someDynamicPhaseIndex;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool GameObject::setPicAniInfo(PicAniInfo *picAniInfo) {
+ if (!(picAniInfo->type & 3)) {
+ warning("StaticANIObject::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
+
+ return false;
+ }
+
+ if (picAniInfo->type & 3) {
+ setOXY(picAniInfo->ox, picAniInfo->oy);
+ _priority = picAniInfo->priority;
+ _okeyCode = picAniInfo->field_8;
+ setFlags(picAniInfo->flags);
+ _field_8 = picAniInfo->field_24;
+ }
+
+ if (picAniInfo->type & 1) {
+ StaticANIObject *ani = (StaticANIObject *)this;
+
+ ani->_messageQueueId = (picAniInfo->type >> 16) & 0xffff;
+
+ if (picAniInfo->staticsId) {
+ ani->_statics = ani->getStaticsById(picAniInfo->staticsId);
+ } else {
+ ani->_statics = 0;
+ }
+
+ if (picAniInfo->movementId) {
+ ani->_movement = ani->getMovementById(picAniInfo->movementId);
+ if (ani->_movement)
+ ani->_movement->setDynamicPhaseIndex(picAniInfo->dynamicPhaseIndex);
+ } else {
+ ani->_movement = 0;
+ }
+
+ ani->setSomeDynamicPhaseIndex(picAniInfo->someDynamicPhaseIndex);
+ }
+
+ return true;
+}
+
+Picture::Picture() {
+ _x = 0;
+ _y = 0;
+ _field_44 = 0;
+ _field_54 = 0;
+ _bitmap = 0;
+ _alpha = -1;
+ _paletteData = 0;
+ _convertedBitmap = 0;
+ _memoryObject2 = 0;
+ _width = 0;
+ _height = 0;
+}
+
+Picture::~Picture() {
+ freePicture();
+
+ _bitmap = 0;
+
+ if (_memoryObject2)
+ delete _memoryObject2;
+
+ if (_paletteData)
+ free(_paletteData);
+
+ if (_convertedBitmap) {
+ delete _convertedBitmap;
+ _convertedBitmap = 0;
+ }
+}
+
+void Picture::freePicture() {
+ if (_bitmap) {
+ if (testFlags() && !_field_54) {
+ freeData();
+ delete _bitmap;
+ _bitmap = 0;
+ }
+ }
+
+ if (_bitmap) {
+ _bitmap = 0;
+ _data = 0;
+ }
+
+ if (_convertedBitmap) {
+ free(_convertedBitmap->_pixels);
+ delete _convertedBitmap;
+ _convertedBitmap = 0;
+ }
+}
+
+bool Picture::load(MfcArchive &file) {
+ debug(5, "Picture::load()");
+ MemoryObject::load(file);
+
+ _x = file.readUint32LE();
+ _y = file.readUint32LE();
+ _field_44 = file.readUint16LE();
+
+ assert(g_fullpipe->_gameProjectVersion >= 2);
+
+ _width = file.readUint32LE();
+ _height = file.readUint32LE();
+
+ _mflags |= 1;
+
+ _memoryObject2 = new MemoryObject2;
+ _memoryObject2->load(file);
+
+ if (_memoryObject2->_data) {
+ setAOIDs();
+ }
+
+ assert (g_fullpipe->_gameProjectVersion >= 12);
+
+ _alpha = file.readUint32LE() & 0xff;
+
+ int havePal = file.readUint32LE();
+
+ if (havePal > 0) {
+ _paletteData = (byte *)calloc(1024, 1);
+ file.read(_paletteData, 1024);
+ }
+
+ getData();
+
+ debug(5, "Picture::load: <%s>", _memfilename);
+
+ return true;
+}
+
+void Picture::setAOIDs() {
+ int w = (g_fullpipe->_pictureScale + _width - 1) / g_fullpipe->_pictureScale;
+ int h = (g_fullpipe->_pictureScale + _height - 1) / g_fullpipe->_pictureScale;
+
+ _memoryObject2->_rows = (byte **)malloc(w * sizeof(int *));
+
+ int pitch = 2 * h;
+ byte *ptr = _memoryObject2->getData();
+ for (int i = 0; i < w; i++) {
+ _memoryObject2->_rows[i] = ptr;
+ ptr += pitch;
+ }
+}
+
+void Picture::init() {
+ _bitmap = new Bitmap();
+
+ getDibInfo();
+
+ _bitmap->_flags |= 0x1000000;
+}
+
+Common::Point *Picture::getDimensions(Common::Point *p) {
+ p->x = _width;
+ p->y = _height;
+
+ return p;
+}
+
+void Picture::getDibInfo() {
+ int off = _dataSize & ~0xf;
+
+ debug(9, "Picture::getDibInfo: _dataSize: %d", _dataSize);
+
+ if (!_dataSize) {
+ warning("Picture::getDibInfo(): Empty data size");
+ return;
+ }
+
+ if (_dataSize != off) {
+ warning("Uneven data size: 0x%x", _dataSize);
+ }
+
+ Common::MemoryReadStream *s = new Common::MemoryReadStream(_data + off - 32, 32);
+
+ _bitmap->load(s);
+ _bitmap->_pixels = _data;
+}
+
+Bitmap *Picture::getPixelData() {
+ if (!_bitmap)
+ init();
+
+ return _bitmap;
+}
+
+void Picture::draw(int x, int y, int style, int angle) {
+ int x1 = x;
+ int y1 = y;
+
+ debug(0, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename);
+
+ if (x != -1)
+ x1 = x;
+
+ if (y != -1)
+ y1 = y;
+
+ if (!_bitmap)
+ init();
+
+ if (!_bitmap)
+ return;
+
+ if ((_alpha & 0xff) < 0xff) {
+ debug(0, "Picture:draw: alpha = %0x", _alpha);
+ }
+
+ byte *pal = _paletteData;
+
+ if (!pal) {
+ //warning("Picture:draw: using global palette");
+ pal = g_fullpipe->_globalPalette;
+ }
+
+ Common::Point point;
+
+ switch (style) {
+ case 1:
+ //flip
+ getDimensions(&point);
+ _bitmap->flipVertical()->drawShaded(1, x1, y1 + 30 + point.y, pal);
+ break;
+ case 2:
+ //vrtSetFadeRatio(g_vrtDrawHandle, 0.34999999);
+ //vrtSetFadeTable(g_vrtDrawHandle, &unk_477F88, 1.0, 1000.0, 0, 0);
+ _bitmap->drawShaded(2, x1, y1, pal);
+ //vrtSetFadeRatio(g_vrtDrawHandle, 0.0);
+ //vrtSetFadeTable(g_vrtDrawHandle, &unk_477F90, 1.0, 1000.0, 0, 0);
+ break;
+ default:
+ if (angle)
+ drawRotated(x1, y1, angle);
+ else {
+ _bitmap->putDib(x1, y1, (int32 *)pal);
+ }
+ }
+}
+
+void Picture::drawRotated(int x, int y, int angle) {
+ warning("STUB: Picture::drawRotated(%d, %d, %d)", x, y, angle);
+}
+
+void Picture::displayPicture() {
+ if (!g_fullpipe->_gameContinue)
+ return;
+
+ getData();
+ init();
+
+ if (!_dataSize)
+ return;
+
+ g_fullpipe->_backgroundSurface.fillRect(Common::Rect(0, 0, 799, 599), 0);
+ g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(0, 0), g_fullpipe->_backgroundSurface.pitch, 0, 0, 799, 599);
+
+ draw(0, 0, 0, 0);
+
+ g_fullpipe->updateEvents();
+ g_fullpipe->_system->delayMillis(10);
+ g_fullpipe->_system->updateScreen();
+
+ while (g_fullpipe->_gameContinue) {
+ g_fullpipe->updateEvents();
+ g_fullpipe->_system->delayMillis(10);
+ g_fullpipe->_system->updateScreen();
+
+ if (g_fullpipe->_keyState == ' ') {
+ g_fullpipe->_keyState = Common::KEYCODE_INVALID;
+ break;
+ }
+ }
+}
+
+void Picture::setPaletteData(byte *pal) {
+ if (_paletteData)
+ free(_paletteData);
+
+ if (pal) {
+ _paletteData = (byte *)malloc(1024);
+ memcpy(_paletteData, pal, 1024);
+ }
+}
+
+void Picture::copyMemoryObject2(Picture *src) {
+ if (_width == src->_width && _height == src->_height) {
+ if (src->_memoryObject2 && src->_memoryObject2->_rows && _memoryObject2) {
+ byte *data = loadData();
+ _memoryObject2->copyData(data, _dataSize);
+ setAOIDs();
+ }
+ }
+}
+
+bool Picture::isPointInside(int x, int y) {
+ if (x >= _x) {
+ if (y >= _y && x < _x + _width && y < _y + _height)
+ return true;
+ }
+ return false;
+}
+
+bool Picture::isPixelHitAtPos(int x, int y) {
+ if (x < _x || y < _y || x >= _x + _width || y >= _y + _height)
+ return false;
+
+ if (!_bitmap)
+ init();
+
+ _bitmap->_x = _x;
+ _bitmap->_y = _y;
+
+ return _bitmap->isPixelHitAtPos(x, y);
+}
+
+int Picture::getPixelAtPos(int x, int y) {
+ return getPixelAtPosEx(x / g_fullpipe->_pictureScale, y / g_fullpipe->_pictureScale);
+
+ return false;
+}
+
+int Picture::getPixelAtPosEx(int x, int y) {
+ if (x < 0 || y < 0)
+ return 0;
+
+ if (x < (g_fullpipe->_pictureScale + _width - 1) / g_fullpipe->_pictureScale &&
+ y < (g_fullpipe->_pictureScale + _height - 1) / g_fullpipe->_pictureScale &&
+ _memoryObject2 != 0 && _memoryObject2->_rows != 0)
+ return _memoryObject2->_rows[x][2 * y];
+
+ return 0;
+}
+
+bool Bitmap::isPixelHitAtPos(int x, int y) {
+ if (x < _x || x >= _width + _x || y < _y || y >= _y + _height)
+ return false;
+
+ int off;
+
+ if (_type == 'CB\x05e')
+ off = 2 * ((_width + 1) / 2);
+ else
+ off = 4 * ((_width + 3) / 4);
+
+ off = x + off * (_y + _height - y - 1) - _x;
+
+ if (_flags & 0x1000000) {
+ switch (_type) {
+ case 'CB\0\0':
+ if (_pixels[off] == (_flags & 0xff))
+ return false;
+ break;
+ case 'CB\x05e':
+ if (!*(int16 *)&_pixels[2 * off])
+ return false;
+ break;
+ case 'RB\0\0':
+ return isPixelAtHitPosRB(x, y);
+ }
+ }
+ return true;
+}
+
+bool Bitmap::isPixelAtHitPosRB(int x, int y) {
+ int ox = _x;
+ int oy = _y;
+
+ _x = _y = 0;
+
+ bool res = putDibRB(0, x, y);
+ _x = ox;
+ _y = oy;
+
+ return res;
+}
+
+void Bitmap::putDib(int x, int y, int32 *palette) {
+ debug(0, "Bitmap::putDib(%d, %d)", x, y);
+
+ _x = x - g_fullpipe->_sceneRect.left;
+ _y = y - g_fullpipe->_sceneRect.top;
+
+ if (_type == MKTAG('R', 'B', '\0', '\0'))
+ putDibRB(palette);
+ else
+ putDibCB(palette);
+}
+
+bool Bitmap::putDibRB(int32 *palette, int pX, int pY) {
+ uint16 *curDestPtr;
+ int endy;
+ int x;
+ int start1;
+ int fillLen;
+ uint16 pixel;
+ int endx;
+ int y;
+ uint16 *srcPtr2;
+ uint16 *srcPtr;
+
+ if (!palette && pX == -1) {
+ warning("Bitmap::putDibRB(): Both global and local palettes are empty");
+ return false;
+ }
+
+ debug(8, "Bitmap::putDibRB()");
+
+ endx = _width + _x - 1;
+ endy = _height + _y - 1;
+
+ if (_x > 799 || endx < 0 || _y > 599 || endy < 0)
+ return false;
+
+ if (pX == -1) {
+ if (endy > 599)
+ endy = 599;
+
+ if (endx > 799)
+ endx = 799;
+ }
+
+ int startx = _x;
+ if (startx < 0)
+ startx = 0;
+
+ int starty = _y;
+ if (starty < 0)
+ starty = 0;
+
+ y = endy;
+
+ srcPtr = (uint16 *)_pixels;
+
+ bool breakup = false;
+ for (y = endy; y >= starty && !breakup; y--) {
+ x = startx;
+
+ while ((pixel = *srcPtr++) != 0) {
+ if (pixel == 0x100) {
+ breakup = true;
+ break;
+ }
+
+ while (pixel == 0x200 && y >= starty) {
+ uint16 value = *srcPtr++;
+
+ x += (byte)(value & 0xff);
+ y -= (byte)((value >> 8) & 0xff);
+
+ pixel = *srcPtr++;
+ }
+
+ if (y < starty || pixel == 0)
+ break;
+
+ start1 = x;
+ fillLen = (byte)(pixel & 0xff);
+
+ if (fillLen) {
+ x += fillLen;
+
+ if (start1 < 0) {
+ fillLen += start1;
+
+ if (fillLen > 0)
+ start1 = 0;
+ }
+
+ if (fillLen > 0 || start1 >= 0) {
+ if (x <= 799 + 1 || (fillLen += 799 - x + 1, fillLen > 0)) {
+ if (y <= endy) {
+ if (pX == -1) {
+ int bgcolor = palette[(pixel >> 8) & 0xff];
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(start1, y);
+ colorFill(curDestPtr, fillLen, bgcolor);
+ } else {
+ if (y == pY && pX >= start1 && pX < start1 + fillLen)
+ return true;
+ }
+ }
+ }
+ }
+ } else {
+ fillLen = (pixel >> 8) & 0xff;
+ srcPtr2 = srcPtr;
+ x += fillLen;
+ srcPtr += (fillLen + 1) >> 1;
+
+ if (start1 < 0) {
+ fillLen += start1;
+ if (fillLen > 0) {
+ srcPtr2 = (uint16 *)((byte *)srcPtr2 - start1);
+ start1 = 0;
+ }
+ }
+
+ if (x > 799 + 1) {
+ fillLen += 799 - x + 1;
+ if (fillLen <= 0)
+ continue;
+ }
+
+ if (y <= endy) {
+ if (pX == -1) {
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(start1, y);
+ paletteFill(curDestPtr, (byte *)srcPtr2, fillLen, (int32 *)palette);
+ } else {
+ if (y == pY && pX >= start1 && pX < start1 + fillLen)
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ if (pX == -1)
+ g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(startx, starty), g_fullpipe->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
+
+ return false;
+}
+
+void Bitmap::putDibCB(int32 *palette) {
+ uint16 *curDestPtr;
+ int endx;
+ int endy;
+ int bpp;
+ uint pitch;
+ bool cb05_format;
+
+ endx = _width + _x - 1;
+ endy = _height + _y - 1;
+
+ debug(8, "Bitmap::putDibCB(): %d, %d, %d, %d [%d, %d]", _x, _y, endx, endy, _width, _height);
+
+ if (_x > 799 || endx < 0 || _y > 599 || endy < 0)
+ return;
+
+ if (endy > 599)
+ endy = 599;
+
+ if (endx > 799)
+ endx = 799;
+
+ cb05_format = (_type == MKTAG('C', 'B', '\05', 'e'));
+
+ if (!palette && !cb05_format)
+ error("Bitmap::putDibCB(): Both global and local palettes are empty");
+
+ bpp = cb05_format ? 2 : 1;
+ pitch = (bpp * _width + 3) & 0xFFFFFFFC;
+
+ byte *srcPtr = &_pixels[pitch * (endy - _y)];
+
+ int starty = _y;
+ if (starty < 0) {
+ starty = 0;
+ srcPtr = &_pixels[pitch * (_height + _y)];
+ }
+
+ int startx = _x;
+ if (startx < 0) {
+ srcPtr += bpp * -_x;
+ startx = 0;
+ }
+
+ if (_flags & 0x1000000) {
+ for (int y = starty; y < endy; srcPtr -= pitch, y++) {
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(startx, y);
+ copierKeyColor(curDestPtr, srcPtr, endx - startx + 1, _flags & 0xff, (int32 *)palette, cb05_format);
+ }
+ } else {
+ for (int y = starty; y <= endy; srcPtr -= pitch, y++) {
+ curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(startx, y);
+ copier(curDestPtr, srcPtr, endx - startx + 1, (int32 *)palette, cb05_format);
+ }
+ }
+
+ g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(startx, starty), g_fullpipe->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
+}
+
+void Bitmap::colorFill(uint16 *dest, int len, int32 color) {
+#if 0
+ if (blendMode) {
+ if (blendMode != 1)
+ error("vrtPutDib : RLE Fill : Invalid alpha blend mode");
+
+ colorFill = ptralphaFillColor16bit;
+ } else {
+ colorFill = ptrfillColor16bit;
+ }
+#endif
+
+ for (int i = 0; i < len; i++)
+ *dest++ = (int16)(color & 0xffff);
+}
+
+void Bitmap::paletteFill(uint16 *dest, byte *src, int len, int32 *palette) {
+#if 0
+ if (blendMode) {
+ if (blendMode != 1)
+ error("vrtPutDib : RLE Fill : Invalid alpha blend mode");
+
+ paletteFill = ptrcopierWithPaletteAlpha;
+ } else {
+ paletteFill = ptrcopierWithPalette;
+ }
+#endif
+
+ for (int i = 0; i < len; i++)
+ *dest++ = READ_LE_UINT32(&palette[*src++]) & 0xffff;
+}
+
+void Bitmap::copierKeyColor(uint16 *dest, byte *src, int len, int keyColor, int32 *palette, bool cb05_format) {
+#if 0
+ if (blendMode) {
+ if (blendMode == 1) {
+ if (cb05_format)
+ copierKeyColor = ptrcopier16bitKeycolorAlpha;
+ else
+ copierKeyColor = ptrcopierKeycolorAlpha;
+ } else {
+ copier = 0;
+ }
+ } else if (cb05_format) {
+ copierKeyColor = ptrcopier16bitKeycolor;
+ } else {
+ copierKeyColor = ptrkeyColor16bit;
+ }
+#endif
+
+ if (!cb05_format) {
+ for (int i = 0; i < len; i++) {
+ if (*src != keyColor)
+ *dest = READ_LE_UINT32(&palette[*src]) & 0xffff;
+
+ dest++;
+ src++;
+ }
+ } else {
+ int16 *src16 = (int16 *)src;
+
+ for (int i = 0; i < len; i++) {
+ if (*src16 != 0)
+ *dest = *src16;
+
+ dest++;
+ src16++;
+ }
+ }
+}
+
+void Bitmap::copier(uint16 *dest, byte *src, int len, int32 *palette, bool cb05_format) {
+#if 0
+ if (blendMode) {
+ if (blendMode == 1) {
+ if (cb05_format)
+ copier = ptrcopier16bitAlpha;
+ else
+ copier = ptrcopierWithPaletteAlpha;
+ } else {
+ copier = 0;
+ }
+ } else if (cb05_format) {
+ copier = ptrcopier16bit;
+ } else {
+ copier = ptrcopierWithPalette;
+ }
+#endif
+
+ if (!cb05_format) {
+ for (int i = 0; i < len; i++)
+ *dest++ = READ_LE_UINT32(&palette[*src++]) & 0xffff;
+ } else {
+ int16 *src16 = (int16 *)src;
+
+ for (int i = 0; i < len; i++)
+ *dest++ = *src16++;
+ }
+}
+
+Bitmap *Bitmap::reverseImage() {
+ switch (_type) {
+ case MKTAG('R', 'B', '\0', '\0'):
+ return reverseImageRB();
+ case MKTAG('C', 'B', '\0', '\0'):
+ return reverseImageCB();
+ case MKTAG('C', 'B', '\05', 'e'):
+ return reverseImageCB05();
+ default:
+ error("Bitmap::reverseImage: Unknown image type: %x", _type);
+ }
+
+ return 0;
+}
+
+Bitmap *Bitmap::reverseImageRB() {
+ uint16 *newpixels = (uint16 *)calloc(((_dataSize + 15) & 0xfffffff0) + sizeof(Bitmap), 1);
+ uint16 *srcPtr = (uint16 *)_pixels;
+
+ int idx = 0;
+ while (srcPtr[idx] != 0x100) {
+ uint16 *srcPtr2 = &srcPtr[idx];
+
+ int prevIdx = idx;
+ int i = idx;
+
+ while (*srcPtr2) {
+ ++srcPtr2;
+ ++idx;
+ }
+
+ int idx2 = idx;
+
+ newpixels[idx] = srcPtr[idx];
+
+ while (i != idx) {
+ int fillLen = 2 - ((srcPtr[prevIdx] & 0xff) != 0 ? 1 : 0);
+ idx2 -= fillLen;
+ memcpy(&newpixels[idx2], &srcPtr[prevIdx], 2 * fillLen);
+ prevIdx = fillLen + i;
+ i += fillLen;
+ }
+ ++idx;
+ }
+ newpixels[idx] = 256;
+
+ int oldBmp = ((_dataSize + 15) >> 1) & 0x7FFFFFF8;
+ memcpy(&newpixels[oldBmp], &srcPtr[oldBmp], sizeof(Bitmap));
+
+ Bitmap *res = new Bitmap(this);
+ res->_pixels = (byte *)newpixels;
+
+ return res;
+}
+
+Bitmap *Bitmap::reverseImageCB() {
+ warning("STUB: Bitmap::reverseImageCB()");
+
+ return this;
+}
+
+Bitmap *Bitmap::reverseImageCB05() {
+ warning("STUB: Bitmap::reverseImageCB05()");
+
+ return this;
+}
+
+Bitmap *Bitmap::flipVertical() {
+ warning("STUB: Bitmap::flipVertical()");
+
+ return this;
+}
+
+void Bitmap::drawShaded(int type, int x, int y, byte *palette) {
+ warning("STUB: Bitmap::drawShaded(%d, %d, %d)", type, x, y);
+
+ putDib(x, y, (int32 *)palette);
+}
+
+ void Bitmap::drawRotated(int x, int y, int angle, byte *palette) {
+ warning("STUB: Bitmap::drawShaded(%d, %d, %d)", x, y, angle);
+
+ putDib(x, y, (int32 *)palette);
+}
+
+bool BigPicture::load(MfcArchive &file) {
+ debug(5, "BigPicture::load()");
+ Picture::load(file);
+
+ return true;
+}
+
+Shadows::Shadows() {
+ _staticAniObjectId = 0;
+ _movementId = 0;
+ _sceneId = 0;
+}
+
+bool Shadows::load(MfcArchive &file) {
+ debug(5, "Shadows::load()");
+ _sceneId = file.readUint32LE();
+ _staticAniObjectId = file.readUint32LE();
+ _movementId = file.readUint32LE();
+
+ return true;
+}
+
+void Shadows::init() {
+ Scene *scene = g_fullpipe->accessScene(_sceneId);
+
+ StaticANIObject *st;
+ Movement *mov;
+
+ if (scene && (st = scene->getStaticANIObject1ById(_staticAniObjectId, -1)) != 0
+ && ((mov = st->getMovementById(_movementId)) != 0))
+ initMovement(mov);
+}
+
+void Shadows::initMovement(Movement *mov) {
+ uint num;
+
+ if (mov->_currMovement)
+ num = mov->_currMovement->_dynamicPhases.size();
+ else
+ num = mov->_dynamicPhases.size();
+
+ _items.clear();
+ _items.resize(num);
+
+ Common::Point point;
+
+ _items[0].dynPhase = (DynamicPhase *)mov->_staticsObj1;
+ _items[0].dynPhase->getDimensions(&point);
+ _items[0].width = point.x;
+ _items[0].height = point.y;
+
+ for (uint i = 1; i < num; i++) {
+ _items[i].dynPhase = mov->getDynamicPhaseByIndex(i - 1);
+ _items[i].dynPhase->getDimensions(&point);
+ _items[i].width = point.x;
+ _items[i].height = point.y;
+ }
+}
+
+DynamicPhase *Shadows::findSize(int width, int height) {
+ int idx = 0;
+ int min = 1000;
+
+ if (!_items.size())
+ return 0;
+
+ for (uint i = 0; i < _items.size(); i++) {
+ int w = abs(width - _items[i].width);
+ if (w < min) {
+ min = w;
+ idx = i;
+ }
+ }
+ return _items[idx].dynPhase;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
new file mode 100644
index 0000000000..82e082d8cb
--- /dev/null
+++ b/engines/fullpipe/gfx.h
@@ -0,0 +1,216 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_GFX_H
+#define FULLPIPE_GFX_H
+
+namespace Fullpipe {
+
+class DynamicPhase;
+class Movement;
+struct PicAniInfo;
+
+struct Bitmap {
+ int _x;
+ int _y;
+ int _width;
+ int _height;
+ byte *_pixels;
+ int _type;
+ int _dataSize;
+ int _flags;
+
+ Bitmap();
+ Bitmap(Bitmap *src);
+ ~Bitmap();
+
+ void load(Common::ReadStream *s);
+ void putDib(int x, int y, int32 *palette);
+ bool putDibRB(int32 *palette, int x = -1, int y = -1);
+ void putDibCB(int32 *palette);
+
+ void colorFill(uint16 *dest, int len, int32 color);
+ void paletteFill(uint16 *dest, byte *src, int len, int32 *palette);
+ void copierKeyColor(uint16 *dest, byte *src, int len, int keyColor, int32 *palette, bool cb05_format);
+ void copier(uint16 *dest, byte *src, int len, int32 *palette, bool cb05_format);
+
+ Bitmap *reverseImage();
+ Bitmap *reverseImageRB();
+ Bitmap *reverseImageCB();
+ Bitmap *reverseImageCB05();
+ Bitmap *flipVertical();
+
+ void drawShaded(int type, int x, int y, byte *palette);
+ void drawRotated(int x, int y, int angle, byte *palette);
+
+ bool isPixelHitAtPos(int x, int y);
+ bool isPixelAtHitPosRB(int x, int y);
+};
+
+class Picture : public MemoryObject {
+ public:
+ Common::Rect _rect;
+ Bitmap *_convertedBitmap;
+ int _x;
+ int _y;
+ int _field_44;
+ int _width;
+ int _height;
+ Bitmap *_bitmap;
+ int _field_54;
+ MemoryObject2 *_memoryObject2;
+ int _alpha;
+ byte *_paletteData;
+
+ void displayPicture();
+
+ public:
+ Picture();
+ virtual ~Picture();
+
+ void freePicture();
+
+ virtual bool load(MfcArchive &file);
+ void setAOIDs();
+ void init();
+ void getDibInfo();
+ Bitmap *getPixelData();
+ void draw(int x, int y, int style, int angle);
+ void drawRotated(int x, int y, int angle);
+
+ byte getAlpha() { return (byte)_alpha; }
+ void setAlpha(byte alpha) { _alpha = alpha; }
+
+ Common::Point *getDimensions(Common::Point *p);
+ bool isPointInside(int x, int y);
+ bool isPixelHitAtPos(int x, int y);
+ int getPixelAtPos(int x, int y);
+ int getPixelAtPosEx(int x, int y);
+
+ byte *getPaletteData() { return _paletteData; }
+ void setPaletteData(byte *pal);
+
+ void copyMemoryObject2(Picture *src);
+};
+
+class BigPicture : public Picture {
+ public:
+ BigPicture() {}
+ virtual bool load(MfcArchive &file);
+};
+
+class GameObject : public CObject {
+ public:
+ int16 _okeyCode;
+ int _field_8;
+ int16 _flags;
+ int16 _id;
+ char *_objectName;
+ int _ox;
+ int _oy;
+ int _priority;
+ int _field_20;
+
+ public:
+ GameObject();
+ GameObject(GameObject *src);
+ ~GameObject();
+
+ virtual bool load(MfcArchive &file);
+ void setOXY(int x, int y);
+ void renumPictures(CPtrList *lst);
+ void setFlags(int16 flags) { _flags = flags; }
+ void clearFlags() { _flags = 0; }
+ const char *getName() { return _objectName; }
+
+ bool getPicAniInfo(PicAniInfo *info);
+ bool setPicAniInfo(PicAniInfo *info);
+};
+
+class PictureObject : public GameObject {
+ public:
+ Picture *_picture;
+ CPtrList *_pictureObject2List;
+ int _ox2;
+ int _oy2;
+
+ public:
+ PictureObject();
+ PictureObject(PictureObject *src);
+
+ bool load(MfcArchive &file, bool bigPicture);
+ Common::Point *getDimensions(Common::Point *p);
+ void draw();
+ void drawAt(int x, int y);
+
+ bool setPicAniInfo(PicAniInfo *picAniInfo);
+ bool isPointInside(int x, int y);
+ bool isPixelHitAtPos(int x, int y);
+};
+
+class Background : public CObject {
+ public:
+ CPtrList _picObjList;
+
+ char *_bgname;
+ int _x;
+ int _y;
+ int16 _messageQueueId;
+ MemoryObject *_palette;
+ int _bigPictureArray1Count;
+ int _bigPictureArray2Count;
+ BigPicture ***_bigPictureArray;
+
+ public:
+ Background();
+ virtual bool load(MfcArchive &file);
+ void addPictureObject(PictureObject *pct);
+
+ BigPicture *getBigPicture(int x, int y) { return _bigPictureArray[x][y]; }
+};
+
+struct ShadowsItem {
+ int width;
+ int height;
+ DynamicPhase *dynPhase;
+};
+
+typedef Common::Array<ShadowsItem> ShadowsItemArray;
+
+class Shadows : public CObject {
+ int _sceneId;
+ int _staticAniObjectId;
+ int _movementId;
+ ShadowsItemArray _items;
+
+ public:
+ Shadows();
+ virtual bool load(MfcArchive &file);
+ void init();
+
+ void initMovement(Movement *mov);
+ DynamicPhase *findSize(int width, int height);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_GFX_H */
diff --git a/engines/fullpipe/init.cpp b/engines/fullpipe/init.cpp
new file mode 100644
index 0000000000..c334542247
--- /dev/null
+++ b/engines/fullpipe/init.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.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/input.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+void FullpipeEngine::initObjectStates() {
+ setLevelStates();
+
+ setObjectState(sO_Dude, getObjectEnumState(sO_Dude, sO_NotCarryingEgg));
+ setObjectState(sO_EggCracker, getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg));
+ setObjectState(sO_GuvTheDrawer, getObjectEnumState(sO_GuvTheDrawer, sO_Awaken));
+ setObjectState(sO_EggGulper, getObjectEnumState(sO_EggGulper, sO_First));
+ setObjectState(sO_EggGulperGaveCoin, getObjectEnumState(sO_EggGulperGaveCoin, sO_No));
+ setObjectState(sO_Jar_4, getObjectEnumState(sO_Jar_4, sO_OnTheSpring));
+ setObjectState(sO_GulpedEggs, getObjectEnumState(sO_GulpedEgg, sO_NotPresent));
+
+ setSwallowedEggsState();
+
+ setObjectState(sO_WeirdWacko, getObjectEnumState(sO_WeirdWacko, sO_InGlasses));
+ setObjectState(sO_TumyTrampie, getObjectEnumState(sO_TumyTrampie, sO_Drinking));
+ setObjectState(sO_StairsUp_8, getObjectEnumState(sO_StairsUp_8, sO_NotBroken));
+ setObjectState(sO_HareTheNooksiter, getObjectEnumState(sO_HareTheNooksiter, sO_WithHandle));
+ setObjectState(sO_Elephantine, getObjectEnumState(sO_Elephantine, sO_WithBoot));
+ setObjectState(sO_Fly_12, 0);
+ setObjectState(sO_ClockAxis, getObjectEnumState(sO_ClockAxis, sO_NotAvailable));
+ setObjectState(sO_ClockHandle, getObjectEnumState(sO_ClockHandle, sO_In_7));
+ setObjectState(sO_BigMumsy, getObjectEnumState(sO_BigMumsy, sO_Sleeping));
+ setObjectState(sO_CoinSlot_1, getObjectEnumState(sO_CoinSlot_1, sO_Empty));
+ setObjectState(sO_FriesPit, getObjectEnumState(sO_FriesPit, sO_WithApple));
+ setObjectState(sO_Jug, getObjectEnumState(sO_Jug, sO_Blocked));
+ setObjectState(sO_RightStairs_9, getObjectEnumState(sO_RightStairs_9, sO_ClosedShe));
+ setObjectState(sO_Pipe_9, getObjectEnumState(sO_Pipe_9, sO_WithJug));
+ setObjectState(sO_Inflater, getObjectEnumState(sO_Inflater, sO_WithGum));
+ setObjectState(sO_Swingie, getObjectEnumState(sO_Swingie, sO_Swinging));
+ setObjectState(sO_DudeJumped, getObjectEnumState(sO_DudeJumped, sO_No));
+ setObjectState(sO_Bridge, getObjectEnumState(sO_Bridge, sO_Convoluted));
+ setObjectState(sO_Guardian, getObjectEnumState(sO_Guardian, sO_OnRight));
+ setObjectState(sO_Grandma, getObjectEnumState(sO_Grandma, sO_In_14));
+ setObjectState(sO_Boot_15, getObjectEnumState(sO_Boot_15, sO_NotPresent));
+ setObjectState(sO_LeftPipe_15, getObjectEnumState(sO_LeftPipe_15, sO_OpenedShe));
+ setObjectState(sO_Pedestal_16, getObjectEnumState(sO_Pedestal_16, sO_IsFree));
+ setObjectState(sO_Cup, getObjectEnumState(sO_Cup, sO_InSmokeRoom));
+ setObjectState(sO_Pedestal_17, getObjectEnumState(sO_Pedestal_17, sO_IsFree));
+ setObjectState(sO_UsherHand, getObjectEnumState(sO_UsherHand, sO_WithoutCoin));
+ setObjectState(sO_RightPipe_17, getObjectEnumState(sO_RightPipe_17, sO_ClosedShe));
+ setObjectState(sO_Fly_17, 1);
+ setObjectState(sO_DudeSwinged, 0);
+ setObjectState(sO_Girl, getObjectEnumState(sO_Girl, sO_Swinging));
+ setObjectState(sO_Sugar, getObjectEnumState(sO_Sugar, sO_Present));
+ setObjectState(sO_Janitors, getObjectEnumState(sO_Janitors, sO_Together));
+ setObjectState(sO_Bag_22, getObjectEnumState(sO_Bag_22, sO_NotFallen));
+ setObjectState(sO_Grandpa, getObjectEnumState(sO_Grandpa, sO_InSock));
+ setObjectState(sO_CoinSlot_22, getObjectEnumState(sO_CoinSlot_22, sO_Empty));
+ setObjectState(sO_UpperHatch_23, getObjectEnumState(sO_UpperHatch_23, sO_Closed));
+ setObjectState(sO_LowerHatch_23, getObjectEnumState(sO_LowerHatch_23, sO_Closed));
+ setObjectState(sO_Lever_23, getObjectEnumState(sO_Lever_23, sO_NotTaken));
+ setObjectState(sO_LeverHandle_23, getObjectEnumState(sO_LeverHandle_23, sO_WithoutStool));
+ setObjectState(sO_LowerPipe_21, getObjectEnumState(sO_LowerPipe_21, sO_ClosedShe));
+ setObjectState(sO_StarsDown_24, getObjectEnumState(sO_StarsDown_24, sO_OpenedShe));
+ setObjectState(sO_Hatch_26, getObjectEnumState(sO_Hatch_26, sO_Closed));
+ setObjectState(sO_Sock_26, getObjectEnumState(sO_Sock_26, sO_NotHanging));
+ setObjectState(sO_LeftPipe_26, getObjectEnumState(sO_LeftPipe_26, sO_ClosedShe));
+ setObjectState(sO_Valve1_26, getObjectEnumState(sO_Valve1_26, sO_Opened));
+ setObjectState(sO_Valve2_26, getObjectEnumState(sO_Valve2_26, sO_Closed));
+ setObjectState(sO_Valve3_26, getObjectEnumState(sO_Valve3_26, sO_Closed));
+ setObjectState(sO_Valve4_26, getObjectEnumState(sO_Valve4_26, sO_Closed));
+ setObjectState(sO_Valve5_26, getObjectEnumState(sO_Valve5_26, sO_Opened));
+ setObjectState(sO_Pool, getObjectEnumState(sO_Pool, sO_Overfull));
+ setObjectState(sO_Plank_25, getObjectEnumState(sO_Plank_25, sO_NearDudesStairs));
+ setObjectState(sO_Driver, getObjectEnumState(sO_Driver, sO_WithSteering));
+ setObjectState(sO_Janitress, getObjectEnumState(sO_Janitress, sO_WithMop));
+ setObjectState(sO_LeftPipe_29, getObjectEnumState(sO_LeftPipe_29, sO_ClosedShe));
+ setObjectState(sO_LeftPipe_30, getObjectEnumState(sO_LeftPipe_30, sO_ClosedShe));
+ setObjectState(sO_Leg, getObjectEnumState(sO_Leg, sO_ShowingHeel));
+ setObjectState(sO_Tub, getObjectEnumState(sO_Tub, sO_EmptyShe));
+ setObjectState(sO_Cactus, getObjectEnumState(sO_Cactus, sO_NotGrown));
+ setObjectState(sO_Fireman, getObjectEnumState(sO_Fireman, sO_WithHose));
+ setObjectState(sO_Cube, getObjectEnumState(sO_Cube, sO_In_33));
+ setObjectState(sO_MommyOfHandle_32, getObjectEnumState(sO_MommyOfHandle_32, sO_WithoutHandle));
+ setObjectState(sO_Pedestal_33, getObjectEnumState(sO_Pedestal_33, sO_IsFree));
+ setObjectState(sO_Valve_34, getObjectEnumState(sO_Valve_34, sO_WithNothing));
+ setObjectState(sO_Stool_34, getObjectEnumState(sO_Stool_34, sO_WithoutDrawer));
+ setObjectState(sO_Plank_34, getObjectEnumState(sO_Plank_34, sO_Passive));
+ setObjectState(sO_Hatch_34, getObjectEnumState(sO_Hatch_34, sO_Closed));
+ setObjectState(sO_Valve_35, getObjectEnumState(sO_Valve_35, sO_TurnedOff));
+ setObjectState(sO_Carpet_35, getObjectEnumState(sO_Carpet_35, sO_CannotTake));
+ setObjectState(sO_CoinSlot_35, getObjectEnumState(sO_CoinSlot_35, sO_WithCoin));
+ setObjectState(sO_BellyInflater, getObjectEnumState(sO_BellyInflater, sO_WithCork));
+ setObjectState(sO_Jawcrucnher, getObjectEnumState(sO_Jawcrucnher, sO_WithoutCarpet));
+ setObjectState(sO_Guard_1, getObjectEnumState(sO_Guard_1, sO_On));
+ setObjectState(sO_Gurad_2, getObjectEnumState(sO_Gurad_2, sO_On));
+ setObjectState(sO_Guard_3, getObjectEnumState(sO_Guard_3, sO_On));
+ setObjectState(sO_Bottle_38, getObjectEnumState(sO_Bottle_38, sO_OnTheTable));
+ setObjectState(sO_Boss, getObjectEnumState(sO_Boss, sO_WithHammer));
+}
+
+void FullpipeEngine::setLevelStates() {
+ CGameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
+
+ if (v) {
+ v->setSubVarAsInt(sO_Level0, 2833);
+ v->setSubVarAsInt(sO_Level1, 2754);
+ v->setSubVarAsInt(sO_Level2, 2757);
+ v->setSubVarAsInt(sO_Level3, 2760);
+ v->setSubVarAsInt(sO_Level4, 2763);
+ v->setSubVarAsInt(sO_Level5, 2766);
+ v->setSubVarAsInt(sO_Level6, 2769);
+ v->setSubVarAsInt(sO_Level7, 2772);
+ v->setSubVarAsInt(sO_Level8, 2775);
+ v->setSubVarAsInt(sO_Level9, 2778);
+ }
+}
+
+void FullpipeEngine::addCursor(CursorInfo *cursorInfo, Scene *inv, int pictureId, int hotspotX, int hotspotY, int itemPictureOffsX, int itemPictureOffsY) {
+ cursorInfo->pictureId = pictureId;
+ cursorInfo->picture = inv->getPictureObjectById(pictureId, 0)->_picture;
+ cursorInfo->hotspotX = hotspotX;
+ cursorInfo->hotspotY = hotspotY;
+ cursorInfo->itemPictureOffsX = itemPictureOffsX;
+ cursorInfo->itemPictureOffsY = itemPictureOffsY;
+
+ getGameLoaderInputController()->addCursor(cursorInfo);
+}
+
+void FullpipeEngine::initCursors() {
+ CursorInfo crs;
+ Scene *inv = accessScene(SC_INV);
+
+ addCursor(&crs, inv, PIC_CSR_DEFAULT, 15, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_DEFAULT_INV, 18, 18, 23, 23);
+ addCursor(&crs, inv, PIC_CSR_ITN, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ITN_RED, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ITN_GREEN, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ITN_INV, 23, 17, 23, 17);
+ addCursor(&crs, inv, PIC_CSR_GOU, 15, 17, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOD, 15, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOL, 26, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOR, 15, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOFAR_L, 1, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_GOFAR_R, 39, 1, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE1, 12, 24, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE2, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE2_D, 22, 15, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE3, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE4, 18, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE5, 23, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE6, 11, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE6_D, 0, 0, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE7, 21, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE7_D, 7, 20, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_ARCADE8, 23, 11, 10, 10);
+ addCursor(&crs, inv, PIC_CSR_LIFT, 6, 13, 10, 10);
+
+ getGameLoaderInputController()->setCursorMode(0);
+}
+
+void FullpipeEngine::initMap() {
+ memset(_mapTable, 0, sizeof(_mapTable));
+
+ updateMapPiece(PIC_MAP_S01, 1);
+ updateMapPiece(PIC_MAP_A13, 1u);
+}
+
+void FullpipeEngine::loadAllScenes() {
+ accessScene(301);
+ accessScene(302);
+ accessScene(303);
+ accessScene(304);
+ accessScene(305);
+ accessScene(321);
+ accessScene(635);
+ accessScene(649);
+ accessScene(650);
+ accessScene(651);
+ accessScene(652);
+ accessScene(653);
+ accessScene(654);
+ accessScene(655);
+ accessScene(726);
+ accessScene(858);
+ accessScene(903);
+ accessScene(1137);
+ accessScene(1138);
+ accessScene(1139);
+ accessScene(1140);
+ accessScene(1141);
+ accessScene(1142);
+ accessScene(1143);
+ accessScene(1144);
+ accessScene(1546);
+ accessScene(1547);
+ accessScene(1548);
+ accessScene(1549);
+ accessScene(1550);
+ accessScene(1551);
+ accessScene(1552);
+ accessScene(2062);
+ accessScene(2063);
+ accessScene(2064);
+ accessScene(2065);
+ accessScene(2066);
+ accessScene(2067);
+ accessScene(2068);
+ accessScene(2069);
+ accessScene(2070);
+ accessScene(2071);
+ accessScene(2072);
+ accessScene(2460);
+ accessScene(3896);
+ accessScene(3907);
+ accessScene(4620);
+ accessScene(4999);
+ accessScene(5000);
+ accessScene(5001);
+ accessScene(5166);
+ accessScene(5222);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
new file mode 100644
index 0000000000..8cc7654f52
--- /dev/null
+++ b/engines/fullpipe/input.cpp
@@ -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.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/input.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+CInputController::CInputController() {
+ g_fullpipe->_inputController = this;
+
+ _flag = 0;
+ _cursorHandle = 0;
+ _hCursor = 0;
+ _field_14 = 0;
+ _cursorId = 0;
+ _cursorIndex = -1;
+ _inputFlags = 1;
+
+ _cursorBounds.left = 0;
+ _cursorBounds.top = 0;
+ _cursorBounds.right = 0;
+ _cursorBounds.bottom = 0;
+
+ _cursorItemPicture = 0;
+}
+
+CInputController::~CInputController() {
+ removeMessageHandler(126, -1);
+
+ g_fullpipe->_inputController = 0;
+}
+
+void CInputController::setInputDisabled(bool state) {
+ _flag = state;
+ g_fullpipe->_inputDisabled = state;
+}
+
+void setInputDisabled(bool state) {
+ g_fullpipe->_inputController->setInputDisabled(state);
+}
+
+void CInputController::addCursor(CursorInfo *cursor) {
+ CursorInfo *newc = new CursorInfo(cursor);
+ Common::Point p;
+
+ cursor->picture->getDimensions(&p);
+
+ newc->width = p.x;
+ newc->height = p.y;
+
+ newc->picture->_x = -1;
+ newc->picture->_y = -1;
+
+ _cursorsArray.push_back(newc);
+}
+
+void CInputController::setCursorMode(bool enabled) {
+ if (enabled)
+ _inputFlags |= 1;
+ else
+ _inputFlags &= ~1;
+}
+
+void CInputController::drawCursor(int x, int y) {
+ if (_cursorIndex == -1)
+ return;
+
+ _cursorBounds.left = g_fullpipe->_sceneRect.left + x - _cursorsArray[_cursorIndex]->hotspotX;
+ _cursorBounds.top = g_fullpipe->_sceneRect.top + y - _cursorsArray[_cursorIndex]->hotspotY;
+ _cursorBounds.right = _cursorBounds.left + _cursorsArray[_cursorIndex]->width;
+ _cursorBounds.bottom = _cursorBounds.top + _cursorsArray[_cursorIndex]->height;
+
+ _cursorsArray[_cursorIndex]->picture->draw(_cursorBounds.left, _cursorBounds.top, 0, 0);
+
+ if (_cursorItemPicture)
+ _cursorItemPicture->draw(_cursorBounds.left + _cursorsArray[_cursorIndex]->itemPictureOffsX,
+ _cursorBounds.top + _cursorsArray[_cursorIndex]->itemPictureOffsY, 0, 0);
+}
+
+void CInputController::setCursor(int cursorId) {
+ if (_cursorIndex == -1 || _cursorsArray[_cursorIndex]->pictureId != cursorId) {
+ _cursorIndex = -1;
+
+ for (uint i = 0; i < _cursorsArray.size(); i++) {
+ if (_cursorsArray[i]->pictureId == cursorId) {
+ _cursorIndex = i;
+ break;
+ }
+ }
+ }
+}
+
+CursorInfo::CursorInfo() {
+ pictureId = 0;
+ picture = 0;
+ hotspotX = 0;
+ hotspotY = 0;
+ itemPictureOffsX = 0;
+ itemPictureOffsY = 0;
+ width = 0;
+ height = 0;
+}
+
+CursorInfo::CursorInfo(CursorInfo *src) {
+ pictureId = src->pictureId;
+ picture = src->picture;
+ hotspotX = src->hotspotX;
+ hotspotY = src->hotspotY;
+ itemPictureOffsX = src->itemPictureOffsX;
+ itemPictureOffsY = src->itemPictureOffsY;
+ width = src->width;
+ height = src->height;
+}
+
+void FullpipeEngine::setCursor(int id) {
+ if (_inputController)
+ _inputController->setCursor(id);
+}
+
+void FullpipeEngine::defHandleKeyDown(int key) {
+ warning("STUB: FullpipeEngine::defHandleKeyDown(%d)", key);
+}
+
+void FullpipeEngine::updateCursorsCommon() {
+ GameObject *ani = _currentScene->getStaticANIObjectAtPos(_mouseVirtX, _mouseVirtY);
+
+ GameObject *pic = _currentScene->getPictureObjectAtPos(_mouseVirtX, _mouseVirtY);
+ if (!ani || (pic && pic->_priority < ani->_priority))
+ ani = pic;
+
+ int selId = getGameLoaderInventory()->getSelectedItemId();
+
+ _objectAtCursor = ani;
+
+ if (ani) {
+ _objectIdAtCursor = ani->_id;
+
+ if (!selId && ani->_id >= _minCursorId && ani->_id <= _maxCursorId) {
+ selId = _objectIdCursors[ani->_id - _minCursorId];
+ if (selId) {
+ _cursorId = selId;
+ return;
+ }
+ }
+ if (canInteractAny(_aniMan, ani, selId)) {
+ _cursorId = selId > 0 ? PIC_CSR_ITN_INV : PIC_CSR_ITN;
+ return;
+ }
+ if (selId) {
+ _cursorId = PIC_CSR_DEFAULT_INV;
+ return;
+ }
+ if (_objectIdAtCursor == ANI_LIFTBUTTON && lift_getButtonIdP(((StaticANIObject *)ani)->_statics->_staticsId)) {
+ _cursorId = PIC_CSR_LIFT;
+ return;
+ }
+ if (_sceneRect.right - _mouseVirtX < 47 && _sceneRect.right < _sceneWidth - 1) {
+ _cursorId = PIC_CSR_GOFAR_R;
+ return;
+ }
+ if (_mouseVirtX - _sceneRect.left < 47 && _sceneRect.left > 0) {
+ _cursorId = PIC_CSR_GOFAR_L;
+ return;
+ }
+ _cursorId = PIC_CSR_DEFAULT;
+ return;
+ } else {
+ _objectIdAtCursor = 0;
+
+ if (selId) {
+ _cursorId = PIC_CSR_DEFAULT_INV;
+ return;
+ }
+ if (_sceneRect.right - _mouseVirtX < 47 && _sceneRect.right < _sceneWidth - 1) {
+ _cursorId = PIC_CSR_GOFAR_R;
+ return;
+ }
+ if (_mouseVirtX - _sceneRect.left < 47 && _sceneRect.left > 0) {
+ _cursorId = PIC_CSR_GOFAR_L;
+ return;
+ }
+ }
+
+ _cursorId = PIC_CSR_DEFAULT;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/input.h b/engines/fullpipe/input.h
new file mode 100644
index 0000000000..4b32e510e3
--- /dev/null
+++ b/engines/fullpipe/input.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_INPUT_H
+#define FULLPIPE_INPUT_H
+
+namespace Fullpipe {
+
+class Picture;
+
+void setInputDisabled(bool state);
+
+struct CursorInfo {
+ int pictureId;
+ Picture *picture;
+ int hotspotX;
+ int hotspotY;
+ int itemPictureOffsX;
+ int itemPictureOffsY;
+ int width;
+ int height;
+
+ CursorInfo();
+ CursorInfo(CursorInfo *src);
+};
+
+typedef Common::Array<CursorInfo *> CursorsArray;
+
+class CInputController {
+ //CObject obj;
+ int _flag;
+ int _inputFlags;
+ int _cursorHandle;
+ int _hCursor;
+ int _field_14;
+ int _cursorId;
+ int _cursorIndex;
+ CursorsArray _cursorsArray;
+ Common::Rect _cursorBounds;
+ Picture *_cursorItemPicture;
+
+ public:
+ CInputController();
+ ~CInputController();
+
+ void setInputDisabled(bool state);
+ void addCursor(CursorInfo *cursor);
+ void setCursorMode(bool mode);
+
+ void drawCursor(int x, int y);
+ void setCursor(int id);
+
+ void setCursorItemPicture(Picture *pic) { _cursorItemPicture = pic; }
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_INPUT_H */
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
new file mode 100644
index 0000000000..dcc7e90145
--- /dev/null
+++ b/engines/fullpipe/interaction.cpp
@@ -0,0 +1,517 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/motion.h"
+
+namespace Fullpipe {
+
+int handleObjectInteraction(StaticANIObject *subject, GameObject *object, int invId) {
+ return getGameLoaderInteractionController()->handleInteraction(subject, object, invId);
+}
+
+bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) {
+ int sceneId = 0;
+
+ if (g_fullpipe->_currentScene)
+ sceneId = g_fullpipe->_currentScene->_sceneId;
+
+ CInteractionController *intC = getGameLoaderInteractionController();
+ for (CObList::iterator i = intC->_interactions.begin(); i != intC->_interactions.end(); ++i) {
+ CInteraction *intr = (CInteraction *)*i;
+
+ if (intr->_sceneId > 0 && intr->_sceneId != sceneId)
+ break;
+
+ if (invId == -3) {
+ invId = getGameLoaderInventory()->getSelectedItemId();
+ }
+ if (intr->canInteract(obj1, obj2, invId))
+ return true;
+ }
+ return false;
+}
+
+bool CInteractionController::load(MfcArchive &file) {
+ debug(5, "CInteractionController::load()");
+
+ return _interactions.load(file);
+}
+
+int static_compSceneId = 0;
+
+bool CInteractionController::compareInteractions(const void *p1, const void *p2) {
+ const CInteraction *i1 = (const CInteraction *)p1;
+ const CInteraction *i2 = (const CInteraction *)p2;
+
+ if (i2->_sceneId < i1->_sceneId) {
+ if (i1->_sceneId != static_compSceneId)
+ return false;
+ }
+ if (i2->_sceneId != i1->_sceneId) {
+ if (i1->_sceneId > 0 && i2->_sceneId == static_compSceneId)
+ return false;
+ if (i2->_sceneId != i1->_sceneId)
+ return true;
+ }
+ if (i2->_objectId3 == -1)
+ return true;
+
+ if (i1->_objectId3 == i2->_objectId3)
+ return true;
+
+ if (i1->_objectId3 == -1 || i1->_objectId3 == -2)
+ return false;
+
+ return true;
+}
+
+void CInteractionController::sortInteractions(int sceneId) {
+ static_compSceneId = sceneId;
+
+ Common::sort(_interactions.begin(), _interactions.end(), CInteractionController::compareInteractions);
+}
+
+bool CInteractionController::handleInteraction(StaticANIObject *subj, GameObject *obj, int invId) {
+ if (subj) {
+ if (!subj->isIdle() || (subj->_flags & 0x100))
+ return false;
+ }
+
+ if (!_interactions.size())
+ return false;
+
+ CInteraction *inter = 0;
+ CInteraction *previnter = 0;
+ int dur = 0;
+ int mindur = 0xFFFF;
+
+ MessageQueue *mq;
+ ExCommand *ex;
+
+ for (CObList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
+ CInteraction *cinter = (CInteraction *)*i;
+
+ if (!cinter->canInteract(subj, obj, invId))
+ continue;
+
+ if ((inter || cinter->_objectId2) && (!obj || cinter->_objectId3 != obj->_id)) {
+ if (cinter->_messageQueue)
+ cinter->_messageQueue->calcDuration(subj);
+
+ PicAniInfo aniInfo;
+
+ obj->getPicAniInfo(&aniInfo);
+
+ if (cinter->_staticsId1) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+ ani->_messageQueueId = 0;
+ ani->changeStatics2(cinter->_staticsId1);
+ }
+ int xpos = cinter->_xOffs + obj->_ox;
+ int ypos = cinter->_yOffs + obj->_oy;
+
+ obj->setPicAniInfo(&aniInfo);
+
+ if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1) {
+ mq = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->method4C(subj, xpos, ypos, 1, cinter->_staticsId2);
+ if (mq) {
+ dur = mq->calcDuration(subj);
+ delete mq;
+ } else {
+ dur = 0x10000;
+ }
+ inter = previnter;
+ } else {
+ dur = 0;
+ }
+ if (dur < mindur) {
+ inter = cinter;
+ mindur = dur;
+ previnter = cinter;
+ }
+ } else {
+ inter = cinter;
+ break;
+ }
+ }
+
+ if (!inter)
+ return false;
+
+ if (!inter->_objectId2) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ if (!ani->isIdle())
+ return false;
+
+ if (ani->_flags & 0x100)
+ return false;
+
+ if (!inter->_staticsId1 || !(inter->_flags & 1))
+ goto LABEL_38;
+
+ if (ani->_movement || ani->_statics == 0 || ani->_statics->_staticsId != inter->_staticsId1) {
+ mq = ani->changeStatics1(inter->_staticsId1);
+ if (!mq)
+ return false;
+
+ ex = new ExCommand((subj ? subj->_id : 0), 55, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = obj->_id;
+ ex->_y = obj->_okeyCode;
+ ex->_keyCode = subj ? subj->_okeyCode : 0;
+ ex->_excFlags = 3;
+ ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
+ ex->_field_20 = invId;
+ mq->_exCommands.push_back(ex);
+
+ if (mq->_isFinished) {
+ mq->_isFinished = 0;
+ ani->queueMessageQueue(mq);
+ }
+ } else {
+ if (ani->getMessageQueue())
+ ani->queueMessageQueue(0);
+LABEL_38:
+ if (inter->_messageQueue) {
+ mq = new MessageQueue(inter->_messageQueue, 0, 1);
+ mq->changeParam28ForObjectId(ani->_id, -1, ani->_okeyCode);
+
+ if (!mq->chain(0))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (obj && !subj)
+ return true;
+
+ if (!obj || inter->_objectId3 == obj->_id) {
+ if (subj) {
+ if (inter->_messageQueue) {
+ if (subj->isIdle()) {
+ mq = new MessageQueue(inter->_messageQueue, 0, 1);
+
+ if (!mq->chain(subj)) {
+ delete mq;
+
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ if (inter->isOverlapping(subj, obj)) {
+ if (obj->_objtype == kObjTypeStaticANIObject) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ ani->queueMessageQueue(0);
+
+ if (inter->_staticsId1)
+ ani->changeStatics2(inter->_staticsId1);
+
+ if (!(inter->_flags & 0x10000))
+ obj->_flags |= 0x80;
+ }
+
+ if (!inter->_messageQueue)
+ return false;
+
+ subj->setOXY(inter->_xOffs + obj->_ox, inter->_yOffs + obj->_oy);
+
+ mq = new MessageQueue(inter->_messageQueue, 0, 1);
+ mq->changeParam28ForObjectId(obj->_id, -1, obj->_okeyCode);
+ mq->_flags |= 1;
+
+ if (!(inter->_flags & 0x10000)) {
+ ex = new ExCommand(obj->_id, 34, 0x80, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = obj->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_messageNum = 0;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+ }
+
+ ex = new ExCommand(obj->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = obj->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_messageNum = 0;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+
+ ex = new ExCommand(subj->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = subj->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_messageNum = 0;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+
+ ex = new ExCommand(subj->_id, 17, 0x40, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = 0;
+ mq->_exCommands.push_back(ex);
+
+ if (!mq->chain(subj)) {
+ delete mq;
+
+ return false;
+ }
+
+ subj->_flags |= 1;
+ obj->_flags |= 1;
+ } else {
+ bool someFlag = false;
+ PicAniInfo aniInfo;
+
+ obj->getPicAniInfo(&aniInfo);
+
+ if (obj->_objtype == kObjTypeStaticANIObject && inter->_staticsId1) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ ani->_messageQueueId = 0;
+ ani->changeStatics2(inter->_staticsId1);
+ }
+
+ int xpos = inter->_yOffs + obj->_ox;
+ int ypos = inter->_yOffs + obj->_oy;
+
+ obj->setPicAniInfo(&aniInfo);
+
+ if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1
+ || (inter->_staticsId2 != 0 && (subj->_statics == 0 || subj->_statics->_staticsId != inter->_staticsId2))) {
+ mq = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->method34(subj, xpos, ypos, 1, inter->_staticsId2);
+
+ if (!mq)
+ return false;
+
+ ex = new ExCommand(subj->_id, 55, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = obj->_id;
+ ex->_y = obj->_okeyCode;
+ ex->_keyCode = subj->_okeyCode;
+ ex->_excFlags = 3;
+ ex->_field_20 = invId;
+ ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
+ mq->_exCommands.push_back(ex);
+
+ someFlag = true;
+
+ ex = new ExCommand(subj->_id, 17, 0x40, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = xpos;
+ ex->_y = ypos;
+ ex->_excFlags |= 3;
+ ex->_keyCode = 6;
+ ex->_field_14 = obj->_id;
+ ex->_field_20 = obj->_okeyCode;
+ ex->postMessage();
+ }
+
+ if (!inter->_staticsId1 || !(inter->_flags & 1))
+ return true;
+
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ if (!ani->isIdle())
+ return false;
+
+ if (ani->getMessageQueue())
+ ani->queueMessageQueue(0);
+
+ if (!ani->_statics || ani->_statics->_staticsId != inter->_staticsId1 || ani->_movement) {
+ mq = ani->changeStatics1(inter->_staticsId1);
+
+ if (!mq)
+ return false;
+
+ if (someFlag) {
+ if (!(inter->_flags & 0x10000)) {
+ if (mq->_isFinished) {
+ ani->_flags |= 0x80u;
+ } else {
+ ex = new ExCommand(ani->_id, 34, 0x80, 0, 0, 0, 1, 0, 0, 0);
+ ex->_field_14 = 0x80;
+ ex->_keyCode = ani->_okeyCode;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+ }
+ }
+ ex = new ExCommand(ani->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = ani->_okeyCode;
+ ex->_field_14 = 0x100;
+ ex->_excFlags = 3;
+ mq->_exCommands.push_back(ex);
+ } else {
+ ex = new ExCommand(subj->_id, 55, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_x = ani->_id;
+ ex->_y = ani->_okeyCode;
+ ex->_keyCode = subj->_okeyCode;
+ ex->_excFlags = 2;
+ ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
+ ex->_field_20 = invId;
+ mq->_exCommands.push_back(ex);
+
+ if (!mq->_isFinished)
+ return true;
+
+ mq->_isFinished = 0;
+ ani->queueMessageQueue(mq);
+ }
+ } else {
+ obj->_flags |= 1;
+
+ if (inter->_flags & 0x10000)
+ return true;
+
+ obj->_flags |= 0x80;
+ }
+ }
+
+ return true;
+}
+
+CInteraction::CInteraction() {
+ _objectId1 = 0;
+ _objectId2 = 0;
+ _staticsId1 = 0;
+ _objectId3 = 0;
+ _objectState2 = 0;
+ _objectState1 = 0;
+ _messageQueue = 0;
+ _flags = 0;
+ _yOffs = 0;
+ _xOffs = 0;
+ _staticsId2 = 0;
+ _field_28 = 0;
+ _sceneId = -1;
+ _actionName = 0;
+}
+
+bool CInteraction::load(MfcArchive &file) {
+ debug(5, "CInteraction::load()");
+
+ _objectId1 = file.readUint16LE();
+ _objectId2 = file.readUint16LE();
+ _staticsId1 = file.readUint16LE();
+ _staticsId2 = file.readUint16LE();
+ _objectId3 = file.readUint16LE();
+ _objectState2 = file.readUint32LE();
+ _objectState1 = file.readUint32LE();
+ _xOffs = file.readUint32LE();
+ _yOffs = file.readUint32LE();
+ _sceneId = file.readUint32LE();
+ _flags = file.readUint32LE();
+ _actionName = file.readPascalString();
+
+ _messageQueue = (MessageQueue *)file.readClass();
+
+ return true;
+}
+
+bool CInteraction::canInteract(GameObject *obj1, GameObject *obj2, int invId) {
+ if (_sceneId > 0 && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_sceneId != _sceneId)
+ return false;
+
+ if (_flags & 0x20000)
+ return false;
+
+ if (!obj2)
+ return false;
+
+ if (obj2->_id != _objectId1)
+ return false;
+
+ if ((_flags & 8) && (_flags & 1)) {
+ if (obj2->_objtype != kObjTypeStaticANIObject)
+ return false;
+
+ StaticANIObject *st = (StaticANIObject *)obj2;
+
+ if (!st->_statics)
+ return false;
+
+ if (st->_statics->_staticsId != _staticsId1) {
+ if (_staticsId1)
+ return false;
+ }
+ }
+
+ if ((_objectId3 != invId && _objectId3 != -1 && _objectId3 != -2) || (!invId && _objectId3 == -2))
+ return false;
+
+ if (_objectState1) {
+ if (_flags & 0x10) {
+ if ((g_fullpipe->getObjectState(obj1->getName()) & _objectState1) == 0)
+ return false;
+ } else {
+ if (g_fullpipe->getObjectState(obj1->getName()) != _objectState1)
+ return false;
+ }
+ }
+
+ if (_objectState2) {
+ if (_flags & 0x10) {
+ if ((g_fullpipe->getObjectState(obj2->getName()) & _objectState2) == 0)
+ return false;
+ } else {
+ if (g_fullpipe->getObjectState(obj2->getName()) != _objectState2)
+ return false;
+ }
+ }
+
+ if (_objectId2 && (!obj1 || _objectId2 != obj1->_id))
+ return false;
+
+ return true;
+}
+
+bool CInteraction::isOverlapping(StaticANIObject *subj, GameObject *obj) {
+ StaticANIObject *ani = (StaticANIObject *)obj;
+
+ if (abs(_xOffs + obj->_ox - subj->_ox) <= 1
+ && abs(obj->_oy + _yOffs - subj->_oy) <= 1) {
+ if (!_staticsId2 || (subj->_statics != 0 && subj->_statics->_staticsId == _staticsId2)) {
+ if (!_staticsId1 || !(_flags & 1) || (ani->_statics != 0 && ani->_statics->_staticsId == _staticsId1))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool EntranceInfo::load(MfcArchive &file) {
+ debug(5, "EntranceInfo::load()");
+
+ _sceneId = file.readUint32LE();
+ _field_4 = file.readUint32LE();
+ _messageQueueId = file.readUint32LE();
+ file.read(_gap_C, 292); // FIXME, Ugh
+ _field_130 = file.readUint32LE();
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/interaction.h b/engines/fullpipe/interaction.h
new file mode 100644
index 0000000000..28a03fb496
--- /dev/null
+++ b/engines/fullpipe/interaction.h
@@ -0,0 +1,96 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_INTERACTION_H
+#define FULLPIPE_INTERACTION_H
+
+#include "fullpipe/utils.h"
+
+namespace Fullpipe {
+
+class GameObject;
+class MessageQueue;
+class StaticANIObject;
+
+int handleObjectInteraction(StaticANIObject *subject, GameObject *object, int invId);
+bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId);
+
+
+class CInteraction : public CObject {
+ public:
+ int16 _objectId1;
+ int16 _objectId2;
+ int16 _objectId3;
+ int16 _staticsId1;
+ int16 _staticsId2;
+ int _objectState1;
+ int _objectState2;
+ int _xOffs;
+ int _yOffs;
+ MessageQueue *_messageQueue;
+ int _sceneId;
+ int _field_28;
+ int _flags;
+ char *_actionName;
+
+ public:
+ CInteraction();
+ virtual bool load(MfcArchive &file);
+ bool canInteract(GameObject *obj1, GameObject *obj2, int invId);
+ bool isOverlapping(StaticANIObject *subj, GameObject *obj);
+};
+
+class CInteractionController : public CObject {
+ public:
+ CObList _interactions;
+ int16 _field_20;
+ bool _flag24;
+
+ private:
+ static bool compareInteractions(const void *p1, const void *p2);
+
+ public:
+ CInteractionController() : _field_20(0), _flag24(true) {}
+
+ virtual bool load(MfcArchive &file);
+
+ void enableFlag24() { _flag24 = true; }
+ void disableFlag24() { _flag24 = false; }
+
+ void sortInteractions(int sceneId);
+
+ bool handleInteraction(StaticANIObject *subj, GameObject *obj, int invId);
+};
+
+struct EntranceInfo {
+ int32 _sceneId;
+ int32 _field_4;
+ int32 _messageQueueId;
+ byte _gap_C[292]; // FIXME
+ int32 _field_130;
+
+ bool load(MfcArchive &file);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_INTERACTION_H */
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
new file mode 100644
index 0000000000..1e229f3408
--- /dev/null
+++ b/engines/fullpipe/inventory.cpp
@@ -0,0 +1,420 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/utils.h"
+#include "fullpipe/inventory.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/input.h"
+
+namespace Fullpipe {
+
+bool CInventory::load(MfcArchive &file) {
+ debug(5, "CInventory::load()");
+
+ _sceneId = file.readUint16LE();
+ int numInvs = file.readUint32LE();
+
+ for (int i = 0; i < numInvs; i++) {
+ InventoryPoolItem *t = new InventoryPoolItem();
+ t->id = file.readUint16LE();
+ t->pictureObjectNormal = file.readUint16LE();
+ t->pictureObjectId1 = file.readUint16LE();
+ t->pictureObjectHover = file.readUint16LE();
+ t->pictureObjectSelected = file.readUint16LE();
+ t->flags = file.readUint32LE();
+ t->field_C = 0;
+ t->field_A = -536;
+ _itemsPool.push_back(t);
+ }
+
+ return true;
+}
+
+int CInventory::getInventoryPoolItemIndexById(int itemId) {
+ if (_itemsPool.size() <= 0)
+ return -1;
+
+ for (uint i = 0; i < _itemsPool.size(); i++) {
+ if (_itemsPool[i]->id == itemId)
+ return i;
+ }
+
+ return 0;
+}
+
+bool CInventory::setItemFlags(int itemId, int flags) {
+ int idx = getInventoryPoolItemIndexById(itemId);
+
+ if (idx < 0)
+ return false;
+ else
+ _itemsPool[idx]->flags = flags;
+
+ return true;
+}
+
+CInventory2::CInventory2() {
+ _selectedId = -1;
+ _field_48 = -1;
+ _scene = 0;
+ _picture = 0;
+ _isInventoryOut = false;
+ _isLocked = 0;
+ _topOffset = -65;
+}
+
+bool CInventory2::loadPartial(MfcArchive &file) { // CInventory2_SerializePartially
+ int numInvs = file.readUint32LE();
+
+ for (int i = 0; i < numInvs; i++) {
+ InventoryItem *t = new InventoryItem();
+ t->itemId = file.readUint16LE();
+ t->count = file.readUint16LE();
+ _inventoryItems.push_back(t);
+ }
+
+ return true;
+}
+
+void CInventory2::addItem(int itemId, int count) {
+ if (getInventoryPoolItemIndexById(itemId) >= 0)
+ _inventoryItems.push_back(new InventoryItem(itemId, count));
+}
+
+void CInventory2::addItem2(StaticANIObject *obj) {
+ if (getInventoryPoolItemIndexById(obj->_id) >= 0 && getInventoryPoolItemFieldCById(obj->_id) != 2) {
+ addItem(obj->_id, 1);
+ obj->hide();
+ }
+}
+
+void CInventory2::removeItem(int itemId, int count) {
+ warning("STUB: CInventory2::removeItem(%d, %d)", itemId, count);
+}
+
+void CInventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int priority) {
+ warning("STUB: void removeItem2(sc, %d, %d, %d, %d)", itemId, x, y, priority);
+}
+
+int CInventory2::getCountItemsWithId(int itemId) {
+ int res = 0;
+
+ for (uint i = 0; i < _inventoryItems.size(); i++) {
+ if (_inventoryItems[i]->itemId == itemId)
+ res += _inventoryItems[i]->count;
+ }
+
+ return res;
+}
+
+int CInventory2::getInventoryItemIndexById(int itemId) {
+ for (uint i = 0; i < _inventoryItems.size(); i++) {
+ if (_inventoryItems[i]->itemId == itemId)
+ return i;
+ }
+
+ return -1;
+}
+
+int CInventory2::getInventoryPoolItemFieldCById(int itemId) {
+ for (uint i = 0; i < _itemsPool.size(); i++) {
+ if (_itemsPool[i]->id == itemId)
+ return _itemsPool[i]->field_C;
+ }
+
+ return 0;
+}
+
+int CInventory2::getItemFlags(int itemId) {
+ int idx = getInventoryPoolItemIndexById(itemId);
+
+ if (idx < 0)
+ return 0;
+
+ return _itemsPool[idx]->flags;
+}
+
+void CInventory2::rebuildItemRects() {
+ _scene = g_fullpipe->accessScene(_sceneId);
+
+ if (!_scene)
+ return;
+
+ _picture = _scene->getBigPicture(0, 0);
+ _picture->setAlpha(50);
+
+ int itemX = 9;
+ int itemY = 0;
+
+ for (uint i = 0; i < _scene->_picObjList.size(); i++) {
+ PictureObject *pic = (PictureObject *)_scene->_picObjList[i];
+
+ for (uint j = 0; j < _itemsPool.size(); j++) {
+ if (_itemsPool[j]->pictureObjectNormal == pic->_id) {
+ if (pic->_okeyCode)
+ _scene->deletePictureObject(pic);
+ else
+ pic->_flags &= 0xFFFB;
+ }
+ }
+ }
+
+ for (uint i = 0; i < _inventoryItems.size(); i++) {
+ Common::Point point;
+
+ int idx = getInventoryPoolItemIndexById(_inventoryItems[i]->itemId);
+
+ InventoryIcon *icn = new InventoryIcon();
+
+ icn->inventoryItemId = _itemsPool[idx]->id;
+
+ icn->pictureObjectNormal = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectNormal, 0);
+ icn->pictureObjectHover = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectHover, 0);
+ icn->pictureObjectSelected = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectSelected, 0);
+
+ icn->pictureObjectNormal->getDimensions(&point);
+
+ if (_itemsPool[idx]->flags & 0x10000) {
+ icn->x1 = 730;
+ icn->y1 = itemY;
+ icn->x2 = point.x + 730;
+ icn->y2 = point.y + itemY + 10;
+ } else {
+ icn->x1 = itemX;
+ icn->y1 = itemY;
+ icn->x2 = itemX + point.x;
+ itemX = icn->x2 + 1;
+ icn->y2 = point.y + itemY + 10;
+ }
+
+ _inventoryIcons.push_back(icn);
+
+ if (itemX >= 2 * (icn->x1 - icn->x2) + 800) {
+ itemX = 9;
+ itemY = icn->y2 + 1;
+ }
+ }
+}
+
+void CInventory2::draw() {
+ if (!_scene)
+ return;
+
+ int oldScLeft = g_fullpipe->_sceneRect.left;
+ int oldScTop = g_fullpipe->_sceneRect.top;
+
+ g_fullpipe->_sceneRect.top = -_topOffset;
+ g_fullpipe->_sceneRect.left = 0;
+
+ _picture->draw(-1, -1, 0, 0);
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ InventoryIcon *icn = _inventoryIcons[i];
+
+ if (icn->isSelected) {
+ icn->pictureObjectSelected->drawAt(icn->x1, icn->y1 + 10);
+ } else {
+ if (icn->isMouseHover)
+ icn->pictureObjectHover->drawAt(icn->x1, icn->y1 + 10);
+ else
+ icn->pictureObjectNormal->drawAt(icn->x1, icn->y1 + 10);
+ }
+ }
+
+ if (!_isInventoryOut)
+ goto LABEL_30;
+
+ int v10, v11, v12;
+
+ if (_topOffset != -10) {
+ if (_topOffset < -10) {
+ v10 = -10;
+ goto LABEL_13;
+ }
+ if (_topOffset + 10 >= 20) {
+ v11 = -20;
+cont:
+ _topOffset += v11;
+ goto reset;
+ }
+ v12 = -10;
+ goto LABEL_25;
+ }
+ if (!_isInventoryOut) {
+LABEL_30:
+ if (_topOffset != -65) {
+ if (_topOffset < -65) {
+ v10 = -65;
+LABEL_13:
+ v11 = v10 - _topOffset;
+ if (v11 >= 20)
+ v11 = 20;
+ goto cont;
+ }
+ if (_topOffset + 65 >= 20) {
+ v11 = -20;
+ goto cont;
+ }
+ v12 = -65;
+LABEL_25:
+ v11 = v12 - _topOffset;
+ goto cont;
+ }
+ }
+
+reset:
+
+ g_fullpipe->_sceneRect.top = oldScTop;
+ g_fullpipe->_sceneRect.left = oldScLeft;
+
+}
+
+void CInventory2::slideIn() {
+ _isInventoryOut = false;
+
+ ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_2C = 10;
+ ex->_field_14 = _isInventoryOut;
+ ex->_field_20 = !_isInventoryOut;
+ ex->_excFlags |= 3;
+ ex->postMessage();
+}
+
+void CInventory2::slideOut() {
+ _isInventoryOut = true;
+
+ ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_2C = 10;
+ ex->_field_14 = _isInventoryOut;
+ ex->_field_20 = !_isInventoryOut;
+ ex->_excFlags |= 3;
+ ex->postMessage();
+}
+
+bool CInventory2::handleLeftClick(ExCommand *cmd) {
+ if (!_isInventoryOut)
+ return false;
+
+ bool res = false;
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ if (cmd->_x >= _inventoryIcons[i]->x1 && cmd->_x <= _inventoryIcons[i]->x2 &&
+ cmd->_y >= _inventoryIcons[i]->y1 && cmd->_y <= _inventoryIcons[i]->y2) {
+ if (getSelectedItemId()) {
+ if (getSelectedItemId() != _inventoryIcons[i]->inventoryItemId)
+ unselectItem(0);
+ }
+ if (getItemFlags(_inventoryIcons[i]->inventoryItemId) & 1) {
+ ExCommand *ex = new ExCommand(0, 17, 65, 0, 0, 0, 1, 0, 0, 0);
+ ex->_field_2C = 11;
+ ex->_field_14 = _inventoryIcons[i]->inventoryItemId;
+ ex->_excFlags |= 3;
+ ex->postMessage();
+ }
+ if (!(getItemFlags(_inventoryIcons[i]->inventoryItemId) & 2)) {
+ selectItem(_inventoryIcons[i]->inventoryItemId);
+ _inventoryIcons[i]->isSelected = true;
+ }
+ res = true;
+ }
+ }
+
+ if (!res)
+ unselectItem(0);
+
+ return res;
+}
+
+int CInventory2::selectItem(int itemId) {
+ if (getInventoryItemIndexById(itemId) < 0)
+ return -1;
+
+ unselectItem(0);
+
+ _selectedId = itemId;
+
+ if (_scene) {
+ int idx = getInventoryPoolItemIndexById(itemId);
+
+ Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture;
+ g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(pic);
+ }
+
+ return _selectedId;
+}
+
+bool CInventory2::unselectItem(bool flag) {
+ if (_selectedId < 0)
+ return false;
+
+ _selectedId = -1;
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ if (_inventoryIcons[i]->isSelected)
+ _inventoryIcons[i]->isSelected = false;
+ }
+
+ g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(0);
+
+ return true;
+}
+
+int CInventory2::getHoveredItem(Common::Point *point) {
+ int selId = getSelectedItemId();
+
+ if (point->y <= 20 && !_isInventoryOut && !_isLocked)
+ slideOut();
+
+ if (!selId && point->y >= 55) {
+ if (!_isInventoryOut)
+ return 0;
+
+ if (!_isLocked)
+ slideIn();
+ }
+
+ if (!_isInventoryOut)
+ return 0;
+
+ for (uint i = 0; i < _inventoryIcons.size(); i++) {
+ InventoryIcon *icn = _inventoryIcons[i];
+ if (selId ||
+ point->x < icn->x1 ||
+ point->x > icn->x2 ||
+ point->y < _topOffset + icn->y1 ||
+ point->y > _topOffset + icn->y2) {
+ icn->isMouseHover = false;
+ } else {
+ icn->isMouseHover = true;
+ return icn->inventoryItemId;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h
new file mode 100644
index 0000000000..f84d27dde5
--- /dev/null
+++ b/engines/fullpipe/inventory.h
@@ -0,0 +1,130 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_INVENTORY_H
+#define FULLPIPE_INVENTORY_H
+
+namespace Fullpipe {
+
+class Scene;
+class BigPicture;
+
+struct InventoryPoolItem {
+ int16 id;
+ int16 pictureObjectNormal;
+ int16 pictureObjectId1;
+ int16 pictureObjectHover;
+ int16 pictureObjectSelected;
+ int16 field_A;
+ int field_C;
+ int obj;
+ int flags;
+};
+
+typedef Common::Array<InventoryPoolItem *> InventoryPoolItems;
+
+class CInventory : public CObject {
+ protected:
+ int16 _sceneId;
+ InventoryPoolItems _itemsPool;
+
+ public:
+ CInventory() { _sceneId = 0; }
+ virtual bool load(MfcArchive &file);
+
+ int getInventoryPoolItemIndexById(int itemId);
+ bool setItemFlags(int itemId, int flags);
+};
+
+struct InventoryItem {
+ int16 itemId;
+ int16 count;
+
+ InventoryItem() { itemId = count = 0; }
+ InventoryItem(int id, int cnt) : itemId(id), count(cnt) {}
+};
+
+typedef Common::Array<InventoryItem *> InventoryItems;
+
+class PictureObject;
+
+struct InventoryIcon {
+ PictureObject *pictureObjectNormal;
+ PictureObject *pictureObjectHover;
+ PictureObject *pictureObjectSelected;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ int16 inventoryItemId;
+ bool isSelected;
+ bool isMouseHover;
+};
+
+typedef Common::Array<InventoryIcon *> InventoryIcons;
+
+class CInventory2 : public CInventory {
+ InventoryItems _inventoryItems;
+ InventoryIcons _inventoryIcons;
+ int _selectedId;
+ int _field_48;
+ bool _isInventoryOut;
+ bool _isLocked;
+ int _topOffset;
+ Scene *_scene;
+ BigPicture *_picture;
+
+ public:
+ CInventory2();
+ bool loadPartial(MfcArchive &file);
+ void addItem(int itemId, int count);
+ void addItem2(StaticANIObject *obj);
+ void removeItem(int itemId, int count);
+ void removeItem2(Scene *sceneObj, int itemId, int x, int y, int priority);
+
+ int getInventoryItemIndexById(int itemId);
+ int getInventoryPoolItemFieldCById(int itemId);
+ int getCountItemsWithId(int itemId);
+ int getItemFlags(int itemId);
+
+ void rebuildItemRects();
+
+ Scene *getScene() { return _scene; }
+ bool getIsLocked() { return _isLocked; }
+ void setIsLocked(bool val) { _isLocked = val; }
+ bool getIsInventoryOut() { return _isInventoryOut; }
+
+ int getSelectedItemId() { return _selectedId < 0 ? 0 : _selectedId; }
+ int getHoveredItem(Common::Point *point);
+ void slideIn();
+ void slideOut();
+
+ bool handleLeftClick(ExCommand *cmd);
+ int selectItem(int itemId);
+ bool unselectItem(bool flag);
+
+ void draw();
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_INVENTORY_H */
diff --git a/engines/fullpipe/lift.cpp b/engines/fullpipe/lift.cpp
new file mode 100644
index 0000000000..25dd2613fe
--- /dev/null
+++ b/engines/fullpipe/lift.cpp
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+int FullpipeEngine::lift_getButtonIdP(int objid) {
+ switch (objid) {
+ case ST_LBN_0N:
+ return ST_LBN_0P;
+ break;
+ case ST_LBN_1N:
+ return ST_LBN_1P;
+ break;
+ case ST_LBN_2N:
+ return ST_LBN_2P;
+ break;
+ case ST_LBN_3N:
+ return ST_LBN_3P;
+ break;
+ case ST_LBN_4N:
+ return ST_LBN_4P;
+ break;
+ case ST_LBN_5N:
+ return ST_LBN_5P;
+ break;
+ case ST_LBN_6N:
+ return ST_LBN_6P;
+ break;
+ case ST_LBN_7N:
+ return ST_LBN_7P;
+ break;
+ case ST_LBN_8N:
+ return ST_LBN_8P;
+ break;
+ case ST_LBN_9N:
+ return ST_LBN_9P;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
new file mode 100644
index 0000000000..36fd1399ce
--- /dev/null
+++ b/engines/fullpipe/messages.cpp
@@ -0,0 +1,727 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/statics.h"
+
+namespace Fullpipe {
+
+ExCommand::ExCommand() {
+ _field_3C = 1;
+ _messageNum = 0;
+ _excFlags = 0;
+ _parId = 0;
+}
+
+ExCommand::ExCommand(ExCommand *src) : Message(src) {
+ _field_3C = 1;
+ _messageNum = src->_messageNum;
+ _excFlags = src->_excFlags;
+ _parId = src->_parId;
+
+}
+
+ExCommand::ExCommand(int16 parentId, int messageKind, int messageNum, int x, int y, int a7, int a8, int sceneClickX, int sceneClickY, int a11) :
+ Message(parentId, messageKind, x, y, a7, a8, sceneClickX, sceneClickY, a11) {
+ _field_3C = 1;
+ _messageNum = messageNum;
+ _excFlags = 0;
+ _parId = 0;
+}
+
+bool ExCommand::load(MfcArchive &file) {
+ debug(5, "ExCommand::load()");
+
+ _parentId = file.readUint16LE();
+ _messageKind = file.readUint32LE();
+ _x = file.readUint32LE();
+ _y = file.readUint32LE();
+ _field_14 = file.readUint32LE();
+ _sceneClickX = file.readUint32LE();
+ _sceneClickY = file.readUint32LE();
+ _field_20 = file.readUint32LE();
+ _field_24 = file.readUint32LE();
+ _keyCode = file.readUint32LE();
+ _field_2C = file.readUint32LE();
+ _field_30 = file.readUint32LE();
+ _field_34 = file.readUint32LE();
+
+ _messageNum = file.readUint32LE();
+
+ _field_3C = 0;
+
+ if (g_fullpipe->_gameProjectVersion >= 12) {
+ _excFlags = file.readUint32LE();
+ _parId = file.readUint32LE();
+ }
+
+ return true;
+}
+
+bool ExCommand::handleMessage() {
+ int cnt = 0;
+ for (MessageHandler *m = g_fullpipe->_messageHandlers; m; m = m->nextItem)
+ cnt += m->callback(this);
+
+ if (_messageKind == 17 || (_excFlags & 1)) {
+ if (_parId) {
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_parId);
+ if (mq)
+ mq->update();
+ }
+ }
+
+ if (_excFlags & 2)
+ delete this;
+
+ return (cnt > 0);
+}
+
+void ExCommand::sendMessage() {
+ g_fullpipe->_exCommandList.push_back(this);
+
+ processMessages();
+}
+
+void ExCommand::postMessage() {
+ g_fullpipe->_exCommandList.push_back(this);
+}
+
+void ExCommand::handle() {
+ if (g_fullpipe->_modalObject) {
+ g_fullpipe->_modalObject->handleMessage(this);
+
+ delete this;
+ } else {
+ postMessage();
+ }
+}
+
+Message::Message() {
+ _messageKind = 0;
+ _parentId = 0;
+
+ _x = 0;
+ _y = 0;
+ _field_14 = 0;
+ _sceneClickX = 0;
+ _sceneClickY = 0;
+ _field_20 = 0;
+ _field_24 = 0;
+ _keyCode = 0;
+ _field_2C = 0;
+ _field_30 = 0;
+ _field_34 = 0;
+}
+
+Message::Message(Message *src) {
+ _parentId = src->_parentId;
+ _messageKind = src->_messageKind;
+ _x = src->_x;
+ _y = src->_y;
+ _field_14 = src->_field_14;
+ _sceneClickX = src->_sceneClickX;
+ _sceneClickY = src->_sceneClickY;
+ _field_20 = src->_field_20;
+ _field_24 = src->_field_24;
+ _keyCode = src->_keyCode;
+ _field_2C = src->_field_2C;
+ _field_30 = src->_field_30;
+ _field_34 = src->_field_34;
+}
+
+Message::Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10) {
+ _messageKind = messageKind;
+ _parentId = parentId;
+ _x = x;
+ _y = y;
+ _field_14 = a6;
+ _sceneClickX = sceneClickX;
+ _sceneClickY = sceneClickY;
+ _field_24 = a7;
+ _field_20 = a10;
+ _keyCode = 0;
+ _field_2C = 0;
+ _field_30 = 0;
+ _field_34 = 0;
+}
+
+CObjstateCommand::CObjstateCommand() {
+ _value = 0;
+ _objCommandName = 0;
+}
+
+bool CObjstateCommand::load(MfcArchive &file) {
+ debug(5, "CObjStateCommand::load()");
+
+ _objtype = kObjTypeObjstateCommand;
+
+ _cmd.load(file);
+
+ _value = file.readUint32LE();
+
+ _objCommandName = file.readPascalString();
+
+ return true;
+}
+
+MessageQueue::MessageQueue() {
+ _field_14 = 0;
+ _parId = 0;
+ _dataId = 0;
+ _id = 0;
+ _isFinished = 0;
+ _flags = 0;
+ _queueName = 0;
+}
+
+MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
+ _counter = 0;
+ _field_38 = (field_38 == 0);
+
+ for (Common::List<ExCommand *>::iterator it = src->_exCommands.begin(); it != src->_exCommands.end(); ++it) {
+ ExCommand *ex = new ExCommand(*it);
+ ex->_excFlags |= 2;
+
+ _exCommands.push_back(ex);
+ }
+ _field_14 = src->_field_14;
+
+ if (parId)
+ _parId = parId;
+ else
+ _parId = src->_parId;
+
+ _id = g_fullpipe->_globalMessageQueueList->compact();
+ _dataId = src->_dataId;
+ _flags = src->_flags;
+
+ g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
+
+ _isFinished = 0;
+}
+
+MessageQueue::~MessageQueue() {
+ for (Common::List<ExCommand *>::iterator it = _exCommands.begin(); it != _exCommands.end(); ++it) {
+ ExCommand *ex = (ExCommand *)*it;
+
+ if (ex && ex->_excFlags & 2)
+ delete ex;
+ }
+
+ _exCommands.clear();
+
+ if (_field_14)
+ delete _field_14;
+
+ if (_flags & 2) {
+ g_fullpipe->_globalMessageQueueList->removeQueueById(_id);
+ }
+
+ finish();
+
+ free(_queueName);
+}
+
+bool MessageQueue::load(MfcArchive &file) {
+ debug(5, "MessageQueue::load()");
+
+ _dataId = file.readUint16LE();
+
+ int count = file.readUint16LE();
+
+ assert(g_fullpipe->_gameProjectVersion >= 12);
+
+ _queueName = file.readPascalString();
+
+ for (int i = 0; i < count; i++) {
+ ExCommand *tmp = (ExCommand *)file.readClass();
+
+ _exCommands.push_back(tmp);
+ }
+
+ _id = -1;
+ _field_14 = 0;
+ _parId = 0;
+ _isFinished = 0;
+
+ return true;
+}
+
+bool MessageQueue::chain(StaticANIObject *ani) {
+ if (checkGlobalExCommandList1() && checkGlobalExCommandList2()) {
+ if (!(getFlags() & 2)) {
+ g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
+ _flags |= 2;
+ }
+ if (ani) {
+ ani->queueMessageQueue(this);
+ return true;
+ } else {
+ sendNextCommand();
+ return true;
+ }
+ }
+ return false;
+}
+
+void MessageQueue::update() {
+ if (_counter > 0)
+ _counter--;
+
+ if (_exCommands.size()) {
+ sendNextCommand();
+ } else if (_counter == 0) {
+ _isFinished = 1;
+ finish();
+ }
+}
+
+void MessageQueue::messageQueueCallback1(int par) {
+ // Autosave
+ debug(3, "STUB: MessageQueue::messageQueueCallback1()");
+}
+
+ExCommand *MessageQueue::getExCommandByIndex(uint idx) {
+ if (idx > _exCommands.size())
+ return 0;
+
+ Common::List<ExCommand *>::iterator it = _exCommands.begin();
+
+ while (idx) {
+ ++it;
+ idx--;
+ }
+
+ return *it;
+}
+
+void MessageQueue::sendNextCommand() {
+ if (_exCommands.size()) {
+ if (!(_flags & 4) && (_flags & 1)) {
+ messageQueueCallback1(16);
+ }
+ ExCommand *ex = _exCommands.front();
+
+ _exCommands.pop_front();
+
+ _counter++;
+ ex->_parId = _id;
+ ex->_excFlags |= (ex->_field_24 == 0 ? 1 : 0) | (ex->_field_3C != 0 ? 2 : 0);
+
+ _flags |= 4;
+ ex->sendMessage();
+ } else if (_counter <= 0) {
+ _isFinished = 1;
+ finish();
+ }
+}
+
+bool MessageQueue::checkGlobalExCommandList1() {
+ ExCommand *ex, *ex1;
+
+ for (uint i = 0; i < getCount(); i++) {
+ ex = getExCommandByIndex(i);
+
+ if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
+ continue;
+
+ for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end(); it++) {
+ ex1 = *it;
+
+ if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27)
+ continue;
+
+ if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1)
+ continue;
+
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
+
+ if (mq) {
+ if (mq->getFlags() & 1)
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool MessageQueue::checkGlobalExCommandList2() {
+ ExCommand *ex, *ex1;
+
+ for (uint i = 0; i < getCount(); i++) {
+ ex = getExCommandByIndex(i);
+
+ if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
+ continue;
+
+ for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end();) {
+ ex1 = *it;
+
+ if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27) {
+ it++;
+ continue;
+ }
+
+ if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1) {
+ it++;
+ continue;
+ }
+
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
+
+ if (mq) {
+ if (mq->getFlags() & 1)
+ return false;
+
+ delete mq;
+ }
+
+ it = g_fullpipe->_exCommandList.erase(it);
+
+ if (ex1->_excFlags & 2) {
+ delete ex1;
+ }
+ }
+ }
+ return true;
+}
+
+void MessageQueue::finish() {
+ if (!_parId)
+ return;
+
+ MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_parId);
+
+ _parId = 0;
+
+ if (!mq)
+ return;
+
+ if (!_flag1) {
+ mq->update();
+ return;
+ }
+
+ mq->_counter--;
+
+ if (!mq->_counter && !mq->_exCommands.size())
+ mq->update();
+}
+
+void MessageQueue::replaceKeyCode(int key1, int key2) {
+ for (uint i = 0; i < getCount(); i++) {
+ ExCommand *ex = getExCommandByIndex(i);
+ int k = ex->_messageKind;
+ if ((k == 1 || k == 20 || k == 5 || k == 6 || k == 2 || k == 18 || k == 19 || k == 22 || k == 55)
+ && ex->_keyCode == key1)
+ ex->_keyCode = key2;
+ }
+}
+
+int MessageQueue::calcDuration(StaticANIObject *obj) {
+ int res = 0;
+ ExCommand *ex;
+ Movement *mov;
+
+ for (uint i = 0; (ex = getExCommandByIndex(i)); i++)
+ if (ex->_parentId == obj->_id) {
+ if (ex->_messageKind == 1 || ex->_messageKind == 20) {
+ if ((mov = obj->getMovementById(ex->_messageNum)) != 0) {
+ if (ex->_field_14 >= 1)
+ res += ex->_field_14;
+ else
+ res += mov->calcDuration();
+ }
+ }
+ }
+
+ return res;
+}
+
+void MessageQueue::changeParam28ForObjectId(int objId, int oldParam28, int newParam28) {
+ for (uint i = 0; i < _exCommands.size(); i++) {
+ ExCommand *ex = getExCommandByIndex(i);
+ int k = ex->_messageKind;
+
+ if ((k == 1 || k == 20 || k == 5 || k == 6 || k == 2 || k == 18 || k == 19 || k == 22 || k == 55)
+ && ex->_keyCode == oldParam28
+ && ex->_parentId == objId)
+ ex->_keyCode = newParam28;
+ }
+}
+
+MessageQueue *GlobalMessageQueueList::getMessageQueueById(int id) {
+ for (Common::Array<MessageQueue *>::iterator s = begin(); s != end(); ++s) {
+ if ((*s)->_id == id)
+ return *s;
+ }
+
+ return 0;
+}
+
+void GlobalMessageQueueList::deleteQueueById(int id) {
+ for (uint i = 0; i < size(); i++)
+ if (_storage[i]->_id == id) {
+ remove_at(i);
+
+ disableQueueById(id);
+ return;
+ }
+}
+
+void GlobalMessageQueueList::removeQueueById(int id) {
+ for (uint i = 0; i < size(); i++)
+ if (_storage[i]->_id == id) {
+ _storage[i]->_flags &= 0xFD; // It is quite pointless
+ remove_at(i);
+
+ disableQueueById(id);
+ return;
+ }
+}
+
+void GlobalMessageQueueList::disableQueueById(int id) {
+ for (Common::Array<MessageQueue *>::iterator s = begin(); s != end(); ++s) {
+ if ((*s)->_parId == id)
+ (*s)->_parId = 0;
+ }
+}
+
+int GlobalMessageQueueList::compact() {
+ for (uint i = 0; i < size();) {
+ if (((MessageQueue *)_storage[i])->_isFinished) {
+ disableQueueById(_storage[i]->_id);
+ remove_at(i);
+ } else {
+ i++;
+ }
+ }
+
+ return size() + 1;
+}
+
+void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) {
+ msg->setFlags(msg->getFlags() | 2);
+
+ push_back(msg);
+}
+
+void clearGlobalMessageQueueList1() {
+ warning("STUB: clearGlobalMessageQueueList1()");
+}
+
+bool removeMessageHandler(int16 id, int pos) {
+ if (g_fullpipe->_messageHandlers) {
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *prevItem = 0;
+ int curPos = 0;
+
+ while (id != curItem->id) {
+ prevItem = curItem;
+ curItem = curItem->nextItem;
+ curPos++;
+
+ if (!curItem)
+ return false;
+ }
+
+ if (pos == -1 || curPos == pos) {
+ prevItem->nextItem = curItem->nextItem;
+ delete curItem;
+ updateMessageHandlerIndex(prevItem->nextItem, -1);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void updateMessageHandlerIndex(MessageHandler *msg, int offset) {
+ for (; msg; msg = msg->nextItem)
+ msg->index += offset;
+}
+
+void addMessageHandler(int (*callback)(ExCommand *), int16 id) {
+ if (getMessageHandlerById(id))
+ return;
+
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ if (!curItem)
+ return;
+
+ int index = 0;
+ for (MessageHandler *i = g_fullpipe->_messageHandlers->nextItem; i; i = i->nextItem) {
+ curItem = i;
+ index++;
+ }
+
+ allocMessageHandler(curItem, id, callback, index);
+
+ if (curItem)
+ updateMessageHandlerIndex(curItem->nextItem->nextItem, 1);
+}
+
+MessageHandler *getMessageHandlerById(int16 id) {
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ if (!curItem)
+ return 0;
+
+ while (id != curItem->id) {
+ curItem = curItem->nextItem;
+
+ if (!curItem)
+ return 0;
+ }
+
+ return curItem;
+}
+
+bool allocMessageHandler(MessageHandler *where, int16 id, int (*callback)(ExCommand *), int index) {
+ MessageHandler *msg = new MessageHandler;
+
+ if (where) {
+ msg->nextItem = where->nextItem;
+ where->nextItem = msg;
+ msg->id = id;
+ msg->callback = callback;
+ msg->index = index;
+ } else {
+ msg->nextItem = 0;
+ msg->id = id;
+ msg->callback = callback;
+ msg->index = 0;
+
+ g_fullpipe->_messageHandlers = msg;
+ }
+
+ return true;
+}
+
+int getMessageHandlersCount() {
+ int result;
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ for (result = 0; curItem; result++)
+ curItem = curItem->nextItem;
+
+ return result;
+}
+
+bool addMessageHandlerByIndex(int (*callback)(ExCommand *), int index, int16 id) {
+ if (getMessageHandlerById(id))
+ return false;
+
+ if (index) {
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ for (int i = index - 1; i > 0; i--)
+ if (curItem)
+ curItem = curItem->nextItem;
+
+ if (!curItem)
+ return false;
+
+ bool res = allocMessageHandler(curItem, id, callback, index);
+
+ if (res)
+ updateMessageHandlerIndex(curItem->nextItem->nextItem, 1);
+
+ return res;
+ } else {
+ MessageHandler *newItem = new MessageHandler;
+
+ newItem->nextItem = g_fullpipe->_messageHandlers;
+ newItem->id = id;
+ newItem->callback = callback;
+ newItem->index = 0;
+
+ updateMessageHandlerIndex(g_fullpipe->_messageHandlers, 1);
+ g_fullpipe->_messageHandlers = newItem;
+
+ return true;
+ }
+}
+
+bool insertMessageHandler(int (*callback)(ExCommand *), int index, int16 id) {
+ if (getMessageHandlerById(id))
+ return false;
+
+ MessageHandler *curItem = g_fullpipe->_messageHandlers;
+
+ for (int i = index; i > 0; i--)
+ if (curItem)
+ curItem = curItem->nextItem;
+
+ bool res = allocMessageHandler(curItem, id, callback, index + 1);
+ if (curItem)
+ updateMessageHandlerIndex(curItem->nextItem->nextItem, 1);
+
+ return res;
+}
+
+void clearMessageHandlers() {
+ MessageHandler *curItem;
+ MessageHandler *nextItem;
+
+ curItem = g_fullpipe->_messageHandlers;
+ if (curItem) {
+ do {
+ nextItem = curItem->nextItem;
+
+ delete curItem;
+
+ curItem = nextItem;
+ } while (nextItem);
+
+ g_fullpipe->_messageHandlers = 0;
+ }
+}
+
+void processMessages() {
+ if (!g_fullpipe->_isProcessingMessages) {
+ g_fullpipe->_isProcessingMessages = true;
+
+ while (g_fullpipe->_exCommandList.size()) {
+ ExCommand *ex = g_fullpipe->_exCommandList.front();
+ g_fullpipe->_exCommandList.pop_front();
+ ex->handleMessage();
+ }
+ g_fullpipe->_isProcessingMessages = false;
+ }
+}
+
+void updateGlobalMessageQueue(int id, int objid) {
+ MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(id);
+ if (m) {
+ m->update();
+ }
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
new file mode 100644
index 0000000000..7ba9126d46
--- /dev/null
+++ b/engines/fullpipe/messages.h
@@ -0,0 +1,175 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_MESSAGEQUEUE_H
+#define FULLPIPE_MESSAGEQUEUE_H
+
+#include "fullpipe/utils.h"
+#include "fullpipe/inventory.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/sound.h"
+#include "fullpipe/scene.h"
+
+namespace Fullpipe {
+
+class Message : public CObject {
+ public:
+ int _messageKind;
+ int16 _parentId;
+ int _x;
+ int _y;
+ int _field_14;
+ int _sceneClickX;
+ int _sceneClickY;
+ int _field_20;
+ int _field_24;
+ int _keyCode;
+ int _field_2C;
+ int _field_30;
+ int _field_34;
+
+ public:
+ Message();
+ Message(Message *src);
+ virtual ~Message() {}
+
+ Message(int16 parentId, int messageKind, int x, int y, int a6, int a7, int sceneClickX, int sceneClickY, int a10);
+};
+
+class ExCommand : public Message {
+ public:
+
+ int _messageNum;
+ int _field_3C;
+ int _excFlags;
+ int _parId;
+
+ ExCommand();
+ ExCommand(ExCommand *src);
+ ExCommand(int16 parentId, int messageKind, int messageNum, int x, int y, int a7, int a8, int sceneClickX, int sceneClickY, int a11);
+ virtual ~ExCommand() {}
+
+ virtual bool load(MfcArchive &file);
+
+ bool handleMessage();
+ void sendMessage();
+ void postMessage();
+ void handle();
+};
+
+class ExCommand2 : public ExCommand {
+ public:
+ Common::Point **_points;
+ int _pointsSize;
+};
+
+class CObjstateCommand : public CObject {
+ public:
+ ExCommand _cmd;
+ char *_objCommandName;
+ int _value;
+
+ public:
+ CObjstateCommand();
+ virtual bool load(MfcArchive &file);
+};
+
+class MessageQueue : public CObject {
+ public:
+ int _id;
+ int _flags;
+ char *_queueName;
+ int16 _dataId;
+ int16 _field_12;
+ CObject *_field_14;
+ Common::List<ExCommand *> _exCommands;
+ int _counter;
+ int _field_38;
+ int _isFinished;
+ int _parId;
+ int _flag1;
+
+ public:
+ MessageQueue();
+ MessageQueue(MessageQueue *src, int parId, int field_38);
+ virtual ~MessageQueue();
+
+ virtual bool load(MfcArchive &file);
+
+ int getFlags() { return _flags; }
+ void setFlags(int flags) { _flags = flags; }
+
+ uint getCount() { return _exCommands.size(); }
+
+ ExCommand *getExCommandByIndex(uint idx);
+
+ void replaceKeyCode(int key1, int key2);
+
+ bool chain(StaticANIObject *ani);
+ void update();
+ void sendNextCommand();
+ void finish();
+
+ void messageQueueCallback1(int par);
+
+ bool checkGlobalExCommandList1();
+ bool checkGlobalExCommandList2();
+
+ int calcDuration(StaticANIObject *obj);
+ void changeParam28ForObjectId(int objId, int oldParam28, int newParam28);
+};
+
+class GlobalMessageQueueList : public Common::Array<MessageQueue *> {
+ public:
+ MessageQueue *getMessageQueueById(int id);
+ void deleteQueueById(int id);
+ void removeQueueById(int id);
+ void disableQueueById(int id);
+ void addMessageQueue(MessageQueue *msg);
+
+ int compact();
+};
+
+struct MessageHandler {
+ int (*callback)(ExCommand *cmd);
+ int16 id;
+ int16 field_6;
+ int index;
+ MessageHandler *nextItem;
+};
+
+bool removeMessageHandler(int16 id, int pos);
+void updateMessageHandlerIndex(MessageHandler *msg, int offset);
+void addMessageHandler(int (*callback)(ExCommand *), int16 id);
+MessageHandler *getMessageHandlerById(int16 id);
+bool allocMessageHandler(MessageHandler *where, int16 id, int (*callback)(ExCommand *), int index);
+int getMessageHandlersCount();
+bool addMessageHandlerByIndex(int (*callback)(ExCommand *), int index, int16 id);
+bool insertMessageHandler(int (*callback)(ExCommand *), int index, int16 id);
+void clearMessageHandlers();
+void processMessages();
+void updateGlobalMessageQueue(int id, int objid);
+void clearGlobalMessageQueueList1();
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_MESSAGEQUEUE_H */
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
new file mode 100644
index 0000000000..6f1bc0cc1f
--- /dev/null
+++ b/engines/fullpipe/modal.cpp
@@ -0,0 +1,106 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/scenes.h"
+
+namespace Fullpipe {
+
+bool CBaseModalObject::handleMessage(ExCommand *message) {
+ warning("STUB: CBaseModalObject::handleMessage()");
+
+ return true;
+}
+
+bool CBaseModalObject::init(int counterdiff) {
+ warning("STUB: CBaseModalObject::init(%d)", counterdiff);
+
+ return true;
+}
+
+bool CBaseModalObject::update() {
+ warning("STUB: CBaseModalObject::update()");
+
+ return true;
+}
+
+void CBaseModalObject::saveload() {
+ warning("STUB: CBaseModalObject::saveload()");
+}
+
+
+CModalIntro::CModalIntro() {
+ _field_8 = 0;
+ _countDown = 0;
+ _needRedraw = 0;
+ if (g_vars->sceneIntro_skipIntro) {
+ _introFlags = 4;
+ } else {
+ _introFlags = 33;
+ _countDown = 150;
+
+ PictureObject *pict = g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0);
+ pict->setFlags(pict->_flags & 0xFFFB);
+ }
+ g_vars->sceneIntro_skipIntro = false;
+ _sfxVolume = g_fullpipe->_sfxVolume;
+}
+
+bool CModalIntro::handleMessage(ExCommand *message) {
+ if (message->_messageKind != 17)
+ return false;
+
+ if (message->_messageNum != 36)
+ return false;
+
+ if (message->_keyCode != 13 && message->_keyCode != 27 && message->_keyCode != 32)
+ return false;
+
+ if (_needRedraw) {
+ if (!(_introFlags & 0x10)) {
+ _countDown = 0;
+ g_vars->sceneIntro_needBlackout = true;
+ return true;
+ }
+ g_vars->sceneIntro_playing = false;
+ g_vars->sceneIntro_needBlackout = true;
+ }
+
+ return true;
+}
+
+void FullpipeEngine::openMap() {
+ warning("STUB: FullpipeEngine::openMap()");
+}
+
+void FullpipeEngine::openHelp() {
+ warning("STUB: FullpipeEngine::openHelp()");
+}
+
+void FullpipeEngine::openMainMenu() {
+ warning("STUB: FullpipeEngine::openMainMenu()");
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
new file mode 100644
index 0000000000..73236e8e5b
--- /dev/null
+++ b/engines/fullpipe/modal.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_MODAL_H
+#define FULLPIPE_MODAL_H
+
+namespace Fullpipe {
+
+class CBaseModalObject {
+ public:
+
+ CBaseModalObject *_parentObj;
+
+ public:
+ CBaseModalObject() : _parentObj(0) {}
+ virtual ~CBaseModalObject() {}
+
+ virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual bool update();
+
+ void saveload();
+};
+
+class CModalIntro : public CBaseModalObject {
+ int _field_8;
+ int _introFlags;
+ int _countDown;
+ int _needRedraw;
+ int _sfxVolume;
+
+ public:
+ CModalIntro();
+
+ virtual bool handleMessage(ExCommand *message);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_MODAL_H */
diff --git a/engines/fullpipe/module.mk b/engines/fullpipe/module.mk
new file mode 100644
index 0000000000..380f582c08
--- /dev/null
+++ b/engines/fullpipe/module.mk
@@ -0,0 +1,31 @@
+MODULE := engines/fullpipe
+
+MODULE_OBJS = \
+ behavior.o \
+ detection.o \
+ fullpipe.o \
+ gameloader.o \
+ gfx.o \
+ init.o \
+ input.o \
+ interaction.o \
+ inventory.o \
+ lift.o \
+ messages.o \
+ modal.o \
+ motion.o \
+ ngiarchive.o \
+ scene.o \
+ scenes.o \
+ sound.o \
+ stateloader.o \
+ statics.o \
+ utils.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_FULLPIPE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
new file mode 100644
index 0000000000..514dde5185
--- /dev/null
+++ b/engines/fullpipe/motion.cpp
@@ -0,0 +1,280 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "common/file.h"
+#include "common/array.h"
+#include "common/list.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/motion.h"
+
+namespace Fullpipe {
+
+bool CMotionController::load(MfcArchive &file) {
+ // Is originally empty file.readClass();
+
+ debug(5, "CMotionController::load()");
+
+ return true;
+}
+
+bool CMctlCompound::load(MfcArchive &file) {
+ debug(5, "CMctlCompound::load()");
+
+ int count = file.readUint32LE();
+
+ debug(6, "CMctlCompound::count = %d", count);
+
+ for (int i = 0; i < count; i++) {
+ debug(6, "CompoundArray[%d]", i);
+ CMctlCompoundArrayItem *obj = (CMctlCompoundArrayItem *)file.readClass();
+
+ int count1 = file.readUint32LE();
+
+ debug(6, "ConnectionPoint::count: %d", count1);
+ for (int j = 0; j < count1; j++) {
+ debug(6, "ConnectionPoint[%d]", j);
+ CMctlConnectionPoint *obj1 = (CMctlConnectionPoint *)file.readClass();
+
+ obj->_connectionPoints.push_back(*obj1);
+ }
+
+ obj->_field_20 = file.readUint32LE();
+ obj->_field_24 = file.readUint32LE();
+
+ debug(6, "graphReact");
+ obj->_movGraphReactObj = (CMovGraphReact *)file.readClass();
+
+ _motionControllers.push_back(*obj);
+ }
+
+ return true;
+}
+
+void CMctlCompound::addObject(StaticANIObject *obj) {
+ warning("STUB: CMctlCompound::addObject()");
+}
+
+void CMctlCompound::initMovGraph2() {
+ warning("STUB: CMctlCompound::initMovGraph2()");
+}
+
+MessageQueue *CMctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+ warning("STUB: CMctlCompound::method34()");
+
+ return 0;
+}
+
+MessageQueue *CMctlCompound::method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+ warning("STUB: CMctlCompound::method4C()");
+
+ return 0;
+}
+
+bool CMctlCompoundArray::load(MfcArchive &file) {
+ debug(5, "CMctlCompoundArray::load()");
+
+ int count = file.readUint32LE();
+
+ debug(0, "CMctlCompoundArray::count = %d", count);
+
+ assert(0);
+
+ return true;
+}
+
+CMovGraph::CMovGraph() {
+ warning("STUB: CMovGraph::CMovGraph()");
+ _itemsCount = 0;
+ _items = 0;
+ //_callback1 = CMovGraphCallback1; // TODO
+ _field_44 = 0;
+ // insertMessageHandler(CMovGraph_messageHandler, getMessageHandlersCount() - 1, 129);
+}
+
+bool CMovGraph::load(MfcArchive &file) {
+ debug(5, "CMovGraph::load()");
+
+ _links.load(file);
+ _nodes.load(file);
+
+ return true;
+}
+
+void CMovGraph::addObject(StaticANIObject *obj) {
+ warning("STUB: CMovGraph::addObject()");
+}
+
+CMovGraphLink::CMovGraphLink() {
+ _distance = 0;
+ _angle = 0;
+ _flags = 0x10000000;
+ _movGraphNode2 = 0;
+ _movGraphNode1 = 0;
+ _field_3C = 0;
+ _field_38 = 0;
+ _movGraphReact = 0;
+ _name = 0;
+}
+
+bool CMovGraphLink::load(MfcArchive &file) {
+ debug(5, "CMovGraphLink::load()");
+
+ _dwordArray1.load(file);
+ _dwordArray2.load(file);
+
+ _flags = file.readUint32LE();
+
+ debug(8, "GraphNode1");
+ _movGraphNode1 = (CMovGraphNode *)file.readClass();
+ debug(8, "GraphNode2");
+ _movGraphNode2 = (CMovGraphNode *)file.readClass();
+
+ _distance = file.readDouble();
+ _angle = file.readDouble();
+
+ debug(8, "distance: %g, angle: %g", _distance, _angle);
+
+ _movGraphReact = (CMovGraphReact *)file.readClass();
+ _name = file.readPascalString();
+
+ return true;
+}
+
+bool CMovGraphNode::load(MfcArchive &file) {
+ debug(5, "CMovGraphNode::load()");
+
+ _field_14 = file.readUint32LE();
+ _x = file.readUint32LE();
+ _y = file.readUint32LE();
+ _distance = file.readUint32LE();
+
+ return true;
+}
+
+CReactParallel::CReactParallel() {
+ _x1 = 0;
+ _x2 = 0;
+ _dy = 0;
+ _dx = 0;
+ _points = 0;
+ _y1 = 0;
+ _y2 = 0;
+}
+
+bool CReactParallel::load(MfcArchive &file) {
+ debug(5, "CReactParallel::load()");
+
+ _x1 = file.readUint32LE();
+ _y1 = file.readUint32LE();
+ _x2 = file.readUint32LE();
+ _y2 = file.readUint32LE();
+ _dx = file.readUint32LE();
+ _dy = file.readUint32LE();
+
+ createRegion();
+
+ return true;
+}
+
+void CReactParallel::createRegion() {
+ _points = (Common::Point **)malloc(sizeof(Common::Point *) * 4);
+
+ for (int i = 0; i < 4; i++)
+ _points[i] = new Common::Point;
+
+ double at = atan2((double)(_x1 - _x2), (double)(_y1 - _y2)) + 1.570796;
+ double sn = sin(at);
+ double cs = cos(at);
+
+ _points[0]->x = (int16)(_x1 - _dx * cs);
+ _points[0]->y = (int16)(_y1 - _dx * sn);
+
+ _points[1]->x = (int16)(_x2 - _dx * cs);
+ _points[1]->y = (int16)(_y2 - _dx * sn);
+
+ _points[2]->x = (int16)(_x1 + _dy * cs);
+ _points[2]->y = (int16)(_y2 + _dy * sn);
+
+ _points[3]->x = (int16)(_x1 + _dy * cs);
+ _points[3]->y = (int16)(_y1 + _dy * sn);
+
+ // GdiObject::Attach(_rgn, CreatePolygonRgn(_points, 4, 2);
+}
+
+CReactPolygonal::CReactPolygonal() {
+ _field_C = 0;
+ _points = 0;
+ _pointCount = 0;
+ _field_10 = 0;
+}
+
+bool CReactPolygonal::load(MfcArchive &file) {
+ debug(5, "CReactPolygonal::load()");
+
+ _field_C = file.readUint32LE();
+ _field_10 = file.readUint32LE();
+ _pointCount = file.readUint32LE();
+
+ if (_pointCount > 0) {
+ _points = (Common::Point **)malloc(sizeof(Common::Point *) * _pointCount);
+
+ for (int i = 0; i < _pointCount; i++) {
+ _points[i] = new Common::Point;
+
+ _points[i]->x = file.readUint32LE();
+ _points[i]->y = file.readUint32LE();
+ }
+
+ }
+
+ createRegion();
+
+ return true;
+}
+
+void CReactPolygonal::createRegion() {
+ if (_points) {
+
+ // GdiObject::Attach(_rgn, CreatePolygonRgn(_points, _pointCount, 2);
+ }
+}
+
+int startWalkTo(int objId, int objKey, int x, int y, int a5) {
+ warning("STUB: startWalkTo(%d, %d, %d, %d, %d)", objId, objKey, x, y, a5);
+
+ return 0;
+}
+
+int doSomeAnimation(int objId, int objKey, int a3) {
+ warning("STUB: doSomeAnimation(%d, %d, %d)", objId, objKey, a3);
+
+ return 0;
+}
+
+int doSomeAnimation2(int objId, int objKey) {
+ return doSomeAnimation(objId, objKey, 0);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
new file mode 100644
index 0000000000..85a52918f0
--- /dev/null
+++ b/engines/fullpipe/motion.h
@@ -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.
+ *
+ */
+
+#ifndef FULLPIPE_MOTION_H
+#define FULLPIPE_MOTION_H
+
+namespace Fullpipe {
+
+int startWalkTo(int objId, int objKey, int x, int y, int a5);
+int doSomeAnimation(int objId, int objKey, int a3);
+int doSomeAnimation2(int objId, int objKey);
+
+class CMotionController : public CObject {
+ public:
+ int _field_4;
+ bool _isEnabled;
+
+ public:
+ CMotionController() : _isEnabled(true) {}
+ virtual bool load(MfcArchive &file);
+
+ void setEnabled() { _isEnabled = true; }
+ void clearEnabled() { _isEnabled = false; }
+
+ virtual void addObject(StaticANIObject *obj) {}
+ virtual void freeItems() {}
+};
+
+class CMctlCompoundArray : public Common::Array<CObject>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class CMctlConnectionPointsArray : public Common::Array<CObject>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class CMctlCompound : public CMotionController {
+ CMctlCompoundArray _motionControllers;
+
+ public:
+ virtual bool load(MfcArchive &file);
+
+ virtual void addObject(StaticANIObject *obj);
+ void initMovGraph2();
+
+ MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId);
+ MessageQueue *method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId);
+};
+
+class Unk2 : public CObject {
+ int _items;
+ int _count;
+
+ public:
+ Unk2() : _items(0), _count(0) {}
+};
+
+class CMovGraphNode : public CObject {
+ int _x;
+ int _y;
+ int _distance;
+ int16 _field_10;
+ int _field_14;
+
+ public:
+ CMovGraphNode() : _x(0), _y(0), _distance(0), _field_10(0), _field_14(0) {}
+ virtual bool load(MfcArchive &file);
+};
+
+class CMovGraphReact : public CObject {
+ // Empty
+};
+
+class CMctlCompoundArrayItem : public CObject {
+ friend class CMctlCompound;
+
+ protected:
+ CMotionController *_motionControllerObj;
+ CMovGraphReact *_movGraphReactObj;
+ CMctlConnectionPointsArray _connectionPoints;
+ int _field_20;
+ int _field_24;
+ int _field_28;
+
+ public:
+ CMctlCompoundArrayItem() : _movGraphReactObj(0) {}
+};
+
+class CReactParallel : public CMovGraphReact {
+ //CRgn _rgn;
+ int _x1;
+ int _y1;
+ int _x2;
+ int _y2;
+ int _dx;
+ int _dy;
+ Common::Point **_points;
+
+ public:
+ CReactParallel();
+ virtual bool load(MfcArchive &file);
+ void createRegion();
+};
+
+class CReactPolygonal : public CMovGraphReact {
+ //CRgn _rgn;
+ int _field_C;
+ int _field_10;
+ int _pointCount;
+ Common::Point **_points;
+
+ public:
+ CReactPolygonal();
+ virtual bool load(MfcArchive &file);
+ void createRegion();
+};
+
+class CMovGraphLink : public CObject {
+ CMovGraphNode *_movGraphNode1;
+ CMovGraphNode *_movGraphNode2;
+ CDWordArray _dwordArray1;
+ CDWordArray _dwordArray2;
+ int _flags;
+ int _field_38;
+ int _field_3C;
+ double _distance;
+ double _angle;
+ CMovGraphReact *_movGraphReact;
+ char *_name;
+
+ public:
+ CMovGraphLink();
+ virtual bool load(MfcArchive &file);
+};
+
+class CMovGraph : public CMotionController {
+ CObList _nodes;
+ CObList _links;
+ int _field_44;
+ int _items;
+ int _itemsCount;
+ int (*_callback1)(int, int, int);
+ Unk2 _unk2;
+
+ public:
+ CMovGraph();
+ virtual bool load(MfcArchive &file);
+
+ virtual void addObject(StaticANIObject *obj);
+};
+
+class CMctlConnectionPoint : public CObject {
+ int _connectionX;
+ int _connectionY;
+ int _field_C;
+ int _field_10;
+ int16 _field_14;
+ int16 _field_16;
+ int _messageQueueObj;
+ int _motionControllerObj;
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_MOTION_H */
diff --git a/engines/fullpipe/ngiarchive.cpp b/engines/fullpipe/ngiarchive.cpp
new file mode 100644
index 0000000000..5d895c17a0
--- /dev/null
+++ b/engines/fullpipe/ngiarchive.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+#include "common/archive.h"
+
+#include "common/file.h"
+#include "common/hash-str.h"
+#include "common/memstream.h"
+#include "common/bufferedstream.h"
+#include "common/textconsole.h"
+
+#include "fullpipe/ngiarchive.h"
+
+namespace Fullpipe {
+
+NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename) {
+ Common::File ngiFile;
+
+ if (!ngiFile.open(_ngiFilename)) {
+ warning("NGIArchive::NGIArchive(): Could not find the archive file");
+ return;
+ }
+
+ ngiFile.seek(4, SEEK_SET);
+
+ unsigned int count = ngiFile.readUint16LE(); // How many entries?
+
+ ngiFile.seek(20, SEEK_SET);
+
+ unsigned int key = ngiFile.readUint16LE();
+
+ byte key1, key2;
+
+ key1 = key & 0xff;
+ key2 = (key >> 8) & 0xff;
+
+ int fatSize = count * 32;
+
+ ngiFile.seek(32, SEEK_SET);
+
+ byte *fat = (byte *)calloc(fatSize, 1);
+
+ ngiFile.read(fat, fatSize);
+
+ for (int i = 0; i < fatSize; i++) {
+ key1 = (key1 << 1) ^ key2;
+ key2 = (key2 >> 1) ^ key1;
+
+ fat[i] ^= key1;
+ }
+
+ NgiHeader header;
+ NgiHeader *head;
+
+ for (uint i = 0; i < count; i++) {
+ memcpy(header.filename, &fat[i * 32], 12);
+ header.filename[12] = 0;
+ header.flags = READ_LE_UINT32(&fat[i * 32 + 16]);
+ header.extVal = READ_LE_UINT32(&fat[i * 32 + 20]);
+ header.pos = READ_LE_UINT32(&fat[i * 32 + 24]);
+ header.size = READ_LE_UINT32(&fat[i * 32 + 28]);
+
+ if (header.flags & 0x1e0) {
+ warning("File has flags: %.8x\n", header.flags & 0x1e0);
+ }
+
+ head = new NgiHeader(header);
+
+ _headers[header.filename] = head;
+ }
+
+ free(fat);
+
+ g_fullpipe->_currArchive = this;
+
+ debug(0, "NGIArchive::NGIArchive(%s): Located %d files", filename.c_str(), _headers.size());
+}
+
+NGIArchive::~NGIArchive() {
+ debug(0, "NGIArchive Destructor Called");
+ NgiHeadersMap::iterator it = _headers.begin();
+ for ( ; it != _headers.end(); ++it) {
+ delete it->_value;
+ }
+
+ g_fullpipe->_currArchive = 0;
+}
+
+bool NGIArchive::hasFile(const Common::String &name) const {
+ return _headers.contains(name);
+}
+
+ int NGIArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int matches = 0;
+
+ NgiHeadersMap::const_iterator it = _headers.begin();
+ for ( ; it != _headers.end(); ++it) {
+ list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_value->filename, this)));
+ matches++;
+ }
+
+ return matches;
+}
+
+const Common::ArchiveMemberPtr NGIArchive::getMember(const Common::String &name) const {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *NGIArchive::createReadStreamForMember(const Common::String &name) const {
+ if (!_headers.contains(name)) {
+ return 0;
+ }
+
+ NgiHeader *hdr = _headers[name];
+
+ Common::File archiveFile;
+ archiveFile.open(_ngiFilename);
+ archiveFile.seek(hdr->pos, SEEK_SET);
+
+ byte *data = (byte *)malloc(hdr->size);
+ assert(data);
+
+ int32 len = archiveFile.read(data, hdr->size);
+ assert(len == hdr->size);
+
+ return new Common::MemoryReadStream(data, hdr->size, DisposeAfterUse::YES);
+}
+
+Common::Archive *makeNGIArchive(const Common::String &name) {
+ return new NGIArchive(name);
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/ngiarchive.h b/engines/fullpipe/ngiarchive.h
new file mode 100644
index 0000000000..a5b05a2e50
--- /dev/null
+++ b/engines/fullpipe/ngiarchive.h
@@ -0,0 +1,69 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_NGIARCHIVE_H
+#define FULLPIPE_NGIARCHIVE_H
+
+#include "common/str.h"
+
+namespace Fullpipe {
+
+class Archive;
+
+#define NGI_FILENAME_MAX 13
+
+struct NgiHeader {
+ int32 pos;
+ int32 extVal;
+ int32 flags;
+ int32 size;
+ char filename[NGI_FILENAME_MAX];
+};
+
+typedef Common::HashMap<Common::String, NgiHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> NgiHeadersMap;
+
+class NGIArchive : public Common::Archive {
+ NgiHeadersMap _headers;
+ Common::String _ngiFilename;
+
+public:
+ NGIArchive(const Common::String &name);
+ virtual ~NGIArchive();
+
+ // Archive implementation
+ virtual bool hasFile(const Common::String &name) const;
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+ virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+};
+
+/**
+ * This factory method creates an Archive instance corresponding to the content
+ * of the NGI compressed file with the given name.
+ *
+ * May return 0 in case of a failure.
+ */
+Common::Archive *makeNGIArchive(const Common::String &name);
+
+} // End of namespace Fullpipe
+
+#endif
diff --git a/engines/fullpipe/objectnames.h b/engines/fullpipe/objectnames.h
new file mode 100644
index 0000000000..015df727e9
--- /dev/null
+++ b/engines/fullpipe/objectnames.h
@@ -0,0 +1,250 @@
+/* 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.
+ *
+ */
+
+// This file is used in order to avoid usage of constants in Russian accross the code
+
+#ifndef FULLPIPE_OBJECTNAMES_H
+#define FULLPIPE_OBJECTNAMES_H
+
+namespace Fullpipe {
+
+#define sO_Grandma "\xc1\xe0\xe1\xf3\xeb\xff" // "Бабуля"
+#define sO_Jar_4 "\xc1\xe0\xed\xea\xe0_4" // "Банка_4"
+#define sO_Pool "\xc1\xe0\xf1\xf1\xe5\xe9\xed" // "Бассейн"
+#define sO_TumyTrampie "\xc1\xe0\xf2\xf3\xf2\xe0" // "Батута"
+#define sO_WithoutBoot "\xc1\xe5\xe7 \xe1\xee\xf2\xe8\xed\xea\xe0" // "Без ботинка"
+#define sO_WithoutJug "\xc1\xe5\xe7 \xe3\xee\xf0\xf8\xea\xee\xe2" // "Без горшков"
+#define sO_WithoutCarpet "\xc1\xe5\xe7 \xea\xee\xe2\xf0\xe8\xea\xe0" // "Без коврика"
+#define sO_WithoutCoin "\xc1\xe5\xe7 \xec\xee\xed\xe5\xf2\xfb" // "Без монеты"
+#define sO_WithNothing "\xc1\xe5\xe7 \xed\xe8\xf7\xe5\xe3\xee" // "Без ничего"
+#define sO_WithoutHandle "\xc1\xe5\xe7 \xf0\xf3\xf7\xea\xe8" // "Без ручки"
+#define sO_WithoutStool "\xc1\xe5\xe7 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xe8" // "Без табуретки"
+#define sO_WithoutDrawer "\xc1\xe5\xe7 \xff\xf9\xe8\xea\xe0" // "Без ящика"
+#define sO_Blocked "\xc1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed" // "Блокирован"
+#define sO_BlockedShe "\xc1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed\xe0" // "Блокирована"
+#define sO_Awaken "\xc1\xee\xe4\xf0\xf1\xf2\xe2\xf3\xe5\xf2" // "Бодрствует"
+#define sO_Boot_15 "\xc1\xee\xf2\xe8\xed\xee\xea_15" // "Ботинок_15"
+#define sO_Bottle_38 "\xc1\xf3\xf2\xfb\xeb\xea\xe0_38" // "Бутылка_38"
+#define sO_InSmokeRoom "\xc2 \xea\xf3\xf0\xe8\xeb\xea\xe5" // "В курилке"
+#define sO_InSock "\xc2 \xed\xee\xf1\xea\xe5" // "В носке"
+#define sO_InGlasses "\xc2 \xee\xf7\xea\xe0\xf5" // "В очках"
+#define sO_In_14 "\xc2_14" // "В_14"
+#define sO_In_32_Lies "\xc2_32 \xeb\xe5\xe6\xe8\xf2" // "В_32 лежит"
+#define sO_In_32_Stands "\xc2_32 \xf2\xee\xf0\xf7\xe8\xf2" // "В_32 торчит"
+#define sO_In_33 "\xc2_33" // "В_33"
+#define sO_In_7 "\xc2_7" // "В_7"
+#define sO_Together "\xc2\xe4\xe2\xee\xe5\xec" // "Вдвоем"
+#define sO_Valve1_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x31_26" // "Вентиль1_26"
+#define sO_Valve2_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x32_26" // "Вентиль2_26"
+#define sO_Valve3_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x33_26" // "Вентиль3_26"
+#define sO_Valve4_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x34_26" // "Вентиль4_26"
+#define sO_Valve5_26 "\xc2\xe5\xed\xf2\xe8\xeb\xfc\x35_26" // "Вентиль5_26"
+#define sO_Valve_34 "\xc2\xe5\xed\xf2\xe8\xeb\xfc_34" // "Вентиль_34"
+#define sO_UpperHatch_23 "\xc2\xe5\xf0\xf5\xed\xe8\xe9 \xeb\xfe\xea_23" // "Верхний люк_23"
+#define sO_Taken "\xc2\xe7\xff\xf2" // "Взят"
+#define sO_HangsOnPipe "\xc2\xe8\xf1\xe8\xf2 \xed\xe0 \xf2\xf0\xf3\xe1\xe5" // "Висит на трубе"
+#define sO_On "\xc2\xea\xeb" // "Вкл"
+#define sO_TurnedOn "\xc2\xea\xeb\xfe\xf7\xe5\xed" // "Включен"
+#define sO_Driver "\xc2\xee\xe4\xe8\xeb\xe0" // "Водила"
+#define sO_HareTheNooksiter "\xc2\xf3\xe3\xeb\xf3\xf1\xe5\xe4" // "Вуглусед"
+#define sO_Off "\xc2\xfb\xea\xeb" // "Выкл"
+#define sO_TurnedOff "\xc2\xfb\xea\xeb\xfe\xf7\xe5\xed" // "Выключен"
+#define sO_HasGrown "\xc2\xfb\xf0\xee\xf1" // "Вырос"
+#define sO_Boss "\xc3\xeb\xe0\xe2\xe0\xf0\xfc" // "Главарь"
+#define sO_Jug "\xc3\xee\xf0\xf8\xee\xea" // "Горшок"
+#define sO_Strolling "\xc3\xf3\xeb\xff\xe5\xf2" // "Гуляет"
+#define sO_Yes "\xc4\xe0" // "Да"
+#define sO_Girl "\xc4\xe5\xe2\xee\xf7\xea\xe0" // "Девочка"
+#define sO_Elephantine "\xc4\xe5\xe2\xee\xf7\xea\xe0-\xf1\xeb\xee\xed\xe8\xea" // "Девочка-слоник"
+#define sO_Grandpa "\xc4\xe5\xe4\xf3\xf8\xea\xe0" // "Дедушка"
+#define sO_Plank_25 "\xc4\xee\xf1\xea\xe0_25" // "Доска_25"
+#define sO_Plank_34 "\xc4\xee\xf1\xea\xe0_34" // "Доска_34"
+#define sO_DudeJumped "\xc4\xff\xe4\xff \xef\xf0\xfb\xe3\xe0\xeb" // "Дядя прыгал"
+#define sO_Dude "\xc4\xff\xe4\xff" // "Дядя"
+#define sO_GuvTheDrawer "\xc4\xff\xe4\xff-\xff\xf9\xe8\xea" // "Дядя-ящик"
+#define sO_DudeSwinged "\xc4\xff\xe4\xff_\xea\xe0\xf2\xe0\xeb\xf1\xff" // "Дядя_катался"
+#define sO_Eats "\xc5\xf1\xf2" // "Ест"
+#define sO_Present "\xc5\xf1\xf2\xfc" // "Есть"
+#define sO_CloseThing1 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 1" // "Закрываемое 1"
+#define sO_CloseThing2 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 2" // "Закрываемое 2"
+#define sO_CloseThing3 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 3" // "Закрываемое 3"
+#define sO_CloseThing "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5" // "Закрываемое"
+#define sO_Closed "\xc7\xe0\xea\xf0\xfb\xf2" // "Закрыт"
+#define sO_ClosedWithBoot "\xc7\xe0\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Закрыта с ботинком"
+#define sO_ClosedShe "\xc7\xe0\xea\xf0\xfb\xf2\xe0" // "Закрыта"
+#define sO_HalfFull "\xc7\xe0\xef\xee\xeb\xed\xe5\xed \xed\xe0\xef\xee\xeb\xee\xe2\xe8\xed\xf3" // "Заполнен наполовину"
+#define sO_Full "\xc7\xe0\xef\xee\xeb\xed\xe5\xed \xf6\xe5\xeb\xe8\xea\xee\xec" // "Заполнен целиком"
+#define sO_MirroredTo "\xc7\xe5\xf0\xea\xe0\xeb\xfc\xed\xe0\xff \xea" // "Зеркальная к"
+#define sO_Playing "\xc8\xe3\xf0\xe0\xe5\xf2" // "Играет"
+#define sO_Tub "\xca\xe0\xe4\xea\xe0" // "Кадка"
+#define sO_Cactus "\xca\xe0\xea\xf2\xf3\xf1" // "Кактус"
+#define sO_SwingingWithBoot "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Катается с ботинком"
+#define sO_Swinging "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff" // "Катается"
+#define sO_Swingie "\xca\xe0\xf7\xe5\xeb\xe5\xed\xff" // "Качеленя"
+#define sO_LiftButtons "\xca\xed\xee\xef\xea\xe8 \xeb\xe8\xf4\xf2\xe0" // "Кнопки лифта"
+#define sO_Carpet_35 "\xca\xee\xe2\xf0\xe8\xea_35" // "Коврик_35"
+#define sO_Valve_35 "\xca\xf0\xe0\xed_35" // "Кран_35"
+#define sO_Cup "\xca\xf0\xf3\xe6\xea\xe0" // "Кружка"
+#define sO_Cube "\xca\xf3\xe1\xe8\xea" // "Кубик"
+#define sO_LeftPipe_15 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_15" // "Левая труба_15"
+#define sO_LeftPipe_26 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_26" // "Левая труба_26"
+#define sO_LeftPipe_29 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_29" // "Левая труба_29"
+#define sO_LeftPipe_30 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_30" // "Левая труба_30"
+#define sO_LeftPipe_37 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_37" // "Левая труба_37"
+#define sO_StarsDown_24 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xe2\xed\xe8\xe7_24" // "Лестница вниз_24"
+#define sO_StairsUp_8 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xf1\xe2\xe5\xf0\xf5\xf3_8" // "Лестница сверху_8"
+#define sO_Stairway "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0" // "Лестница"
+#define sO_Fliers "\xcb\xe5\xf2\xf3\xed\xfb" // "Летуны"
+#define sO_Hatch_26 "\xcb\xfe\xea_26" // "Люк_26"
+#define sO_Hatch_34 "\xcb\xfe\xea_34" // "Люк_34"
+#define sO_MommyOfHandle_32 "\xcc\xe0\xec\xe0 \xf0\xf3\xf7\xea\xe8_32" // "Мама ручки_32"
+#define sO_BigMumsy "\xcc\xe0\xec\xe0\xf8\xe0" // "Мамаша"
+#define sO_Bag_22 "\xcc\xe5\xf8\xee\xea_22" // "Мешок_22"
+#define sO_CoinSlot_1 "\xcc\xee\xed\xe5\xf2\xee\xef\xf0\xe8\xe5\xec\xed\xe8\xea 1" // "Монетоприемник 1"
+#define sO_CoinSlot_22 "\xcc\xee\xed\xe5\xf2\xee\xef\xf0\xe8\xe5\xec\xed\xe8\xea_22" // "Монетоприемник_22"
+#define sO_CoinSlot_35 "\xcc\xee\xed\xe5\xf2\xee\xef\xf0\xe8\xe5\xec\xed\xe8\xea_35" // "Монетоприемник_35"
+#define sO_Bridge "\xcc\xee\xf1\xf2" // "Мост"
+#define sO_Fly_12 "\xcc\xf3\xf5\xe0_12" // "Муха_12"
+#define sO_Fly_17 "\xcc\xf3\xf5\xe0_17" // "Муха_17"
+#define sO_OnTheFloor "\xcd\xe0 \xef\xee\xeb\xf3" // "На полу"
+#define sO_OnTheSpring "\xcd\xe0 \xef\xf0\xf3\xe6\xe8\xed\xe5" // "На пружине"
+#define sO_OnTheTable "\xcd\xe0 \xf1\xf2\xee\xeb\xe5" // "На столе"
+#define sO_OnStool "\xcd\xe0 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xe5" // "На табуретке"
+#define sO_Inflater "\xcd\xe0\xe4\xf3\xe2\xe0\xf2\xe5\xeb\xfc" // "Надуватель"
+#define sO_NotTaken "\xcd\xe5 \xe2\xe7\xff\xf2" // "Не взят"
+#define sO_NotHanging "\xcd\xe5 \xe2\xe8\xf1\xe8\xf2" // "Не висит"
+#define sO_NotGrown "\xcd\xe5 \xe2\xfb\xf0\xee\xf1" // "Не вырос"
+#define sO_DidNotCrackEgg "\xcd\xe5 \xea\xee\xeb\xee\xeb \xff\xe9\xf6\xee" // "Не колол яйцо"
+#define sO_NotFallen "\xcd\xe5 \xef\xe0\xe4\xe0\xeb" // "Не падал"
+#define sO_NotAvailable "\xcd\xe5\xe4\xee\xf1\xf2\xf3\xef\xed\xe0" // "Недоступна"
+#define sO_CannotTake "\xcd\xe5\xeb\xfc\xe7\xff \xe2\xe7\xff\xf2\xfc" // "Нельзя взять"
+#define sO_No "\xcd\xe5\xf2" // "Нет"
+#define sO_LowerHatch_23 "\xcd\xe8\xe6\xed\xe8\xe9 \xeb\xfe\xea_23" // "Нижний люк_23"
+#define sO_LowerPipe "\xcd\xe8\xe6\xed\xff\xff \xf2\xf0\xf3\xe1\xe0" // "Нижняя труба"
+#define sO_LowerPipe_21 "\xcd\xe8\xe6\xed\xff\xff \xf2\xf0\xf3\xe1\xe0_21" // "Нижняя труба_21"
+#define sO_WantsNothing "\xcd\xe8\xf7\xe5\xe3\xee \xed\xe5 \xf5\xee\xf7\xe5\xf2" // "Ничего не хочет"
+#define sO_Leg "\xcd\xee\xe3\xe0" // "Нога"
+#define sO_FriesPit "\xcd\xee\xf0\xea\xe0 \xea\xee\xe7\xff\xe2\xea\xe8" // "Норка козявки"
+#define sO_Sock_26 "\xcd\xee\xf1\xee\xea_26" // "Носок_26"
+#define sO_ClockAxis "\xce\xf1\xfc \xf7\xe0\xf1\xee\xe2" // "Ось часов"
+#define sO_Opened "\xce\xf2\xea\xf0\xfb\xf2" // "Открыт"
+#define sO_OpenedWithBoot "\xce\xf2\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Открыта с ботинком"
+#define sO_OpenedShe "\xce\xf2\xea\xf0\xfb\xf2\xe0" // "Открыта"
+#define sO_WeirdWacko "\xce\xf2\xec\xee\xf0\xee\xe6\xe5\xed\xed\xfb\xe9" // "Отмороженный"
+#define sO_NotPresent "\xce\xf2\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "Отсутствует"
+#define sO_Error "\xce\xf8\xe8\xe1\xea\xe0" // "Ошибка"
+#define sO_Passive "\xcf\xe0\xf1\xf1\xe8\xe2\xed\xe0" // "Пассивна"
+#define sO_First "\xcf\xe5\xf0\xe2\xfb\xe9" // "Первый"
+#define sO_UpsideDown "\xcf\xe5\xf0\xe5\xe2\xe5\xf0\xed\xf3\xf2\xe0" // "Перевернута"
+#define sO_Overfull "\xcf\xe5\xf0\xe5\xef\xee\xeb\xed\xe5\xed" // "Переполнен"
+#define sO_Fireman "\xcf\xee\xe6\xe0\xf0\xed\xe8\xea" // "Пожарник"
+#define sO_ShowingHeel "\xcf\xee\xea\xe0\xe7\xfb\xe2\xe0\xe5\xf2 \xef\xff\xf2\xea\xf3" // "Показывает пятку"
+#define sO_FullPipe "\xcf\xee\xeb\xed\xe0\xff \xd2\xf0\xf3\xe1\xe0" // "Полная Труба"
+#define sO_RightStairs_9 "\xcf\xf0\xe0\xe2\xe0\xff \xeb\xe5\xf1\xf2\xed\xe8\xf6\xe0_9" // "Правая лестница_9"
+#define sO_RightPipe_17 "\xcf\xf0\xe0\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_17" // "Правая труба_17"
+#define sO_Available "\xcf\xf0\xe8\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "Присутствует"
+#define sO_GulpedEgg "\xcf\xf0\xee\xe3\xeb\xee\xf7\xe5\xed\xed\xee\xe5 \xff\xe9\xf6\xee" // "Проглоченное яйцо"
+#define sO_GulpedEggs "\xcf\xf0\xee\xe3\xeb\xee\xf7\xe5\xed\xed\xfb\xe5 \xff\xe9\xf6\xe0" // "Проглоченные яйца"
+#define sO_BellyInflater "\xcf\xf3\xe7\xee\xe4\xf3\xe2" // "Пузодув"
+#define sO_Empty "\xcf\xf3\xf1\xf2" // "Пуст"
+#define sO_EmptyShe "\xcf\xf3\xf1\xf2\xe0\xff" // "Пустая"
+#define sO_WayToPipe "\xcf\xf3\xf2\xfc \xea \xf2\xf0\xf3\xe1\xe5" // "Путь к трубе"
+#define sO_Drinking "\xcf\xfc\xe5\xf2" // "Пьет"
+#define sO_BrokenInPieces "\xd0\xe0\xe7\xe1\xe8\xf2\xe0" // "Разбита"
+#define sO_Unblocked "\xd0\xe0\xe7\xe1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed" // "Разблокирован"
+#define sO_Unfolded "\xd0\xe0\xe7\xe2\xe5\xf0\xed\xf3\xf2" // "Развернут"
+#define sO_Jawcrucnher "\xd0\xee\xf2\xee\xf5\xf0\xf3\xf1" // "Ротохрус"
+#define sO_UsherHand "\xd0\xf3\xea\xe0 \xc1\xe8\xeb\xe5\xf2\xe5\xf0\xf8\xe8" // "Рука Билетерши"
+#define sO_LeverHandle_23 "\xd0\xf3\xea\xee\xff\xf2\xea\xe0 \xf0\xfb\xf7\xe0\xe3\xe0_23" // "Рукоятка рычага_23"
+#define sO_ClockHandle "\xd0\xf3\xf7\xea\xe0 \xee\xf2 \xf7\xe0\xf1\xee\xe2" // "Ручка от часов"
+#define sO_Lever_23 "\xd0\xfb\xf7\xe0\xe3_23" // "Рычаг_23"
+#define sO_WithDudeOnLeft "\xd1 \xc4\xff\xe4\xe5\xe9 \xf1\xeb\xe5\xe2\xe0" // "С Дядей слева"
+#define sO_WithDudeOnRight "\xd1 \xc4\xff\xe4\xe5\xe9 \xf1\xef\xf0\xe0\xe2\xe0" // "С Дядей справа"
+#define sO_WithBoot "\xd1 \xe1\xe0\xf8\xec\xe0\xea\xee\xec" // "С башмаком"
+#define sO_WithBig "\xd1 \xe1\xee\xeb\xfc\xf8\xe8\xec" // "С большим"
+#define sO_WithPlunger "\xd1 \xe2\xe0\xed\xf2\xf3\xe7\xee\xec" // "С вантузом"
+#define sO_WithJug "\xd1 \xe3\xee\xf0\xf8\xea\xee\xec" // "С горшком"
+#define sO_WithGum "\xd1 \xe6\xe2\xe0\xf7\xea\xee\xe9" // "С жвачкой"
+#define sO_WithShovel "\xd1 \xeb\xee\xef\xe0\xf2\xee\xe9" // "С лопатой"
+#define sO_WithTiny "\xd1 \xec\xe0\xeb\xfb\xec" // "С малым"
+#define sO_WithHammer "\xd1 \xec\xee\xeb\xee\xf2\xea\xee\xec" // "С молотком"
+#define sO_WithCoin "\xd1 \xec\xee\xed\xe5\xf2\xee\xe9" // "С монетой"
+#define sO_WithSock "\xd1 \xed\xee\xf1\xea\xee\xec" // "С носком"
+#define sO_WithCork "\xd1 \xef\xf0\xee\xe1\xea\xee\xe9" // "С пробкой"
+#define sO_WithSteering "\xd1 \xf0\xf3\xeb\xe5\xec" // "С рулем"
+#define sO_WithHandle "\xd1 \xf0\xf3\xf7\xea\xee\xe9" // "С ручкой"
+#define sO_WithApple "\xd1 \xff\xe1\xeb\xee\xea\xee\xec" // "С яблоком"
+#define sO_WithDrawer "\xd1 \xff\xf9\xe8\xea\xee\xec" // "С ящиком"
+#define sO_Sugar "\xd1\xe0\xf5\xe0\xf0\xee\xea" // "Сахарок"
+#define sO_Convoluted "\xd1\xe2\xe5\xf0\xed\xf3\xf2" // "Свернут"
+#define sO_IsFree "\xd1\xe2\xee\xe1\xee\xe4\xed\xe0" // "Свободна"
+#define sO_Sitting "\xd1\xe8\xe4\xe8\xf2" // "Сидит"
+#define sO_Laughing "\xd1\xec\xe5\xe5\xf2\xf1\xff" // "Смеется"
+#define sO_WithEveryone "\xd1\xee \xe2\xf1\xe5\xec\xe8" // "Со всеми"
+#define sO_WithMop "\xd1\xee \xf8\xe2\xe0\xe1\xf0\xee\xe9" // "Со шваброй"
+#define sO_WithHose "\xd1\xee \xf8\xeb\xe0\xed\xe3\xee\xec" // "Со шлангом"
+#define sO_WithBrush "\xd1\xee \xf9\xe5\xf2\xea\xee\xe9" // "Со щеткой"
+#define sO_Sleeping "\xd1\xef\xe8\xf2" // "Спит"
+#define sO_OnRight "\xd1\xef\xf0\xe0\xe2\xe0" // "Справа"
+#define sO_StandsInBoots "\xd1\xf2\xee\xe8\xf2 \xe2 \xe1\xee\xf2\xe8\xed\xea\xe0\xf5" // "Стоит в ботинках"
+#define sO_StandsInCorner "\xd1\xf2\xee\xe8\xf2 \xe2 \xf3\xe3\xeb\xf3" // "Стоит в углу"
+#define sO_Guardian "\xd1\xf2\xee\xf0\xee\xe6" // "Сторож"
+#define sO_Guard_1 "\xd1\xf2\xf0\xe0\xe6 1" // "Страж 1"
+#define sO_Gurad_2 "\xd1\xf2\xf0\xe0\xe6 2" // "Страж 2"
+#define sO_Guard_3 "\xd1\xf2\xf0\xe0\xe6 3" // "Страж 3"
+#define sO_Stool_34 "\xd2\xe0\xe1\xf3\xf0\xe5\xf2_34" // "Табурет_34"
+#define sO_Pipe_9 "\xd2\xf0\xf3\xe1\xe0_9" // "Труба_9"
+#define sO_Pedestal_16 "\xd2\xf3\xec\xe1\xe0_16" // "Тумба_16"
+#define sO_Pedestal_17 "\xd2\xf3\xec\xe1\xe0_17" // "Тумба_17"
+#define sO_Pedestal_33 "\xd2\xf3\xec\xe1\xe0_33" // "Тумба_33"
+#define sO_NearDudesStairs "\xd3 \xc4\xff\xe4\xe8 \xed\xe0 \xeb\xe5\xf1\xf2\xed\xe8\xf6\xe5" // "У Дяди на лестнице"
+#define sO_NearDude "\xd3 \xc4\xff\xe4\xe8" // "У Дяди"
+#define sO_NearPipeWithStool "\xd3 \xf2\xf0\xf3\xe1\xfb \xf1 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xee\xe9" // "У трубы с табуреткой"
+#define sO_NearPipe "\xd3 \xf2\xf0\xf3\xe1\xfb" // "У трубы"
+#define sO_Janitors "\xd3\xe1\xee\xf0\xf9\xe8\xea\xe8" // "Уборщики"
+#define sO_Janitress "\xd3\xe1\xee\xf0\xf9\xe8\xf6\xe0" // "Уборщица"
+#define sO_Gone "\xd3\xe5\xf5\xe0\xeb\xe0" // "Уехала"
+#define sO_FallenOnce "\xd3\xef\xe0\xeb \xf0\xe0\xe7" // "Упал раз"
+#define sO_FallenBrush "\xd3\xef\xe0\xeb\xe0 \xf9\xe5\xf2\xea\xe0" // "Упала щетка"
+#define sO_NotBroken "\xd6\xe5\xeb\xe0" // "Цела"
+#define sO_ScratchingBelly "\xd7\xe5\xf8\xe5\xf2 \xef\xf3\xe7\xee" // "Чешет пузо"
+#define sO_Level0 "\xdd\xf2\xe0\xe6 0" // "Этаж 0"
+#define sO_Level1 "\xdd\xf2\xe0\xe6 1" // "Этаж 1"
+#define sO_Level2 "\xdd\xf2\xe0\xe6 2" // "Этаж 2"
+#define sO_Level3 "\xdd\xf2\xe0\xe6 3" // "Этаж 3"
+#define sO_Level4 "\xdd\xf2\xe0\xe6 4" // "Этаж 4"
+#define sO_Level5 "\xdd\xf2\xe0\xe6 5" // "Этаж 5"
+#define sO_Level6 "\xdd\xf2\xe0\xe6 6" // "Этаж 6"
+#define sO_Level7 "\xdd\xf2\xe0\xe6 7" // "Этаж 7"
+#define sO_Level8 "\xdd\xf2\xe0\xe6 8" // "Этаж 8"
+#define sO_Level9 "\xdd\xf2\xe0\xe6 9" // "Этаж 9"
+#define sO_EggGulperGaveCoin "\xdf\xe9\xf6\xe5\xe3\xeb\xee\xf2 \xee\xf2\xe4\xe0\xeb \xec\xee\xed\xe5\xf2\xf3" // "Яйцеглот отдал монету"
+#define sO_EggGulper "\xdf\xe9\xf6\xe5\xe3\xeb\xee\xf2" // "Яйцеглот"
+#define sO_EggCracker "\xdf\xe9\xf6\xe5\xea\xee\xeb" // "Яйцекол"
+#define sO_NotCarryingEgg "\xdf\xe9\xf6\xee \xed\xe5 \xed\xe5\xf1\xe5\xf2" // "Яйцо не несет"
+#define sO_Egg1 "\xdf\xe9\xf6\xee\x31" // "Яйцо1"
+#define sO_Egg2 "\xdf\xe9\xf6\xee\x32" // "Яйцо2"
+#define sO_Egg3 "\xdf\xe9\xf6\xee\x33" // "Яйцо3"
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_OBJECTNAMES_H */
diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h
new file mode 100644
index 0000000000..9e7c7531a7
--- /dev/null
+++ b/engines/fullpipe/objects.h
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_OBJECTS_H
+#define FULLPIPE_OBJECTS_H
+
+#include "fullpipe/utils.h"
+
+namespace Fullpipe {
+
+class MessageQueue;
+class SceneTagList;
+
+class GameProject : public CObject {
+ public:
+ int _field_4;
+ char *_headerFilename;
+ SceneTagList *_sceneTagList;
+ int _field_10;
+
+ public:
+ GameProject();
+ ~GameProject();
+ virtual bool load(MfcArchive &file);
+};
+
+struct PicAniInfo {
+ int32 type;
+ int16 objectId;
+ int16 field_6;
+ int32 field_8;
+ int16 sceneId;
+ int16 field_E;
+ int32 ox;
+ int32 oy;
+ int32 priority;
+ int16 staticsId;
+ int16 movementId;
+ int16 dynamicPhaseIndex;
+ int16 flags;
+ int32 field_24;
+ int32 someDynamicPhaseIndex;
+
+ bool load(MfcArchive &file);
+};
+
+union VarValue {
+ float floatValue;
+ int32 intValue;
+ char *stringValue;
+};
+
+class CGameVar : public CObject {
+ public:
+ CGameVar *_nextVarObj;
+ CGameVar *_prevVarObj;
+ CGameVar *_parentVarObj;
+ CGameVar *_subVars;
+ CGameVar *_field_14;
+ char *_varName;
+ VarValue _value;
+ int _varType;
+
+ public:
+ CGameVar();
+ virtual bool load(MfcArchive &file);
+ CGameVar *getSubVarByName(const char *name);
+ bool setSubVarAsInt(const char *name, int value);
+ int getSubVarAsInt(const char *name);
+ CGameVar *addSubVarAsInt(const char *name, int value);
+ bool addSubVar(CGameVar *subvar);
+ int getSubVarsCount();
+ CGameVar *getSubVarByIndex(int idx);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_OBJECTS_H */
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
new file mode 100644
index 0000000000..6ac062fb37
--- /dev/null
+++ b/engines/fullpipe/scene.cpp
@@ -0,0 +1,690 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/ngiarchive.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/gameloader.h"
+
+#include "fullpipe/constants.h"
+
+#include "common/algorithm.h"
+
+namespace Fullpipe {
+
+Scene *FullpipeEngine::accessScene(int sceneId) {
+ SceneTag *t = 0;
+
+ for (SceneTagList::iterator s = _gameProject->_sceneTagList->begin(); s != _gameProject->_sceneTagList->end(); ++s) {
+ if (s->_sceneId == sceneId) {
+ t = &(*s);
+ break;
+ }
+ }
+
+ if (!t)
+ return 0;
+
+ if (!t->_scene) {
+ t->loadScene();
+ }
+
+ return t->_scene;
+}
+
+bool SceneTagList::load(MfcArchive &file) {
+ debug(5, "SceneTagList::load()");
+
+ int numEntries = file.readUint16LE();
+
+ for (int i = 0; i < numEntries; i++) {
+ SceneTag *t = new SceneTag();
+ t->load(file);
+ push_back(*t);
+ }
+
+ return true;
+}
+
+SceneTag::SceneTag() {
+ _field_4 = 0;
+ _scene = 0;
+ _tag = 0;
+}
+
+bool SceneTag::load(MfcArchive &file) {
+ debug(5, "SceneTag::load()");
+
+ _field_4 = 0;
+ _scene = 0;
+
+ _sceneId = file.readUint16LE();
+
+ _tag = file.readPascalString();
+
+ debug(6, "sceneId: %d tag: %s", _sceneId, _tag);
+
+ return true;
+}
+
+SceneTag::~SceneTag() {
+ free(_tag);
+}
+
+void SceneTag::loadScene() {
+ char *archname = genFileName(0, _sceneId, "nl");
+
+ Common::Archive *arch = makeNGIArchive(archname);
+
+ char *fname = genFileName(0, _sceneId, "sc");
+
+ Common::SeekableReadStream *file = arch->createReadStreamForMember(fname);
+
+ _scene = new Scene();
+
+ MfcArchive archive(file);
+
+ _scene->load(archive);
+
+ if (_scene->_shadows)
+ _scene->_shadows->init();
+
+ delete file;
+
+ g_fullpipe->_currArchive = 0;
+
+ free(fname);
+ free(archname);
+}
+
+Scene::Scene() {
+ _sceneId = 0;
+ _field_BC = 0;
+ _shadows = 0;
+ _soundList = 0;
+ _libHandle = 0;
+ _sceneName = 0;
+}
+
+bool Scene::load(MfcArchive &file) {
+ debug(5, "Scene::load()");
+
+ Background::load(file);
+
+ _sceneId = file.readUint16LE();
+
+ _sceneName = file.readPascalString();
+ debug(0, "scene: <%s> %d", transCyrillic((byte *)_sceneName), _sceneId);
+
+ int count = file.readUint16LE();
+ debug(7, "scene.ani: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ int aniNum = file.readUint16LE();
+ char *aniname = genFileName(0, aniNum, "ani");
+
+ Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(aniname);
+
+ StaticANIObject *ani = new StaticANIObject();
+
+ MfcArchive archive(f);
+
+ ani->load(archive);
+ ani->_sceneId = _sceneId;
+
+ _staticANIObjectList1.push_back(ani);
+
+ delete f;
+ free(aniname);
+ }
+
+ count = file.readUint16LE();
+ debug(7, "scene.mq: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ int qNum = file.readUint16LE();
+ char *qname = genFileName(0, qNum, "qu");
+
+ Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(qname);
+ MfcArchive archive(f);
+
+ archive.readUint16LE(); // Skip 2 bytes
+
+ MessageQueue *mq = new MessageQueue();
+
+ mq->load(archive);
+
+ _messageQueueList.push_back(mq);
+
+ delete f;
+ free(qname);
+ }
+
+ count = file.readUint16LE();
+ debug(7, "scene.fa: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ // There are no .FA files
+ assert(0);
+ }
+
+ _libHandle = g_fullpipe->_currArchive;
+
+ if (_picObjList.size() > 0 && _bgname && strlen(_bgname) > 1) {
+ char fname[260];
+
+ strcpy(fname, _bgname);
+ strcpy(strrchr(fname, '.') + 1, "col");
+
+ MemoryObject *col = new MemoryObject();
+ col->loadFile(fname);
+
+ _palette = col;
+ }
+
+ char *shdname = genFileName(0, _sceneId, "shd");
+
+ Shadows *shd = new Shadows();
+
+ if (shd->loadFile(shdname))
+ _shadows = shd;
+
+ free(shdname);
+
+ char *slsname = genFileName(0, _sceneId, "sls");
+
+ if (g_fullpipe->_soundEnabled) {
+ _soundList = new SoundList();
+
+ if (g_fullpipe->_flgSoundList) {
+ char *nlname = genFileName(17, _sceneId, "nl");
+
+ _soundList->loadFile(slsname, nlname);
+
+ free(nlname);
+ } else {
+ _soundList->loadFile(slsname, 0);
+ }
+ }
+
+ free(slsname);
+
+ initStaticANIObjects();
+
+ if (file.size() - file.pos() > 0)
+ error("Scene::load (%d bytes left)", file.size() - file.pos());
+
+ return true;
+}
+
+void Scene::initStaticANIObjects() {
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ ((StaticANIObject *)_staticANIObjectList1[i])->initMovements();
+}
+
+void Scene::init() {
+ _x = 0;
+ _y = 0;
+
+ g_fullpipe->_sceneRect.moveTo(0, 0);
+
+ for (uint i = 0; i < _picObjList.size(); i++)
+ ((PictureObject *)_picObjList[i])->clearFlags();
+
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ ((StaticANIObject *)_staticANIObjectList1[i])->clearFlags();
+
+ if (_staticANIObjectList2.size() != _staticANIObjectList1.size()) {
+ _staticANIObjectList2.clear();
+
+ for (CPtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s)
+ _staticANIObjectList2.push_back(*s);
+ }
+}
+
+StaticANIObject *Scene::getAniMan() {
+ StaticANIObject *aniMan = getStaticANIObject1ById(ANI_MAN, -1);
+
+ deleteStaticANIObject(aniMan);
+
+ return aniMan;
+}
+
+StaticANIObject *Scene::getStaticANIObject1ById(int obj, int a3) {
+ for (CPtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s) {
+ StaticANIObject *o = (StaticANIObject *)*s;
+ if (o->_id == obj && (a3 == -1 || o->_okeyCode == a3))
+ return o;
+ }
+
+ return 0;
+}
+
+StaticANIObject *Scene::getStaticANIObject1ByName(char *name, int a3) {
+ for (uint n = 0; n < _staticANIObjectList1.size(); n++) {
+ StaticANIObject *o = (StaticANIObject *)_staticANIObjectList1[n];
+ if (!strcmp(o->_objectName, name) && (a3 == -1 || o->_okeyCode == a3))
+ return o;
+ }
+
+ return 0;
+}
+
+void Scene::deleteStaticANIObject(StaticANIObject *obj) {
+ for (uint n = 0; n < _staticANIObjectList1.size(); n++)
+ if ((StaticANIObject *)_staticANIObjectList1[n] == obj) {
+ _staticANIObjectList1.remove_at(n);
+ break;
+ }
+
+ for (uint n = 0; n < _staticANIObjectList2.size(); n++)
+ if ((StaticANIObject *)_staticANIObjectList2[n] == obj) {
+ _staticANIObjectList2.remove_at(n);
+ break;
+ }
+}
+
+void Scene::addStaticANIObject(StaticANIObject *obj, bool addList2) {
+ if (obj->_okeyCode)
+ obj->renumPictures(&_staticANIObjectList1);
+
+ _staticANIObjectList1.push_back(obj);
+
+ if (addList2) {
+ if (!obj->_okeyCode)
+ obj->clearFlags();
+
+ _staticANIObjectList2.push_back(obj);
+ }
+}
+
+void Scene::setPictureObjectsFlag4() {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ ((PictureObject *)_picObjList[i])->_flags |= 4;
+ }
+}
+
+PictureObject *Scene::getPictureObjectById(int objId, int flags) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i])->_id == objId && ((PictureObject *)_picObjList[i])->_okeyCode == flags)
+ return (PictureObject *)_picObjList[i];
+ }
+
+ return 0;
+}
+
+PictureObject *Scene::getPictureObjectByName(const char *objName, int flags) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (!strcmp(((PictureObject *)_picObjList[i])->_objectName, objName) && (((PictureObject *)_picObjList[i])->_okeyCode == flags || flags == -1))
+ return (PictureObject *)_picObjList[i];
+ }
+
+ return 0;
+}
+
+void Scene::deletePictureObject(PictureObject *obj) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i]) == obj) {
+ _picObjList.remove_at(i);
+ delete obj;
+
+ return;
+ }
+ }
+}
+
+MessageQueue *Scene::getMessageQueueById(int messageId) {
+ for (uint i = 0; i < _messageQueueList.size(); i++)
+ if (((MessageQueue *)_messageQueueList[i])->_dataId == messageId)
+ return (MessageQueue *)_messageQueueList[i];
+
+ return 0;
+}
+
+MessageQueue *Scene::getMessageQueueByName(char *name) {
+ for (uint i = 0; i < _messageQueueList.size(); i++)
+ if (!strcmp(((MessageQueue *)_messageQueueList[i])->_queueName, name))
+ return (MessageQueue *)_messageQueueList[i];
+
+ return 0;
+}
+
+void Scene::preloadMovements(CGameVar *var) {
+ CGameVar *preload = var->getSubVarByName("PRELOAD");
+ if (!preload)
+ return;
+
+ for (CGameVar *i = preload->_subVars; i; i = i->_nextVarObj) {
+ StaticANIObject *ani = getStaticANIObject1ByName(i->_varName, -1);
+
+ if (ani) {
+ CGameVar *subVars = i->_subVars;
+
+ if (subVars) {
+ for (;subVars; subVars = subVars->_nextVarObj) {
+ Movement *mov = ani->getMovementByName(subVars->_varName);
+
+ if (mov)
+ mov->loadPixelData();
+ }
+ } else {
+ ani->loadMovementsPixelData();
+ }
+ }
+ }
+}
+
+void Scene::initObjectCursors(const char *varname) {
+ CGameVar *cursorsVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(varname)->getSubVarByName("CURSORS");
+
+ if (!cursorsVar || !cursorsVar->_subVars)
+ return;
+
+ int maxId = 0;
+ int minId = 0xffff;
+
+ for (CGameVar *sub = cursorsVar->_subVars; sub; sub = sub->_nextVarObj) {
+ GameObject *obj = getPictureObjectByName(sub->_varName, -1);
+
+ if (obj || (obj = getStaticANIObject1ByName(sub->_varName, -1)) != 0) {
+ if (obj->_id < minId)
+ minId = obj->_id;
+ if (obj->_id > maxId)
+ maxId = obj->_id;
+ }
+ }
+
+ g_fullpipe->_minCursorId = minId;
+ g_fullpipe->_maxCursorId = maxId;
+
+ g_fullpipe->_objectIdCursors.resize(maxId - minId + 1);
+
+ for (CGameVar *sub = cursorsVar->_subVars; sub; sub = sub->_nextVarObj) {
+ GameObject *obj = getPictureObjectByName(sub->_varName, -1);
+
+ if (!obj)
+ obj = getStaticANIObject1ByName(sub->_varName, -1);
+
+ PictureObject *pic = getGameLoaderInventory()->getScene()->getPictureObjectByName(sub->_value.stringValue, -1);
+
+ if (obj && pic)
+ g_fullpipe->_objectIdCursors[obj->_id - minId] = pic->_id;
+ }
+}
+
+bool Scene::compareObjPriority(const void *p1, const void *p2) {
+ if (((const StaticANIObject *)p1)->_priority > ((const StaticANIObject *)p2)->_priority)
+ return true;
+
+ return false;
+}
+
+void Scene::objectList_sortByPriority(CPtrList &list) {
+ Common::sort(list.begin(), list.end(), Scene::compareObjPriority);
+}
+
+void Scene::draw() {
+ debug(0, ">>>>> Scene::draw()");
+ updateScrolling();
+
+ drawContent(60000, 0, true);
+
+ objectList_sortByPriority(_staticANIObjectList2);
+
+ for (CPtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) {
+ ((StaticANIObject *)*s)->draw2();
+ }
+
+ int priority = -1;
+ for (CPtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) {
+ drawContent(((StaticANIObject *)*s)->_priority, priority, false);
+ ((StaticANIObject *)*s)->draw();
+
+ priority = ((StaticANIObject *)*s)->_priority;
+ }
+
+ drawContent(-1, priority, false);
+}
+
+void Scene::updateScrolling() {
+ debug(0, "STUB Scene::updateScrolling()");
+}
+
+void Scene::updateScrolling2() {
+ warning("STUB Scene::updateScrolling2()");
+}
+
+StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) {
+ StaticANIObject *res = 0;
+
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++) {
+ StaticANIObject *p = (StaticANIObject *)_staticANIObjectList1[i];
+ int pixel;
+
+ if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
+ p->getPixelAtPos(x, y, &pixel) &&
+ (!res || res->_priority >= p->_priority))
+ res = p;
+ }
+
+ return res;
+}
+
+PictureObject *Scene::getPictureObjectAtPos(int x, int y) {
+ PictureObject *res = 0;
+
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ PictureObject *p = (PictureObject *)_picObjList[i];
+ if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
+ p->isPixelHitAtPos(x, y) &&
+ (!res || res->_priority >= p->_priority))
+ res = p;
+ }
+
+ return res;
+}
+
+int Scene::getPictureObjectIdAtPos(int x, int y) {
+ PictureObject *resp = 0;
+ int res = 0;
+
+ for (uint i = 0; i < _picObjList.size(); i++) {
+ PictureObject *p = (PictureObject *)_picObjList[i];
+ if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
+ p->isPixelHitAtPos(x, y) &&
+ (!res || resp->_priority >= p->_priority)) {
+ resp = p;
+ res = p->_id;
+ }
+ }
+
+ return res;
+}
+
+void Scene::update(int counterdiff) {
+ debug(0, "Scene::update(%d)", counterdiff);
+
+ for (CPtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s)
+ ((StaticANIObject *)*s)->update(counterdiff);
+}
+
+void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
+ if (!_picObjList.size() && !_bigPictureArray1Count)
+ return;
+
+ if (_palette) {
+ g_fullpipe->_globalPalette = _palette->_data;
+ }
+
+ debug(8, "Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
+
+ if (_picObjList.size() > 2) { // We need to z-sort them
+ objectList_sortByPriority(_picObjList);
+ }
+
+ if (minPri == -1 && _picObjList.size())
+ minPri = ((PictureObject *)_picObjList.back())->_priority - 1;
+
+ if (maxPri == -1)
+ maxPri = 60000;
+
+ debug(8, "-> Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
+
+ Common::Point point;
+
+ debug(8, "_bigPict: %d objlist: %d", _bigPictureArray1Count, _picObjList.size());
+ if (drawBg && _bigPictureArray1Count && _picObjList.size()) {
+
+ _bigPictureArray[0][0]->getDimensions(&point);
+
+ int width = point.x;
+ int height = point.y;
+
+ debug(8, "w: %d h:%d", width, height);
+
+ ((PictureObject *)_picObjList[0])->getDimensions(&point);
+
+ debug(8, "w2: %d h2:%d", point.x, point.y);
+
+ int bgStX = g_fullpipe->_sceneRect.left % point.x;
+
+ if (bgStX < 0)
+ bgStX += point.x;
+
+ int bgNumX = bgStX / width;
+ int bgOffsetX = bgStX % width;
+
+ int bgStY = g_fullpipe->_sceneRect.top % point.y;
+
+ if (bgStY < 0)
+ bgStY += point.y;
+
+ int bgNumY = bgStY / height;
+ int bgOffsetY = bgStY % height;
+
+ int bgPosX = g_fullpipe->_sceneRect.left - bgOffsetX;
+
+ if (bgPosX < g_fullpipe->_sceneRect.right - 1) {
+ while (1) {
+ int v25 = bgNumY;
+ for (int y = g_fullpipe->_sceneRect.top - bgOffsetY; y < g_fullpipe->_sceneRect.bottom - 1;) {
+ BigPicture *v27 = _bigPictureArray[bgNumX][v25];
+ v27->draw(bgPosX, y, 0, 0);
+ y += v27->getDimensions(&point)->y;
+ v25++;
+
+ if (v25 >= _bigPictureArray2Count) {
+ if (!(((PictureObject *)_picObjList[0])->_flags & 0x20))
+ break;
+ v25 = 0;
+ }
+ }
+ _bigPictureArray[bgNumX][0]->getDimensions(&point);
+ int v32 = point.x + bgPosX;
+ bgPosX += point.x;
+ bgNumX++;
+
+ if (bgNumX >= _bigPictureArray1Count) {
+ if (!(((PictureObject *)_picObjList[0])->_flags & 0x2))
+ break;
+ bgNumX = 0;
+ }
+ if (v32 >= g_fullpipe->_sceneRect.right - 1)
+ break;
+ }
+ }
+ }
+
+
+ for (uint i = 1; i < _picObjList.size(); i++) {
+ PictureObject *obj = (PictureObject *)_picObjList[i];
+
+ debug(8, "pri: %d", obj->_priority);
+ if (obj->_priority < minPri || obj->_priority >= maxPri)
+ continue;
+
+ int objX = obj->_ox;
+ int objY = obj->_oy;
+
+ debug(8, "obj: %d %d", objX, objY);
+
+ obj->getDimensions(&point);
+
+ int width = point.x;
+ int height = point.y;
+
+ if (obj->_flags & 8) {
+ while (objX > g_fullpipe->_sceneRect.right) {
+ objX -= width;
+ obj->setOXY(objX, objY);
+ }
+ for (int j = width + objX; width + objX < g_fullpipe->_sceneRect.left; j = width + objX) {
+ objX = j;
+ obj->setOXY(j, objY);
+ }
+ }
+
+ if (obj->_flags & 0x10) {
+ while (objY > g_fullpipe->_sceneRect.bottom) {
+ objY -= height;
+ obj->setOXY(objX, objY);
+ }
+ for (int j = objY + height; objY + height < g_fullpipe->_sceneRect.top; j = objY + height) {
+ objY = j;
+ obj->setOXY(objX, j);
+ }
+ }
+ if (obj->_flags & 4)
+ obj->draw();
+
+ if (obj->_flags & 2) {
+ if (objX > g_fullpipe->_sceneRect.left) {
+ obj->setOXY(objX - width, objY);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ if (width + objX < g_fullpipe->_sceneRect.right) {
+ obj->setOXY(width + objX, objY);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ }
+
+ if (obj->_flags & 0x20) {
+ if (objY > g_fullpipe->_sceneRect.top) {
+ obj->setOXY(objX, objY - height);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ if (height + objY < g_fullpipe->_sceneRect.bottom) {
+ obj->setOXY(objX, height + objY);
+ obj->draw();
+ obj->setOXY(objX, objY);
+ }
+ }
+ }
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
new file mode 100644
index 0000000000..c1c8d47ba8
--- /dev/null
+++ b/engines/fullpipe/scene.h
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_SCENE_H
+#define FULLPIPE_SCENE_H
+
+#include "fullpipe/gfx.h"
+
+namespace Fullpipe {
+
+class MessageQueue;
+
+class Scene : public Background {
+ public:
+ CPtrList _staticANIObjectList1;
+ CPtrList _staticANIObjectList2;
+ CPtrList _messageQueueList;
+ CPtrList _faObjectList;
+ Shadows *_shadows;
+ SoundList *_soundList;
+ int16 _sceneId;
+ char *_sceneName;
+ int _field_BC;
+ NGIArchive *_libHandle;
+
+ public:
+ Scene();
+
+ virtual bool load(MfcArchive &file);
+
+ void initStaticANIObjects();
+ void init();
+ void draw();
+ void drawContent(int minPri, int maxPri, bool drawBG);
+ void updateScrolling();
+ void updateScrolling2();
+
+ void update(int counterdiff);
+
+ StaticANIObject *getAniMan();
+ StaticANIObject *getStaticANIObject1ById(int obj, int a3);
+ StaticANIObject *getStaticANIObject1ByName(char *name, int a3);
+ MessageQueue *getMessageQueueById(int messageId);
+ MessageQueue *getMessageQueueByName(char *name);
+
+ void deleteStaticANIObject(StaticANIObject *obj);
+ void addStaticANIObject(StaticANIObject *obj, bool addList2);
+
+ void setPictureObjectsFlag4();
+ PictureObject *getPictureObjectById(int objId, int flags);
+ PictureObject *getPictureObjectByName(const char *name, int keyCode);
+ void deletePictureObject(PictureObject *obj);
+ void preloadMovements(CGameVar *var);
+
+ StaticANIObject *getStaticANIObjectAtPos(int x, int y);
+ PictureObject *getPictureObjectAtPos(int x, int y);
+ int getPictureObjectIdAtPos(int x, int y);
+
+ void initObjectCursors(const char *name);
+
+ private:
+ static bool compareObjPriority(const void *p1, const void *p2);
+ void objectList_sortByPriority(CPtrList &list);
+};
+
+class SceneTag : public CObject {
+ public:
+ int _field_4;
+ char *_tag;
+ Scene *_scene;
+ int16 _sceneId;
+ int16 _field_12;
+
+ public:
+ SceneTag();
+ ~SceneTag();
+
+ virtual bool load(MfcArchive &file);
+ void loadScene();
+};
+
+class SceneTagList : public Common::List<SceneTag>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_SCENE_H */
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
new file mode 100644
index 0000000000..37be7facc9
--- /dev/null
+++ b/engines/fullpipe/scenes.cpp
@@ -0,0 +1,1508 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/utils.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/objects.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/sound.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/input.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/behavior.h"
+
+#include "fullpipe/constants.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+int defaultUpdateCursor();
+void setElevatorButton(const char *name, int state);
+
+int sceneIntro_updateCursor();
+void sceneIntro_initScene(Scene *sc);
+int sceneHandlerIntro(ExCommand *cmd);
+
+void scene01_fixEntrance();
+void scene01_initScene(Scene *sc, int entrance);
+int sceneHandler01(ExCommand *cmd);
+
+void sceneDbgMenu_initScene(Scene *sc);
+int sceneHandlerDbgMenu(ExCommand *cmd);
+
+Vars::Vars() {
+ sceneIntro_aniin1man = 0;
+ sceneIntro_needSleep = true;
+ sceneIntro_needGetup = false;
+ sceneIntro_skipIntro = true;
+ sceneIntro_playing = false;
+ sceneIntro_needBlackout = false;
+
+ swallowedEgg1 = 0;
+ swallowedEgg2 = 0;
+ swallowedEgg3 = 0;
+
+ scene01_picSc01Osk = 0;
+ scene01_picSc01Osk2 = 0;
+}
+
+bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
+ CGameVar *sceneVar;
+ Common::Point sceneDim;
+
+ Scene *scene = accessScene(entrance->_sceneId);
+
+ if (!scene)
+ return 0;
+
+ ((PictureObject *)scene->_picObjList.front())->getDimensions(&sceneDim);
+ _sceneWidth = sceneDim.x;
+ _sceneHeight = sceneDim.y;
+
+ _sceneRect.top = 0;
+ _sceneRect.left = 0;
+ _sceneRect.right = 799;
+ _sceneRect.bottom = 599;
+
+ scene->_x = 0;
+ scene->_y = 0;
+
+ _aniMan->setOXY(0, 0);
+ _aniMan->clearFlags();
+ _aniMan->_callback1 = 0;
+ _aniMan->_callback2 = 0;
+ _aniMan->_shadowsOn = 1;
+
+ _scrollSpeed = 8;
+
+ _isSaveAllowed = true;
+ _updateFlag = true;
+ _flgCanOpenMap = true;
+
+ if (entrance->_sceneId == SC_DBGMENU) {
+ _inventoryScene = 0;
+ } else {
+ _gameLoader->loadScene(SC_INV);
+ getGameLoaderInventory()->rebuildItemRects();
+ _inventoryScene = getGameLoaderInventory()->getScene();
+ }
+ if (_soundEnabled) {
+ if (scene->_soundList) {
+ _currSoundListCount = 2;
+ _currSoundList1[0] = accessScene(SC_COMMON)->_soundList;
+ _currSoundList1[1] = scene->_soundList;
+
+ for (int i = 0; i < scene->_soundList->getCount(); i++) {
+ scene->_soundList->getSoundByIndex(i)->updateVolume();
+ }
+ } else {
+ _currSoundListCount = 1;
+ _currSoundList1[0] = accessScene(SC_COMMON)->_soundList;
+ }
+ }
+
+ getGameLoaderInteractionController()->sortInteractions(scene->_sceneId);
+ _currentScene = scene;
+ scene->addStaticANIObject(_aniMan, 1);
+ _scene2 = scene;
+ _aniMan->_movement = 0;
+ _aniMan->_statics = _aniMan->getStaticsById(ST_MAN_EMPTY);
+ _aniMan->setOXY(0, 0);
+
+ if (_aniMan) {
+ _aniMan2 = _aniMan;
+ CMctlCompound *cmp = getSc2MctlCompoundBySceneId(entrance->_sceneId);
+ cmp->initMovGraph2();
+ cmp->addObject(_aniMan);
+ cmp->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+ setInputDisabled(0);
+ } else {
+ _aniMan2 = 0;
+ }
+
+ scene->setPictureObjectsFlag4();
+
+ for (CPtrList::iterator s = scene->_staticANIObjectList1.begin(); s != scene->_staticANIObjectList1.end(); ++s) {
+ StaticANIObject *o = (StaticANIObject *)*s;
+ o->setFlags(o->_flags & 0xFE7F);
+ }
+
+ PictureObject *p = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0);
+ p->setFlags(p->_flags & 0xFFFB);
+
+ removeMessageHandler(2, -1);
+ _updateScreenCallback = 0;
+
+ switch (entrance->_sceneId) {
+ case SC_INTRO1:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_INTRO1");
+ scene->preloadMovements(sceneVar);
+ sceneIntro_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_INTRO1");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandlerIntro, 2);
+ _updateCursorCallback = sceneIntro_updateCursor;
+ break;
+
+ case SC_1:
+ scene01_fixEntrance();
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_1");
+ scene->preloadMovements(sceneVar);
+ scene01_initScene(scene, entrance->_field_4);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_1");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler01, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+#if 0
+ case SC_2:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_2");
+ scene->preloadMovements(sceneVar);
+ scene02_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_2");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler02, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_3:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_3");
+ scene->preloadMovements(sceneVar);
+ scene03_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_3");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler03, 2);
+ j_Scene_sc03_sub_40F160(scene);
+ _updateCursorCallback = scene03_updateCursor;
+ break;
+
+ case SC_4:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_4");
+ scene->preloadMovements(sceneVar);
+ scene04_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_4");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler04, 2, 2);
+ _updateCursorCallback = scene04_updateCursor;
+ break;
+
+ case SC_5:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_5");
+ scene->preloadMovements(sceneVar);
+ scene05_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_5");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler05, 2, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_6:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_6");
+ scene->preloadMovements(sceneVar);
+ scene06_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_6");
+ setSceneMusicParameters(sceneVar);
+ sub_415300();
+ insertMessageHandler(sceneHandler06, 2, 2);
+ _updateCursorCallback = scene06_updateCursor;
+ break;
+
+ case SC_7:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_7");
+ scene->preloadMovements(sceneVar);
+ scene07_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_7");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler07, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_8:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_8");
+ scene->preloadMovements(sceneVar);
+ scene08_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_8");
+ setSceneMusicParameters(sceneVar);
+ sub_416890();
+ addMessageHandler(sceneHandler08, 2);
+ _updateCursorCallback = scene08_updateCursor;
+ break;
+
+ case SC_9:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_9");
+ scene->preloadMovements(sceneVar);
+ scene09_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_9");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler09, 2, 2);
+ _updateCursorCallback = scene09_updateCursor;
+ break;
+
+ case SC_10:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_10");
+ scene->preloadMovements(sceneVar);
+ scene10_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_10");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler10, 2, 2);
+ _updateCursorCallback = scene10_updateCursor;
+ break;
+
+ case SC_11:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_11");
+ scene->preloadMovements(sceneVar);
+ scene11_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_11");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler11, 2, 2);
+ scene11_sub_41A980();
+ _updateCursorCallback = scene11_updateCursor;
+ break;
+
+ case SC_12:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_12");
+ scene->preloadMovements(sceneVar);
+ scene12_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_12");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler12, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_13:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_13");
+ scene->preloadMovements(sceneVar);
+ scene13_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_13");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler13, 2, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_14:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_14");
+ scene->preloadMovements(sceneVar);
+ scene14_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_14");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler14, 2, 2);
+ scene14_sub_41D2B0();
+ _updateCursorCallback = scene14_updateCursor;
+ break;
+
+ case SC_15:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_15");
+ scene->preloadMovements(sceneVar);
+ scene15_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_15");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler15, 2, 2);
+ _updateCursorCallback = scene15_updateCursor;
+ break;
+
+ case SC_16:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_16");
+ scene->preloadMovements(sceneVar);
+ scene16_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_16");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler16, 2);
+ _updateCursorCallback = scene16_updateCursor;
+ break;
+
+ case SC_17:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_17");
+ scene->preloadMovements(sceneVar);
+ scene17_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_17");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler17, 2);
+ scene17_sub_41F060();
+ _updateCursorCallback = scene17_updateCursor;
+ break;
+
+ case SC_18:
+ sub_40E1B0();
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_18");
+ scene->preloadMovements(sceneVar);
+ sub_4062D0();
+ if (dword_476C38)
+ scene18_initScene1(scene);
+ else
+ scene18_initScene2(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_18");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler18, 2, 2);
+ _updateCursorCallback = scene18_updateCursor;
+ break;
+
+ case SC_19:
+ if (!g_scene3) {
+ g_scene3 = accessScene(SC_18);
+ getGameLoader()->loadScene(SC_18);
+ scene18_initScene2(g_scene3);
+ sub_40C5F0();
+ scene19_sub_420B10(g_scene3, entrance->field_4);
+ dword_476C38 = 1;
+ }
+ sub_40C650();
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_19");
+ scene->preloadMovements(sceneVar);
+ sub_4062D0();
+ if (dword_476C38)
+ scene18_initScene1(scene);
+ else
+ scene19_initScene2();
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_19");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler19, 2);
+ scene19_sub_4211D0(scene);
+ _updateCursorCallback = scene19_updateCursor;
+ break;
+
+ case SC_20:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_20");
+ scene->preloadMovements(sceneVar);
+ scene20_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_20");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler20, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_21:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_21");
+ scene->preloadMovements(sceneVar);
+ scene21_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_21");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler21, 2, 2);
+ _updateCursorCallback = scene21_updateCursor;
+ break;
+
+ case SC_22:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_22");
+ scene->preloadMovements(sceneVar);
+ scene22_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_22");
+ setSceneMusicParameters(sceneVar);
+ scene22_sub_4228A0();
+ insertMessageHandler(sceneHandler22, 2, 2);
+ _updateCursorCallback = scene22_updateCursor;
+ break;
+
+ case SC_23:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_23");
+ scene->preloadMovements(sceneVar);
+ scene23_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_23");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler23, 2, 2);
+ scene23_sub_423B00();
+ _updateCursorCallback = scene23_updateCursor;
+ break;
+
+ case SC_24:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_24");
+ scene->preloadMovements(sceneVar);
+ scene24_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_24");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler24, 2);
+ scene24_sub_423DD0();
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_25:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_25");
+ scene->preloadMovements(sceneVar);
+ scene25_initScene(scene, entrance->field_4);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_25");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler25, 2);
+ scene25_sub_4253B0(scene, entrance->field_4);
+ _updateCursorCallback = scene25_updateCursor;
+ break;
+
+ case SC_26:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_26");
+ scene->preloadMovements(sceneVar);
+ scene26_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_26");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler26, 2, 2);
+ scene26_sub_426140(scene);
+ _updateCursorCallback = scene26_updateCursor;
+ break;
+
+ case SC_27:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_27");
+ scene->preloadMovements(sceneVar);
+ scene27_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_27");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler27, 2);
+ _updateCursorCallback = scene27_updateCursor;
+ break;
+
+ case SC_28:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_28");
+ scene->preloadMovements(sceneVar);
+ scene28_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_28");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler28, 2, 2);
+ _updateCursorCallback = scene28_updateCursor;
+ break;
+
+ case SC_29:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_29");
+ scene->preloadMovements(sceneVar);
+ scene29_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_29");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler29, 2);
+ _updateCursorCallback = scene29_updateCursor;
+ break;
+
+ case SC_30:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_30");
+ scene->preloadMovements(sceneVar);
+ scene30_initScene(scene, entrance->field_4);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_30");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler30, 2);
+ _updateCursorCallback = scene30_updateCursor;
+ break;
+
+ case SC_31:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_31");
+ scene->preloadMovements(sceneVar);
+ scene31_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_31");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler31, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_32:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_32");
+ scene->preloadMovements(sceneVar);
+ scene32_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_32");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler32, 2, 2);
+ scene32_sub_42C5C0();
+ _updateCursorCallback = scene32_updateCursor;
+ break;
+
+ case SC_33:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_33");
+ scene->preloadMovements(sceneVar);
+ scene33_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_33");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler33, 2, 2);
+ scene33_sub_42CEF0();
+ _updateCursorCallback = scene33_updateCursor;
+ break;
+
+ case SC_34:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_34");
+ scene->preloadMovements(sceneVar);
+ scene34_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_34");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler34, 2, 2);
+ scene34_sub_42DEE0();
+ _updateCursorCallback = scene34_updateCursor;
+ break;
+
+ case SC_35:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_35");
+ scene->preloadMovements(sceneVar);
+ scene35_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_35");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler35, 2, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_36:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_36");
+ scene->preloadMovements(sceneVar);
+ scene36_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_36");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler36, 2);
+ _updateCursorCallback = scene36_updateCursor;
+ break;
+
+ case SC_37:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_37");
+ scene->preloadMovements(sceneVar);
+ scene37_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_37");
+ setSceneMusicParameters(sceneVar);
+ insertMessageHandler(sceneHandler37, 2, 2);
+ _updateCursorCallback = scene37_updateCursor;
+ break;
+
+ case SC_38:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_38");
+ scene->preloadMovements(sceneVar);
+ scene38_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_38");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandler38, 2);
+ _updateCursorCallback = defaultUpdateCursor;
+ break;
+
+ case SC_FINAL1:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_FINAL1");
+ scene->preloadMovements(sceneVar);
+ sceneFinal1_initScene();
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_FINAL1");
+ setSceneMusicParameters(sceneVar);
+ addMessageHandler(sceneHandlerFinal1, 2);
+ _updateCursorCallback = sceneFinal1_updateCursor;
+ break;
+#endif
+
+ case SC_DBGMENU:
+ sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_DBGMENU");
+ scene->preloadMovements(sceneVar);
+ sceneDbgMenu_initScene(scene);
+ _behaviorManager->initBehavior(scene, sceneVar);
+ scene->initObjectCursors("SC_DBGMENU");
+ addMessageHandler(sceneHandlerDbgMenu, 2);
+ break;
+
+ default:
+ _behaviorManager->initBehavior(0, 0);
+ break;
+ }
+
+ return true;
+}
+
+void setElevatorButton(const char *name, int state) {
+ CGameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
+
+ if (var)
+ var->setSubVarAsInt(name, state);
+}
+
+void global_messageHandler_KickStucco() {
+ warning("STUB: global_messageHandler_KickStucco()");
+}
+
+void global_messageHandler_KickMetal() {
+ warning("STUB: global_messageHandler_KickMetal()");
+}
+
+int global_messageHandler1(ExCommand *cmd) {
+ debug(0, "global_messageHandler1: %d %d", cmd->_messageKind, cmd->_messageNum);
+
+ if (cmd->_excFlags & 0x10000) {
+ if (cmd->_messageNum == MV_MAN_TOLADDER)
+ cmd->_messageNum = MV_MAN_TOLADDER2;
+ if (cmd->_messageNum == MV_MAN_STARTLADDER)
+ cmd->_messageNum = MV_MAN_STARTLADDER2;
+ if (cmd->_messageNum == MV_MAN_GOLADDER)
+ cmd->_messageNum = MV_MAN_GOLADDER2;
+ if (cmd->_messageNum == MV_MAN_STOPLADDER)
+ cmd->_messageNum = MV_MAN_STOPLADDER2;
+ }
+
+ if (g_fullpipe->_inputDisabled) {
+ if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case 29:
+ case 30:
+ case 36:
+ case 106:
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ } else if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case MSG_MANSHADOWSON:
+ g_fullpipe->_aniMan->_shadowsOn = 1;
+ break;
+ case MSG_HMRKICK_STUCCO:
+ global_messageHandler_KickStucco();
+ break;
+ case MSG_MANSHADOWSOFF:
+ g_fullpipe->_aniMan->_shadowsOn = 0;
+ break;
+ case MSG_DISABLESAVES:
+ g_fullpipe->disableSaves(cmd);
+ break;
+ case MSG_ENABLESAVES:
+ g_fullpipe->enableSaves();
+ break;
+ case MSG_HMRKICK_METAL:
+ global_messageHandler_KickMetal();
+ break;
+ case 29: // left mouse
+ if (g_fullpipe->_inventoryScene) {
+ if (getGameLoaderInventory()->handleLeftClick(cmd))
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 107: // right mouse
+ if (getGameLoaderInventory()->getSelectedItemId()) {
+ getGameLoaderInventory()->unselectItem(0);
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 36: // keydown
+ switch (cmd->_keyCode) {
+ case '\x1B': // ESC
+ if (g_fullpipe->_currentScene) {
+ getGameLoaderInventory()->unselectItem(0);
+ g_fullpipe->openMainMenu();
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 't':
+ g_fullpipe->stopAllSounds();
+ cmd->_messageKind = 0;
+ break;
+ case 'u':
+ g_fullpipe->toggleMute();
+ cmd->_messageKind = 0;
+ break;
+ case ' ':
+ if (getGameLoaderInventory()->getIsLocked()) {
+ if (getGameLoaderInventory()->getIsInventoryOut()) {
+ getGameLoaderInventory()->setIsLocked(0);
+ }
+ } else {
+ getGameLoaderInventory()->slideOut();
+ getGameLoaderInventory()->setIsLocked(1);
+ }
+ break;
+ case '\t':
+ if (g_fullpipe->_flgCanOpenMap)
+ g_fullpipe->openMap();
+ cmd->_messageKind = 0;
+ break;
+ case 'p':
+ if (g_fullpipe->_flgCanOpenMap)
+ g_fullpipe->openHelp();
+ cmd->_messageKind = 0;
+ break;
+ default:
+ g_fullpipe->defHandleKeyDown(cmd->_keyCode);
+ break;
+ }
+ break;
+ case 33:
+ if (!g_fullpipe->_inventoryScene)
+ break;
+
+ int invItem;
+
+ if (g_fullpipe->_updateFlag && (invItem = g_fullpipe->_inventory->getHoveredItem(&g_fullpipe->_mouseScreenPos))) {
+ g_fullpipe->_cursorId = PIC_CSR_ITN;
+ if (!g_fullpipe->_currSelectedInventoryItemId && !g_fullpipe->_aniMan->_movement &&
+ !(g_fullpipe->_aniMan->_flags & 0x100) && g_fullpipe->_aniMan->isIdle()) {
+ int st = g_fullpipe->_aniMan->_statics->_staticsId;
+ ExCommand *newex = 0;
+
+ if (st == ST_MAN_RIGHT) {
+ newex = new ExCommand(g_fullpipe->_aniMan->_id, 1, rMV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
+ } else if (st == (0x4000 | ST_MAN_RIGHT)) {
+ newex = new ExCommand(g_fullpipe->_aniMan->_id, 1, MV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
+ }
+
+ if (newex) {
+ newex->_keyCode = g_fullpipe->_aniMan->_okeyCode;
+ newex->_excFlags |= 3;
+ newex->postMessage();
+ }
+ }
+
+ if (g_fullpipe->_currSelectedInventoryItemId != invItem)
+ g_fullpipe->playSound(SND_CMN_070, 0);
+
+ g_fullpipe->_currSelectedInventoryItemId = invItem;
+ g_fullpipe->setCursor(g_fullpipe->_cursorId);
+ break;
+ }
+ if (g_fullpipe->_updateCursorCallback)
+ g_fullpipe->_updateCursorCallback();
+
+ g_fullpipe->_currSelectedInventoryItemId = 0;
+ g_fullpipe->setCursor(g_fullpipe->_cursorId);
+ break;
+ case 65: // open map
+ if (cmd->_field_2C == 11 && cmd->_field_14 == ANI_INV_MAP && g_fullpipe->_flgCanOpenMap)
+ g_fullpipe->openMap();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (cmd->_messageKind == 56) {
+ getGameLoaderInventory()->rebuildItemRects();
+
+ ExCommand *newex = new ExCommand(0, 35, SND_CMN_031, 0, 0, 0, 1, 0, 0, 0);
+
+ newex->_field_14 = 1;
+ newex->_excFlags |= 3;
+ newex->postMessage();
+
+ return 1;
+ } else if (cmd->_messageKind == 57) {
+ getGameLoaderInventory()->rebuildItemRects();
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void staticANIObjectCallback(int *arg) {
+ (*arg)--;
+}
+
+int global_messageHandler2(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ int res = 0;
+ StaticANIObject *ani;
+
+ switch (cmd->_messageNum) {
+ case 0x44c8:
+ error("0x44c8");
+ // Unk3_sub_4477A0(&unk3, _parentId, _field_14 != 0);
+ break;
+
+ case 28:
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani)
+ ani->_priority = cmd->_field_14;
+ break;
+
+ case 25:
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ if (cmd->_field_14) {
+ ani->setFlags40(true);
+ ani->_callback2 = staticANIObjectCallback;
+ } else {
+ ani->setFlags40(false);
+ ani->_callback2 = 0;
+ }
+ }
+ break;
+
+ case 26:
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ Movement *mov = ani->_movement;
+ if (mov)
+ mov->_currDynamicPhase->_field_68 = 0;
+ }
+ break;
+
+ default:
+#if 0
+ // We never put anything into _defMsgArray
+ while (::iterator it = g_fullpipe->_defMsgArray.begin(); it != g_fullpipe->_defMsgArray.end(); ++it)
+ if (((ExCommand *)*it)->_field_24 == _messageNum) {
+ ((ExCommand *)*it)->firef34(v13);
+ res = 1;
+ }
+#endif
+
+ //debug_msg(_messageNum);
+
+ if (!g_fullpipe->_soundEnabled || cmd->_messageNum != 33 || g_fullpipe->_currSoundListCount <= 0)
+ return res;
+
+ for (int snd = 0; snd < g_fullpipe->_currSoundListCount; snd++) {
+ SoundList *s = g_fullpipe->_currSoundList1[snd];
+ int ms = s->getCount();
+ for (int i = 0; i < ms; i++) {
+ s->getSoundByIndex(i)->setPanAndVolumeByStaticAni();
+ }
+ }
+ }
+
+ return res;
+}
+
+int global_messageHandler3(ExCommand *cmd) {
+ int result = 0;
+
+ if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 36:
+ if (g_fullpipe->_inputDisabled)
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ StaticANIObject *ani, *ani2;
+
+ switch (cmd->_messageKind) {
+ case 17:
+ switch (cmd->_messageNum) {
+ case 61:
+ return g_fullpipe->_gameLoader->preloadScene(cmd->_parentId, cmd->_keyCode);
+ case 62:
+ return g_fullpipe->_gameLoader->gotoScene(cmd->_parentId, cmd->_keyCode);
+ case 64:
+ if (g_fullpipe->_currentScene && g_fullpipe->_msgObjectId2
+ && (!(cmd->_keyCode & 4) || g_fullpipe->_msgObjectId2 != cmd->_field_14 || g_fullpipe->_msgId != cmd->_field_20)) {
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_msgObjectId2, g_fullpipe->_msgId);
+ if (ani) {
+ ani->_flags &= 0xFF7F;
+ ani->_flags &= 0xFEFF;
+ ani->deleteFromGlobalMessageQueue();
+ }
+ }
+ g_fullpipe->_msgX = 0;
+ g_fullpipe->_msgY = 0;
+ g_fullpipe->_msgObjectId2 = 0;
+ g_fullpipe->_msgId = 0;
+ if ((cmd->_keyCode & 1) || (cmd->_keyCode & 2)) {
+ g_fullpipe->_msgX = cmd->_x;
+ g_fullpipe->_msgY = cmd->_y;
+ }
+ if (cmd->_keyCode & 4) {
+ g_fullpipe->_msgObjectId2 = cmd->_field_14;
+ g_fullpipe->_msgId = cmd->_field_20;
+ }
+ return result;
+ case 29:
+ if (!g_fullpipe->_currentScene)
+ return result;
+
+ if (g_fullpipe->_gameLoader->_interactionController->_flag24) {
+ ani = g_fullpipe->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ ani2 = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+ if (ani) {
+ if (g_fullpipe->_msgObjectId2 == ani->_id && g_fullpipe->_msgId == ani->_okeyCode) {
+ cmd->_messageKind = 0;
+ return result;
+ }
+ if (canInteractAny(ani2, ani, cmd->_keyCode)) {
+ handleObjectInteraction(ani2, ani, cmd->_keyCode);
+ return 1;
+ }
+ } else {
+ int id = g_fullpipe->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fullpipe->_currentScene->getPictureObjectById(id, 0);
+ if (pic) {
+ if (g_fullpipe->_msgObjectId2 == pic->_id && g_fullpipe->_msgId == pic->_okeyCode) {
+ cmd->_messageKind = 0;
+ return result;
+ }
+ if (!ani2 || canInteractAny(ani2, pic, cmd->_keyCode)) {
+ if (!ani2 || (ani2->isIdle() && !(ani2->_flags & 0x80) && !(ani2->_flags & 0x100)))
+ handleObjectInteraction(ani2, pic, cmd->_keyCode);
+ return 1;
+ }
+ }
+ }
+ }
+ if (getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->_isEnabled && cmd->_keyCode <= 0) {
+ if (g_fullpipe->_msgX != cmd->_sceneClickX || g_fullpipe->_msgY != cmd->_sceneClickY) {
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+ if (!ani || (ani->isIdle() && !(ani->_flags & 0x80) && !(ani->_flags & 0x100))) {
+ result = startWalkTo(g_fullpipe->_gameLoader->_field_FA, -1, cmd->_sceneClickX, cmd->_sceneClickY, 0);
+ if (result) {
+ ExCommand *ex = new ExCommand(g_fullpipe->_gameLoader->_field_FA, 17, 64, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = 1;
+ ex->_excFlags |= 3;
+ ex->_x = cmd->_sceneClickX;
+ ex->_y = cmd->_sceneClickY;
+ ex->postMessage();
+ }
+ }
+ } else {
+ cmd->_messageKind = 0;
+ }
+ }
+ return result;
+ default:
+ return result;
+ }
+ case 58:
+ g_fullpipe->setCursor(cmd->_keyCode);
+ return result;
+ case 59:
+ setInputDisabled(1);
+ return result;
+ case 60:
+ setInputDisabled(0);
+ return result;
+ case 56:
+ if (cmd->_field_2C) {
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ getGameLoaderInventory()->addItem2(ani);
+ result = 1;
+ }
+ } else {
+ result = 1;
+ getGameLoaderInventory()->addItem(cmd->_parentId, 1);
+ }
+ getGameLoaderInventory()->rebuildItemRects();
+ return result;
+ case 57:
+ if (cmd->_field_2C) {
+ if (!cmd->_field_20) {
+ getGameLoaderInventory()->removeItem2(g_fullpipe->_currentScene, cmd->_parentId, cmd->_x, cmd->_y, cmd->_field_14);
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ }
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
+ if (ani) {
+ getGameLoaderInventory()->removeItem2(g_fullpipe->_currentScene, cmd->_parentId, ani->_ox + cmd->_x, ani->_oy + cmd->_y, ani->_priority + cmd->_field_14);
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ }
+ } else {
+ getGameLoaderInventory()->removeItem(cmd->_parentId, 1);
+ }
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ case 55:
+ if (g_fullpipe->_currentScene) {
+ GameObject *obj;
+ if (cmd->_field_14)
+ obj = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_x, cmd->_y);
+ else
+ obj = g_fullpipe->_currentScene->getPictureObjectById(cmd->_x, cmd->_y);
+ handleObjectInteraction(g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode), obj, cmd->_field_20);
+ result = 1;
+ }
+ return result;
+ case 51:
+ return startWalkTo(cmd->_parentId, cmd->_keyCode, cmd->_x, cmd->_y, cmd->_field_20);
+ case 52:
+ return doSomeAnimation(cmd->_parentId, cmd->_keyCode, cmd->_field_20);
+ case 53:
+ return doSomeAnimation2(cmd->_parentId, cmd->_keyCode);
+ case 63:
+ if (cmd->_objtype == kObjTypeObjstateCommand) {
+ CObjstateCommand *c = (CObjstateCommand *)cmd;
+ result = 1;
+ g_fullpipe->setObjectState(c->_objCommandName, c->_value);
+ }
+ return result;
+ default:
+ return result;
+ }
+}
+
+int global_messageHandler4(ExCommand *cmd) {
+ StaticANIObject *ani = 0;
+
+ switch (cmd->_messageKind) {
+ case 18: {
+ MessageQueue *mq = new MessageQueue(g_fullpipe->_currentScene->getMessageQueueById(cmd->_messageNum), cmd->_parId, 0);
+
+ if (cmd->_excFlags & 1)
+ mq->_flag1 = 1;
+ else
+ mq->_flag1 = 0;
+
+ mq->sendNextCommand();
+ break;
+ }
+ case 2:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->trySetMessageQueue(cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 1: {
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ int flags = cmd->_field_14;
+ if (flags <= 0)
+ flags = -1;
+
+ if (cmd->_excFlags & 1)
+ ani->startAnim(cmd->_messageNum, 0, flags);
+ else
+ ani->startAnim(cmd->_messageNum, cmd->_parId, flags);
+
+ break;
+ }
+ case 8:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->startAnimEx(cmd->_messageNum, cmd->_parId, -1, -1);
+ break;
+
+ case 20: {
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ int flags = cmd->_field_14;
+ if (flags <= 0)
+ flags = -1;
+
+ ExCommand2 *cmd2 = (ExCommand2 *)cmd;
+
+ if (cmd->_excFlags & 1) {
+ ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ } else {
+ ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ }
+ break;
+ }
+ case 21:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->queueMessageQueue(0);
+ ani->playIdle();
+ break;
+ case 9:
+ // Nop in original
+ break;
+ case 3:
+ g_fullpipe->_currentScene->_y = cmd->_messageNum - cmd->_messageNum % g_fullpipe->_scrollSpeed;
+ break;
+
+ case 4:
+ g_fullpipe->_currentScene->_x = cmd->_messageNum - cmd->_messageNum % g_fullpipe->_scrollSpeed;
+ break;
+
+ case 19: {
+ if (!g_fullpipe->_currentScene)
+ break;
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ MessageQueue *mq = ani->getMessageQueue();
+ MessageQueue *mq2 = ani->changeStatics1(cmd->_messageNum);
+
+ if (!mq2 || !mq2->getExCommandByIndex(0) || !mq)
+ break;
+
+ mq2->_parId = mq->_id;
+ mq2->_flag1 = (cmd->_field_24 == 0);
+ break;
+ }
+ case 22:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->_flags |= 4;
+ ani->changeStatics2(cmd->_messageNum);
+ break;
+
+ case 6:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->hide();
+ break;
+
+ case 27:
+ if (!g_fullpipe->_currentScene || g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode) == 0) {
+ ani = g_fullpipe->accessScene(cmd->_field_20)->getStaticANIObject1ById(cmd->_parentId, -1);
+ if (ani) {
+ ani = new StaticANIObject(ani);
+ g_fullpipe->_currentScene->addStaticANIObject(ani, 1);
+ }
+ }
+
+ // fall through
+ case 5:
+ if (g_fullpipe->_currentScene)
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+
+ if (!ani)
+ break;
+
+ if (cmd->_field_14 >= 0)
+ ani->_priority = cmd->_field_14;
+
+ ani->show1(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 10:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ if (cmd->_field_14 >= 0)
+ ani->_priority = cmd->_field_14;
+
+ ani->show2(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 7: {
+ if (!g_fullpipe->_currentScene->_picObjList.size())
+ break;
+
+ int offX = g_fullpipe->_scrollSpeed * (cmd->_x / g_fullpipe->_scrollSpeed);
+ int offY = g_fullpipe->_scrollSpeed * (cmd->_y / g_fullpipe->_scrollSpeed);
+
+ if (cmd->_messageNum) {
+ g_fullpipe->_currentScene->_x = offX - g_fullpipe->_sceneRect.left;
+ g_fullpipe->_currentScene->_y = offY - g_fullpipe->_sceneRect.top;
+
+ if (cmd->_field_24) {
+ g_fullpipe->_currentScene->_messageQueueId = cmd->_parId;
+ }
+ } else {
+ g_fullpipe->_sceneRect.moveTo(offX, offY);
+
+ g_fullpipe->_currentScene->_x = 0;
+ g_fullpipe->_currentScene->_y = 0;
+
+ g_fullpipe->_currentScene->updateScrolling2();
+ }
+ break;
+ }
+ case 34:
+ if (!g_fullpipe->_currentScene)
+ break;
+
+ ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->_flags = cmd->_messageNum | (ani->_flags & ~cmd->_field_14);
+
+ break;
+
+ case 35:
+ global_messageHandler_handleSound(cmd);
+ break;
+
+ case 11:
+ case 12:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+int defaultUpdateCursor() {
+ g_fullpipe->updateCursorsCommon();
+
+ return g_fullpipe->_cursorId;
+}
+
+int sceneIntro_updateCursor() {
+ g_fullpipe->_cursorId = 0;
+
+ return 0;
+}
+
+void FullpipeEngine::setSwallowedEggsState() {
+ CGameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
+
+ g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
+ g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
+ g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
+
+ g_vars->swallowedEgg1->_value.intValue = 0;
+ g_vars->swallowedEgg2->_value.intValue = 0;
+ g_vars->swallowedEgg3->_value.intValue = 0;
+}
+
+void sceneIntro_initScene(Scene *sc) {
+ g_fullpipe->_gameLoader->loadScene(SC_INTRO2);
+
+ g_vars->sceneIntro_aniin1man = sc->getStaticANIObject1ById(ANI_IN1MAN, -1);
+ g_vars->sceneIntro_needSleep = true;
+ g_vars->sceneIntro_needGetup = false;
+ g_vars->sceneIntro_playing = true;
+ g_vars->sceneIntro_needBlackout = false;
+
+ if (g_fullpipe->_recordEvents || g_fullpipe->_inputArFlag)
+ g_vars->sceneIntro_skipIntro = false;
+
+ g_fullpipe->_modalObject = new CModalIntro;
+}
+
+int sceneHandlerIntro(ExCommand *cmd) {
+ warning("STUB: sceneHandlerIntro()");
+
+ return 0;
+}
+
+void scene01_fixEntrance() {
+ CGameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
+ if (var->getSubVarAsInt("Entrance") == TrubaLeft)
+ var->setSubVarAsInt("Entrance", TrubaRight);
+}
+
+void scene01_initScene(Scene *sc, int entrance) {
+ g_vars->scene01_picSc01Osk = sc->getPictureObjectById(PIC_SC1_OSK, 0);
+ g_vars->scene01_picSc01Osk->_flags &= 0xFFFB;
+
+ g_vars->scene01_picSc01Osk2 = sc->getPictureObjectById(PIC_SC1_OSK2, 0);
+ g_vars->scene01_picSc01Osk2->_flags &= 0xFFFB;
+
+ if (g_fullpipe->getObjectState(sO_EggCracker) == g_fullpipe->getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg)) {
+ PictureObject *pic = sc->getPictureObjectById(PIC_SC1_KUCHKA, 0);
+ if (pic)
+ pic->_flags &= 0xFFFB;
+ }
+
+ if (entrance != TrubaLeft) {
+ StaticANIObject *bootAnim = sc->getStaticANIObject1ById(ANI_BOOT_1, -1);
+ if (bootAnim)
+ bootAnim->_flags &= ~0x04;
+ }
+
+ setElevatorButton(sO_Level2, ST_LBN_2N);
+}
+
+int sceneHandler01(ExCommand *cmd) {
+ int res = 0;
+
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ if (cmd->_messageNum > MSG_SC1_SHOWOSK) {
+ if (cmd->_messageNum == MSG_SC1_UTRUBACLICK)
+ handleObjectInteraction(g_fullpipe->_aniMan, g_fullpipe->_currentScene->getPictureObjectById(PIC_SC1_LADDER, 0), 0);
+
+ return 0;
+ }
+
+ if (cmd->_messageNum == MSG_SC1_SHOWOSK) {
+ g_vars->scene01_picSc01Osk->_flags |= 4;
+
+ g_vars->scene01_picSc01Osk->_priority = 20;
+ g_vars->scene01_picSc01Osk2->_priority = 21;
+
+ return 0;
+ }
+
+ if (cmd->_messageNum != 0x21) {
+ if (cmd->_messageNum == MSG_SC1_SHOWOSK2) {
+ g_vars->scene01_picSc01Osk2->_flags |= 4;
+ g_vars->scene01_picSc01Osk2->_priority = 20;
+ g_vars->scene01_picSc01Osk->_priority = 21;
+
+ return 0;
+ }
+
+ return 0;
+ }
+
+ if (g_fullpipe->_aniMan2) {
+ if (g_fullpipe->_aniMan2->_ox < g_fullpipe->_sceneRect.left + 200) {
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.left - 300;
+ }
+
+ if (g_fullpipe->_aniMan2->_ox > g_fullpipe->_sceneRect.right - 200)
+ g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.right + 300;
+
+ res = 1;
+ }
+ g_fullpipe->_behaviorManager->updateBehaviors();
+
+ g_fullpipe->startSceneTrack();
+
+ return res;
+}
+
+void sceneDbgMenu_initScene(Scene *sc) {
+ g_vars->selector = sc->getPictureObjectById(PIC_SCD_SEL, 0);
+ getGameLoaderInteractionController()->disableFlag24();
+ setInputDisabled(0);
+}
+
+GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
+ if (g_fullpipe->_currentScene)
+ for (uint i = 0; i < g_fullpipe->_currentScene->_picObjList.size(); i++) {
+ PictureObject *pic = (PictureObject *)g_fullpipe->_currentScene->_picObjList[i];
+
+ if (x >= pic->_ox && y >= pic->_oy) {
+ Common::Point point;
+
+ pic->getDimensions(&point);
+
+ if (x <= pic->_ox + point.x && y <= pic->_oy + point.y && pic != g_vars->selector)
+ return pic;
+ }
+ }
+
+ return 0;
+}
+
+int sceneHandlerDbgMenu(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ int mx = g_fullpipe->_mouseScreenPos.x + g_fullpipe->_sceneRect.left;
+ int my = g_fullpipe->_mouseScreenPos.y + g_fullpipe->_sceneRect.top;
+
+ if (ex->_messageNum == 29) {
+ GameObject *obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
+ if (obj && canInteractAny(0, obj, -3) ) {
+ getGameLoaderInteractionController()->enableFlag24();
+ handleObjectInteraction(0, obj, 0);
+ }
+ return 0;
+ }
+ if (ex->_messageNum != 33) {
+ if (ex->_messageNum == MSG_RESTARTGAME) {
+ g_fullpipe->_needRestart = true;
+ return 0;
+ }
+ return 0;
+ }
+
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ GameObject *obj = g_fullpipe->_currentScene->getStaticANIObjectAtPos(mx, my);
+ if (obj) {
+ if (canInteractAny(0, obj, -3)) {
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ g_fullpipe->setCursor(PIC_CSR_DEFAULT);
+ return 0;
+ }
+ } else {
+ obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
+ if (obj && canInteractAny(0, obj, -3) ) {
+ g_vars->selector->_flags |= 4;
+ g_vars->selector->setOXY(obj->_ox, obj->_oy);
+ g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
+ g_fullpipe->setCursor(PIC_CSR_DEFAULT);
+ return 0;
+ }
+ g_vars->selector->_flags &= 0xFFFB;
+ }
+ g_fullpipe->setCursor(g_fullpipe->_cursorId);
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes.h b/engines/fullpipe/scenes.h
new file mode 100644
index 0000000000..be42838920
--- /dev/null
+++ b/engines/fullpipe/scenes.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_SCENES_H
+#define FULLPIPE_SCENES_H
+
+namespace Fullpipe {
+
+class StaticANIObject;
+
+class Vars {
+ public:
+ Vars();
+
+ CGameVar *swallowedEgg1;
+ CGameVar *swallowedEgg2;
+ CGameVar *swallowedEgg3;
+
+ StaticANIObject *sceneIntro_aniin1man;
+ bool sceneIntro_needSleep;
+ bool sceneIntro_needGetup;
+ bool sceneIntro_skipIntro;
+ bool sceneIntro_playing;
+ bool sceneIntro_needBlackout;
+
+ PictureObject *scene01_picSc01Osk;
+ PictureObject *scene01_picSc01Osk2;
+
+ GameObject *selector;
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_SCENES_H */
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
new file mode 100644
index 0000000000..7f34412334
--- /dev/null
+++ b/engines/fullpipe/sound.cpp
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/sound.h"
+#include "fullpipe/ngiarchive.h"
+
+namespace Fullpipe {
+
+SoundList::SoundList() {
+ _soundItems = 0;
+ _soundItemsCount = 0;
+ _libHandle = 0;
+}
+
+bool SoundList::load(MfcArchive &file, char *fname) {
+ debug(5, "SoundList::load()");
+
+ _soundItemsCount = file.readUint32LE();
+ _soundItems = (Sound **)calloc(_soundItemsCount, sizeof(Sound *));
+
+ if (fname) {
+ _libHandle = (NGIArchive *)makeNGIArchive(fname);
+ } else {
+ _libHandle = 0;
+ }
+
+ for (int i = 0; i < _soundItemsCount; i++) {
+ Sound *snd = new Sound();
+
+ _soundItems[i] = 0;
+ snd->load(file, _libHandle);
+ }
+
+ return true;
+
+}
+
+bool SoundList::loadFile(const char *fname, char *libname) {
+ Common::File file;
+
+ if (!file.open(fname))
+ return false;
+
+ MfcArchive archive(&file);
+
+ return load(archive, libname);
+}
+
+Sound::Sound() {
+ _id = 0;
+ _directSoundBuffer = 0;
+ _soundData = 0;
+ _objectId = 0;
+ memset(_directSoundBuffers, 0, sizeof(_directSoundBuffers));
+ _description = 0;
+}
+
+
+bool Sound::load(MfcArchive &file, NGIArchive *archive) {
+ debug(5, "Sound::load()");
+
+ MemoryObject::load(file);
+
+ _id = file.readUint32LE();
+ _description = file.readPascalString();
+
+ assert(g_fullpipe->_gameProjectVersion >= 6);
+
+ _objectId = file.readUint16LE();
+
+ if (archive && archive->hasFile(_memfilename)) {
+ Common::SeekableReadStream *s = archive->createReadStreamForMember(_memfilename);
+
+ _soundData = (byte *)calloc(s->size(), 1);
+
+ s->read(_soundData, s->size());
+
+ delete s;
+ }
+
+ return true;
+}
+
+void Sound::updateVolume() {
+ debug(3, "STUB Sound::updateVolume()");
+}
+
+void Sound::setPanAndVolumeByStaticAni() {
+ debug(3, "STUB Sound::setPanAndVolumeByStaticAni()");
+}
+
+void FullpipeEngine::setSceneMusicParameters(CGameVar *var) {
+ warning("STUB: FullpipeEngine::setSceneMusicParameters()");
+}
+
+void FullpipeEngine::startSceneTrack() {
+ debug(3, "STUB: FullpipeEngine::startSceneTrack()");
+}
+
+void FullpipeEngine::stopAllSounds() {
+ warning("STUB: FullpipeEngine::stopAllSounds()");
+}
+
+void FullpipeEngine::toggleMute() {
+ warning("STUB: FullpipeEngine::toggleMute()");
+}
+
+void FullpipeEngine::playSound(int id, int flag) {
+ warning("STUB: FullpipeEngine::playSounds(%d, %d)", id, flag);
+}
+
+void global_messageHandler_handleSound(ExCommand *cmd) {
+ debug(0, "STUB: global_messageHandler_handleSound()");
+}
+
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h
new file mode 100644
index 0000000000..4014cdd94e
--- /dev/null
+++ b/engines/fullpipe/sound.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_SOUND_H
+#define FULLPIPE_SOUND_H
+
+namespace Fullpipe {
+
+class Sound : public MemoryObject {
+ int _id;
+ char *_description;
+ int16 _objectId;
+ int16 _field_32;
+ int _directSoundBuffer;
+ int _directSoundBuffers[7];
+ byte *_soundData;
+
+ public:
+ Sound();
+ bool load(MfcArchive &file, NGIArchive *archive);
+ void updateVolume();
+
+ void setPanAndVolumeByStaticAni();
+};
+
+class SoundList : public CObject {
+ Sound **_soundItems;
+ int _soundItemsCount;
+ NGIArchive *_libHandle;
+
+ public:
+ SoundList();
+ bool load(MfcArchive &file, char *fname);
+ bool loadFile(const char *fname, char *libname);
+
+ int getCount() { return _soundItemsCount; }
+ Sound *getSoundByIndex(int idx) { return _soundItems[idx]; }
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_SOUND_H */
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
new file mode 100644
index 0000000000..dd00361ce9
--- /dev/null
+++ b/engines/fullpipe/stateloader.cpp
@@ -0,0 +1,339 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "common/file.h"
+#include "common/array.h"
+#include "common/list.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/interaction.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+bool FullpipeEngine::loadGam(const char *fname, int scene) {
+ _gameLoader = new CGameLoader();
+
+ if (!_gameLoader->loadFile(fname))
+ return false;
+
+ _currSoundListCount = 0;
+ initObjectStates();
+ // set_g_messageQueueCallback1(messageQueueCallback1); // substituted with direct call
+
+ addMessageHandlerByIndex(global_messageHandler1, 0, 4);
+
+ _inventory = getGameLoaderInventory();
+ _inventory->setItemFlags(ANI_INV_MAP, 0x10003);
+ _inventory->addItem(ANI_INV_MAP, 1);
+
+ _inventory->rebuildItemRects();
+
+ for (CPtrList::iterator p = _inventory->getScene()->_picObjList.begin(); p != _inventory->getScene()->_picObjList.end(); ++p) {
+ ((MemoryObject *)((PictureObject *)*p)->_picture)->load();
+ }
+
+ // _sceneSwitcher = sceneSwitcher; // substituted with direct call
+ _gameLoader->_preloadCallback = preloadCallback;
+ // _readSavegameCallback = gameLoaderReadSavegameCallback; // TODO
+
+ _aniMan = accessScene(SC_COMMON)->getAniMan();
+ _scene2 = 0;
+
+ _movTable = _aniMan->countMovements();
+
+ _aniMan->setSpeed(1);
+
+ PictureObject *pic = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0);
+
+ pic->setFlags(pic->_flags & 0xFFFB);
+
+ // Not used in full game
+ //_evalVersionPic = accessScene(SC_COMMON)->getPictureObjectById(PIC_CMN_EVAL, 0);
+
+ initMap();
+ initCursors();
+
+ setMusicAllowed(_gameLoader->_gameVar->getSubVarAsInt("MUSIC_ALLOWED"));
+
+ if (scene) {
+ _gameLoader->loadScene(scene);
+ _gameLoader->gotoScene(scene, TrubaLeft);
+ } else {
+ if (_flgPlayIntro) {
+ _gameLoader->loadScene(SC_INTRO1);
+ _gameLoader->gotoScene(SC_INTRO1, TrubaUp);
+ } else {
+ _gameLoader->loadScene(SC_1);
+ _gameLoader->gotoScene(SC_1, TrubaLeft);
+ }
+ }
+
+ if (!_currentScene)
+ return false;
+
+ return true;
+}
+
+GameProject::GameProject() {
+ _field_4 = 0;
+ _headerFilename = 0;
+ _field_10 = 12;
+}
+
+bool GameProject::load(MfcArchive &file) {
+ debug(5, "GameProject::load()");
+
+ _field_4 = 0;
+ _headerFilename = 0;
+ _field_10 = 12;
+
+ g_fullpipe->_gameProjectVersion = file.readUint32LE();
+ g_fullpipe->_pictureScale = file.readUint16LE();
+ g_fullpipe->_scrollSpeed = file.readUint32LE();
+
+ _headerFilename = file.readPascalString();
+
+ debug(1, "_gameProjectVersion = %d", g_fullpipe->_gameProjectVersion);
+ debug(1, "_pictureScale = %d", g_fullpipe->_pictureScale);
+ debug(1, "_scrollSpeed = %d", g_fullpipe->_scrollSpeed);
+ debug(1, "_headerFilename = %s", _headerFilename);
+
+ _sceneTagList = new SceneTagList();
+
+ _sceneTagList->load(file);
+
+ if (g_fullpipe->_gameProjectVersion >= 3)
+ _field_4 = file.readUint32LE();
+
+ if (g_fullpipe->_gameProjectVersion >= 5) {
+ file.readUint32LE();
+ file.readUint32LE();
+ }
+
+ return true;
+}
+
+GameProject::~GameProject() {
+ free(_headerFilename);
+}
+
+bool PreloadItems::load(MfcArchive &file) {
+ debug(5, "PreloadItems::load()");
+
+ int count = file.readCount();
+
+ resize(count);
+
+ for (int i = 0; i < count; i++) {
+ PreloadItem *t = new PreloadItem();
+ t->preloadId1 = file.readUint32LE();
+ t->preloadId2 = file.readUint32LE();
+ t->sceneId = file.readUint32LE();
+ t->keyCode = file.readUint32LE();
+
+ push_back(*t);
+ }
+
+ return true;
+}
+
+CGameVar::CGameVar() {
+ _subVars = 0;
+ _parentVarObj = 0;
+ _nextVarObj = 0;
+ _prevVarObj = 0;
+ _field_14 = 0;
+ _varType = 0;
+ _value.floatValue = 0;
+ _varName = 0;
+}
+
+bool CGameVar::load(MfcArchive &file) {
+ _varName = file.readPascalString();
+ _varType = file.readUint32LE();
+
+ debugN(6, "[%03d] ", file.getLevel());
+ for (int i = 0; i < file.getLevel(); i++)
+ debugN(6, " ");
+
+ debugN(6, "<%s>: ", transCyrillic((byte *)_varName));
+
+ switch (_varType) {
+ case 0:
+ _value.intValue = file.readUint32LE();
+ debug(6, "d --> %d", _value.intValue);
+ break;
+ case 1:
+ _value.intValue = file.readUint32LE(); // FIXME
+ debug(6, "f --> %f", _value.floatValue);
+ break;
+ case 2:
+ _value.stringValue = file.readPascalString();
+ debug(6, "s --> %s", _value.stringValue);
+ break;
+ default:
+ error("Unknown var type: %d (0x%x)", _varType, _varType);
+ }
+
+ file.incLevel();
+ _parentVarObj = (CGameVar *)file.readClass();
+ _prevVarObj = (CGameVar *)file.readClass();
+ _nextVarObj = (CGameVar *)file.readClass();
+ _field_14 = (CGameVar *)file.readClass();
+ _subVars = (CGameVar *)file.readClass();
+ file.decLevel();
+
+ return true;
+}
+
+CGameVar *CGameVar::getSubVarByName(const char *name) {
+ CGameVar *sv = 0;
+
+ if (_subVars != 0) {
+ sv = _subVars;
+ for (;sv && scumm_stricmp(sv->_varName, name); sv = sv->_nextVarObj)
+ ;
+ }
+ return sv;
+}
+
+bool CGameVar::setSubVarAsInt(const char *name, int value) {
+ CGameVar *var = getSubVarByName(name);
+
+ if (var) {
+ if (var->_varType == 0) {
+ var->_value.intValue = value;
+
+ return true;
+ }
+ return false;
+ }
+
+ var = new CGameVar();
+ var->_varType = 0;
+ var->_value.intValue = value;
+ var->_varName = (char *)calloc(strlen(name) + 1, 1);
+ strcpy(var->_varName, name);
+
+ return addSubVar(var);
+}
+
+int CGameVar::getSubVarAsInt(const char *name) {
+ CGameVar *var = getSubVarByName(name);
+
+ if (var)
+ return var->_value.intValue;
+ else
+ return 0;
+}
+
+CGameVar *CGameVar::addSubVarAsInt(const char *name, int value) {
+ if (getSubVarByName(name)) {
+ return 0;
+ } else {
+ CGameVar *var = new CGameVar();
+
+ var->_varType = 0;
+ var->_value.intValue = value;
+
+ var->_varName = (char *)calloc(strlen(name) + 1, 1);
+ strcpy(var->_varName, name);
+
+ return (addSubVar(var) != 0) ? var : 0;
+ }
+}
+
+bool CGameVar::addSubVar(CGameVar *subvar) {
+ CGameVar *var = _subVars;
+
+ if (var) {
+ for (CGameVar *i = var->_nextVarObj; i; i = i->_nextVarObj)
+ var = i;
+
+ var->_nextVarObj = subvar;
+ subvar->_prevVarObj = var;
+ subvar->_parentVarObj = this;
+
+ return true;
+ } else {
+ _subVars = subvar;
+ subvar->_parentVarObj = this;
+
+ return true;
+ }
+
+ return false;
+}
+
+int CGameVar::getSubVarsCount() {
+ int res;
+ CGameVar *sub = _subVars;
+
+ for (res = 0; sub; res++)
+ sub = sub->_nextVarObj;
+
+ return res;
+}
+
+CGameVar *CGameVar::getSubVarByIndex(int idx) {
+ CGameVar *sub = _subVars;
+
+ while (idx--) {
+ sub = sub->_nextVarObj;
+
+ if (!sub)
+ return 0;
+ }
+
+ return sub;
+}
+
+bool PicAniInfo::load(MfcArchive &file) {
+ debug(5, "PicAniInfo::load()");
+
+ type = file.readUint32LE();
+ objectId = file.readUint16LE();
+ field_6 = file.readUint16LE();
+ field_8 = file.readUint32LE();
+ sceneId = file.readUint16LE();
+ field_E = file.readUint16LE();
+ ox = file.readUint32LE();
+ oy = file.readUint32LE();
+ priority = file.readUint32LE();
+ staticsId = file.readUint16LE();
+ movementId = file.readUint16LE();
+ dynamicPhaseIndex = file.readUint16LE();
+ flags = file.readUint16LE();
+ field_24 = file.readUint32LE();
+ someDynamicPhaseIndex = file.readUint32LE();
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
new file mode 100644
index 0000000000..1fd02f8eb6
--- /dev/null
+++ b/engines/fullpipe/statics.cpp
@@ -0,0 +1,1720 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/ngiarchive.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/interaction.h"
+
+#include "fullpipe/constants.h"
+#include "fullpipe/objectnames.h"
+
+namespace Fullpipe {
+
+CStepArray::CStepArray() {
+ _points = 0;
+ _maxPointIndex = 0;
+ _currPointIndex = 0;
+ _pointsCount = 0;
+ _isEos = 0;
+}
+
+CStepArray::~CStepArray() {
+ if (_pointsCount) {
+ for (int i = 0; i < _pointsCount; i++)
+ delete _points[i];
+
+ delete _points;
+
+ _points = 0;
+ }
+}
+
+void CStepArray::clear() {
+ _currPointIndex = 0;
+ _maxPointIndex = 0;
+ _isEos = 0;
+
+ for (int i = 0; i < _pointsCount; i++) {
+ _points[i]->x = 0;
+ _points[i]->y = 0;
+ }
+}
+
+Common::Point *CStepArray::getCurrPoint(Common::Point *point) {
+ if (_isEos || _points == 0) {
+ point->x = 0;
+ point->y = 0;
+ } else {
+ point = _points[_currPointIndex];
+ }
+ return point;
+}
+
+bool CStepArray::gotoNextPoint() {
+ if (_currPointIndex < _maxPointIndex) {
+ _currPointIndex++;
+ return true;
+ } else {
+ _isEos = 1;
+ return false;
+ }
+}
+
+StaticANIObject::StaticANIObject() {
+ _shadowsOn = 1;
+ _field_30 = 0;
+ _field_34 = 1;
+ _initialCounter = 0;
+ _messageQueueId = 0;
+ _animExFlag = 0;
+ _counter = 0;
+ _movement = 0;
+ _statics = 0;
+ _flags = 0;
+ _callback1 = 0;
+ _callback2 = 0;
+ _sceneId = -1;
+ _someDynamicPhaseIndex = -1;
+
+ _field_32 = 0;
+ _field_96 = 0;
+ _messageNum = 0;
+ _objtype = kObjTypeStaticANIObject;
+}
+
+StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
+ _shadowsOn = src->_shadowsOn;
+ _field_30 = src->_field_30;
+ _field_34 = 1;
+ _initialCounter = 0;
+
+ _field_32 = 0;
+ _field_96 = 0;
+ _messageNum = 0;
+
+ _messageQueueId = 0;
+ _animExFlag = 0;
+ _counter = 0;
+ _someDynamicPhaseIndex = -1;
+ _sceneId = src->_sceneId;
+ _callback1 = src->_callback1;
+ _callback2 = src->_callback2;
+ _objtype = kObjTypeStaticANIObject;
+
+ for (uint i = 0; i < src->_staticsList.size(); i++)
+ _staticsList.push_back(new Statics((Statics *)src->_staticsList[i], 0));
+
+ _movement = 0;
+ _statics = 0;
+
+ for (uint i = 0; i < src->_movements.size(); i++) {
+ Movement *mov;
+ if (((Movement *)src->_movements[i])->_currMovement) {
+ mov = new Movement(getMovementById(src->getMovementIdById(((Movement *)src->_movements[i])->_id)), this);
+ mov->_id = ((Movement *)src->_movements[i])->_id;
+ } else {
+ mov = new Movement(((Movement *)src->_movements[i]), 0, -1, this);
+ }
+
+ _movements.push_back(mov);
+ }
+}
+
+bool StaticANIObject::load(MfcArchive &file) {
+ debug(5, "StaticANIObject::load()");
+
+ GameObject::load(file);
+
+ int count = file.readUint16LE();
+
+ for (int i = 0; i < count; i++) {
+ Statics *st = new Statics();
+
+ st->load(file);
+ _staticsList.push_back(st);
+ }
+
+ count = file.readUint16LE();
+ debug(7, "Movements: %d", count);
+
+ for (int i = 0; i < count; i++) {
+ int movNum = file.readUint16LE();
+
+ char *movname = genFileName(_id, movNum, "mov");
+
+ Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(movname);
+
+ Movement *mov = new Movement();
+
+ MfcArchive archive(f);
+
+ mov->load(archive, this);
+
+ _movements.push_back(mov);
+
+ delete f;
+ free(movname);
+ }
+
+ Common::Point pt;
+ if (count) { // We have movements
+ ((Movement *)_movements[0])->getCurrDynamicPhaseXY(pt);
+ } else {
+ pt.x = pt.y = 100;
+ }
+
+ setOXY(pt.x, pt.y);
+
+ return true;
+}
+
+void StaticANIObject::setOXY(int x, int y) {
+ _ox = x;
+ _oy = y;
+
+ if (_movement)
+ _movement->setOXY(x, y);
+}
+
+void StaticANIObject::clearFlags() {
+ _flags = 0;
+
+ deleteFromGlobalMessageQueue();
+ _messageQueueId = 0;
+ _movement = 0;
+ _statics = 0;
+ _animExFlag = 0;
+ _counter = 0;
+ _messageNum = 0;
+ _stepArray.clear();
+}
+
+void StaticANIObject::setFlags40(bool state) {
+ if (state) {
+ _flags |= 0x40;
+ } else {
+ if (_flags & 0x40)
+ _flags ^= 0x40;
+ }
+}
+
+void StaticANIObject::deleteFromGlobalMessageQueue() {
+ while (_messageQueueId) {
+ if (g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId)) {
+ if (!isIdle())
+ return;
+
+ g_fullpipe->_globalMessageQueueList->deleteQueueById(_messageQueueId);
+ } else {
+ _messageQueueId = 0;
+ }
+ }
+}
+
+void StaticANIObject::queueMessageQueue(MessageQueue *mq) {
+ if (isIdle() && !(_flags & 0x80)) {
+ deleteFromGlobalMessageQueue();
+ _messageQueueId = 0;
+ _messageNum = 0;
+
+ if (_flags & 2)
+ _flags ^= 2;
+
+ if (mq) {
+ _animExFlag = 0;
+ if (_movement)
+ _messageQueueId = mq->_id;
+ else
+ mq->sendNextCommand();
+ } else {
+ _messageQueueId = 0;
+ }
+ }
+}
+
+MessageQueue *StaticANIObject::getMessageQueue() {
+ if (this->_messageQueueId <= 0)
+ return 0;
+
+ return g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+}
+
+bool StaticANIObject::trySetMessageQueue(int msgNum, int qId) {
+ if (_messageQueueId || !msgNum) {
+ updateGlobalMessageQueue(qId, _id);
+ return false;
+ }
+
+ _flags |= 2;
+
+ _messageNum = msgNum;
+ _messageQueueId = qId;
+
+ return true;
+}
+
+bool StaticANIObject::isIdle() {
+ if (_messageQueueId) {
+ MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+
+ if (m && m->getFlags() & 1)
+ return false;
+ }
+
+ return true;
+}
+
+Statics *StaticANIObject::getStaticsById(int itemId) {
+ for (uint i = 0; i < _staticsList.size(); i++)
+ if (((Statics *)_staticsList[i])->_staticsId == itemId)
+ return (Statics *)_staticsList[i];
+
+ return 0;
+}
+
+Statics *StaticANIObject::getStaticsByName(char *name) {
+ for (uint i = 0; i < _staticsList.size(); i++)
+ if (!strcmp(((Statics *)_staticsList[i])->_staticsName, name))
+ return (Statics *)_staticsList[i];
+
+ return 0;
+}
+
+Movement *StaticANIObject::getMovementById(int itemId) {
+ for (uint i = 0; i < _movements.size(); i++)
+ if (((Movement *)_movements[i])->_id == itemId)
+ return (Movement *)_movements[i];
+
+ return 0;
+}
+
+int StaticANIObject::getMovementIdById(int itemId) {
+ for (uint i = 0; i < _movements.size(); i++) {
+ Movement *mov = (Movement *)_movements[i];
+ if (mov->_currMovement) {
+ if (mov->_id == itemId)
+ return mov->_id;
+ if (mov->_currMovement->_id == itemId)
+ return mov->_id;
+ }
+ }
+
+ return 0;
+}
+
+Movement *StaticANIObject::getMovementByName(char *name) {
+ for (uint i = 0; i < _movements.size(); i++)
+ if (!strcmp(((Movement *)_movements[i])->_objectName, name))
+ return (Movement *)_movements[i];
+
+ return 0;
+}
+
+bool StaticANIObject::getPixelAtPos(int x, int y, int *pixel) {
+ bool res = false;
+ Picture *pic;
+
+ if (_movement)
+ pic = _movement->_currDynamicPhase;
+ else
+ pic = _statics;
+
+ if (!pic)
+ return false;
+
+ int ongoing;
+ int xani, yani;
+ int oxani, oyani;
+ Common::Point point;
+
+ if (_movement)
+ ongoing = _movement->_currMovement != 0;
+ else
+ ongoing = _statics->_staticsId & 0x4000;
+
+ if (_movement) {
+ _movement->getCurrDynamicPhaseXY(point);
+ xani = point.x;
+ yani = point.y;
+ oxani = _movement->_ox;
+ oyani = _movement->_oy;
+ } else {
+ _statics->getSomeXY(point);
+ xani = point.x;
+ yani = point.y;
+ oxani = _ox;
+ oyani = _oy;
+ }
+
+ int xtarget = x - (oxani - xani);
+ int ytarget = y - (oyani - yani);
+
+ if (ongoing && _movement)
+ xtarget = pic->getDimensions(&point)->x - xtarget;
+
+ x = pic->_x;
+ y = pic->_y;
+ pic->_x = 0;
+ pic->_y = 0;
+ if (pic->isPixelHitAtPos(xtarget, ytarget)) {
+ *pixel = pic->getPixelAtPos(xtarget, ytarget);
+
+ res = true;
+ } else {
+ res = false;
+ }
+ pic->_x = x;
+ pic->_y = y;
+
+ return res;
+}
+
+void Movement::draw(bool flipFlag, int angle) {
+ debug(3, "Movement::draw(%d, %d)", flipFlag, angle);
+
+ Common::Point point;
+
+ getCurrDynamicPhaseXY(point);
+
+ int x = _ox - point.x;
+ int y = _oy - point.y;
+
+ if (_currDynamicPhase->getPaletteData())
+ g_fullpipe->_globalPalette = _currDynamicPhase->getPaletteData();
+
+ if (_currDynamicPhase->getAlpha() < 0xFF) {
+ warning("Movement::draw: alpha < 0xff: %d", _currDynamicPhase->getAlpha());
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, _currDynamicPhase->getAlpha());
+ }
+
+ Bitmap *bmp;
+ if (_currMovement) {
+ bmp = _currDynamicPhase->getPixelData()->reverseImage();
+ } else {
+ bmp = _currDynamicPhase->getPixelData();
+ }
+
+ if (flipFlag) {
+ bmp->flipVertical()->drawShaded(1, x, y + 30 + _currDynamicPhase->_rect->bottom, _currDynamicPhase->_paletteData);
+ } if (angle) {
+ bmp->drawRotated(x, y, angle, _currDynamicPhase->_paletteData);
+ } else {
+ bmp->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData);
+ }
+
+ if (_currDynamicPhase->_rect->top) {
+ if (!_currDynamicPhase->_convertedBitmap) {
+ //v12 = Picture_getPixelData(v5);
+ //v13 = Bitmap_convertTo16Bit565(v12, (unsigned int *)&_currDynamicPhase->rect);
+ //_currDynamicPhase->convertedBitmap = v13;
+ }
+
+ if (_currDynamicPhase->_convertedBitmap) {
+ if (_currMovement) {
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top));
+ _currDynamicPhase->_convertedBitmap->reverseImage()->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData);
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
+ } else {
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, LOBYTE(_currDynamicPhase->rect.top));
+ _currDynamicPhase->_convertedBitmap->putDib(x, y, (int32 *)_currDynamicPhase->_paletteData);
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
+ }
+ }
+ }
+}
+
+
+void StaticANIObject::loadMovementsPixelData() {
+ for (uint i = 0; i < _movements.size(); i++)
+ ((Movement *)_movements[i])->loadPixelData();
+}
+
+Statics *StaticANIObject::addReverseStatics(Statics *st) {
+ Statics *res = getStaticsById(st->_staticsId ^ 0x4000);
+
+ if (!res) {
+ res = new Statics(st, true);
+
+ _staticsList.push_back(res);
+ }
+
+ return res;
+}
+
+void StaticANIObject::draw() {
+ if ((_flags & 4) == 0)
+ return;
+
+ Common::Point point;
+ Common::Rect rect;
+
+ debug(0, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
+
+ if (_shadowsOn && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_shadows
+ && (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) {
+
+ DynamicPhase *dyn;
+
+ if (!_movement || _flags & 0x20)
+ dyn = _statics;
+ else
+ dyn = _movement->_currDynamicPhase;
+
+ if (!dyn) {
+ warning("HACK: StaticANIObject::draw(): dyn is missing");
+ return;
+ }
+
+ if (dyn->getDynFlags() & 4) {
+ rect = *dyn->_rect;
+
+ DynamicPhase *shd = g_fullpipe->_currentScene->_shadows->findSize(rect.width(), rect.height());
+ if (shd) {
+ shd->getDimensions(&point);
+ int midx = _ox - point.x / 2 - dyn->_someX;
+ int midy = _oy - point.y / 2 - dyn->_someY + rect.bottom - 3;
+ int shdw = point.y;
+
+ int px;
+ if (!_movement || (_flags & 0x20))
+ px = _statics->getCenter(&point)->x;
+ else
+ px = _movement->getCenter(&point)->x;
+
+ if (_shadowsOn != 1)
+ midy = _shadowsOn - shdw / 2;
+
+ shd->draw(px + midx, midy, 0, 0);
+ }
+ }
+ }
+
+ int angle = 0;
+ if (_field_30 & 0xC000) {
+ if (_field_30 & 0x8000)
+ angle = -(_field_30 ^ 0x8000);
+ else
+ angle = _field_30 ^ 0x4000;
+ }
+
+ if (!_movement || (_flags & 0x20)) {
+ _statics->getSomeXY(point);
+ _statics->_x = _ox - point.x;
+ _statics->_y = _oy - point.y;
+ _statics->draw(_statics->_x, _statics->_y, 0, angle);
+ } else {
+ _movement->draw(0, angle);
+ }
+}
+
+void StaticANIObject::draw2() {
+ debug(0, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
+
+ if ((_flags & 4) && (_flags & 0x10)) {
+ if (_movement) {
+ _movement->draw(1, 0);
+ } else {
+ Common::Point point;
+
+ _statics->getSomeXY(point);
+
+ _statics->draw(_ox - point.x, _oy - point.y, 1, 0);
+ }
+ }
+}
+
+MovTable *StaticANIObject::countMovements() {
+ CGameVar *preloadSubVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("PRELOAD");
+
+ if (preloadSubVar || preloadSubVar->getSubVarsCount() == 0)
+ return 0;
+
+ MovTable *movTable = new MovTable;
+
+ movTable->count = _movements.size();
+ movTable->movs = (int16 *)calloc(_movements.size(), sizeof(int16));
+
+ for (uint i = 0; i < _movements.size(); i++) {
+ GameObject *obj = (GameObject *)_movements[i];
+ movTable->movs[i] = 2;
+
+ for (CGameVar *sub = preloadSubVar->_subVars; sub; sub = sub->_nextVarObj) {
+ if (scumm_stricmp(obj->getName(), sub->_varName) == 0) {
+ movTable->movs[i] = 1;
+ break;
+ }
+ }
+ }
+
+ return movTable;
+}
+
+void StaticANIObject::setSpeed(int speed) {
+ CGameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("SpeedUp");
+
+ if (!var)
+ return;
+
+ for (var = var->_subVars; var; var = var->_nextVarObj) {
+ Movement *mov = getMovementById(var->_value.intValue);
+
+ if (mov) {
+ if (speed) {
+ if (mov->_counterMax == 83)
+ mov->_counterMax = 41;
+ } else if (mov->_counterMax == 41) {
+ mov->_counterMax = 83;
+ }
+ }
+ }
+
+}
+
+void StaticANIObject::setAlpha(int alpha) {
+ for (uint i = 0; i < _movements.size(); i++)
+ ((Movement *)_movements[i])->setAlpha(alpha);
+
+ for (uint i = 0; i < _staticsList.size(); i++)
+ ((Statics *)_staticsList[i])->setAlpha(alpha);
+}
+
+void StaticANIObject::initMovements() {
+ for (uint i = 0; i < _movements.size(); i++)
+ ((Movement *)_movements[i])->removeFirstPhase();
+}
+
+Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
+ Picture *pic;
+
+ if (_movement)
+ pic = _movement->_currDynamicPhase;
+ else
+ pic = _statics;
+
+ if (pic) {
+ Common::Point point;
+
+ pic->getDimensions(&point);
+ p.x = point.x;
+ p.y = point.y;
+ } else {
+ p.x = 0;
+ p.y = 0;
+ }
+
+ return &p;
+}
+
+void StaticANIObject::update(int counterdiff) {
+ int mqid;
+
+ debug(6, "StaticANIObject::update() (%s) [%d] [%d, %d] fl: %x", transCyrillic((byte *)_objectName), _id, _ox, _oy, _flags);
+
+ if (_flags & 2) {
+ _messageNum--;
+ if (_messageNum)
+ return;
+
+ mqid = _messageQueueId;
+ _messageQueueId = 0;
+ _flags ^= 2;
+
+ updateGlobalMessageQueue(mqid, _id);
+ return;
+ }
+
+ Common::Point point;
+ ExCommand *ex, *newex;
+
+ if (_movement) {
+ _movement->_counter += counterdiff;
+
+ if (_movement->_counter < _movement->_counterMax)
+ return;
+
+ _movement->_counter = 0;
+
+ if (_flags & 1) {
+ if (_counter) {
+ _counter--;
+
+ return;
+ }
+
+ DynamicPhase *dyn = _movement->_currDynamicPhase;
+ if (dyn->_initialCountdown == dyn->_countdown) {
+
+ ex = dyn->getExCommand();
+ if (ex && ex->_messageKind != 35) {
+ newex = new ExCommand(ex);
+ newex->_excFlags |= 2;
+ if (newex->_messageKind == 17) {
+ newex->_parentId = _id;
+ newex->_keyCode = _okeyCode;
+ }
+ newex->sendMessage();
+
+ if (!_movement)
+ return;
+ }
+ }
+
+ if (dyn->_initialCountdown != dyn->_countdown || dyn->_field_68 == 0) {
+ newex = new ExCommand(_id, 17, dyn->_field_68, 0, 0, 0, 1, 0, 0, 0);
+ newex->_excFlags = 2;
+ newex->_keyCode = _okeyCode;
+ newex->sendMessage();
+
+ if (!_movement)
+ return;
+ }
+
+ if (!_movement->gotoNextFrame(_callback1, _callback2)) {
+ stopAnim_maybe();
+ } else {
+ setOXY(_movement->_ox, _movement->_oy);
+ _counter = _initialCounter;
+
+ if (dyn->_initialCountdown == dyn->_countdown) {
+ ex = dyn->getExCommand();
+ if (ex) {
+ if (ex->_messageKind == 35) {
+ newex = new ExCommand(ex);
+ newex->_excFlags |= 2;
+ newex->sendMessage();
+ }
+ }
+ }
+ if (!_movement)
+ return;
+
+ _stepArray.getCurrPoint(&point);
+ setOXY(point.x + _ox, point.y + _oy);
+ _stepArray.gotoNextPoint();
+ if (_someDynamicPhaseIndex == _movement->_currDynamicPhaseIndex)
+ adjustSomeXY();
+ }
+ } else if (_flags & 0x20) {
+ _flags ^= 0x20;
+ _flags |= 1;
+
+ _movement->gotoFirstFrame();
+ _movement->getCurrDynamicPhaseXY(point);
+
+ Common::Point pointS;
+ _statics->getSomeXY(pointS);
+ _movement->setOXY(_ox + point.x + _movement->_mx - pointS.x,
+ _oy + point.y + _movement->_my - pointS.y);
+ }
+ } else {
+ if (_statics) {
+ if (_messageQueueId) {
+ if (_statics->_countdown) {
+ _statics->_countdown--;
+ return;
+ }
+ mqid = _messageQueueId;
+ _messageQueueId = 0;
+ updateGlobalMessageQueue(mqid, _id);
+ }
+ }
+ }
+}
+
+void StaticANIObject::stopAnim_maybe() {
+ debug(6, "StaticANIObject::stopAnim_maybe()");
+
+ if (!(_flags & 1))
+ return;
+
+ _flags ^= 1;
+
+ int oid = 0;
+ int oldmqid = _messageQueueId;
+ Common::Point point;
+
+ if (_movement) {
+ setOXY(_movement->_ox, _movement->_oy);
+
+ if (_flags & 0x40) {
+ if (!_movement->_currMovement && !_movement->_currDynamicPhaseIndex) {
+ _statics = _movement->_staticsObj1;
+ _movement->getCurrDynamicPhaseXY(point);
+ _ox -= point.x;
+ _oy -= point.y;
+
+ _ox -= _movement->_mx;
+ _oy -= _movement->_my;
+
+ _statics->getSomeXY(point);
+ if (_movement->_currMovement) {
+ _oy += point.y;
+ _ox -= point.x;
+ _ox += _statics->getDimensions(&point)->x;
+ } else {
+ _ox += point.x;
+ _oy += point.y;
+ }
+ }
+ }
+
+ if (_movement->_currDynamicPhaseIndex || !(_flags & 0x40))
+ _statics = _movement->_staticsObj2;
+
+ _statics->getSomeXY(point);
+
+ _statics->_x = _ox - point.x;
+ _statics->_y = _oy - point.y;
+ oid = _movement->_id;
+ _movement = 0;
+
+ ExCommand *ex = new ExCommand(_id, 17, 24, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = _okeyCode;
+ ex->_excFlags = 2;
+ ex->postMessage();
+ }
+
+ int mqid = _messageQueueId;
+
+ if (_animExFlag) {
+ _messageQueueId = 0;
+ startAnimEx(oid, mqid, -1, -1);
+ } else {
+ if (_messageQueueId == oldmqid) {
+ _messageQueueId = 0;
+ if (_field_34 == 1)
+ updateGlobalMessageQueue(mqid, _id);
+ }
+ }
+}
+
+void StaticANIObject::adjustSomeXY() {
+ warning("STUB: StaticANIObject::adjustSomeXY()");
+}
+
+MessageQueue *StaticANIObject::changeStatics1(int msgNum) {
+ warning("STUB: StaticANIObject::changeStatics1(%d)", msgNum);
+
+ return 0;
+}
+
+void StaticANIObject::changeStatics2(int objId) {
+ warning("STUB: StaticANIObject::changeStatics2(%d)", objId);
+}
+
+void StaticANIObject::hide() {
+ if (!_messageQueueId) {
+ if (_flags & 4)
+ _flags ^= 4;
+ }
+}
+
+void StaticANIObject::show1(int x, int y, int movId, int mqId) {
+ debug(0, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId);
+
+ if (_messageQueueId)
+ return;
+
+ if (movId == -1) {
+ _flags |= 4u;
+ if (x != -1 && y != -1) {
+ setOXY(x, y);
+ }
+
+ return;
+ }
+
+ Movement *mov = getMovementById(movId);
+ if (!mov)
+ return;
+
+ if (x != -1 && y != -1) {
+ setOXY(x, y);
+ }
+
+ _statics = mov->_staticsObj1;
+
+ Common::Point point;
+
+ mov->_staticsObj1->getSomeXY(point);
+ _statics->_x = x - point.x;
+ _statics->_y = y - point.y;
+
+ _statics->_countdown = _statics->_initialCountdown;
+
+ _flags |= 4;
+ _ox = x;
+ _oy = y;
+ _movement = 0;
+
+ if (mov->_currMovement)
+ _flags |= 8;
+ else if (_flags & 8)
+ _flags ^= 8;
+
+ if (_flags & 1)
+ _flags ^= 1;
+
+ _messageQueueId = mqId;
+}
+
+void StaticANIObject::show2(int x, int y, int movementId, int mqId) {
+ warning("STUB: StaticANIObject::show2(%d, %d, %d, %d)", x, y, movementId, mqId);
+}
+
+void StaticANIObject::playIdle() {
+ if (isIdle())
+ adjustSomeXY();
+}
+
+void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex) {
+ warning("STUB: StaticANIObject::startAnimSteps()");
+}
+
+bool StaticANIObject::startAnimEx(int movid, int parId, int flag1, int flag2) {
+ bool res = startAnim(movid, parId, -1);
+ if (res)
+ _animExFlag = 1;
+
+ _someDynamicPhaseIndex = -1;
+ return res;
+}
+
+bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhaseIdx) {
+ if (_flags & 0x80)
+ return false;
+
+ debug(0, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy);
+
+ if (_messageQueueId) {
+ updateGlobalMessageQueue(messageQueueId, _id);
+ return false;
+ }
+
+ Movement *mov = 0;
+
+ for (uint i = 0; i < _movements.size(); i++) {
+
+ if (((Movement *)_movements[i])->_id == movementId) {
+ mov = (Movement *)_movements[i];
+ break;
+ }
+ }
+
+ if (!mov) {
+ updateGlobalMessageQueue(messageQueueId, _id);
+ return false;
+ }
+
+ if (mov == _movement) {
+ _flags |= 1;
+ _messageQueueId = messageQueueId;
+
+ return true;
+ }
+
+ int newx = _ox;
+ int newy = _oy;
+ Common::Point point;
+
+ debug(0, "0 %d %d", newx, newy);
+ if (_movement) {
+ _movement->getCurrDynamicPhaseXY(point);
+
+ newx -= point.x;
+ newy -= point.y;
+
+ debug(0, "1 %d %d", newx, newy);
+ } else if (_statics) {
+ _statics->getSomeXY(point);
+
+ newx -= point.x;
+ newy -= point.y;
+ debug(0, "2 %d %d - %d %d assa", newx, newy, point.x, point.y);
+ }
+
+ _movement = mov;
+
+ _stepArray.clear();
+
+ if (_flags & 0x40)
+ _movement->gotoLastFrame();
+ else
+ _movement->gotoFirstFrame();
+
+ if (!(_flags & 0x40)) {
+ if (!_movement->_currDynamicPhaseIndex) {
+ _stepArray.getCurrPoint(&point);
+ newx += point.x + _movement->_mx;
+ newy += point.y + _movement->_my;
+
+ debug(0, "3 %d %d", newx, newy);
+ _stepArray.gotoNextPoint();
+
+ ExCommand *ex = _movement->_currDynamicPhase->getExCommand();
+ if (ex) {
+ if (ex->_messageKind == 35) {
+ ExCommand *newex = new ExCommand(ex);
+ newex->_excFlags |= 2;
+ newex->sendMessage();
+ }
+ }
+ }
+ }
+
+ _movement->getCurrDynamicPhaseXY(point);
+ setOXY(point.x + newx, point.y + newy);
+
+ if (_movement->_staticsObj2->_staticsId & 0x4000)
+ _flags |= 8;
+ else
+ _flags &= 0xFFF7;
+
+ _flags |= 1;
+
+ _messageQueueId = messageQueueId;
+ _movement->_currDynamicPhase->_countdown = _movement->_currDynamicPhase->_initialCountdown;
+ _movement->_counter = 0;
+
+ _counter = _initialCounter;
+ _someDynamicPhaseIndex = dynPhaseIdx;
+
+ _stepArray.clear();
+
+ ExCommand *newex = new ExCommand(_id, 17, 23, 0, 0, movementId, 1, 0, 0, 0);
+
+ newex->_keyCode = _okeyCode;
+ newex->_excFlags = 2;
+
+ newex->postMessage();
+
+ return true;
+}
+
+Statics::Statics() {
+ _staticsId = 0;
+ _picture = 0;
+ _staticsName = 0;
+}
+
+Statics::Statics(Statics *src, bool reverse) : DynamicPhase(src, reverse) {
+ _staticsId = src->_staticsId;
+
+ if (reverse) {
+ _staticsId ^= 0x4000;
+ int newlen = strlen(src->_staticsName) + strlen(sO_MirroredTo) + 1;
+ _staticsName = (char *)calloc(newlen, 1);
+
+ snprintf(_staticsName, newlen, "%s%s", sO_MirroredTo, src->_staticsName);
+ } else {
+ _staticsName = (char *)calloc(strlen(src->_staticsName) + 1, 1);
+ strncpy(_staticsName, src->_staticsName, strlen(src->_staticsName) + 1);
+ }
+
+ _memfilename = (char *)calloc(strlen(src->_memfilename) + 1, 1);
+ strncpy(_memfilename, src->_memfilename, strlen(src->_memfilename) + 1);
+
+ _picture = new Picture();
+}
+
+bool Statics::load(MfcArchive &file) {
+ debug(5, "Statics::load()");
+
+ DynamicPhase::load(file);
+
+ _staticsId = file.readUint16LE();
+
+ _staticsName = file.readPascalString();
+ debug(7, "statics: <%s> id: %d (%x)", transCyrillic((byte *)_staticsName), _staticsId, _staticsId);
+
+ _picture = new Picture();
+ _picture->load(file);
+
+ return true;
+}
+
+Common::Point *Statics::getSomeXY(Common::Point &p) {
+ p.x = _someX;
+ p.y = _someY;
+
+ return &p;
+}
+
+Common::Point *Statics::getCenter(Common::Point *p) {
+ Common::Rect rect;
+
+ rect = *_rect;
+
+ if (_staticsId & 0x4000) {
+ Common::Point point;
+
+ getDimensions(&point);
+ rect.moveTo(point.x - _rect->right, _rect->top);
+ }
+
+ p->x = rect.left + _rect->width() / 2;
+ p->y = rect.top + _rect->height() / 2;
+
+ return p;
+}
+
+Movement::Movement() {
+ _lastFrameSpecialFlag = 0;
+ _flipFlag = 0;
+ _updateFlag1 = 0;
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+ _mx = 0;
+ _my = 0;
+ _m2x = 0;
+ _m2y = 0;
+ _field_50 = 1;
+ _field_78 = 0;
+ _framePosOffsets = 0;
+ _field_84 = 0;
+ _currDynamicPhase = 0;
+ _field_8C = 0;
+ _currDynamicPhaseIndex = 0;
+ _field_94 = 0;
+ _currMovement = 0;
+ _counter = 0;
+ _counterMax = 83;
+
+ _field_24 = 0;
+ _field_28 = 0;
+}
+
+Movement::Movement(Movement *src, StaticANIObject *ani) {
+ _lastFrameSpecialFlag = 0;
+ _flipFlag = src->_flipFlag;
+ _updateFlag1 = src->_updateFlag1;
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+ _mx = 0;
+ _my = 0;
+ _m2x = 0;
+ _m2y = 0;
+
+ _field_78 = 0;
+ _framePosOffsets = 0;
+ _field_84 = 0;
+ _currDynamicPhase = 0;
+ _field_8C = 0;
+ _currDynamicPhaseIndex = src->_currDynamicPhaseIndex;
+ _field_94 = 0;
+
+ _currMovement = src;
+ _ox = src->_ox;
+ _oy = src->_oy;
+
+ initStatics(ani);
+
+ _counterMax = src->_counterMax;
+ _counter = src->_counter;
+ _field_50 = src->_field_50;
+
+ updateCurrDynamicPhase();
+}
+
+Movement::Movement(Movement *src, int *flag1, int flag2, StaticANIObject *ani) {
+ warning("STUB: Movement(src, %p, %d, ani)", (void *)flag1, flag2);
+}
+
+bool Movement::load(MfcArchive &file) {
+ warning("STUB: Movement::load");
+ return true;
+}
+
+bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
+ GameObject::load(file);
+
+ int dynCount = file.readUint16LE();
+
+ debug(7, "dynCount: %d _id: %d", dynCount, _id);
+ if (dynCount != 0xffff || _id == MV_MAN_TURN_LU) {
+ _framePosOffsets = (Common::Point **)calloc(dynCount + 2, sizeof(Common::Point *));
+
+ for (int i = 0; i < dynCount + 2; i++)
+ _framePosOffsets[i] = new Common::Point();
+
+ for (int i = 0; i < dynCount; i++) {
+ DynamicPhase *ph = new DynamicPhase();
+ ph->load(file);
+
+ _dynamicPhases.push_back(ph);
+
+ _framePosOffsets[i]->x = ph->_x;
+ _framePosOffsets[i]->y = ph->_y;
+ }
+
+ int staticsid = file.readUint16LE();
+
+ _staticsObj1 = ani->getStaticsById(staticsid);
+
+ if (!_staticsObj1 && (staticsid & 0x4000)) {
+ Statics *s = ani->getStaticsById(staticsid ^ 0x4000);
+ _staticsObj1 = ani->addReverseStatics(s);
+ }
+
+ _mx = file.readUint32LE();
+ _my = file.readUint32LE();
+
+ staticsid = file.readUint16LE();
+
+ _staticsObj2 = ani->getStaticsById(staticsid);
+
+ if (!_staticsObj2 && (staticsid & 0x4000)) {
+ Statics *s = ani->getStaticsById(staticsid ^ 0x4000);
+ _staticsObj2 = ani->addReverseStatics(s);
+ }
+
+ _m2x = file.readUint32LE();
+ _m2y = file.readUint32LE();
+
+ if (_staticsObj2) {
+ _dynamicPhases.push_back(_staticsObj2);
+
+ _framePosOffsets[_dynamicPhases.size() - 1]->x = _m2x;
+ _framePosOffsets[_dynamicPhases.size() - 1]->y = _m2y;
+ }
+
+ } else {
+ int movid = file.readUint16LE();
+
+ _currMovement = ani->getMovementById(movid);
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+
+ initStatics(ani);
+ }
+
+ if (_staticsObj1 && _staticsObj2) {
+ if ((_staticsObj1->_staticsId ^ _staticsObj2->_staticsId) & 0x4000)
+ _flipFlag = 1;
+ }
+
+ if (g_fullpipe->_gameProjectVersion >= 8)
+ _field_50 = file.readUint32LE();
+
+ if (g_fullpipe->_gameProjectVersion < 12)
+ _counterMax = 83;
+ else
+ _counterMax = file.readUint32LE();
+
+ _counter = 0;
+ updateCurrDynamicPhase();
+
+ return true;
+}
+
+Common::Point *Movement::getCurrDynamicPhaseXY(Common::Point &p) {
+ p.x = _currDynamicPhase->_someX;
+ p.y = _currDynamicPhase->_someY;
+
+ return &p;
+}
+
+void Movement::setAlpha(int alpha) {
+ if (_currMovement)
+ for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
+ ((DynamicPhase *)_currMovement->_dynamicPhases[i])->setAlpha(alpha);
+ }
+ else
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ ((DynamicPhase *)_dynamicPhases[i])->setAlpha(alpha);
+ }
+}
+
+Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex) {
+ int idx = phaseIndex;
+
+ if (idx == -1)
+ idx = _currDynamicPhaseIndex;
+
+ DynamicPhase *dyn;
+
+ if (_currMovement)
+ dyn = (DynamicPhase *)_currMovement->_dynamicPhases[idx];
+ else
+ dyn = (DynamicPhase *)_dynamicPhases[idx];
+
+ Common::Point point;
+
+ dyn->getDimensions(&point);
+
+ *p = point;
+
+ return p;
+}
+
+void Movement::initStatics(StaticANIObject *ani) {
+ if (!_currMovement)
+ return;
+
+ debug(7, "Movement::initStatics()");
+
+ _staticsObj2 = ani->addReverseStatics(_currMovement->_staticsObj2);
+ _staticsObj1 = ani->addReverseStatics(_currMovement->_staticsObj1);
+
+ _mx = _currMovement->_mx;
+ _my = _currMovement->_my;
+
+ _currMovement->setDynamicPhaseIndex(_currMovement->_updateFlag1 != 0 ? 1 : 0);
+
+ Common::Point point;
+
+ int x1 = _currMovement->_staticsObj1->getDimensions(&point)->x - _mx;
+
+ _mx = x1 - _currMovement->_currDynamicPhase->getDimensions(&point)->x;
+
+ _currMovement->setDynamicPhaseIndex(_currMovement->_currDynamicPhaseIndex);
+
+ _m2x = _currMovement->_m2x;
+ _m2y = _currMovement->_m2y;
+ _currMovement->gotoLastFrame();
+
+ x1 = _currMovement->_staticsObj2->getDimensions(&point)->x;
+ _m2x = _currMovement->_currDynamicPhase->getDimensions(&point)->x - _m2x - x1;
+}
+
+void Movement::updateCurrDynamicPhase() {
+ debug(7, "Movement::updateCurrDynamicPhase()");
+
+ if (_currMovement) {
+ if (_currMovement->_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _currMovement->_dynamicPhases.size())
+ return;
+
+ if (_currMovement->_dynamicPhases[_currDynamicPhaseIndex])
+ _currDynamicPhase = (DynamicPhase *)_currMovement->_dynamicPhases[_currDynamicPhaseIndex];
+ } else {
+ if (_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _dynamicPhases.size())
+ return;
+
+ if (_dynamicPhases[_currDynamicPhaseIndex])
+ _currDynamicPhase = (DynamicPhase *)_dynamicPhases[_currDynamicPhaseIndex];
+ }
+}
+
+int Movement::calcDuration() {
+ int res = 0;
+
+ if (_currMovement)
+ for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
+ res += ((DynamicPhase *)_currMovement->_dynamicPhases[i])->_initialCountdown;
+ }
+ else
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ res += ((DynamicPhase *)_dynamicPhases[i])->_initialCountdown;
+ }
+
+ return res;
+}
+
+void Movement::setDynamicPhaseIndex(int index) {
+ debug(7, "Movement::setDynamicPhaseIndex(%d)", index);
+ while (_currDynamicPhaseIndex < index)
+ gotoNextFrame(0, 0);
+
+ while (_currDynamicPhaseIndex > index)
+ gotoPrevFrame();
+}
+
+DynamicPhase *Movement::getDynamicPhaseByIndex(int idx) {
+ debug(7, "Movement::updateCurrDynamicPhase()");
+
+ if (_currMovement) {
+ if (_currMovement->_dynamicPhases.size() == 0 || (uint)idx >= _currMovement->_dynamicPhases.size())
+ return 0;
+
+ return (DynamicPhase *)_currMovement->_dynamicPhases[idx];
+ } else {
+ if (_dynamicPhases.size() == 0 || (uint)idx >= _dynamicPhases.size())
+ return 0;
+
+ return (DynamicPhase *)_dynamicPhases[idx];
+ }
+}
+
+void Movement::loadPixelData() {
+ Movement *mov = this;
+ for (Movement *i = _currMovement; i; i = i->_currMovement)
+ mov = i;
+
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ if ((Statics *)_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000))
+ ((Statics *)_dynamicPhases[i])->getPixelData();
+ }
+
+ if (!(mov->_staticsObj1->_staticsId & 0x4000))
+ mov->_staticsObj1->getPixelData();
+}
+
+void Movement::removeFirstPhase() {
+ if (_updateFlag1) {
+ if (!_currDynamicPhaseIndex)
+ gotoNextFrame(0, 0);
+
+ if (!_currMovement) {
+ _dynamicPhases.remove_at(0);
+
+ for (uint i = 0; i < _dynamicPhases.size(); i++) {
+ _framePosOffsets[i - 1]->x = _framePosOffsets[i]->x;
+ _framePosOffsets[i - 1]->y = _framePosOffsets[i]->y;
+ }
+ }
+ _currDynamicPhaseIndex--;
+ }
+
+ updateCurrDynamicPhase();
+ _updateFlag1 = 0;
+}
+
+bool Movement::gotoNextFrame(int callback1, void (*callback2)(int *)) {
+ debug(8, "Movement::gotoNextFrame()");
+
+ if (!callback2) {
+ if (_currMovement) {
+ if ((uint)_currDynamicPhaseIndex == _currMovement->_dynamicPhases.size() - 1
+ && !(((DynamicPhase *)(_currMovement->_dynamicPhases.back()))->_countdown)) {
+ return false;
+ }
+ } else if ((uint)_currDynamicPhaseIndex == _dynamicPhases.size() - 1
+ && !(((DynamicPhase *)(_dynamicPhases.back()))->_countdown)) {
+ return false;
+ }
+ }
+
+ if (_currDynamicPhase->_countdown) {
+ _currDynamicPhase->_countdown--;
+ return true;
+ }
+
+ Common::Point point;
+
+ getCurrDynamicPhaseXY(point);
+ _ox -= point.x;
+ _oy -= point.y;
+
+ int deltax = 0;
+
+ if (_currMovement)
+ deltax = _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+
+ int oldDynIndex = _currDynamicPhaseIndex;
+
+ if (callback2)
+ callback2(&_currDynamicPhaseIndex);
+ else
+ _currDynamicPhaseIndex++;
+
+ bool result = true;
+
+ if (_currMovement) {
+ if (_currMovement->_dynamicPhases.size() <= (uint)_currDynamicPhaseIndex) {
+ _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1;
+ result = (callback2 == 0);
+ }
+ if (_currDynamicPhaseIndex < 0) {
+ _currDynamicPhaseIndex = 0;
+ result = false;
+ }
+ if (_currMovement->_framePosOffsets) {
+ if (callback1) {
+ point = *_currMovement->_framePosOffsets[_currDynamicPhaseIndex];
+ //callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
+
+ _ox += deltax - point.x;
+ _oy += point.y;
+
+ _ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+ } else if (oldDynIndex >= _currDynamicPhaseIndex) {
+ while (oldDynIndex > _currDynamicPhaseIndex) {
+ _ox += deltax;
+ deltax = _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x;
+
+ _ox += _currMovement->_framePosOffsets[oldDynIndex]->x;
+ _oy -= _currMovement->_framePosOffsets[oldDynIndex]->y;
+ oldDynIndex--;
+
+ _ox -= _currMovement->getDimensionsOfPhase(&point, oldDynIndex)->x;
+ }
+ } else {
+ for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
+ _ox += deltax;
+ deltax = _currMovement->getDimensionsOfPhase(&point, i)->x;
+ _ox -= _currMovement->_framePosOffsets[i]->x;
+ _oy += _currMovement->_framePosOffsets[i]->y;
+ _ox -= _currMovement->getDimensionsOfPhase(&point, i)->x;
+ }
+ }
+ }
+ } else {
+ if (_dynamicPhases.size() <= (uint)_currDynamicPhaseIndex) {
+ _currDynamicPhaseIndex = _dynamicPhases.size() - 1;
+ result = (callback2 == 0);
+ }
+ if (_currDynamicPhaseIndex < 0) {
+ _currDynamicPhaseIndex = 0;
+ result = false;
+ }
+
+ if (_framePosOffsets) {
+ if (callback1) {
+ point.x = _framePosOffsets[_currDynamicPhaseIndex]->x;
+ point.y = _framePosOffsets[_currDynamicPhaseIndex]->y;
+
+ //callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
+ _ox += point.x;
+ _oy += point.y;
+ } else if (oldDynIndex >= _currDynamicPhaseIndex) {
+ for (int i = oldDynIndex; i > _currDynamicPhaseIndex; i--) {
+ _ox -= _framePosOffsets[i]->x;
+ _oy -= _framePosOffsets[i]->y;
+ }
+ } else {
+ for (int i = oldDynIndex + 1; i <= _currDynamicPhaseIndex; i++) {
+ _ox += _framePosOffsets[i]->x;
+ _oy += _framePosOffsets[i]->y;
+ }
+ }
+ }
+ }
+
+ updateCurrDynamicPhase();
+ getCurrDynamicPhaseXY(point);
+ _ox += point.x;
+ _oy += point.y;
+
+ _currDynamicPhase->_countdown = _currDynamicPhase->_initialCountdown;
+
+ return result;
+}
+
+bool Movement::gotoPrevFrame() {
+ debug(8, "Movement::gotoPrevFrame()");
+
+ if (!_currDynamicPhaseIndex) {
+ gotoLastFrame();
+ return false;
+ }
+
+ Common::Point point;
+
+ getCurrDynamicPhaseXY(point);
+
+ _ox -= point.x;
+ _oy -= point.y;
+
+ if (_currMovement) {
+ if (_currMovement->_framePosOffsets) {
+ _ox += _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+ _ox += _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->x;
+ _oy -= _currMovement->_framePosOffsets[_currDynamicPhaseIndex]->y;
+ }
+
+ _currDynamicPhaseIndex--;
+ if (_currDynamicPhaseIndex < 0)
+ _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1;
+
+ _ox -= _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex)->x;
+ } else {
+ if (_framePosOffsets) {
+ _ox -= _framePosOffsets[_currDynamicPhaseIndex]->x;
+ _oy -= _framePosOffsets[_currDynamicPhaseIndex]->y;
+ }
+
+ _currDynamicPhaseIndex--;
+ if (_currDynamicPhaseIndex < 0)
+ _currDynamicPhaseIndex = _currMovement->_dynamicPhases.size() - 1;
+ }
+
+ updateCurrDynamicPhase();
+ getCurrDynamicPhaseXY(point);
+
+ _ox += point.x;
+ _oy += point.y;
+
+ return true;
+}
+
+void Movement::gotoFirstFrame() {
+ while (_currDynamicPhaseIndex)
+ gotoPrevFrame();
+}
+
+void Movement::gotoLastFrame() {
+ if (_currMovement) {
+ while ((uint)_currDynamicPhaseIndex != _currMovement->_dynamicPhases.size() - 1)
+ gotoNextFrame(0, 0);
+ } else {
+ while ((uint)_currDynamicPhaseIndex != _dynamicPhases.size() - 1)
+ gotoNextFrame(0, 0);
+ }
+}
+
+Common::Point *Movement::getCenter(Common::Point *p) {
+ Common::Rect rect;
+
+ rect = *_currDynamicPhase->_rect;
+
+ if (_currMovement) {
+ Common::Point point;
+
+ _currMovement->getDimensionsOfPhase(&point, _currDynamicPhaseIndex);
+
+ rect.moveTo(point.x - _currDynamicPhase->_rect->right, _currDynamicPhase->_rect->top);
+ }
+
+ p->x = rect.left + _currDynamicPhase->_rect->width() / 2;
+ p->y = rect.top + _currDynamicPhase->_rect->height() / 2;
+
+ return p;
+}
+
+DynamicPhase::DynamicPhase() {
+ _someX = 0;
+ _rect = 0;
+ _field_7C = 0;
+ _field_7E = 0;
+ _dynFlags = 0;
+ _someY = 0;
+}
+
+DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
+ _field_7C = src->_field_7C;
+ _field_7E = 0;
+ _rect = new Common::Rect();
+
+ debug(0, "DynamicPhase::DynamicPhase(src, %d)", reverse);
+
+ if (reverse) {
+ if (!src->_bitmap)
+ src->init();
+
+ _bitmap = src->_bitmap->reverseImage();
+ _data = _bitmap->_pixels;
+ _dataSize = src->_dataSize;
+
+ if (g_fullpipe->_currArchive) {
+ _mfield_14 = 0;
+ _libHandle = g_fullpipe->_currArchive;
+ }
+
+ _mflags |= 1;
+
+ _someX = src->_someX;
+ _someY = src->_someY;
+ } else {
+ _mfield_14 = src->_mfield_14;
+ _mfield_8 = src->_mfield_8;
+ _mflags = src->_mflags;
+
+ _memfilename = (char *)calloc(strlen(src->_memfilename) + 1, 1);
+ strncpy(_memfilename, src->_memfilename, strlen(src->_memfilename) + 1);
+ _dataSize = src->_dataSize;
+ _mfield_10 = src->_mfield_10;
+ _libHandle = src->_libHandle;
+
+ _bitmap = src->_bitmap;
+ if (_bitmap)
+ _field_54 = 1;
+
+ _someX = src->_someX;
+ _someY = src->_someY;
+ }
+
+ *_rect = *src->_rect;
+
+ _width = src->_width;
+ _height = src->_height;
+ _field_7C = src->_field_7C;
+
+ if (src->getExCommand())
+ _exCommand = new ExCommand(src->getExCommand());
+ else
+ _exCommand = 0;
+
+ _initialCountdown = src->_initialCountdown;
+ _field_6A = src->_field_6A;
+ _dynFlags = src->_dynFlags;
+
+ setPaletteData(src->getPaletteData());
+
+ copyMemoryObject2(src);
+}
+
+bool DynamicPhase::load(MfcArchive &file) {
+ debug(5, "DynamicPhase::load()");
+
+ StaticPhase::load(file);
+
+ _field_7C = file.readUint16LE();
+ _rect = new Common::Rect();
+ _rect->left = file.readUint32LE();
+ _rect->top = file.readUint32LE();
+ _rect->right = file.readUint32LE();
+ _rect->bottom = file.readUint32LE();
+
+ assert (g_fullpipe->_gameProjectVersion >= 1);
+
+ _someX = file.readUint32LE();
+ _someY = file.readUint32LE();
+
+ assert (g_fullpipe->_gameProjectVersion >= 12);
+
+ _dynFlags = file.readUint32LE();
+
+ return true;
+}
+
+StaticPhase::StaticPhase() {
+ _field_6A = 1;
+ _initialCountdown = 0;
+ _countdown = 0;
+ _field_68 = 0;
+ _exCommand = 0;
+}
+
+bool StaticPhase::load(MfcArchive &file) {
+ debug(5, "StaticPhase::load()");
+
+ Picture::load(file);
+
+ _initialCountdown = file.readUint16LE();
+ _field_6A = file.readUint16LE();
+
+ if (g_fullpipe->_gameProjectVersion >= 12) {
+ _exCommand = (ExCommand *)file.readClass();
+
+ return true;
+ }
+
+ assert (g_fullpipe->_gameProjectVersion >= 12);
+
+ return true;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
new file mode 100644
index 0000000000..3d45ac6623
--- /dev/null
+++ b/engines/fullpipe/statics.h
@@ -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.
+ *
+ */
+
+#ifndef FULLPIPE_STATICS_H
+#define FULLPIPE_STATICS_H
+
+#include "fullpipe/gfx.h"
+
+namespace Fullpipe {
+
+class ExCommand;
+
+class CStepArray : public CObject {
+ int _currPointIndex;
+ Common::Point **_points;
+ int _maxPointIndex;
+ int _pointsCount;
+ int _isEos;
+
+ public:
+ CStepArray();
+ ~CStepArray();
+ void clear();
+
+ int getCurrPointIndex() { return _currPointIndex; }
+ Common::Point *getCurrPoint(Common::Point *point);
+ bool gotoNextPoint();
+};
+
+class StaticPhase : public Picture {
+ public:
+ int16 _initialCountdown;
+ int16 _countdown;
+ int16 _field_68;
+ int16 _field_6A;
+ ExCommand *_exCommand;
+
+ public:
+ StaticPhase();
+
+ virtual bool load(MfcArchive &file);
+
+ ExCommand *getExCommand() { return _exCommand; }
+};
+
+class DynamicPhase : public StaticPhase {
+ public:
+ int _someX;
+ int _someY;
+ Common::Rect *_rect;
+ int16 _field_7C;
+ int16 _field_7E;
+ int _dynFlags;
+
+ public:
+ DynamicPhase();
+ DynamicPhase(DynamicPhase *src, bool reverse);
+
+ virtual bool load(MfcArchive &file);
+
+ int getDynFlags() { return _dynFlags; }
+};
+
+class Statics : public DynamicPhase {
+ public:
+ int16 _staticsId;
+ char *_staticsName;
+ Picture *_picture;
+
+ public:
+ Statics();
+ Statics(Statics *src, bool reverse);
+
+ virtual bool load(MfcArchive &file);
+ Statics *getStaticsById(int itemId);
+
+ Common::Point *getSomeXY(Common::Point &p);
+ Common::Point *getCenter(Common::Point *p);
+};
+
+class StaticANIObject;
+
+class Movement : public GameObject {
+ public:
+ int _field_24;
+ int _field_28;
+ int _lastFrameSpecialFlag;
+ int _flipFlag;
+ int _updateFlag1;
+ Statics *_staticsObj1;
+ Statics *_staticsObj2;
+ int _mx;
+ int _my;
+ int _m2x;
+ int _m2y;
+ int _field_50;
+ int _counterMax;
+ int _counter;
+ CPtrList _dynamicPhases;
+ int _field_78;
+ Common::Point **_framePosOffsets;
+ Movement *_currMovement;
+ int _field_84;
+ DynamicPhase *_currDynamicPhase;
+ int _field_8C;
+ int _currDynamicPhaseIndex;
+ int _field_94;
+
+ public:
+ Movement();
+ Movement(Movement *src, StaticANIObject *ani);
+ Movement(Movement *src, int *flag1, int flag2, StaticANIObject *ani);
+
+ virtual bool load(MfcArchive &file);
+ bool load(MfcArchive &file, StaticANIObject *ani);
+
+ Common::Point *getCurrDynamicPhaseXY(Common::Point &p);
+ Common::Point *getCenter(Common::Point *p);
+ Common::Point *getDimensionsOfPhase(Common::Point *p, int phaseIndex);
+
+ void initStatics(StaticANIObject *ani);
+ void updateCurrDynamicPhase();
+
+ void setAlpha(int alpha);
+
+ void setDynamicPhaseIndex(int index);
+ DynamicPhase *getDynamicPhaseByIndex(int idx);
+
+ int calcDuration();
+
+ void removeFirstPhase();
+ bool gotoNextFrame(int callback1, void (*callback2)(int *));
+ bool gotoPrevFrame();
+ void gotoFirstFrame();
+ void gotoLastFrame();
+
+ void loadPixelData();
+
+ void draw(bool flipFlag, int angle);
+};
+
+class StaticANIObject : public GameObject {
+ public:
+ Movement *_movement;
+ Statics *_statics;
+ int _shadowsOn;
+ int16 _field_30;
+ int16 _field_32;
+ int _field_34;
+ int _initialCounter;
+ int _callback1;
+ void (*_callback2)(int *);
+ CPtrList _movements;
+ CPtrList _staticsList;
+ CStepArray _stepArray;
+ int16 _field_96;
+ int _messageQueueId;
+ int _messageNum;
+ int _animExFlag;
+ int _counter;
+ int _someDynamicPhaseIndex;
+
+ public:
+ int16 _sceneId;
+
+ public:
+ StaticANIObject();
+ StaticANIObject(StaticANIObject *src);
+
+ virtual bool load(MfcArchive &file);
+
+ void setOXY(int x, int y);
+ Statics *getStaticsById(int id);
+ Statics *getStaticsByName(char *name);
+ Movement *getMovementById(int id);
+ int getMovementIdById(int itemId);
+ Movement *getMovementByName(char *name);
+ Common::Point *getCurrDimensions(Common::Point &p);
+
+ void clearFlags();
+ void setFlags40(bool state);
+ bool isIdle();
+ void setAlpha(int alpha);
+
+ void deleteFromGlobalMessageQueue();
+ void queueMessageQueue(MessageQueue *msg);
+ MessageQueue *getMessageQueue();
+ bool trySetMessageQueue(int msgNum, int qId);
+
+ void initMovements();
+ void loadMovementsPixelData();
+
+ void setSomeDynamicPhaseIndex(int val) { _someDynamicPhaseIndex = val; }
+ void adjustSomeXY();
+
+ bool startAnim(int movementId, int messageQueueId, int dynPhaseIdx);
+ bool startAnimEx(int movid, int parId, int flag1, int flag2);
+ void startAnimSteps(int movementId, int messageQueueId, int x, int y, Common::Point **points, int pointsCount, int someDynamicPhaseIndex);
+
+ void hide();
+ void show1(int x, int y, int movementId, int mqId);
+ void show2(int x, int y, int movementId, int mqId);
+ void playIdle();
+ void update(int counterdiff);
+
+ Statics *addReverseStatics(Statics *ani);
+ void draw();
+ void draw2();
+
+ MovTable *countMovements();
+ void setSpeed(int speed);
+
+ void stopAnim_maybe();
+
+ MessageQueue *changeStatics1(int msgNum);
+ void changeStatics2(int objId);
+
+ bool getPixelAtPos(int x, int y, int *pixel);
+};
+
+struct MovTable {
+ int count;
+ int16 *movs;
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_STATICS_H */
diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp
new file mode 100644
index 0000000000..ee73aeaa64
--- /dev/null
+++ b/engines/fullpipe/utils.cpp
@@ -0,0 +1,484 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "common/file.h"
+#include "common/memstream.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/ngiarchive.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+bool CObject::loadFile(const char *fname) {
+ Common::File file;
+
+ if (!file.open(fname))
+ return false;
+
+ MfcArchive archive(&file);
+
+ return load(archive);
+}
+
+bool CObList::load(MfcArchive &file) {
+ debug(5, "CObList::load()");
+ int count = file.readCount();
+
+ debug(9, "CObList::count: %d:", count);
+
+ for (int i = 0; i < count; i++) {
+ debug(9, "CObList::[%d]", i);
+ CObject *t = file.readClass();
+
+ push_back(t);
+ }
+
+ return true;
+}
+
+bool CObArray::load(MfcArchive &file) {
+ debug(5, "CObArray::load()");
+ int count = file.readCount();
+
+ resize(count);
+
+ for (int i = 0; i < count; i++) {
+ CObject *t = file.readClass();
+
+ push_back(*t);
+ }
+
+ return true;
+}
+
+bool CDWordArray::load(MfcArchive &file) {
+ debug(5, "CWordArray::load()");
+ int count = file.readCount();
+
+ debug(9, "CDWordArray::count: %d", count);
+
+ resize(count);
+
+ for (int i = 0; i < count; i++) {
+ int32 t = file.readUint32LE();
+
+ push_back(t);
+ }
+
+ return true;
+}
+
+char *MfcArchive::readPascalString(bool twoByte) {
+ char *tmp;
+ int len;
+
+ if (twoByte)
+ len = readUint16LE();
+ else
+ len = readByte();
+
+ tmp = (char *)calloc(len + 1, 1);
+ read(tmp, len);
+
+ debug(9, "readPascalString: %d <%s>", len, transCyrillic((byte *)tmp));
+
+ return tmp;
+}
+
+MemoryObject::MemoryObject() {
+ _memfilename = 0;
+ _mfield_8 = 0;
+ _mfield_C = 0;
+ _mfield_10 = -1;
+ _mfield_14 = 1;
+ _dataSize = 0;
+ _mflags = 0;
+ _libHandle = 0;
+ _data = 0;
+}
+
+MemoryObject::~MemoryObject() {
+ freeData();
+ if (_memfilename)
+ free(_memfilename);
+}
+
+bool MemoryObject::load(MfcArchive &file) {
+ debug(5, "MemoryObject::load()");
+ _memfilename = file.readPascalString();
+
+ if (char *p = strchr(_memfilename, '\\')) {
+ for (char *d = _memfilename; *p;) {
+ p++;
+ *d++ = *p;
+ }
+ }
+
+ if (g_fullpipe->_currArchive) {
+ _mfield_14 = 0;
+ _libHandle = g_fullpipe->_currArchive;
+ }
+
+ return true;
+}
+
+void MemoryObject::loadFile(char *filename) {
+ debug(5, "MemoryObject::loadFile(<%s>)", filename);
+ if (!_data) {
+ Common::SeekableReadStream *s = g_fullpipe->_currArchive->createReadStreamForMember(filename);
+
+ if (s) {
+ assert(s->size() > 0);
+
+ _dataSize = s->size();
+
+ debug(5, "Loading %s (%d bytes)", filename, _dataSize);
+ _data = (byte *)calloc(_dataSize, 1);
+ s->read(_data, _dataSize);
+
+ delete s;
+ }
+ }
+}
+
+byte *MemoryObject::getData() {
+ load();
+
+ if (_mfield_14 || _mflags & 1) {
+ return _data;
+ } else {
+ error("Unhandled packed data");
+ }
+}
+
+byte *MemoryObject::loadData() {
+ load();
+ return _data;
+}
+
+void MemoryObject::freeData() {
+ if (_data)
+ free(_data);
+
+ _data = 0;
+}
+
+bool MemoryObject::testFlags() {
+ if (_mfield_8)
+ return false;
+
+ if (_mflags & 1)
+ return true;
+
+ return false;
+}
+
+MemoryObject2::MemoryObject2() {
+ _rows = 0;
+}
+
+MemoryObject2::~MemoryObject2() {
+ if (_rows)
+ free(_rows);
+}
+
+bool MemoryObject2::load(MfcArchive &file) {
+ debug(5, "MemoryObject2::load()");
+ MemoryObject::load(file);
+
+ _mflags |= 1;
+
+ debug(5, "MemoryObject2::load: <%s>", _memfilename);
+
+ if (_memfilename && *_memfilename) {
+ MemoryObject::loadFile(_memfilename);
+ }
+
+ return true;
+}
+
+void MemoryObject2::copyData(byte *src, int dataSize) {
+ if (_data)
+ freeData();
+
+ _dataSize = dataSize;
+ _data = (byte *)malloc(dataSize);
+
+ memcpy(_data, src, _dataSize);
+}
+
+int MfcArchive::readCount() {
+ int count = readUint16LE();
+
+ if (count == 0xffff)
+ count = readUint32LE();
+
+ return count;
+}
+
+double MfcArchive::readDouble() {
+ // FIXME: This is utterly cruel and unportable
+ // Some articles on the matter:
+ // http://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/
+ // http://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/
+
+ union {
+ struct {
+ int32 a;
+ int32 b;
+ } i;
+ double d;
+ } tmp;
+
+ tmp.i.a = readUint32LE();
+ tmp.i.b = readUint32LE();
+
+ return tmp.d;
+}
+
+enum {
+ kNullObject,
+ kCInteraction,
+ kMessageQueue,
+ kExCommand,
+ kCObjstateCommand,
+ kCGameVar,
+ kCMctlCompound,
+ kCMovGraph,
+ kCMovGraphLink,
+ kCMovGraphNode,
+ kCReactParallel,
+ kCReactPolygonal
+};
+
+const struct {
+ const char *name;
+ int id;
+} classMap[] = {
+ { "CInteraction", kCInteraction },
+ { "MessageQueue", kMessageQueue },
+ { "ExCommand", kExCommand },
+ { "CObjstateCommand", kCObjstateCommand },
+ { "CGameVar", kCGameVar },
+ { "CMctlCompound", kCMctlCompound },
+ { "CMovGraph", kCMovGraph },
+ { "CMovGraphLink", kCMovGraphLink },
+ { "CMovGraphNode", kCMovGraphNode },
+ { "CReactParallel", kCReactParallel },
+ { "CReactPolygonal", kCReactPolygonal },
+ { 0, 0 }
+};
+
+static const char *lookupObjectId(int id) {
+ for (int i = 0; classMap[i].name; i++) {
+ if (classMap[i].id == id)
+ return classMap[i].name;
+ }
+
+ return "";
+}
+
+static CObject *createObject(int objectId) {
+ switch (objectId) {
+ case kNullObject:
+ return 0;
+ case kCInteraction:
+ return new CInteraction();
+ case kMessageQueue:
+ return new MessageQueue();
+ case kExCommand:
+ return new ExCommand();
+ case kCObjstateCommand:
+ return new CObjstateCommand();
+ case kCGameVar:
+ return new CGameVar();
+ case kCMctlCompound:
+ return new CMctlCompound();
+ case kCMovGraph:
+ return new CMovGraph();
+ case kCMovGraphLink:
+ return new CMovGraphLink();
+ case kCMovGraphNode:
+ return new CMovGraphNode();
+ case kCReactParallel:
+ return new CReactParallel();
+ case kCReactPolygonal:
+ return new CReactPolygonal();
+ default:
+ error("Unknown objectId: %d", objectId);
+ }
+
+ return 0;
+}
+
+MfcArchive::MfcArchive(Common::SeekableReadStream *stream) {
+ for (int i = 0; classMap[i].name; i++) {
+ _classMap[classMap[i].name] = classMap[i].id;
+ }
+
+ _lastIndex = 1;
+ _level = 0;
+
+ _stream = stream;
+
+ _objectMap.push_back(0);
+ _objectIdMap.push_back(kNullObject);
+}
+
+CObject *MfcArchive::readClass() {
+ bool isCopyReturned;
+ CObject *res = parseClass(&isCopyReturned);
+
+ if (res && !isCopyReturned)
+ res->load(*this);
+
+ return res;
+}
+
+CObject *MfcArchive::parseClass(bool *isCopyReturned) {
+ char *name;
+ int objectId = 0;
+ CObject *res = 0;
+
+ uint obTag = readUint16LE();
+
+ debug(7, "parseClass::obTag = %d (%04x) at 0x%08x", obTag, obTag, pos() - 2);
+
+ if (obTag == 0xffff) {
+ int schema = readUint16LE();
+
+ debug(7, "parseClass::schema = %d", schema);
+
+ name = readPascalString(true);
+ debug(7, "parseClass::class <%s>", name);
+
+ if (!_classMap.contains(name)) {
+ error("Unknown class in MfcArchive: <%s>", name);
+ }
+
+ objectId = _classMap[name];
+
+ debug(7, "tag: %d 0x%x (%x)", _objectMap.size() - 1, _objectMap.size() - 1, objectId);
+
+ res = createObject(objectId);
+ _objectMap.push_back(res);
+ _objectIdMap.push_back(objectId);
+
+ _objectMap.push_back(res); // Basically a hack, but behavior is all correct
+ _objectIdMap.push_back(objectId);
+
+ *isCopyReturned = false;
+ } else if ((obTag & 0x8000) == 0) {
+ if (_objectMap.size() < obTag) {
+ error("Object index too big: %d at 0x%08x", obTag, pos() - 2);
+ }
+ res = _objectMap[obTag];
+
+ *isCopyReturned = true;
+ } else {
+
+ obTag &= ~0x8000;
+
+ if (_objectMap.size() < obTag) {
+ error("Object index too big: %d at 0x%08x", obTag, pos() - 2);
+ }
+
+ debug(7, "parseClass::obTag <%s>", lookupObjectId(_objectIdMap[obTag]));
+
+ objectId = _objectIdMap[obTag];
+
+ res = createObject(objectId);
+ _objectMap.push_back(res);
+ _objectIdMap.push_back(objectId);
+
+ *isCopyReturned = false;
+ }
+
+ return res;
+}
+
+char *genFileName(int superId, int sceneId, const char *ext) {
+ char *s = (char *)calloc(256, 1);
+
+ if (superId) {
+ snprintf(s, 255, "%04d%04d.%s", superId, sceneId, ext);
+ } else {
+ snprintf(s, 255, "%04d.%s", sceneId, ext);
+ }
+
+ debug(7, "genFileName: %s", s);
+
+ return s;
+}
+
+// Translates cp-1251..utf-8
+byte *transCyrillic(byte *s) {
+ static byte tmp[1024];
+
+ static int trans[] = { 0xa8, 0xd081, 0xb8, 0xd191, 0xc0, 0xd090,
+ 0xc1, 0xd091, 0xc2, 0xd092, 0xc3, 0xd093, 0xc4, 0xd094,
+ 0xc5, 0xd095, 0xc6, 0xd096, 0xc7, 0xd097, 0xc8, 0xd098,
+ 0xc9, 0xd099, 0xca, 0xd09a, 0xcb, 0xd09b, 0xcc, 0xd09c,
+ 0xcd, 0xd09d, 0xce, 0xd09e, 0xcf, 0xd09f, 0xd0, 0xd0a0,
+ 0xd1, 0xd0a1, 0xd2, 0xd0a2, 0xd3, 0xd0a3, 0xd4, 0xd0a4,
+ 0xd5, 0xd0a5, 0xd6, 0xd0a6, 0xd7, 0xd0a7, 0xd8, 0xd0a8,
+ 0xd9, 0xd0a9, 0xda, 0xd0aa, 0xdb, 0xd0ab, 0xdc, 0xd0ac,
+ 0xdd, 0xd0ad, 0xde, 0xd0ae, 0xdf, 0xd0af, 0xe0, 0xd0b0,
+ 0xe1, 0xd0b1, 0xe2, 0xd0b2, 0xe3, 0xd0b3, 0xe4, 0xd0b4,
+ 0xe5, 0xd0b5, 0xe6, 0xd0b6, 0xe7, 0xd0b7, 0xe8, 0xd0b8,
+ 0xe9, 0xd0b9, 0xea, 0xd0ba, 0xeb, 0xd0bb, 0xec, 0xd0bc,
+ 0xed, 0xd0bd, 0xee, 0xd0be, 0xef, 0xd0bf, 0xf0, 0xd180,
+ 0xf1, 0xd181, 0xf2, 0xd182, 0xf3, 0xd183, 0xf4, 0xd184,
+ 0xf5, 0xd185, 0xf6, 0xd186, 0xf7, 0xd187, 0xf8, 0xd188,
+ 0xf9, 0xd189, 0xfa, 0xd18a, 0xfb, 0xd18b, 0xfc, 0xd18c,
+ 0xfd, 0xd18d, 0xfe, 0xd18e, 0xff, 0xd18f };
+
+ int i = 0;
+
+ for (byte *p = s; *p; p++) {
+ if (*p < 128) {
+ tmp[i++] = *p;
+ } else {
+ int j;
+ for (j = 0; trans[j]; j += 2) {
+ if (trans[j] == *p) {
+ tmp[i++] = (trans[j + 1] >> 8) & 0xff;
+ tmp[i++] = trans[j + 1] & 0xff;
+ break;
+ }
+ }
+
+ assert(trans[j]);
+ }
+ }
+
+ tmp[i] = 0;
+
+ return tmp;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
new file mode 100644
index 0000000000..76a1ae944c
--- /dev/null
+++ b/engines/fullpipe/utils.h
@@ -0,0 +1,154 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_UTILS_H
+#define FULLPIPE_UTILS_H
+
+#include "common/hash-str.h"
+#include "common/array.h"
+#include "common/file.h"
+
+namespace Fullpipe {
+
+class CObject;
+class NGIArchive;
+
+typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ClassMap;
+
+class MfcArchive : public Common::SeekableReadStream {
+ ClassMap _classMap;
+ Common::Array<CObject *> _objectMap;
+ Common::Array<int> _objectIdMap;
+
+ int _lastIndex;
+ int _level;
+
+ Common::SeekableReadStream *_stream;
+
+ public:
+ MfcArchive(Common::SeekableReadStream *file);
+
+ char *readPascalString(bool twoByte = false);
+ int readCount();
+ double readDouble();
+ CObject *parseClass(bool *isCopyReturned);
+ CObject *readClass();
+
+ void incLevel() { _level++; }
+ void decLevel() { _level--; }
+ int getLevel() { return _level; }
+
+ virtual bool eos() const { return _stream->eos(); }
+ virtual uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
+ virtual int32 pos() const { return _stream->pos(); }
+ virtual int32 size() const { return _stream->size(); }
+ virtual bool seek(int32 offset, int whence = SEEK_SET) { return _stream->seek(offset, whence); }
+};
+
+enum ObjType {
+ kObjTypeDefault,
+ kObjTypeObjstateCommand,
+ kObjTypeStaticANIObject,
+ kObjTypePictureObject
+};
+
+class CObject {
+ public:
+ ObjType _objtype;
+
+ CObject() : _objtype(kObjTypeDefault) {}
+ virtual bool load(MfcArchive &in) { return true; }
+ virtual ~CObject() {}
+
+ bool loadFile(const char *fname);
+};
+
+class CObList : public Common::List<CObject *>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class MemoryObject : CObject {
+ friend class Picture;
+ friend class Scene;
+
+ protected:
+ char *_memfilename;
+ int _mfield_8;
+ int _mfield_C;
+ int _mfield_10;
+ char _mfield_14;
+ char _mfield_15;
+ char _mfield_16;
+ char _mfield_17;
+ byte *_data;
+ int _dataSize;
+ int _mflags;
+ NGIArchive *_libHandle;
+
+ public:
+ MemoryObject();
+ virtual ~MemoryObject();
+
+ virtual bool load(MfcArchive &file);
+ void loadFile(char *filename);
+ void load() { loadFile(_memfilename); }
+ byte *getData();
+ byte *loadData();
+
+ bool testFlags();
+
+ void freeData();
+};
+
+class MemoryObject2 : public MemoryObject {
+ friend class Picture;
+
+ protected:
+ byte **_rows;
+
+ public:
+ MemoryObject2();
+ virtual ~MemoryObject2();
+ virtual bool load(MfcArchive &file);
+
+ void copyData(byte *src, int dataSize);
+};
+
+class CObArray : public Common::Array<CObject>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+class CDWordArray : public Common::Array<int32>, public CObject {
+ public:
+ virtual bool load(MfcArchive &file);
+};
+
+typedef Common::Array<void *> CPtrList;
+
+char *genFileName(int superId, int sceneId, const char *ext);
+byte *transCyrillic(byte *s);
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_UTILS_H */
diff --git a/engines/kyra/text_rpg.cpp b/engines/kyra/text_rpg.cpp
index a19d678e35..24c523c856 100644
--- a/engines/kyra/text_rpg.cpp
+++ b/engines/kyra/text_rpg.cpp
@@ -129,7 +129,7 @@ void TextDisplayer_rpg::displayText(char *str, ...) {
uint16 charsPerLine = (sd->w << 3) / (_screen->getFontWidth() + _screen->_charWidth);
while (c) {
- char a = tolower(_ctrl[1]);
+ char a = tolower((unsigned char)_ctrl[1]);
if (!_tempString2 && c == '%') {
if (a == 'd') {
diff --git a/engines/lastexpress/data/scene.h b/engines/lastexpress/data/scene.h
index 69a1417459..b99e56a74c 100644
--- a/engines/lastexpress/data/scene.h
+++ b/engines/lastexpress/data/scene.h
@@ -83,6 +83,7 @@ class Scene;
class SceneHotspot {
public:
enum Action {
+ kActionNone = 0,
kActionInventory = 1,
kActionSavePoint = 2,
kActionPlaySound = 3,
@@ -152,8 +153,19 @@ public:
byte cursor;
uint32 next;
- SceneHotspot() {}
+ SceneHotspot() {
+ coordsOffset = 0;
+ scene = kSceneNone;
+ location = 0;
+ action = kActionNone;
+ param1 = 0;
+ param2 = 0;
+ param3 = 0;
+ cursor = 0;
+ next = 0;
+ }
~SceneHotspot();
+
static SceneHotspot *load(Common::SeekableReadStream *stream);
bool isInside(const Common::Point &point);
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index db3a3e3962..7c83aff93d 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -487,7 +487,9 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
// Handle right-click to interrupt sequence
Common::Event ev;
- _engine->getEventManager()->pollEvent(ev);
+ if (!_engine->getEventManager()->pollEvent(ev))
+ break;
+
if (ev.type == Common::EVENT_RBUTTONUP)
break;
@@ -596,7 +598,9 @@ bool Debugger::cmdPlaySbe(int argc, const char **argv) {
// Handle right-click to interrupt sequence
Common::Event ev;
- _engine->getEventManager()->pollEvent(ev);
+ if (!_engine->getEventManager()->pollEvent(ev))
+ break;
+
if (ev.type == Common::EVENT_RBUTTONUP)
break;
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index a2c7226b93..82688fff2e 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -587,8 +587,8 @@ void SceneManager::updateDoorsAndClock() {
Common::String name = Common::String::format("633X%c-%02d.seq", (index - firstIndex) + 65, scene->position);
Sequence *sequence = loadSequence1(name, 255);
- // If the sequence doesn't exists, skip
- if (!sequence || !sequence->isLoaded())
+ // If the sequence doesn't exists or could not be loaded, skip index
+ if (!sequence)
continue;
// Adjust frame data and store in frame list
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 2c484f6976..944f6d47b1 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -502,6 +502,7 @@ public:
volume = _defaultVolume;
//Game data
+ field_0 = 0;
time = kTimeCityParis;
timeDelta = _defaultTimeDelta;
timeTicks = 0;
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 01d2634dec..bc1624d171 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -165,10 +165,10 @@ Common::Error LastExpressEngine::run() {
void LastExpressEngine::pollEvents() {
Common::Event ev;
- _eventMan->pollEvent(ev);
+ if (!_eventMan->pollEvent(ev))
+ return;
switch (ev.type) {
-
case Common::EVENT_LBUTTONUP:
getGameLogic()->getGameState()->getGameFlags()->mouseLeftClick = true;
break;
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 8140817eb3..975c6c2a21 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -418,6 +418,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
_sound->stopSound();
_sound->stopBackgroundMyst();
+ _video->stopVideos();
if (linkSrcSound)
_sound->playSoundBlocking(linkSrcSound);
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f17d765c99..dc5f433ce7 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -691,6 +691,7 @@ void Myst::toggleVar(uint16 var) {
else
_state.courtyardImageBoxes |= mask;
}
+ break;
case 41: // Vault white page
if (_globals.ending != 4) {
if (_dockVaultState == 1) {
diff --git a/engines/mortevielle/actions.cpp b/engines/mortevielle/actions.cpp
index 3e3db5b224..b68dd48b0f 100644
--- a/engines/mortevielle/actions.cpp
+++ b/engines/mortevielle/actions.cpp
@@ -91,31 +91,41 @@ void MortevielleEngine::fctMove() {
oldMenu = (_menu._moveMenu[menuChoice]._menuId << 8) | _menu._moveMenu[menuChoice]._actionId;
}
- if (_coreVar._currPlace == MOUNTAIN) {
+ switch (_coreVar._currPlace) {
+ case MOUNTAIN:
if (menuChoice == 1)
gotoManorFront();
else if (menuChoice == 2)
checkManorDistance();
_menu.setDestinationText(_coreVar._currPlace);
return;
- } else if (_coreVar._currPlace == INSIDE_WELL) {
+ case INSIDE_WELL:
if (menuChoice == 1)
floodedInWell();
else if (menuChoice == 2)
gotoManorBack();
_menu.setDestinationText(_coreVar._currPlace);
return;
- } else if ((_coreVar._currPlace == BUREAU) && (menuChoice == 1))
- menuChoice = 6;
- else if (_coreVar._currPlace == KITCHEN) {
+ case BUREAU:
+ if (menuChoice == 1)
+ menuChoice = 6;
+ break;
+ case KITCHEN:
if (menuChoice == 2)
menuChoice = 6;
else if (menuChoice == 5)
menuChoice = 16;
- } else if ((_coreVar._currPlace == CELLAR) && (menuChoice == 3))
- menuChoice = 6;
- else if (((_coreVar._currPlace == LANDING) || (_coreVar._currPlace == ROOM26)) && (menuChoice == 4))
- menuChoice = 6;
+ break;
+ case CELLAR:
+ if (menuChoice == 3)
+ menuChoice = 6;
+ break;
+ case LANDING:
+ case ROOM26:
+ if (menuChoice == 4)
+ menuChoice = 6;
+ break;
+ }
if ((_coreVar._currPlace > MOUNTAIN) && (_coreVar._currPlace != ROOM26))
menuChoice += 10;
@@ -132,32 +142,40 @@ void MortevielleEngine::fctMove() {
else if ((_coreVar._currPlace == WELL) && (menuChoice > 13) && (menuChoice != 17))
menuChoice = 15;
- if (menuChoice == 1)
+ switch (menuChoice) {
+ case 1:
_coreVar._currPlace = BUREAU;
- else if (menuChoice == 2)
+ break;
+ case 2:
_coreVar._currPlace = KITCHEN;
- else if (menuChoice == 3)
+ break;
+ case 3:
_coreVar._currPlace = CELLAR;
- else if (menuChoice == 4)
+ break;
+ case 4:
_coreVar._currPlace = LANDING;
- else if (menuChoice == 5)
- menuChoice = 12;
- else if (menuChoice == 6)
- menuChoice = 11;
-
- if (menuChoice == 11)
- gotoDiningRoom();
- else if (menuChoice == 12)
+ break;
+ case 5:
+ case 12:
gotoManorFront();
- else if (menuChoice == 13)
+ break;
+ case 6:
+ case 11:
+ gotoDiningRoom();
+ break;
+ case 13:
_coreVar._currPlace = CHAPEL;
- else if (menuChoice == 14)
+ break;
+ case 14:
_coreVar._currPlace = WELL;
- else if (menuChoice == 15)
+ break;
+ case 15:
checkManorDistance();
- else if (menuChoice == 16)
+ break;
+ case 16:
gotoManorBack();
- else if (menuChoice == 17) {
+ break;
+ case 17:
if ((_coreVar._wellObjectId != 120) && (_coreVar._wellObjectId != 140))
_crep = 997;
else if (_coreVar._wellObjectId == 120)
@@ -169,7 +187,9 @@ void MortevielleEngine::fctMove() {
_coreVar._currPlace = INSIDE_WELL;
prepareDisplayText();
}
+ break;
}
+
if ((menuChoice < 5) || (menuChoice == 13) || (menuChoice == 14))
prepareDisplayText();
resetRoomVariables(_coreVar._currPlace);
@@ -340,7 +360,7 @@ void MortevielleEngine::fctLift() {
++_coreVar._faithScore;
_crep = 997;
if ((_coreVar._currPlace == PURPLE_ROOM) && (_coreVar._purpleRoomObjectId != 0))
- treg(_coreVar._purpleRoomObjectId);
+ displayLookScreen(_coreVar._purpleRoomObjectId);
}
return;
}
@@ -409,29 +429,29 @@ void MortevielleEngine::fctLook() {
if (_num == 1) {
_crep = 164;
if (_coreVar._atticRodHoleObjectId != 0)
- treg(_coreVar._atticRodHoleObjectId);
+ displayLookScreen(_coreVar._atticRodHoleObjectId);
else if (_coreVar._atticBallHoleObjectId != 0)
- treg(_coreVar._atticBallHoleObjectId);
+ displayLookScreen(_coreVar._atticBallHoleObjectId);
} else {
_crep = 193;
if (_coreVar._atticRodHoleObjectId != 0)
- treg(_coreVar._atticRodHoleObjectId);
+ displayLookScreen(_coreVar._atticRodHoleObjectId);
}
}
if (_coreVar._currPlace == CELLAR) {
_crep = 164;
if (_coreVar._cellarObjectId != 0)
- treg(_coreVar._cellarObjectId);
+ displayLookScreen(_coreVar._cellarObjectId);
}
if (_coreVar._currPlace == SECRET_PASSAGE) {
_crep = 174;
if (_coreVar._secretPassageObjectId != 0)
- treg(_coreVar._secretPassageObjectId);
+ displayLookScreen(_coreVar._secretPassageObjectId);
}
if (_coreVar._currPlace == WELL) {
_crep = 131;
if (_coreVar._wellObjectId != 0)
- treg(_coreVar._wellObjectId);
+ displayLookScreen(_coreVar._wellObjectId);
}
}
return;
@@ -451,15 +471,15 @@ void MortevielleEngine::fctLook() {
if (_crep == 255)
_crep = 131;
if ((_coreVar._currPlace == GREEN_ROOM) && (_num == 1))
- treg(144);
+ displayLookScreen(144);
if ((_coreVar._currPlace == BLUE_ROOM) && (_num == 3))
- treg(147);
+ displayLookScreen(147);
if ((_coreVar._currPlace == GREEN_ROOM2) && (_num == 3))
- treg(149);
+ displayLookScreen(149);
if ((_coreVar._currPlace == JULIA_ROOM) && (_num == 2))
- treg(30);
+ displayLookScreen(30);
if ((_coreVar._currPlace == DINING_ROOM) && (_num == 3))
- treg(31);
+ displayLookScreen(31);
}
/**
@@ -468,7 +488,7 @@ void MortevielleEngine::fctLook() {
*/
void MortevielleEngine::fctSelftLook() {
if (_coreVar._selectedObjectId != 0)
- treg(_coreVar._selectedObjectId);
+ displayLookScreen(_coreVar._selectedObjectId);
else
_crep = 186;
}
@@ -503,9 +523,12 @@ void MortevielleEngine::fctSearch() {
setCoordinates(7);
if (_num != 0) {
int i;
- for (i = 1; (i <= 6) && (_num != _openObjects[i]); i++)
- ;
- if (_num == _openObjects[i]) {
+ for (i = 1; i <= 6; i++) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
if (_currBitIndex > 0)
_coreVar._faithScore += 3;
@@ -529,12 +552,12 @@ void MortevielleEngine::fctSearch() {
if (_coreVar._currPlace == PURPLE_ROOM) {
_crep = 123;
if (_coreVar._purpleRoomObjectId != 0)
- treg(_coreVar._purpleRoomObjectId);
+ displayLookScreen(_coreVar._purpleRoomObjectId);
}
if (_coreVar._currPlace == CRYPT) {
_crep = 123;
if (_coreVar._cryptObjectId != 0)
- treg(_coreVar._cryptObjectId);
+ displayLookScreen(_coreVar._cryptObjectId);
}
}
}
@@ -584,7 +607,7 @@ void MortevielleEngine::fctOpen() {
if (_caff == ROOM26) {
if (_roomDoorId != OWN_ROOM) {
- _currAction = OPCODE_ENTER;
+ _currAction = _menu._opcodeEnter;
_syn = true;
} else
_crep = 997;
@@ -606,9 +629,20 @@ void MortevielleEngine::fctOpen() {
_coreVar._faithScore += 2;
++_openObjCount;
int i;
- for (i = 1; (i <= 6) && (_openObjects[i] != 0) && (_openObjects[i] != _num); i++)
- ;
- if (_openObjects[i] != _num) {
+ for (i = 1; (i <= 6); i++) {
+ if ((_openObjects[i] == 0) || (_openObjects[i] == _num))
+ break;
+ }
+
+ if (i > 6) {
+ warning("Unexpected action: Too many open objects");
+ return;
+ }
+
+ if (_openObjects[i] == _num)
+ // display "Already Opened"
+ _crep = 18;
+ else {
if (!( ((_num == 3) && ((_coreVar._currPlace == OWN_ROOM)
|| (_coreVar._currPlace == JULIA_ROOM)
|| (_coreVar._currPlace == BLUE_ROOM)
@@ -633,6 +667,7 @@ void MortevielleEngine::fctOpen() {
}
_openObjects[i] = _num;
displayAnimFrame(1, _num);
+ _soundManager.waitSpeech();
}
int tmpPlace = _coreVar._currPlace;
if (_coreVar._currPlace == CRYPT)
@@ -640,9 +675,7 @@ void MortevielleEngine::fctOpen() {
_crep = _tabdon[kAouvr + (tmpPlace * 7) + _num - 1];
if (_crep == 254)
_crep = 999;
- } else
- // display "Already Opened"
- _crep = 18;
+ }
}
}
@@ -701,14 +734,14 @@ void MortevielleEngine::fctPlace() {
_soundManager.startSpeech(6, -9, 1);
// Do you want to enter the hidden passage?
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
if (answer == 1) {
Common::String alertTxt = getString(582);
- _dialogManager.show(alertTxt, 1);
+ _dialogManager.show(alertTxt);
bool enterPassageFl = _dialogManager.showKnowledgeCheck();
_mouse.hideMouse();
- hirs();
+ clearScreen();
drawRightFrame();
clearDescriptionBar();
clearVerbBar();
@@ -731,7 +764,7 @@ void MortevielleEngine::fctPlace() {
displayAnimFrame(1, 2);
displayAnimFrame(1, 1);
alertTxt = getString(577);
- _dialogManager.show(alertTxt, 1);
+ _dialogManager.show(alertTxt);
displayAnimFrame(2, 1);
_crep = 166;
}
@@ -800,7 +833,7 @@ void MortevielleEngine::fctTurn() {
if ((_coreVar._currPlace == ATTIC) && (_coreVar._atticRodHoleObjectId == 159) && (_coreVar._atticBallHoleObjectId == 141)) {
handleDescriptionText(2, 167);
_soundManager.startSpeech(7, 9, 1);
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
if (answer == 1)
_endGame = true;
else
@@ -810,7 +843,7 @@ void MortevielleEngine::fctTurn() {
handleDescriptionText(2, 175);
clearVerbBar();
_soundManager.startSpeech(6, -9, 1);
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
if (answer == 1) {
_coreVar._currPlace = CRYPT;
prepareDisplayText();
@@ -883,9 +916,12 @@ void MortevielleEngine::fctClose() {
setCoordinates(7);
if (_num != 0) {
int i;
- for (i = 1; (i <= 6) && (_num != _openObjects[i]); ++i)
- ;
- if (_num == _openObjects[i]) {
+ for (i = 1; i <= 6; ++i) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
displayAnimFrame(2, _num);
_crep = 998;
_openObjects[i] = 0;
@@ -913,7 +949,7 @@ void MortevielleEngine::fctKnock() {
displayTextInVerbBar(getEngineString(S_HIT));
if (_coreVar._currPlace == LANDING) {
- _dialogManager.show(getEngineString(S_BEFORE_USE_DEP_MENU), 1);
+ _dialogManager.show(getEngineString(S_BEFORE_USE_DEP_MENU));
return;
}
@@ -932,14 +968,13 @@ void MortevielleEngine::fctKnock() {
if (_coreVar._currPlace == ROOM26) {
int rand = (getRandomNumber(0, 8)) - 4;
_soundManager.startSpeech(11, rand, 1);
- int p = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
- int l = _roomDoorId;
- if (l != OWN_ROOM) {
- if (p != -500) {
- if (rand > p)
+ int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
+ if (_roomDoorId != OWN_ROOM) {
+ if (pres != -500) {
+ if (rand > pres)
_crep = 190;
else {
- setPresenceFlags(l);
+ setPresenceFlags(_roomDoorId);
getKnockAnswer();
}
} else
@@ -979,9 +1014,12 @@ void MortevielleEngine::fctSelfPut() {
_crep = 997;
else {
int i;
- for (i = 1; (i <= 6) && (_num != _openObjects[i]); i++)
- ;
- if (_num == _openObjects[i]) {
+ for (i = 1; i <= 6; i++) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
_curSearchObjId = objId;
_crep = 999;
} else
@@ -1002,12 +1040,15 @@ void MortevielleEngine::fctSelfPut() {
if (_num == 1) {
if (_coreVar._atticBallHoleObjectId != 0)
_crep = 188;
- else
+ else {
_coreVar._atticBallHoleObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 7);
+ }
} else if (_coreVar._atticRodHoleObjectId != 0) {
_crep = 188;
} else {
_coreVar._atticRodHoleObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 6);
}
}
@@ -1053,18 +1094,17 @@ void MortevielleEngine::fctListen() {
if (_currBitIndex != 0)
++_coreVar._faithScore;
int rand;
- int p = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
- int l = _roomDoorId;
- if (l != OWN_ROOM) {
- if (p != -500) {
- if (rand > p)
+ int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
+ if (_roomDoorId != OWN_ROOM) {
+ if (pres != -500) {
+ if (rand > pres)
_crep = 101;
else {
- setPresenceFlags(l);
- int j, h, m;
- updateHour(j, h, m);
+ setPresenceFlags(_roomDoorId);
+ int day, hour, minute;
+ updateHour(day, hour, minute);
rand = getRandomNumber(1, 100);
- if ((h >= 0) && (h < 8)) {
+ if ((hour >= 0) && (hour < 8)) {
if (rand > 30)
_crep = 101;
else
@@ -1094,25 +1134,25 @@ void MortevielleEngine::fctEat() {
resetRoomVariables(_coreVar._currPlace);
_menu.setDestinationText(_coreVar._currPlace);
- int j, h, m;
- updateHour(j, h, m);
- if ((h == 12) || (h == 13) || (h == 19)) {
+ int day, hour, minute;
+ updateHour(day, hour, minute);
+ if ((hour == 12) || (hour == 13) || (hour == 19)) {
_coreVar._faithScore -= (_coreVar._faithScore / 7);
- if (h == 12) {
- if (m == 0)
- h = 4;
+ if (hour == 12) {
+ if (minute == 0)
+ hour = 4;
else
- h = 3;
+ hour = 3;
}
- if ((h == 13) || (h == 19)) {
- if (m == 0)
- h = 2;
+ if ((hour == 13) || (hour == 19)) {
+ if (minute == 0)
+ hour = 2;
else
- h = 1;
+ hour = 1;
}
- _currentHourCount += h;
+ _currentHourCount += hour;
_crep = 135;
prepareRoom();
} else {
@@ -1137,18 +1177,19 @@ void MortevielleEngine::fctEnter() {
_crep = 189;
_coreVar._availableQuestion[8] = '*';
} else {
- int z = 0;
+ int pres = 0;
if (!_blo)
- z = getPresence(_roomDoorId);
- if (z != 0) {
+ pres = getPresence(_roomDoorId);
+ if (pres != 0) {
if ((_roomDoorId == TOILETS) || (_roomDoorId == BATHROOM))
_crep = 179;
else {
int randVal = (getRandomNumber(0, 10)) - 5;
_soundManager.startSpeech(7, randVal, 1);
displayAnimFrame(1, 1);
+ _soundManager.waitSpeech();
- int charIndex = convertBitIndexToCharacterIndex(z);
+ int charIndex = convertBitIndexToCharacterIndex(pres);
++_coreVar._faithScore;
_coreVar._currPlace = LANDING;
_currMenu = MENU_DISCUSS;
@@ -1168,6 +1209,7 @@ void MortevielleEngine::fctEnter() {
int randVal = (getRandomNumber(0, 10)) - 5;
_soundManager.startSpeech(7, randVal, 1);
displayAnimFrame(1, 1);
+ _soundManager.waitSpeech();
_coreVar._currPlace = _roomDoorId;
prepareDisplayText();
@@ -1185,8 +1227,6 @@ void MortevielleEngine::fctEnter() {
* @remarks Originally called 'tdormir'
*/
void MortevielleEngine::fctSleep() {
- int j, h, m;
-
if ((_coreVar._currPlace > LANDING) && (_coreVar._currPlace < ROOM26)) {
_crep = 148;
return;
@@ -1202,25 +1242,26 @@ void MortevielleEngine::fctSleep() {
clearVerbBar();
clearDescriptionBar();
prepareScreenType2();
- ecr2(getEngineString(S_WANT_TO_WAKE_UP));
- updateHour(j, h, m);
+ displayTextBlock(getEngineString(S_WANT_TO_WAKE_UP));
+ int day, hour, minute;
+ updateHour(day, hour, minute);
int answer;
do {
- if (h < 8) {
+ if (hour < 8) {
_coreVar._faithScore -= (_coreVar._faithScore / 20);
- int z = (7 - h) * 2;
- if (m == 30)
+ int z = (7 - hour) * 2;
+ if (minute == 30)
--z;
_currentHourCount += z;
- h = 7;
+ hour = 7;
}
_currentHourCount += 2;
- ++h;
- if (h > 23)
- h = 0;
+ ++hour;
+ if (hour > 23)
+ hour = 0;
prepareRoom();
- answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ answer = _dialogManager.show(getEngineString(S_YES_NO));
_anyone = false;
} while (answer != 1);
_crep = 998;
@@ -1310,7 +1351,7 @@ void MortevielleEngine::fctWait() {
return;
}
handleDescriptionText(2, 102);
- answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ answer = _dialogManager.show(getEngineString(S_YES_NO));
} while (answer != 2);
_crep = 998;
if (!_anyone)
@@ -1361,12 +1402,12 @@ void MortevielleEngine::fctDiscuss() {
displId = _caff + 60;
}
testKey(false);
- mennor();
+ menuUp();
_mouse.hideMouse();
- hirs();
- premtet();
+ clearScreen();
+ drawDiscussionBox();
startDialog(displId);
- hirs();
+ clearScreen();
for (int ix = 1; ix <= 46; ++ix)
questionAsked[ix] = false;
for (int ix = 1; ix <= 45; ++ix) {
@@ -1408,7 +1449,7 @@ void MortevielleEngine::fctDiscuss() {
return;
_mouse.getMousePosition(x, y, click);
- x *= (3 - _resolutionScaler);
+ x *= (3 - kResolutionScaler);
if (x > 319)
cx = 41;
else
@@ -1493,8 +1534,8 @@ void MortevielleEngine::fctDiscuss() {
displId = 139;
}
_mouse.hideMouse();
- hirs();
- premtet();
+ clearScreen();
+ drawDiscussionBox();
startDialog(displId);
_mouse.showMouse();
if ((displId == 84) || (displId == 86)) {
@@ -1511,15 +1552,15 @@ void MortevielleEngine::fctDiscuss() {
_coreVar._availableQuestion[32] = '*';
}
_mouse.hideMouse();
- hirs();
+ clearScreen();
_mouse.showMouse();
}
} while ((choice != 46) && (displId != 138));
if (_col) {
_coreVar._faithScore += (3 * (_coreVar._faithScore / 10));
_mouse.hideMouse();
- hirs();
- premtet();
+ clearScreen();
+ drawDiscussionBox();
startDialog(138);
_mouse.showMouse();
_col = false;
@@ -1527,7 +1568,7 @@ void MortevielleEngine::fctDiscuss() {
}
_controlMenu = 0;
_mouse.hideMouse();
- hirs();
+ clearScreen();
drawRightFrame();
_mouse.showMouse();
showPeoplePresent(_currBitIndex);
@@ -1577,7 +1618,7 @@ void MortevielleEngine::fctScratch() {
*/
void MortevielleEngine::endGame() {
_quitGame = true;
- tlu(13, 152);
+ displayNarrativePicture(13, 152);
displayEmptyHand();
clearUpperLeftPart();
clearDescriptionBar();
@@ -1587,8 +1628,8 @@ void MortevielleEngine::endGame() {
_mouse.hideMouse();
_caff = 70;
_text.taffich();
- hirs();
- premtet();
+ clearScreen();
+ drawDiscussionBox();
startDialog(141);
_mouse.showMouse();
clearUpperLeftPart();
@@ -1626,7 +1667,7 @@ void MortevielleEngine::askRestart() {
_day = 0;
handleDescriptionText(2, 180);
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
_quitGame = (answer != 1);
}
diff --git a/engines/mortevielle/detection.cpp b/engines/mortevielle/detection.cpp
index 28cbc77b8b..ee9cb40c99 100644
--- a/engines/mortevielle/detection.cpp
+++ b/engines/mortevielle/detection.cpp
@@ -24,13 +24,22 @@
#include "engines/advancedDetector.h"
#include "mortevielle/mortevielle.h"
-#include "mortevielle/detection_tables.h"
#include "mortevielle/saveload.h"
namespace Mortevielle {
-uint32 MortevielleEngine::getGameFlags() const { return _gameDescription->flags; }
+struct MortevielleGameDescription {
+ ADGameDescription desc;
+ Common::Language originalLanguage;
+ uint8 dataFeature;
+};
+
+uint32 MortevielleEngine::getGameFlags() const { return _gameDescription->desc.flags; }
+
+Common::Language MortevielleEngine::getLanguage() const { return _gameDescription->desc.language; }
-Common::Language MortevielleEngine::getLanguage() const { return _gameDescription->language; }
+Common::Language MortevielleEngine::getOriginalLanguage() const { return _gameDescription->originalLanguage; }
+
+bool MortevielleEngine::useOriginalData() const { return _gameDescription->dataFeature == kUseOriginalData; }
}
@@ -39,12 +48,17 @@ static const PlainGameDescriptor MortevielleGame[] = {
{0, 0}
};
+#include "mortevielle/detection_tables.h"
+
class MortevielleMetaEngine : public AdvancedMetaEngine {
public:
- MortevielleMetaEngine() : AdvancedMetaEngine(Mortevielle::MortevielleGameDescriptions, sizeof(ADGameDescription),
+ MortevielleMetaEngine() : AdvancedMetaEngine(Mortevielle::MortevielleGameDescriptions, sizeof(Mortevielle::MortevielleGameDescription),
MortevielleGame) {
_md5Bytes = 512;
_singleid = "mortevielle";
+ // Use kADFlagUseExtraAsHint to distinguish between original and improved versions
+ // (i.e. use or not of the game data file).
+ _flags = kADFlagUseExtraAsHint;
}
virtual const char *getName() const {
return "Mortevielle";
@@ -63,7 +77,7 @@ public:
bool MortevielleMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc) {
- *engine = new Mortevielle::MortevielleEngine(syst, desc);
+ *engine = new Mortevielle::MortevielleEngine(syst, (const Mortevielle::MortevielleGameDescription *)desc);
}
return desc != 0;
}
diff --git a/engines/mortevielle/detection_tables.h b/engines/mortevielle/detection_tables.h
index 689fee1222..8d0cd5630c 100644
--- a/engines/mortevielle/detection_tables.h
+++ b/engines/mortevielle/detection_tables.h
@@ -22,67 +22,95 @@
namespace Mortevielle {
-static const ADGameDescription MortevielleGameDescriptions[] = {
+static const MortevielleGameDescription MortevielleGameDescriptions[] = {
// French
{
- "mortevielle",
- "",
{
- {"menufr.mor", 0, "e413f36b9e14eef16130adc347a9391f", 144},
- {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
- AD_LISTEND
- },
- Common::FR_FRA,
- Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO0()
+ "mortevielle",
+ "",
+ {
+ {"menufr.mor", 0, "e413f36b9e14eef16130adc347a9391f", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::FR_FRA,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::FR_FRA, kUseOriginalData
},
- // French
+ // German
{
- "mortevielle",
- "",
{
- {"menu.mor", 0, "3fef0a3f8fca99fdcb6dbca8cbcef46f", 160},
- {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
- AD_LISTEND
- },
- Common::FR_FRA,
- Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO0()
+ "mortevielle",
+ "",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseOriginalData
},
- // German
+
+ // German, improved translation
+ {
+ {
+ "mortevielle",
+ "Improved Translation",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseEngineDataFile
+ },
+
+ // DOS English version doesn't exist. Technically, they are French or German versions,
+ // using English strings stored mort.dat
+
+ // English on top of French version
{
- "mortevielle",
- "",
{
- {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
- {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
- AD_LISTEND
- },
- Common::DE_DEU,
- Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO0()
+ "mortevielle",
+ "",
+ {
+ {"menufr.mor", 0, "e413f36b9e14eef16130adc347a9391f", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::FR_FRA, kUseEngineDataFile
},
- // English. Note that this is technically the French version, but English strings in mort.dat
- // will automatically replace all the French strings
+ // English on top of German version
{
- "mortevielle",
- "",
{
- {"menufr.mor", 0, "e413f36b9e14eef16130adc347a9391f", 144},
- {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformDOS,
- ADGF_NO_FLAGS,
- GUIO0()
+ "mortevielle",
+ "",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseEngineDataFile
},
- AD_TABLE_END_MARKER
+ { AD_TABLE_END_MARKER , Common::EN_ANY, kUseEngineDataFile}
};
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/dialogs.cpp b/engines/mortevielle/dialogs.cpp
index 264839c158..9a2ade60ab 100644
--- a/engines/mortevielle/dialogs.cpp
+++ b/engines/mortevielle/dialogs.cpp
@@ -39,7 +39,7 @@ namespace Mortevielle {
* Alert function - Show
* @remarks Originally called 'do_alert'
*/
-int DialogManager::show(const Common::String &msg, int n) {
+int DialogManager::show(const Common::String &msg) {
// Make a copy of the current screen surface for later restore
_vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
@@ -57,13 +57,12 @@ int DialogManager::show(const Common::String &msg, int n) {
decodeAlertDetails(msg, caseNumb, lignNumb, colNumb, alertStr, caseStr);
- int i = 0;
Common::Point curPos;
if (alertStr == "") {
drawAlertBox(10, 5, colNumb);
} else {
drawAlertBox(8, 7, colNumb);
- i = 0;
+ int i = 0;
_vm->_screenSurface._textPos.y = 70;
do {
curPos.x = 320;
@@ -71,10 +70,7 @@ int DialogManager::show(const Common::String &msg, int n) {
while ((alertStr[i + 1] != '\174') && (alertStr[i + 1] != '\135')) {
++i;
displayStr += alertStr[i];
- if (_vm->_resolutionScaler == 2)
- curPos.x -= 3;
- else
- curPos.x -= 5;
+ curPos.x -= 3;
}
_vm->_screenSurface.putxy(curPos.x, _vm->_screenSurface._textPos.y);
_vm->_screenSurface._textPos.y += 6;
@@ -95,12 +91,12 @@ int DialogManager::show(const Common::String &msg, int n) {
int limit[3][3];
memset(&limit[0][0], 0, sizeof(int) * 3 * 3);
- limit[1][1] = ((uint)(coldep) / 2) * _vm->_resolutionScaler;
+ limit[1][1] = ((uint)(coldep) / 2) * kResolutionScaler;
limit[1][2] = limit[1][1] + 40;
if (caseNumb == 1) {
limit[2][1] = limit[2][2];
} else {
- limit[2][1] = ((uint)(320 + ((uint)esp >> 1)) / 2) * _vm->_resolutionScaler;
+ limit[2][1] = ((uint)(320 + ((uint)esp >> 1)) / 2) * kResolutionScaler;
limit[2][2] = (limit[2][1]) + 40;
}
_vm->_mouse.showMouse();
@@ -168,10 +164,10 @@ int DialogManager::show(const Common::String &msg, int n) {
_vm->setMouseClick(false);
_vm->_mouse.hideMouse();
if (!test3) {
- id = n;
- setPosition(n, coldep, esp);
+ id = 1;
+ setPosition(1, coldep, esp);
Common::String tmp4(" ");
- tmp4 += buttonStr[n];
+ tmp4 += buttonStr[1];
tmp4 += " ";
_vm->_screenSurface.drawString(tmp4, 1);
}
@@ -221,10 +217,7 @@ void DialogManager::decodeAlertDetails(Common::String inputStr, int &choiceNumb,
}
choiceListStr = Common::String(inputStr.c_str() + i);
- if (_vm->_resolutionScaler == 2)
- col *= 6;
- else
- col *= 10;
+ col *= 6;
}
void DialogManager::setPosition(int ji, int coldep, int esp) {
@@ -235,13 +228,13 @@ void DialogManager::setPosition(int ji, int coldep, int esp) {
* Alert function - Draw Alert Box
* @remarks Originally called 'fait_boite'
*/
-void DialogManager::drawAlertBox(int lidep, int nli, int tx) {
- if (tx > 640)
- tx = 640;
- int x = 320 - ((uint)tx / 2);
- int y = (lidep - 1) * 8;
- int xx = x + tx;
- int yy = y + (nli * 8);
+void DialogManager::drawAlertBox(int firstLine, int lineNum, int width) {
+ if (width > 640)
+ width = 640;
+ int x = 320 - ((uint)width / 2);
+ int y = (firstLine - 1) * 8;
+ int xx = x + width;
+ int yy = y + (lineNum * 8);
_vm->_screenSurface.fillRect(15, Common::Rect(x, y, xx, yy));
_vm->_screenSurface.fillRect(0, Common::Rect(x, y + 2, xx, y + 4));
_vm->_screenSurface.fillRect(0, Common::Rect(x, yy - 4, xx, yy - 2));
@@ -300,13 +293,9 @@ bool DialogManager::showKnowledgeCheck() {
for (int indx = 0; indx < 10; ++indx) {
_vm->_mouse.hideMouse();
- _vm->hirs();
+ _vm->clearScreen();
_vm->_mouse.showMouse();
- int dialogHeight;
- if (_vm->_resolutionScaler == 1)
- dialogHeight = 29;
- else
- dialogHeight = 23;
+ int dialogHeight = 23;
_vm->_screenSurface.fillRect(15, Common::Rect(0, 14, 630, dialogHeight));
Common::String tmpStr = _vm->getString(textIndexArr[indx]);
_vm->_text.displayStr(tmpStr, 20, 15, 100, 2, 0);
@@ -335,7 +324,7 @@ bool DialogManager::showKnowledgeCheck() {
}
for (int j = 1; j <= lastOption - firstOption + 1; ++j) {
- coor[j]._rect = Common::Rect(45 * _vm->_resolutionScaler, 27 + j * 8, (maxLength * 3 + 55) * _vm->_resolutionScaler, 34 + j * 8);
+ coor[j]._rect = Common::Rect(45 * kResolutionScaler, 27 + j * 8, (maxLength * 3 + 55) * kResolutionScaler, 34 + j * 8);
coor[j]._enabled = true;
while ((int)choiceArray[j].size() < maxLength) {
@@ -343,11 +332,7 @@ bool DialogManager::showKnowledgeCheck() {
}
}
coor[lastOption - firstOption + 2]._enabled = false;
- int rep;
- if (_vm->_resolutionScaler == 1)
- rep = 10;
- else
- rep = 6;
+ int rep = 6;
_vm->_screenSurface.drawBox(80, 33, 40 + (maxLength * rep), (lastOption - firstOption) * 8 + 16, 15);
rep = 0;
@@ -431,12 +416,6 @@ void DialogManager::checkForF8(int SpeechNum, bool drawFrame2Fl) {
_vm->_key = waitForF3F8();
if (_vm->shouldQuit())
return;
-
- if (_vm->_newGraphicalDevice != _vm->_currGraphicalDevice) {
- _vm->_currGraphicalDevice = _vm->_newGraphicalDevice;
- _vm->hirs();
- displayIntroScreen(drawFrame2Fl);
- }
} while (_vm->_key != 66); // keycode for F8
}
@@ -483,7 +462,7 @@ void DialogManager::displayIntroFrame2() {
_vm->displayPicture(&_vm->_curAnim[_vm->_crep], 63, 12);
_vm->_crep = _vm->getAnimOffset(2, 1);
_vm->displayPicture(&_vm->_curAnim[_vm->_crep], 63, 12);
- _vm->_largestClearScreen = (_vm->_resolutionScaler == 1);
+ _vm->_largestClearScreen = false;
_vm->handleDescriptionText(2, kDialogStringIndex + 143);
}
diff --git a/engines/mortevielle/dialogs.h b/engines/mortevielle/dialogs.h
index af667e40c5..3f30851960 100644
--- a/engines/mortevielle/dialogs.h
+++ b/engines/mortevielle/dialogs.h
@@ -48,11 +48,11 @@ private:
void decodeAlertDetails(Common::String inputStr, int &choiceNumb, int &lineNumb, int &col, Common::String &choiceStr, Common::String &choiceListStr);
void setPosition(int ji, int coldep, int esp);
- void drawAlertBox(int lidep, int nli, int tx);
+ void drawAlertBox(int firstLine, int lineNum, int width);
void setButtonText(Common::String c, int coldep, int nbcase, Common::String *str, int esp);
public:
void setParent(MortevielleEngine *vm);
- int show(const Common::String &msg, int n);
+ int show(const Common::String &msg);
void drawF3F8();
void checkForF8(int SpeechNum, bool drawFrame2Fl);
int waitForF3F8();
diff --git a/engines/mortevielle/graphics.cpp b/engines/mortevielle/graphics.cpp
index 059f5a9be8..daf7926438 100644
--- a/engines/mortevielle/graphics.cpp
+++ b/engines/mortevielle/graphics.cpp
@@ -1015,11 +1015,6 @@ void ScreenSurface::writeCharacter(const Common::Point &pt, unsigned char ch, in
* simulate the original 640x400 surface, all Y values have to be doubled
*/
void ScreenSurface::drawBox(int x, int y, int dx, int dy, int col) {
- if (_vm->_resolutionScaler == 1) {
- x = (uint)x >> 1;
- dx = (uint)dx >> 1;
- }
-
Graphics::Surface destSurface = lockArea(Common::Rect(x, y * 2, x + dx, (y + dy) * 2));
destSurface.hLine(0, 0, dx, col);
@@ -1078,11 +1073,7 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
_vm->_mouse.hideMouse();
Common::Point pt = _textPos;
- int charWidth;
- if (_vm->_resolutionScaler == 2)
- charWidth = 6;
- else
- charWidth = 10;
+ int charWidth = 6;
int x = pt.x + charWidth * l.size();
int color = 0;
@@ -1118,7 +1109,7 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
* Gets the width in pixels of the specified string
*/
int ScreenSurface::getStringWidth(const Common::String &s) {
- int charWidth = (_vm->_resolutionScaler == 2) ? 6 : 10;
+ int charWidth = 6;
return s.size() * charWidth;
}
@@ -1165,13 +1156,7 @@ void ScreenSurface::drawLine(int x, int y, int xx, int yy, int coul) {
* @remarks Originally called 'paint_rect'
*/
void ScreenSurface::drawRectangle(int x, int y, int dx, int dy) {
- int co;
-
- if (_vm->_currGraphicalDevice == MODE_CGA)
- co = 3;
- else
- co = 11;
- _vm->_screenSurface.fillRect(co, Common::Rect(x, y, x + dx, y + dy));
+ _vm->_screenSurface.fillRect(11, Common::Rect(x, y, x + dx, y + dy));
}
void ScreenSurface::setParent(MortevielleEngine *vm) {
diff --git a/engines/mortevielle/menu.cpp b/engines/mortevielle/menu.cpp
index f32c551ddb..641a527c98 100644
--- a/engines/mortevielle/menu.cpp
+++ b/engines/mortevielle/menu.cpp
@@ -48,34 +48,164 @@ const byte menuConstants[8][4] = {
{62, 46, 13, 10}
};
+Menu::Menu() {
+ _opcodeAttach = _opcodeWait = _opcodeForce = _opcodeSleep = OPCODE_NONE;
+ _opcodeListen = _opcodeEnter = _opcodeClose = _opcodeSearch = OPCODE_NONE;
+ _opcodeKnock = _opcodeScratch = _opcodeRead = _opcodeEat = OPCODE_NONE;
+ _opcodePlace = _opcodeOpen = _opcodeTake = _opcodeLook = OPCODE_NONE;
+ _opcodeSmell = _opcodeSound = _opcodeLeave = _opcodeLift = OPCODE_NONE;
+ _opcodeTurn = _opcodeSHide = _opcodeSSearch = _opcodeSRead = OPCODE_NONE;
+ _opcodeSPut = _opcodeSLook = OPCODE_NONE;
+}
+
+void Menu::readVerbNums(Common::File &f, int dataSize) {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(_vm->getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ return;
+ }
+
+ assert(dataSize == 52);
+ _opcodeAttach = f.readUint16LE();
+ _opcodeWait = f.readUint16LE();
+ _opcodeForce = f.readUint16LE();
+ _opcodeSleep = f.readUint16LE();
+ _opcodeListen = f.readUint16LE();
+ _opcodeEnter = f.readUint16LE();
+ _opcodeClose = f.readUint16LE();
+ _opcodeSearch = f.readUint16LE();
+ _opcodeKnock = f.readUint16LE();
+ _opcodeScratch = f.readUint16LE();
+ _opcodeRead = f.readUint16LE();
+ _opcodeEat = f.readUint16LE();
+ _opcodePlace = f.readUint16LE();
+ _opcodeOpen = f.readUint16LE();
+ _opcodeTake = f.readUint16LE();
+ _opcodeLook = f.readUint16LE();
+ _opcodeSmell = f.readUint16LE();
+ _opcodeSound = f.readUint16LE();
+ _opcodeLeave = f.readUint16LE();
+ _opcodeLift = f.readUint16LE();
+ _opcodeTurn = f.readUint16LE();
+ _opcodeSHide = f.readUint16LE();
+ _opcodeSSearch = f.readUint16LE();
+ _opcodeSRead = f.readUint16LE();
+ _opcodeSPut = f.readUint16LE();
+ _opcodeSLook = f.readUint16LE();
+
+ _actionMenu[0]._menuId = OPCODE_NONE >> 8;
+ _actionMenu[0]._actionId = OPCODE_NONE & 0xFF;
+
+ _actionMenu[1]._menuId = _opcodeSHide >> 8;
+ _actionMenu[1]._actionId = _opcodeSHide & 0xFF;
+
+ _actionMenu[2]._menuId = _opcodeAttach >> 8;
+ _actionMenu[2]._actionId = _opcodeAttach & 0xFF;
+
+ _actionMenu[3]._menuId = _opcodeForce >> 8;
+ _actionMenu[3]._actionId = _opcodeForce & 0xFF;
+
+ _actionMenu[4]._menuId = _opcodeSleep >> 8;
+ _actionMenu[4]._actionId = _opcodeSleep & 0xFF;
+
+ _actionMenu[5]._menuId = _opcodeEnter >> 8;
+ _actionMenu[5]._actionId = _opcodeEnter & 0xFF;
+
+ _actionMenu[6]._menuId = _opcodeClose >> 8;
+ _actionMenu[6]._actionId = _opcodeClose & 0xFF;
+
+ _actionMenu[7]._menuId = _opcodeKnock >> 8;
+ _actionMenu[7]._actionId = _opcodeKnock & 0xFF;
+
+ _actionMenu[8]._menuId = _opcodeEat >> 8;
+ _actionMenu[8]._actionId = _opcodeEat & 0xFF;
+
+ _actionMenu[9]._menuId = _opcodePlace >> 8;
+ _actionMenu[9]._actionId = _opcodePlace & 0xFF;
+
+ _actionMenu[10]._menuId = _opcodeOpen >> 8;
+ _actionMenu[10]._actionId = _opcodeOpen & 0xFF;
+
+ _actionMenu[11]._menuId = _opcodeLeave >> 8;
+ _actionMenu[11]._actionId = _opcodeLeave & 0xFF;
+}
+
/**
* Setup a menu's contents
* @remarks Originally called 'menut'
*/
-void Menu::setText(int menuId, int actionId, Common::String name) {
+void Menu::setText(MenuItem item, Common::String name) {
Common::String s = name;
- while (s.size() < 22)
- s += ' ';
-
- switch (menuId) {
+ switch (item._menuId) {
case MENU_INVENTORY:
- if (actionId != 7) {
- _inventoryStringArray[actionId] = s;
- _inventoryStringArray[actionId].insertChar(' ', 0);
+ if (item._actionId != 7) {
+ while (s.size() < 22)
+ s += ' ';
+
+ _inventoryStringArray[item._actionId] = s;
+ _inventoryStringArray[item._actionId].insertChar(' ', 0);
}
break;
- case MENU_MOVE:
- _moveStringArray[actionId] = s;
+ case MENU_MOVE: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 22)
+ s += ' ';
+
+ _moveStringArray[item._actionId] = s;
+ }
break;
- case MENU_ACTION:
- _actionStringArray[actionId] = s;
+ case MENU_ACTION: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 10)
+ s += ' ';
+
+ _actionStringArray[item._actionId] = s;
+ }
break;
- case MENU_SELF:
- _selfStringArray[actionId] = s;
+ case MENU_SELF: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 10)
+ s += ' ';
+
+ _selfStringArray[item._actionId] = s;
+ }
break;
case MENU_DISCUSS:
- _discussStringArray[actionId] = s;
+ _discussStringArray[item._actionId] = s;
break;
default:
break;
@@ -89,7 +219,7 @@ void Menu::setText(int menuId, int actionId, Common::String name) {
void Menu::setDestinationText(int roomId) {
Common::String nomp;
- if (roomId == 26)
+ if (roomId == ROOM26)
roomId = LANDING;
int destinationId = 0;
@@ -97,11 +227,11 @@ void Menu::setDestinationText(int roomId) {
nomp = _vm->getString(_vm->_destinationArray[destinationId][roomId] + kMenuPlaceStringIndex);
while (nomp.size() < 20)
nomp += ' ';
- setText(_moveMenu[destinationId + 1]._menuId, _moveMenu[destinationId + 1]._actionId, nomp);
+ setText(_moveMenu[destinationId + 1], nomp);
}
nomp = "* ";
for (int i = 7; i >= destinationId + 1; --i)
- setText(_moveMenu[i]._menuId, _moveMenu[i]._actionId, nomp);
+ setText(_moveMenu[i], nomp);
}
/**
@@ -109,26 +239,26 @@ void Menu::setDestinationText(int roomId) {
* @param menuId Menu number
* @param actionId Item index
*/
-void Menu::disableMenuItem(int menuId, int actionId) {
- switch (menuId) {
+void Menu::disableMenuItem(MenuItem item) {
+ switch (item._menuId) {
case MENU_INVENTORY:
- if (actionId > 6) {
- _inventoryStringArray[actionId].setChar('<', 0);
- _inventoryStringArray[actionId].setChar('>', 21);
+ if (item._actionId > 6) {
+ _inventoryStringArray[item._actionId].setChar('<', 0);
+ _inventoryStringArray[item._actionId].setChar('>', 21);
} else
- _inventoryStringArray[actionId].setChar('*', 0);
+ _inventoryStringArray[item._actionId].setChar('*', 0);
break;
case MENU_MOVE:
- _moveStringArray[actionId].setChar('*', 0);
+ _moveStringArray[item._actionId].setChar('*', 0);
break;
case MENU_ACTION:
- _actionStringArray[actionId].setChar('*', 0);
+ _actionStringArray[item._actionId].setChar('*', 0);
break;
case MENU_SELF:
- _selfStringArray[actionId].setChar('*', 0);
+ _selfStringArray[item._actionId].setChar('*', 0);
break;
case MENU_DISCUSS:
- _discussStringArray[actionId].setChar('*', 0);
+ _discussStringArray[item._actionId].setChar('*', 0);
break;
default:
break;
@@ -141,25 +271,23 @@ void Menu::disableMenuItem(int menuId, int actionId) {
* @param actionId Item index
* @remarks Originally called menu_enable
*/
-void Menu::enableMenuItem(int menuId, int actionId) {
- switch (menuId) {
+void Menu::enableMenuItem(MenuItem item) {
+ switch (item._menuId) {
case MENU_INVENTORY:
- _inventoryStringArray[actionId].setChar(' ', 0);
- _inventoryStringArray[actionId].setChar(' ', 21);
+ _inventoryStringArray[item._actionId].setChar(' ', 0);
+ _inventoryStringArray[item._actionId].setChar(' ', 21);
break;
case MENU_MOVE:
- _moveStringArray[actionId].setChar(' ', 0);
+ _moveStringArray[item._actionId].setChar(' ', 0);
break;
case MENU_ACTION:
- _actionStringArray[actionId].setChar(' ', 0);
+ _actionStringArray[item._actionId].setChar(' ', 0);
break;
case MENU_SELF:
- _selfStringArray[actionId].setChar(' ', 0);
- // The original sets two times the same value. Skipped
- // _selfStringArray[l].setChar(' ', 0);
+ _selfStringArray[item._actionId].setChar(' ', 0);
break;
case MENU_DISCUSS:
- _discussStringArray[actionId].setChar(' ', 0);
+ _discussStringArray[item._actionId].setChar(' ', 0);
break;
default:
break;
@@ -167,44 +295,33 @@ void Menu::enableMenuItem(int menuId, int actionId) {
}
void Menu::displayMenu() {
- int ind_tabl, k, col;
-
- int pt, x, y, color, msk, num_letr;
-
_vm->_mouse.hideMouse();
-
_vm->_screenSurface.fillRect(7, Common::Rect(0, 0, 639, 10));
- col = 28 * _vm->_resolutionScaler;
- if (_vm->_currGraphicalDevice == MODE_CGA)
- color = 1;
- else
- color = 9;
- num_letr = 0;
- do { // One character after the other
- ++num_letr;
- ind_tabl = 0;
- y = 1;
- do { // One column after the other
- k = 0;
- x = col;
- do { // One line after the other
- msk = 0x80;
- for (pt = 0; pt <= 7; ++pt) {
- if ((_charArr[num_letr - 1][ind_tabl] & msk) != 0) {
+
+ int col = 28 * kResolutionScaler;
+ for (int charNum = 0; charNum < 6; charNum++) {
+ // One character after the other
+ int idx = 0;
+ for (int y = 1; y < 9; ++y) {
+ // One column after the other
+ int x = col;
+ for (int k = 0; k < 3; ++k) {
+ // One line after the other
+ uint msk = 0x80;
+ for (int pt = 0; pt <= 7; ++pt) {
+ if ((_charArr[charNum][idx] & msk) != 0) {
_vm->_screenSurface.setPixel(Common::Point(x + 1, y + 1), 0);
_vm->_screenSurface.setPixel(Common::Point(x, y + 1), 0);
- _vm->_screenSurface.setPixel(Common::Point(x, y), color);
+ _vm->_screenSurface.setPixel(Common::Point(x, y), 9);
}
- msk = (uint)msk >> 1;
+ msk >>= 1;
++x;
}
- ++ind_tabl;
- ++k;
- } while (k != 3);
- ++y;
- } while (y != 9);
- col += 48 * _vm->_resolutionScaler;
- } while (num_letr != 6);
+ ++idx;
+ }
+ }
+ col += 48 * kResolutionScaler;
+ }
_vm->_mouse.showMouse();
}
@@ -280,16 +397,12 @@ void Menu::util(Common::Point pos) {
int ymx = (menuConstants[_msg3 - 1][3] << 3) + 16;
int dxcar = menuConstants[_msg3 - 1][2];
- int xmn = (menuConstants[_msg3 - 1][0] << 2) * _vm->_resolutionScaler;
+ int xmn = (menuConstants[_msg3 - 1][0] << 2) * kResolutionScaler;
- int ix;
- if (_vm->_resolutionScaler == 1)
- ix = 5;
- else
- ix = 3;
- int xmx = dxcar * ix * _vm->_resolutionScaler + xmn + 2;
+ int charWidth = 6;
+ int xmx = dxcar * charWidth + xmn + 2;
if ((pos.x > xmn) && (pos.x < xmx) && (pos.y < ymx) && (pos.y > 15)) {
- ix = (((uint)pos.y >> 3) - 1) + (_msg3 << 8);
+ int ix = (((uint)pos.y >> 3) - 1) + (_msg3 << 8);
if (ix != _msg4) {
invert(1);
_msg4 = ix;
@@ -305,79 +418,70 @@ void Menu::util(Common::Point pos) {
* Draw a menu
*/
void Menu::menuDown(int ii) {
- int cx, xcc, xco;
- int lignNumb;
-
// Make a copy of the current screen surface for later restore
_vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
// Draw the menu
- xco = menuConstants[ii - 1][0];
- lignNumb = menuConstants[ii - 1][3];
+ int minX = menuConstants[ii - 1][0] << 3;
+ int lineNum = menuConstants[ii - 1][3];
_vm->_mouse.hideMouse();
- xco = xco << 3;
- if (_vm->_resolutionScaler == 1)
- cx = 10;
- else
- cx = 6;
- xcc = xco + (menuConstants[ii - 1][2] * cx) + 6;
+ int deltaX = 6;
+ int maxX = minX + (menuConstants[ii - 1][2] * deltaX) + 6;
if ((ii == 4) && (_vm->getLanguage() == Common::EN_ANY))
// Extra width needed for Self menu in English version
- xcc = 435;
-
- _vm->_screenSurface.fillRect(15, Common::Rect(xco, 12, xcc, 10 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.fillRect(0, Common::Rect(xcc, 12, xcc + 4, 10 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.fillRect(0, Common::Rect(xco, 8 + (menuConstants[ii - 1][1] << 1), xcc + 4, 12 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.putxy(xco, 16);
- cx = 0;
- do {
- ++cx;
+ maxX = 435;
+
+ _vm->_screenSurface.fillRect(15, Common::Rect(minX, 12, maxX, 10 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface.fillRect(0, Common::Rect(maxX, 12, maxX + 4, 10 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface.fillRect(0, Common::Rect(minX, 8 + (menuConstants[ii - 1][1] << 1), maxX + 4, 12 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface.putxy(minX, 16);
+ for (int i = 1; i <= lineNum; i++) {
switch (ii) {
case 1:
- if (_inventoryStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_inventoryStringArray[cx], 4);
+ if (_inventoryStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_inventoryStringArray[i], 4);
break;
case 2:
- if (_moveStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_moveStringArray[cx], 4);
+ if (_moveStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_moveStringArray[i], 4);
break;
case 3:
- if (_actionStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_actionStringArray[cx], 4);
+ if (_actionStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_actionStringArray[i], 4);
break;
case 4:
- if (_selfStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_selfStringArray[cx], 4);
+ if (_selfStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_selfStringArray[i], 4);
break;
case 5:
- if (_discussStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_discussStringArray[cx], 4);
+ if (_discussStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_discussStringArray[i], 4);
break;
case 6:
- _vm->_screenSurface.drawString(_vm->getEngineString(S_SAVE_LOAD + cx), 4);
+ _vm->_screenSurface.drawString(_vm->getEngineString(S_SAVE_LOAD + i), 4);
break;
case 7: {
Common::String s = _vm->getEngineString(S_SAVE_LOAD + 1);
s += ' ';
- s += (char)(48 + cx);
+ s += (char)(48 + i);
_vm->_screenSurface.drawString(s, 4);
}
break;
case 8:
- if (cx == 1)
+ if (i == 1)
_vm->_screenSurface.drawString(_vm->getEngineString(S_RESTART), 4);
else {
Common::String s = _vm->getEngineString(S_SAVE_LOAD + 2);
s += ' ';
- s += (char)(47 + cx);
+ s += (char)(47 + i);
_vm->_screenSurface.drawString(s, 4);
}
break;
default:
break;
}
- _vm->_screenSurface.putxy(xco, _vm->_screenSurface._textPos.y + 8);
- } while (cx != lignNumb);
+ _vm->_screenSurface.putxy(minX, _vm->_screenSurface._textPos.y + 8);
+ }
_multiTitle = true;
_vm->_mouse.showMouse();
}
@@ -427,24 +531,24 @@ void Menu::updateMenu() {
_vm->_prevPos = curPos;
bool tes = (curPos.y < 11)
- && ((curPos.x >= (28 * _vm->_resolutionScaler) && curPos.x <= (28 * _vm->_resolutionScaler + 24))
- || (curPos.x >= (76 * _vm->_resolutionScaler) && curPos.x <= (76 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 124 * _vm->_resolutionScaler) && (curPos.x < 124 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 172 * _vm->_resolutionScaler) && (curPos.x < 172 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 220 * _vm->_resolutionScaler) && (curPos.x < 220 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 268 * _vm->_resolutionScaler) && (curPos.x < 268 * _vm->_resolutionScaler + 24)));
+ && ((curPos.x >= (28 * kResolutionScaler) && curPos.x <= (28 * kResolutionScaler + 24))
+ || (curPos.x >= (76 * kResolutionScaler) && curPos.x <= (76 * kResolutionScaler + 24))
+ || ((curPos.x > 124 * kResolutionScaler) && (curPos.x < 124 * kResolutionScaler + 24))
+ || ((curPos.x > 172 * kResolutionScaler) && (curPos.x < 172 * kResolutionScaler + 24))
+ || ((curPos.x > 220 * kResolutionScaler) && (curPos.x < 220 * kResolutionScaler + 24))
+ || ((curPos.x > 268 * kResolutionScaler) && (curPos.x < 268 * kResolutionScaler + 24)));
if (tes) {
int ix;
- if (curPos.x < 76 * _vm->_resolutionScaler)
+ if (curPos.x < 76 * kResolutionScaler)
ix = MENU_INVENTORY;
- else if (curPos.x < 124 * _vm->_resolutionScaler)
+ else if (curPos.x < 124 * kResolutionScaler)
ix = MENU_MOVE;
- else if (curPos.x < 172 * _vm->_resolutionScaler)
+ else if (curPos.x < 172 * kResolutionScaler)
ix = MENU_ACTION;
- else if (curPos.x < 220 * _vm->_resolutionScaler)
+ else if (curPos.x < 220 * kResolutionScaler)
ix = MENU_SELF;
- else if (curPos.x < 268 * _vm->_resolutionScaler)
+ else if (curPos.x < 268 * kResolutionScaler)
ix = MENU_DISCUSS;
else
ix = MENU_FILE;
@@ -486,18 +590,37 @@ void Menu::updateMenu() {
}
}
-void Menu::initMenu(MortevielleEngine *vm) {
+void Menu::setParent(MortevielleEngine *vm) {
_vm = vm;
+}
- int i;
+void Menu::initMenu() {
Common::File f;
- bool enMenuLoaded = false;
- if (_vm->getLanguage() == Common::EN_ANY) {
- // Open the mort.dat file
+ bool menuLoaded = false;
+ // First try to read it from mort.dat if useOriginalData() is false
+ if (!_vm->useOriginalData()) {
if (!f.open(MORT_DAT))
warning("File %s not found. Using default menu from game data", MORT_DAT);
else {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(_vm->getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+
// Validate the data file header
char fileId[4];
f.read(fileId, 4);
@@ -512,12 +635,20 @@ void Menu::initMenu(MortevielleEngine *vm) {
f.read(dataType, 4);
dataSize = f.readUint16LE();
if (!strncmp(dataType, "MENU", 4)) {
- // MENU section
- if (dataSize <= 7 * 24) {
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ continue;
+ }
+ if (dataSize == 6 * 24) {
f.read(_charArr, dataSize);
- enMenuLoaded = true;
+ menuLoaded = true;
} else
- warning("Wrong size %d for menu data. Expected %d or less", dataSize, 7*24);
+ warning("Wrong size %d for menu data. Expected %d or less", dataSize, 6 * 24);
break;
} else {
// Other sections
@@ -527,46 +658,50 @@ void Menu::initMenu(MortevielleEngine *vm) {
}
// Close the file
f.close();
- if (!enMenuLoaded)
- warning("Failed to load English menu. Will use default menu from game data instead");
+ if (!menuLoaded)
+ warning("Failed to load menu from mort.dat. Will use default menu from game data instead.");
}
}
- if (!enMenuLoaded) {
- if (!f.open("menufr.mor"))
+ if (!menuLoaded) {
+ // Load menu from game data using the original language
+ if (_vm->getOriginalLanguage() == Common::FR_FRA) {
+ if (!f.open("menufr.mor"))
+ error("Missing file - menufr.mor");
+ } else { // Common::DE_DEU
if (!f.open("menual.mor"))
- if (!f.open("menu.mor"))
- error("Missing file - menufr.mor or menual.mor or menu.mor");
-
- f.read(_charArr, 7 * 24);
+ error("Missing file - menual.mor");
+ }
+ f.read(_charArr, 6 * 24);
f.close();
}
// Skipped: dialog asking to swap floppy
- for (i = 1; i <= 8; ++i)
+ for (int i = 1; i <= 8; ++i)
_inventoryStringArray[i] = "* ";
_inventoryStringArray[7] = "< -*-*-*-*-*-*-*-*-*- ";
- for (i = 1; i <= 7; ++i)
+ for (int i = 1; i <= 7; ++i)
_moveStringArray[i] = "* ";
- i = 1;
- do {
+ for (int i = 1; i < 22; i++) {
_actionStringArray[i] = _vm->getString(i + kMenuActionStringIndex);
-
+ if ((_actionStringArray[i][0] != '*') && (_actionStringArray[i][0] != ' '))
+ _actionStringArray[i].insertChar(' ', 0);
while (_actionStringArray[i].size() < 10)
_actionStringArray[i] += ' ';
if (i < 9) {
if (i < 6) {
_selfStringArray[i] = _vm->getString(i + kMenuSelfStringIndex);
+ if ((_selfStringArray[i][0] != '*') && (_selfStringArray[i][0] != ' '))
+ _selfStringArray[i].insertChar(' ', 0);
while (_selfStringArray[i].size() < 10)
_selfStringArray[i] += ' ';
}
_discussStringArray[i] = _vm->getString(i + kMenuSayStringIndex) + ' ';
}
- ++i;
- } while (i != 22);
- for (i = 1; i <= 8; ++i) {
+ }
+ for (int i = 1; i <= 8; ++i) {
_discussMenu[i]._menuId = MENU_DISCUSS;
_discussMenu[i]._actionId = i;
if (i < 8) {
@@ -576,7 +711,7 @@ void Menu::initMenu(MortevielleEngine *vm) {
_inventoryMenu[i]._menuId = MENU_INVENTORY;
_inventoryMenu[i]._actionId = i;
if (i > 6)
- disableMenuItem(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId);
+ disableMenuItem(_inventoryMenu[i]);
}
_msg3 = OPCODE_NONE;
_msg4 = OPCODE_NONE;
@@ -591,13 +726,21 @@ void Menu::initMenu(MortevielleEngine *vm) {
*/
void Menu::setSearchMenu() {
for (int i = 1; i <= 7; ++i)
- disableMenuItem(MENU_MOVE, _moveMenu[i]._actionId);
+ disableMenuItem(_moveMenu[i]);
for (int i = 1; i <= 11; ++i)
- disableMenuItem(_actionMenu[i]._menuId, _actionMenu[i]._actionId);
+ disableMenuItem(_actionMenu[i]);
+
+ MenuItem miSound;
+ miSound._menuId = _opcodeSound >> 8;
+ miSound._actionId = _opcodeSound & 0xFF;
- setText(OPCODE_SOUND >> 8, OPCODE_SOUND & 0xFF, _vm->getEngineString(S_SUITE));
- setText(OPCODE_LIFT >> 8, OPCODE_LIFT & 0xFF, _vm->getEngineString(S_STOP));
+ MenuItem miLift;
+ miLift._menuId = _opcodeLift >> 8;
+ miLift._actionId = _opcodeLift & 0xFF;
+
+ setText(miSound, _vm->getEngineString(S_SUITE));
+ setText(miLift, _vm->getEngineString(S_STOP));
}
/**
@@ -607,10 +750,18 @@ void Menu::setSearchMenu() {
void Menu::unsetSearchMenu() {
setDestinationText(_vm->_coreVar._currPlace);
for (int i = 1; i <= 11; ++i)
- enableMenuItem(_actionMenu[i]._menuId, _actionMenu[i]._actionId);
+ enableMenuItem(_actionMenu[i]);
+
+ MenuItem miSound;
+ miSound._menuId = _opcodeSound >> 8;
+ miSound._actionId = _opcodeSound & 0xFF;
+
+ MenuItem miLift;
+ miLift._menuId = _opcodeLift >> 8;
+ miLift._actionId = _opcodeLift & 0xFF;
- setText(OPCODE_SOUND >> 8, OPCODE_SOUND & 0xFF, _vm->getEngineString(S_PROBE));
- setText(OPCODE_LIFT >> 8, OPCODE_LIFT & 0xFF, _vm->getEngineString(S_RAISE));
+ setText(miSound, _vm->getEngineString(S_PROBE));
+ setText(miLift, _vm->getEngineString(S_RAISE));
}
/**
@@ -626,15 +777,15 @@ void Menu::setInventoryText() {
++cy;
int r = _vm->_coreVar._inventory[i] + 400;
nomp = _vm->getString(r - 501 + kInventoryStringIndex);
- setText(_inventoryMenu[cy]._menuId, _inventoryMenu[cy]._actionId, nomp);
- enableMenuItem(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId);
+ setText(_inventoryMenu[cy], nomp);
+ enableMenuItem(_inventoryMenu[i]);
}
}
if (cy < 6) {
for (int i = cy + 1; i <= 6; ++i) {
- setText(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId, " ");
- disableMenuItem(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId);
+ setText(_inventoryMenu[i], " ");
+ disableMenuItem(_inventoryMenu[i]);
}
}
}
diff --git a/engines/mortevielle/menu.h b/engines/mortevielle/menu.h
index 2428d8917b..debf5b09b6 100644
--- a/engines/mortevielle/menu.h
+++ b/engines/mortevielle/menu.h
@@ -40,45 +40,28 @@ enum {
MENU_LOAD = 8
};
-enum verbs {OPCODE_NONE = 0, OPCODE_ATTACH = 0x301, OPCODE_WAIT = 0x302, OPCODE_FORCE = 0x303, OPCODE_SLEEP = 0x304, OPCODE_LISTEN = 0x305,
-OPCODE_ENTER = 0x306, OPCODE_CLOSE = 0x307, OPCODE_SEARCH = 0x308, OPCODE_KNOCK = 0x309, OPCODE_SCRATCH = 0x30a,
-OPCODE_READ = 0x30b, OPCODE_EAT = 0x30c, OPCODE_PLACE = 0x30d, OPCODE_OPEN = 0x30e, OPCODE_TAKE = 0x30f,
-OPCODE_LOOK = 0x310, OPCODE_SMELL = 0x311, OPCODE_SOUND = 0x312, OPCODE_LEAVE = 0x313, OPCODE_LIFT = 0x314,
-OPCODE_TURN = 0x315, OPCODE_SHIDE = 0x401, OPCODE_SSEARCH = 0x402, OPCODE_SREAD = 0x403, OPCODE_SPUT = 0x404,
-OPCODE_SLOOK = 0x405};
-
-struct menuItem {
+const int OPCODE_NONE = 0;
+
+struct MenuItem {
int _menuId;
int _actionId;
};
-static const menuItem _actionMenu[12] = {
- {OPCODE_NONE >> 8, OPCODE_NONE & 0xFF},
- {OPCODE_SHIDE >> 8, OPCODE_SHIDE & 0xFF},
- {OPCODE_ATTACH >> 8, OPCODE_ATTACH & 0xFF},
- {OPCODE_FORCE >> 8, OPCODE_FORCE & 0xFF},
- {OPCODE_SLEEP >> 8, OPCODE_SLEEP & 0xFF},
- {OPCODE_ENTER >> 8, OPCODE_ENTER & 0xFF},
- {OPCODE_CLOSE >> 8, OPCODE_CLOSE & 0xFF},
- {OPCODE_KNOCK >> 8, OPCODE_KNOCK & 0xFF},
- {OPCODE_EAT >> 8, OPCODE_EAT & 0xFF},
- {OPCODE_PLACE >> 8, OPCODE_PLACE & 0xFF},
- {OPCODE_OPEN >> 8, OPCODE_OPEN & 0xFF},
- {OPCODE_LEAVE >> 8, OPCODE_LEAVE & 0xFF}
-};
-
class Menu {
private:
MortevielleEngine *_vm;
- byte _charArr[7][24];
+ byte _charArr[6][24];
int _msg3;
int _msg4;
void util(Common::Point pos);
void invert(int indx);
void menuDown(int ii);
+
public:
+ Menu();
+
bool _menuActive;
bool _menuSelected;
bool _multiTitle;
@@ -88,21 +71,51 @@ public:
Common::String _actionStringArray[22];
Common::String _selfStringArray[7];
Common::String _discussStringArray[9];
- menuItem _discussMenu[9];
- menuItem _inventoryMenu[9];
- menuItem _moveMenu[8];
-
- void setText(int menuId, int actionId, Common::String name);
+ MenuItem _discussMenu[9];
+ MenuItem _inventoryMenu[9];
+ MenuItem _moveMenu[8];
+
+ int _opcodeAttach;
+ int _opcodeWait;
+ int _opcodeForce;
+ int _opcodeSleep;
+ int _opcodeListen;
+ int _opcodeEnter;
+ int _opcodeClose;
+ int _opcodeSearch;
+ int _opcodeKnock;
+ int _opcodeScratch;
+ int _opcodeRead;
+ int _opcodeEat;
+ int _opcodePlace;
+ int _opcodeOpen;
+ int _opcodeTake;
+ int _opcodeLook;
+ int _opcodeSmell;
+ int _opcodeSound;
+ int _opcodeLeave;
+ int _opcodeLift;
+ int _opcodeTurn;
+ int _opcodeSHide;
+ int _opcodeSSearch;
+ int _opcodeSRead;
+ int _opcodeSPut;
+ int _opcodeSLook;
+ MenuItem _actionMenu[12];
+
+ void setParent(MortevielleEngine *vm);
+ void readVerbNums(Common::File &f, int dataSize);
+ void setText(MenuItem item, Common::String name);
void setDestinationText(int roomId);
void setInventoryText();
- void disableMenuItem(int menuId, int actionId);
- void enableMenuItem(int menuId, int actionId);
+ void disableMenuItem(MenuItem item);
+ void enableMenuItem(MenuItem item);
void displayMenu();
void drawMenu();
void menuUp(int msgId);
void eraseMenu();
void updateMenu();
- void initMenu(MortevielleEngine *vm);
+ void initMenu();
void setSearchMenu();
void unsetSearchMenu();
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index 0b6b82c1a9..d434150977 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -46,7 +46,7 @@ namespace Mortevielle {
MortevielleEngine *g_vm;
-MortevielleEngine::MortevielleEngine(OSystem *system, const ADGameDescription *gameDesc):
+MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc):
Engine(system), _gameDescription(gameDesc), _randomSource("mortevielle"),
_soundManager(_mixer) {
g_vm = this;
@@ -57,11 +57,13 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const ADGameDescription *g
_text.setParent(this);
_soundManager.setParent(this);
_savegameManager.setParent(this);
+ _menu.setParent(this);
_lastGameFrame = 0;
_mouseClick = false;
_inMainGameLoop = false;
_quitGame = false;
+ _pauseStartTime = -1;
_roomPresenceLuc = false;
_roomPresenceIda = false;
@@ -91,8 +93,6 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const ADGameDescription *g
_uptodatePresence = false;
_textColor = 0;
- _currGraphicalDevice = -1;
- _newGraphicalDevice = -1;
_place = -1;
_x26KeyCount = -1;
@@ -166,6 +166,25 @@ Common::String MortevielleEngine::generateSaveFilename(const Common::String &tar
}
/**
+ * Pause the game.
+ */
+void MortevielleEngine::pauseEngineIntern(bool pause) {
+ Engine::pauseEngineIntern(pause);
+ if (pause) {
+ if (_pauseStartTime == -1)
+ _pauseStartTime = readclock();
+ } else {
+ if (_pauseStartTime != -1) {
+ int pauseEndTime = readclock();
+ _currentTime += (pauseEndTime - _pauseStartTime);
+ if (_uptodatePresence)
+ _startTime += (pauseEndTime - _pauseStartTime);
+ }
+ _pauseStartTime = -1;
+ }
+}
+
+/**
* Initialize the game state
*/
Common::ErrorCode MortevielleEngine::initialize() {
@@ -179,10 +198,6 @@ Common::ErrorCode MortevielleEngine::initialize() {
// Set up an intermediate screen surface
_screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
- // Set the screen mode
- _currGraphicalDevice = MODE_EGA;
- _resolutionScaler = 2;
-
_txxFileFl = false;
// Load texts from TXX files
loadTexts();
@@ -203,8 +218,6 @@ Common::ErrorCode MortevielleEngine::initialize() {
// Setup the mouse cursor
initMouse();
- _currGraphicalDevice = MODE_EGA;
- _newGraphicalDevice = _currGraphicalDevice;
loadPalette();
loadCFIPH();
loadCFIEC();
@@ -219,11 +232,8 @@ Common::ErrorCode MortevielleEngine::initialize() {
testKeyboard();
showConfigScreen();
- _newGraphicalDevice = _currGraphicalDevice;
testKeyboard();
- if (_newGraphicalDevice != _currGraphicalDevice)
- _currGraphicalDevice = _newGraphicalDevice;
- hirs();
+ clearScreen();
_soundManager.loadNoise();
_soundManager.loadAmbiantSounds();
@@ -273,6 +283,8 @@ Common::ErrorCode MortevielleEngine::loadMortDat() {
readStaticStrings(f, dataSize, kStaticStrings);
} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
readStaticStrings(f, dataSize, kGameStrings);
+ } else if (!strncmp(dataType, "VERB", 4)) {
+ _menu.readVerbNums(f, dataSize);
} else {
// Unknown section
f.skip(dataSize);
@@ -286,6 +298,7 @@ Common::ErrorCode MortevielleEngine::loadMortDat() {
return Common::kNoError;
}
+
/**
* Read in a static strings block, and if the language matches, load up the static strings
*/
@@ -354,10 +367,16 @@ Common::Error MortevielleEngine::run() {
if (loadSlot == 0)
// Show the game introduction
showIntroduction();
+ else {
+ _caff = 51;
+ _text.taffich();
+ }
// Either load the initial game state savegame, or the specified savegame number
adzon();
- _savegameManager.loadSavegame(generateSaveFilename(loadSlot));
+ resetVariables();
+ if (loadSlot != 0)
+ _savegameManager.loadSavegame(generateSaveFilename(loadSlot));
// Run the main game loop
mainGame();
@@ -400,11 +419,11 @@ void MortevielleEngine::mainGame() {
for (_crep = 1; _crep <= _x26KeyCount; ++_crep)
decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
- _menu.initMenu(this);
+ _menu.initMenu();
charToHour();
initGame();
- hirs();
+ clearScreen();
drawRightFrame();
_mouse.showMouse();
diff --git a/engines/mortevielle/mortevielle.h b/engines/mortevielle/mortevielle.h
index 699ee3f37a..5ae94987a0 100644
--- a/engines/mortevielle/mortevielle.h
+++ b/engines/mortevielle/mortevielle.h
@@ -62,6 +62,11 @@ enum {
MORTDAT_LANG_GERMAN = 2
};
+enum {
+ kUseOriginalData = 0,
+ kUseEngineDataFile = 1
+};
+
// Static string list
enum {
S_YES_NO = 0, S_GO_TO = 1, S_SOMEONE_ENTERS = 2, S_COOL = 3, S_LOURDE = 4,
@@ -115,6 +120,7 @@ const int kMenuSelfStringIndex = 497;
const int kMenuSayStringIndex = 502;
const int kMaxPatt = 20;
+const int kResolutionScaler = 2;
/*
9 "A glance at the forbidden$",
18 "It's already open$",
@@ -129,18 +135,6 @@ enum Places {
DOOR = 25, ROOM26 = 26, COAT_ARMS = 27
};
-enum GraphicModes { MODE_AMSTRAD1512 = 0, MODE_CGA = 1, MODE_EGA = 2, MODE_HERCULES = 3, MODE_TANDY = 4 };
-
-struct nhom {
- byte _id; /* number between 0 and 32 */
- byte _hom[4];
-};
-
-struct CgaPalette {
- byte _p;
- nhom _a[16];
-};
-
struct Pattern {
byte _tay, _tax;
byte _des[kMaxPatt + 1][kMaxPatt + 1];
@@ -169,16 +163,17 @@ struct Hint {
byte _point;
};
+struct MortevielleGameDescription;
+
class MortevielleEngine : public Engine {
private:
- const ADGameDescription *_gameDescription;
+ const MortevielleGameDescription *_gameDescription;
Common::Stack<int> _keypresses;
uint32 _lastGameFrame;
Common::Point _mousePos;
Common::StringArray _engineStrings;
Common::StringArray _gameStrings;
- Pattern _patternArr[15];
int _menuOpcode;
bool _inMainGameLoop; // Flag when the main game loop is active
@@ -219,10 +214,9 @@ private:
int _minute;
int _curSearchObjId;
int _controlMenu;
- int _startHour;
- int _endHour;
+ int _startTime;
+ int _endTime;
Common::Point _stdPal[91][17];
- CgaPalette _cgaPal[91];
int _x26KeyCount;
int _roomDoorId;
@@ -235,7 +229,8 @@ private:
int _x;
int _y;
int _currentHourCount;
- int _currentDayHour;
+ int _currentTime;
+ int _pauseStartTime;
Common::String _hintPctMessage;
byte *_cfiecBuffer;
@@ -255,7 +250,6 @@ private:
void mainGame();
void playGame();
void handleAction();
- void displayCGAPattern(int n, Pattern *p, nhom *pal);
void loadPalette();
void loadTexts();
void loadCFIEC();
@@ -276,7 +270,6 @@ private:
void getReadDescription(int objId);
void getSearchDescription(int objId);
int checkLeaveSecretPassage();
- void changeGraphicalDevice(int newDevice);
void startDialog(int16 rep);
void endSearch();
int convertCharacterIndexToBitIndex(int characterIndex);
@@ -384,6 +377,7 @@ private:
void displayQuestionText(Common::String s, int cmd);
void displayTextInDescriptionBar(int x, int y, int nb, int mesgId);
void displayTextInVerbBar(Common::String text);
+ void displayTextBlock(Common::String text);
void mapMessageId(int &mesgId);
void resetOpenObjects();
void setCoordinates(int sx);
@@ -397,13 +391,12 @@ private:
void prepareNextObject();
void putObject();
void resetObjectPlace();
+ void drawDiscussionBox();
+ void displayNarrativePicture(int af, int ob);
+ void menuUp();
+ void displayLookScreen(int objId);
void adzon();
- void premtet();
- void ecr2(Common::String text);
- void tlu(int af, int ob);
- void mennor();
- void treg(int objId);
public:
Common::Point _prevPos;
@@ -417,8 +410,6 @@ public:
bool _blo;
bool _destinationOk;
bool _largestClearScreen;
- int _currGraphicalDevice;
- int _newGraphicalDevice;
float _addFix;
int _savedBitIndex;
int _numpal;
@@ -430,7 +421,6 @@ public:
int _caff;
int _crep;
- int _resolutionScaler;
byte _destinationArray[7][25];
byte *_curPict;
@@ -449,7 +439,7 @@ public:
TextHandler _text;
DialogManager _dialogManager;
- MortevielleEngine(OSystem *system, const ADGameDescription *gameDesc);
+ MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc);
~MortevielleEngine();
virtual bool hasFeature(EngineFeature f) const;
virtual bool canLoadGameStateCurrently();
@@ -457,8 +447,12 @@ public:
virtual Common::Error loadGameState(int slot);
virtual Common::Error saveGameState(int slot, const Common::String &desc);
virtual Common::Error run();
+ virtual void pauseEngineIntern(bool pause);
+ virtual GUI::Debugger *getDebugger() {return &_debugger;}
uint32 getGameFlags() const;
Common::Language getLanguage() const;
+ Common::Language getOriginalLanguage() const;
+ bool useOriginalData() const;
static Common::String generateSaveFilename(const Common::String &target, int slot);
Common::String generateSaveFilename(int slot) { return generateSaveFilename(_targetName, slot); }
@@ -490,7 +484,7 @@ public:
void handleDescriptionText(int f, int mesgId);
int getAnimOffset(int frameNum, int animNum);
- void hirs();
+ void clearScreen();
};
extern MortevielleEngine *g_vm;
diff --git a/engines/mortevielle/mouse.cpp b/engines/mortevielle/mouse.cpp
index dfc9ccd706..9eb4e129c0 100644
--- a/engines/mortevielle/mouse.cpp
+++ b/engines/mortevielle/mouse.cpp
@@ -65,8 +65,8 @@ void MouseHandler::showMouse() {
* @remarks Originally called 'pos_mouse'
*/
void MouseHandler::setMousePosition(Common::Point newPos) {
- if (newPos.x > 314 * _vm->_resolutionScaler)
- newPos.x = 314 * _vm->_resolutionScaler;
+ if (newPos.x > 314 * kResolutionScaler)
+ newPos.x = 314 * kResolutionScaler;
else if (newPos.x < 0)
newPos.x = 0;
if (newPos.y > 199)
@@ -138,16 +138,16 @@ void MouseHandler::moveMouse(bool &funct, char &key) {
cy = 190;
break;
case '9':
- cx = 315 * _vm->_resolutionScaler;
+ cx = 315 * kResolutionScaler;
cy = 1;
break;
case '3':
cy = 190;
- cx = 315 * _vm->_resolutionScaler;
+ cx = 315 * kResolutionScaler;
break;
case '5':
cy = 100;
- cx = 155 * _vm->_resolutionScaler;
+ cx = 155 * kResolutionScaler;
break;
case ' ':
case '\15':
@@ -201,27 +201,27 @@ void MouseHandler::moveMouse(bool &funct, char &key) {
}
break;
case 'I':
- cx = _vm->_resolutionScaler * 32;
+ cx = kResolutionScaler * 32;
cy = 8;
break;
case 'D':
- cx = 80 * _vm->_resolutionScaler;
+ cx = 80 * kResolutionScaler;
cy = 8;
break;
case 'A':
- cx = 126 * _vm->_resolutionScaler;
+ cx = 126 * kResolutionScaler;
cy = 8;
break;
case 'S':
- cx = 174 * _vm->_resolutionScaler;
+ cx = 174 * kResolutionScaler;
cy = 8;
break;
case 'P':
- cx = 222 * _vm->_resolutionScaler;
+ cx = 222 * kResolutionScaler;
cy = 8;
break;
case 'F':
- cx = _vm->_resolutionScaler * 270;
+ cx = kResolutionScaler * 270;
cy = 8;
break;
case '\23':
diff --git a/engines/mortevielle/outtext.cpp b/engines/mortevielle/outtext.cpp
index 99c06c7c4c..d50f4005de 100644
--- a/engines/mortevielle/outtext.cpp
+++ b/engines/mortevielle/outtext.cpp
@@ -53,7 +53,6 @@ int TextHandler::nextWord(int p, const char *ch, int &tab) {
* @remarks Originally called 'afftex'
*/
void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int dy, int typ) {
- int tab;
Common::String s;
int i, j;
@@ -61,10 +60,7 @@ void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int
inputStr += '$';
_vm->_screenSurface.putxy(x, y);
- if (_vm->_resolutionScaler == 1)
- tab = 10;
- else
- tab = 6;
+ int tab = 6;
dx *= 6;
dy *= 6;
int xc = x;
@@ -168,14 +164,11 @@ void TextHandler::loadAniFile(Common::String filename, int32 skipSize, int lengt
}
void TextHandler::taffich() {
- static const byte rang[16] = {15, 14, 11, 7, 13, 12, 10, 6, 9, 5, 3, 1, 2, 4, 8, 0};
-
static const byte tran1[] = { 121, 121, 138, 139, 120 };
static const byte tran2[] = { 150, 150, 152, 152, 100, 110, 159, 100, 100 };
int cx, drawingSize, npal;
int32 drawingStartPos;
- int alllum[16];
int a = _vm->_caff;
if ((a >= 153) && (a <= 161))
@@ -272,21 +265,6 @@ void TextHandler::taffich() {
npal = a + 37;
}
loadPictureFile(filename, altFilename, drawingStartPos, drawingSize);
- if (_vm->_currGraphicalDevice == MODE_HERCULES) {
- for (int i = 0; i <= 15; ++i) {
- int palh = READ_LE_UINT16(&_vm->_curPict[2 + (i << 1)]);
- alllum[i] = (palh & 15) + (((uint)palh >> 12) & 15) + (((uint)palh >> 8) & 15);
- }
- for (int i = 0; i <= 15; ++i) {
- int k = 0;
- for (int j = 0; j <= 15; ++j) {
- if (alllum[j] > alllum[k])
- k = j;
- }
- _vm->_curPict[2 + (k << 1)] = rang[i];
- alllum[k] = -1;
- }
- }
_vm->_numpal = npal;
_vm->setPal(npal);
@@ -314,7 +292,7 @@ void TextHandler::taffich() {
loadAniFile(filename, drawingStartPos, drawingSize);
}
_vm->_mouse.showMouse();
- if ((a < COAT_ARMS) && ((_vm->_maff < COAT_ARMS) || (_vm->_coreVar._currPlace == LANDING)) && (_vm->_currAction != OPCODE_ENTER)) {
+ if ((a < COAT_ARMS) && ((_vm->_maff < COAT_ARMS) || (_vm->_coreVar._currPlace == LANDING)) && (_vm->_currAction != _vm->_menu._opcodeEnter)) {
if ((a == ATTIC) || (a == CELLAR))
_vm->displayAloneText();
else if (!_vm->_blo)
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
index 651ed07b65..c14a03cd60 100644
--- a/engines/mortevielle/saveload.cpp
+++ b/engines/mortevielle/saveload.cpp
@@ -72,15 +72,16 @@ void SavegameManager::sync_save(Common::Serializer &sz) {
* Inner code for loading a saved game
* @remarks Originally called 'takesav'
*/
-void SavegameManager::loadSavegame(const Common::String &filename) {
+bool SavegameManager::loadSavegame(const Common::String &filename) {
// Try loading first from the save area
Common::SeekableReadStream *stream = g_system->getSavefileManager()->openForLoading(filename);
Common::File f;
if (stream == NULL) {
- if (!f.open(filename))
- error("Unable to open save file '%s'", filename.c_str());
-
+ if (!f.open(filename)) {
+ warning("Unable to open save file '%s'", filename.c_str());
+ return false;
+ }
stream = f.readStream(f.size());
f.close();
}
@@ -107,6 +108,8 @@ void SavegameManager::loadSavegame(const Common::String &filename) {
// Close the stream
delete stream;
+
+ return true;
}
/**
@@ -115,14 +118,15 @@ void SavegameManager::loadSavegame(const Common::String &filename) {
Common::Error SavegameManager::loadGame(const Common::String &filename) {
g_vm->_mouse.hideMouse();
g_vm->displayEmptyHand();
- loadSavegame(filename);
-
- /* Initialization */
- g_vm->charToHour();
- g_vm->initGame();
- g_vm->gameLoaded();
- g_vm->_mouse.showMouse();
- return Common::kNoError;
+ if (loadSavegame(filename)) {
+ /* Initialization */
+ g_vm->charToHour();
+ g_vm->initGame();
+ g_vm->gameLoaded();
+ g_vm->_mouse.showMouse();
+ return Common::kNoError;
+ } else
+ return Common::kUnknownError;
}
/**
diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h
index 0121a04d8e..79747e6889 100644
--- a/engines/mortevielle/saveload.h
+++ b/engines/mortevielle/saveload.h
@@ -57,7 +57,7 @@ private:
void sync_save(Common::Serializer &sz);
public:
void setParent(MortevielleEngine *vm);
- void loadSavegame(const Common::String &filename);
+ bool loadSavegame(const Common::String &filename);
Common::Error loadGame(const Common::String &filename);
Common::Error saveGame(int n, const Common::String &saveName);
Common::Error loadGame(int slot);
diff --git a/engines/mortevielle/sound.cpp b/engines/mortevielle/sound.cpp
index 30dc4ce79f..b670246726 100644
--- a/engines/mortevielle/sound.cpp
+++ b/engines/mortevielle/sound.cpp
@@ -258,7 +258,7 @@ void SoundManager::litph(tablint &t, int typ, int tempo) {
} else if (idx == 46) {
if (!_audioStream)
_audioStream = Audio::makeQueuingAudioStream(freq, false);
- for (int i = 0; i < 10; i++)
+ for (int j = 0; j < 10; j++)
_audioStream->queueBuffer(emptyBuf, 19, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
} else {
warning("Other code: %d - %d %d", idx, _troctBuf[i], _troctBuf[i + 1]);
@@ -741,6 +741,10 @@ void SoundManager::startSpeech(int rep, int ht, int typ) {
uint16 savph[501];
int tempo;
+ // Hack to avoid a crash in the ending version. To be removed when the speech are implemented
+ if ((rep == 141) && (typ == 0))
+ return;
+
if (_vm->_soundOff)
return;
@@ -784,4 +788,13 @@ void SoundManager::startSpeech(int rep, int ht, int typ) {
_vm->setPal(_vm->_numpal);
}
+void SoundManager::waitSpeech() {
+ while (_mixer->isSoundHandleActive(_soundHandle) && !_vm->keyPressed() && !_vm->_mouseClick && !_vm->shouldQuit())
+ ;
+ // In case the handle is still active, stop it.
+ _mixer->stopHandle(_soundHandle);
+
+ if (!_vm->keyPressed() && !_vm->_mouseClick && !_vm->shouldQuit())
+ g_system->delayMillis(600);
+}
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/sound.h b/engines/mortevielle/sound.h
index 1e4a4cd54c..cc0567fd98 100644
--- a/engines/mortevielle/sound.h
+++ b/engines/mortevielle/sound.h
@@ -98,6 +98,7 @@ public:
void loadAmbiantSounds();
void loadNoise();
void startSpeech(int rep, int ht, int typ);
+ void waitSpeech();
};
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/utils.cpp b/engines/mortevielle/utils.cpp
index 80f19277df..7809143176 100644
--- a/engines/mortevielle/utils.cpp
+++ b/engines/mortevielle/utils.cpp
@@ -67,9 +67,10 @@ bool MortevielleEngine::keyPressed() {
* @remarks Originally called 'get_ch'
*/
int MortevielleEngine::getChar() {
+ bool end = false;
// If there isn't any pending keypress, wait until there is
- while (!shouldQuit() && _keypresses.empty()) {
- keyPressed();
+ while (!shouldQuit() && !end) {
+ end = keyPressed();
}
// Return the top keypress
@@ -283,10 +284,6 @@ void MortevielleEngine::handleAction() {
_menu.eraseMenu();
_menu._menuDisplayed = false;
- if ((inkey == '\1') || (inkey == '\3') || (inkey == '\5') || (inkey == '\7') || (inkey == '\11')) {
- changeGraphicalDevice((uint)((int)inkey - 1) >> 1);
- return;
- }
if (_menu._menuSelected && (_currMenu == MENU_SAVE)) {
Common::String saveName = Common::String::format("Savegame #%d", _currAction & 15);
_savegameManager.saveGame(_currAction & 15, saveName);
@@ -294,7 +291,7 @@ void MortevielleEngine::handleAction() {
if (_menu._menuSelected && (_currMenu == MENU_LOAD))
_savegameManager.loadGame((_currAction & 15) - 1);
if (inkey == '\103') { /* F9 */
- temps = _dialogManager.show(_hintPctMessage, 1);
+ temps = _dialogManager.show(_hintPctMessage);
return;
} else if (inkey == '\77') {
if ((_menuOpcode != OPCODE_NONE) && ((_currMenu == MENU_ACTION) || (_currMenu == MENU_SELF))) {
@@ -327,15 +324,15 @@ void MortevielleEngine::handleAction() {
if (_mouse._pos.y < 12)
return;
- if ((_currAction == OPCODE_SOUND) || (_currAction == OPCODE_LIFT)) {
+ if ((_currAction == _menu._opcodeSound) || (_currAction == _menu._opcodeLift)) {
handledOpcodeFl = true;
- if ((_currAction == OPCODE_LIFT) || (_obpart)) {
+ if ((_currAction == _menu._opcodeLift) || (_obpart)) {
endSearch();
_caff = _coreVar._currPlace;
_crep = 998;
} else
prepareNextObject();
- mennor();
+ menuUp();
}
}
}
@@ -416,8 +413,8 @@ void MortevielleEngine::prepareScreenType3() {
* @remarks Originally called 'calch'
*/
void MortevielleEngine::updateHour(int &day, int &hour, int &minute) {
- int newHour = readclock();
- int th = _currentHourCount + ((newHour - _currentDayHour) / _inGameHourDuration);
+ int newTime = readclock();
+ int th = _currentHourCount + ((newTime - _currentTime) / _inGameHourDuration);
minute = ((th % 2) + _currHalfHour) * 30;
hour = ((uint)th >> 1) + _currHour;
if (minute == 60) {
@@ -506,48 +503,48 @@ void MortevielleEngine::showPeoplePresent(int bitIndex) {
int xp = 580 - (_screenSurface.getStringWidth("LEO") / 2);
for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]._menuId, _menu._discussMenu[i]._actionId);
+ _menu.disableMenuItem(_menu._discussMenu[i]);
clearUpperRightPart();
if ((bitIndex & 128) == 128) {
_screenSurface.putxy(xp, 24);
_screenSurface.drawString("LEO", 4);
- _menu.enableMenuItem(_menu._discussMenu[1]._menuId, _menu._discussMenu[1]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[1]);
}
if ((bitIndex & 64) == 64) {
_screenSurface.putxy(xp, 32);
_screenSurface.drawString("PAT", 4);
- _menu.enableMenuItem(_menu._discussMenu[2]._menuId, _menu._discussMenu[2]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[2]);
}
if ((bitIndex & 32) == 32) {
_screenSurface.putxy(xp, 40);
_screenSurface.drawString("GUY", 4);
- _menu.enableMenuItem(_menu._discussMenu[3]._menuId, _menu._discussMenu[3]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[3]);
}
if ((bitIndex & 16) == 16) {
_screenSurface.putxy(xp, 48);
_screenSurface.drawString("EVA", 4);
- _menu.enableMenuItem(_menu._discussMenu[4]._menuId, _menu._discussMenu[4]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[4]);
}
if ((bitIndex & 8) == 8) {
_screenSurface.putxy(xp, 56);
_screenSurface.drawString("BOB", 4);
- _menu.enableMenuItem(_menu._discussMenu[5]._menuId, _menu._discussMenu[5]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[5]);
}
if ((bitIndex & 4) == 4) {
_screenSurface.putxy(xp, 64);
_screenSurface.drawString("LUC", 4);
- _menu.enableMenuItem(_menu._discussMenu[6]._menuId, _menu._discussMenu[6]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[6]);
}
if ((bitIndex & 2) == 2) {
_screenSurface.putxy(xp, 72);
_screenSurface.drawString("IDA", 4);
- _menu.enableMenuItem(_menu._discussMenu[7]._menuId, _menu._discussMenu[7]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[7]);
}
if ((bitIndex & 1) == 1) {
_screenSurface.putxy(xp, 80);
_screenSurface.drawString("MAX", 4);
- _menu.enableMenuItem(_menu._discussMenu[8]._menuId, _menu._discussMenu[8]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[8]);
}
_currBitIndex = bitIndex;
}
@@ -701,7 +698,7 @@ int MortevielleEngine::getPresenceStatsRedRoom() {
*/
void MortevielleEngine::displayAloneText() {
for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]._menuId, _menu._discussMenu[i]._actionId);
+ _menu.disableMenuItem(_menu._discussMenu[i]);
Common::String sYou = getEngineString(S_YOU);
Common::String sAre = getEngineString(S_ARE);
@@ -1085,7 +1082,7 @@ void MortevielleEngine::initGame() {
if (!_coreVar._alreadyEnteredManor)
_blo = true;
_inGameHourDuration = kTime1;
- _currentDayHour = readclock();
+ _currentTime = readclock();
}
/**
@@ -1338,7 +1335,7 @@ void MortevielleEngine::startDialog(int16 rep) {
_mouse.hideMouse();
Common::String dialogStr = getString(rep + kDialogStringIndex);
- _text.displayStr(dialogStr, 230, 4, 65, 24, 5);
+ _text.displayStr(dialogStr, 230, 4, 65, 26, 5);
_dialogManager.drawF3F8();
key = 0;
@@ -1348,7 +1345,7 @@ void MortevielleEngine::startDialog(int16 rep) {
if (shouldQuit())
return;
} while (key != 66);
- hirs();
+ clearScreen();
_mouse.showMouse();
}
@@ -1385,10 +1382,10 @@ void MortevielleEngine::gotoDiningRoom() {
_screenSurface.drawBox(223, 47, 155, 92, 15);
handleDescriptionText(2, 33);
testKey(false);
- mennor();
+ menuUp();
_mouse.hideMouse();
- hirs();
- premtet();
+ clearScreen();
+ drawDiscussionBox();
startDialog(140);
drawRightFrame();
drawClock();
@@ -1450,31 +1447,6 @@ void MortevielleEngine::floodedInWell() {
}
/**
- * Engine function - Change Graphical Device
- * @remarks Originally called 'change_gd'
- */
-void MortevielleEngine::changeGraphicalDevice(int newDevice) {
- _mouse.hideMouse();
- _currGraphicalDevice = newDevice;
- hirs();
- _mouse.initMouse();
- _mouse.showMouse();
- drawRightFrame();
- prepareRoom();
- drawClock();
- if (_currBitIndex != 0)
- showPeoplePresent(_currBitIndex);
- else
- displayAloneText();
- clearDescriptionBar();
- clearVerbBar();
- _maff = 68;
- drawPictureWithText();
- handleDescriptionText(2, _crep);
- _menu.displayMenu();
-}
-
-/**
* Called when a savegame has been loaded.
* @remarks Originally called 'antegame'
*/
@@ -1493,8 +1465,8 @@ void MortevielleEngine::gameLoaded() {
_x = 0;
_y = 0;
_num = 0;
- _startHour = 0;
- _endHour = 0;
+ _startTime = 0;
+ _endTime = 0;
_searchCount = 0;
_roomDoorId = OWN_ROOM;
_syn = true;
@@ -1536,79 +1508,79 @@ void MortevielleEngine::handleOpcode() {
_keyPressedEsc = false;
if (!_anyone) {
if (_uptodatePresence) {
- if ((_currMenu == MENU_MOVE) || (_currAction == OPCODE_LEAVE) || (_currAction == OPCODE_SLEEP) || (_currAction == OPCODE_EAT)) {
+ if ((_currMenu == MENU_MOVE) || (_currAction == _menu._opcodeLeave) || (_currAction == _menu._opcodeSleep) || (_currAction == _menu._opcodeEat)) {
_controlMenu = 4;
- mennor();
+ menuUp();
return;
}
}
+
if (_currMenu == MENU_MOVE)
fctMove();
- if (_currMenu == MENU_DISCUSS)
+ else if (_currMenu == MENU_DISCUSS)
fctDiscuss();
- if (_currMenu == MENU_INVENTORY)
+ else if (_currMenu == MENU_INVENTORY)
fctInventoryTake();
- if (_currAction == OPCODE_ATTACH)
+ else if (_currAction == _menu._opcodeAttach)
fctAttach();
- if (_currAction == OPCODE_WAIT)
+ else if (_currAction == _menu._opcodeWait)
fctWait();
- if (_currAction == OPCODE_FORCE)
+ else if (_currAction == _menu._opcodeForce)
fctForce();
- if (_currAction == OPCODE_SLEEP)
+ else if (_currAction == _menu._opcodeSleep)
fctSleep();
- if (_currAction == OPCODE_LISTEN)
+ else if (_currAction == _menu._opcodeListen)
fctListen();
- if (_currAction == OPCODE_ENTER)
+ else if (_currAction == _menu._opcodeEnter)
fctEnter();
- if (_currAction == OPCODE_CLOSE)
+ else if (_currAction == _menu._opcodeClose)
fctClose();
- if (_currAction == OPCODE_SEARCH)
+ else if (_currAction == _menu._opcodeSearch)
fctSearch();
- if (_currAction == OPCODE_KNOCK)
+ else if (_currAction == _menu._opcodeKnock)
fctKnock();
- if (_currAction == OPCODE_SCRATCH)
+ else if (_currAction == _menu._opcodeScratch)
fctScratch();
- if (_currAction == OPCODE_READ)
+ else if (_currAction == _menu._opcodeRead)
fctRead();
- if (_currAction == OPCODE_EAT)
+ else if (_currAction == _menu._opcodeEat)
fctEat();
- if (_currAction == OPCODE_PLACE)
+ else if (_currAction == _menu._opcodePlace)
fctPlace();
- if (_currAction == OPCODE_OPEN)
+ else if (_currAction == _menu._opcodeOpen)
fctOpen();
- if (_currAction == OPCODE_TAKE)
+ else if (_currAction == _menu._opcodeTake)
fctTake();
- if (_currAction == OPCODE_LOOK)
+ else if (_currAction == _menu._opcodeLook)
fctLook();
- if (_currAction == OPCODE_SMELL)
+ else if (_currAction == _menu._opcodeSmell)
fctSmell();
- if (_currAction == OPCODE_SOUND)
+ else if (_currAction == _menu._opcodeSound)
fctSound();
- if (_currAction == OPCODE_LEAVE)
+ else if (_currAction == _menu._opcodeLeave)
fctLeave();
- if (_currAction == OPCODE_LIFT)
+ else if (_currAction == _menu._opcodeLift)
fctLift();
- if (_currAction == OPCODE_TURN)
+ else if (_currAction == _menu._opcodeTurn)
fctTurn();
- if (_currAction == OPCODE_SSEARCH)
+ else if (_currAction == _menu._opcodeSSearch)
fctSelfSearch();
- if (_currAction == OPCODE_SREAD)
+ else if (_currAction == _menu._opcodeSRead)
fctSelfRead();
- if (_currAction == OPCODE_SPUT)
+ else if (_currAction == _menu._opcodeSPut)
fctSelfPut();
- if (_currAction == OPCODE_SLOOK)
+ else if (_currAction == _menu._opcodeSLook)
fctSelftLook();
+
_hiddenHero = false;
- if (_currAction == OPCODE_SHIDE)
+ if (_currAction == _menu._opcodeSHide)
fctSelfHide();
- } else {
- if (_anyone) {
- interactNPC();
- _anyone = false;
- mennor();
- return;
- }
+ } else if (_anyone) {
+ interactNPC();
+ _anyone = false;
+ menuUp();
+ return;
}
int hour, day, minute;
updateHour(day, hour, minute);
@@ -1620,17 +1592,15 @@ void MortevielleEngine::handleOpcode() {
if ((_coreVar._faithScore > 99) && (hour > 8) && (hour < 16)) {
_crep = 1501;
loseGame();
- }
- if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
+ } else if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
_crep = 1508;
loseGame();
- }
- if ((day > 1) && (hour > 8) && (!_loseGame)) {
+ } else if ((day > 1) && (hour > 8) && (!_loseGame)) {
_crep = 1502;
loseGame();
}
}
- mennor();
+ menuUp();
}
/**
@@ -1708,19 +1678,12 @@ void MortevielleEngine::clearVerbBar() {
* @remarks Originally called 'clsf10'
*/
void MortevielleEngine::clearUpperRightPart() {
- int x1, x2;
Common::String st;
_mouse.hideMouse();
- if (_resolutionScaler == 1) {
- x2 = 634;
- x1 = 534;
- } else {
- x2 = 600;
- x1 = 544;
- }
+
// Clear ambiance description
- _screenSurface.fillRect(15, Common::Rect(x1, 93, x2, 98));
+ _screenSurface.fillRect(15, Common::Rect(544, 93, 600, 98));
if (_coreVar._faithScore < 33)
st = getEngineString(S_COOL);
else if (_coreVar._faithScore < 66)
@@ -1728,7 +1691,7 @@ void MortevielleEngine::clearUpperRightPart() {
else if (_coreVar._faithScore > 65)
st = getEngineString(S_MALSAINE);
- x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
+ int x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
_screenSurface.putxy(x1, 92);
_screenSurface.drawString(st, 4);
@@ -1750,7 +1713,7 @@ int MortevielleEngine::getRandomNumber(int minval, int maxval) {
* @remarks Originally called 'aldepl'
*/
void MortevielleEngine::showMoveMenuAlert() {
- _dialogManager.show(getEngineString(S_USE_DEP_MENU), 1);
+ _dialogManager.show(getEngineString(S_USE_DEP_MENU));
}
/**
@@ -1980,46 +1943,9 @@ void MortevielleEngine::resetVariables() {
* @remarks Originally called 'writepal'
*/
void MortevielleEngine::setPal(int n) {
- switch (_currGraphicalDevice) {
- case MODE_TANDY:
- case MODE_EGA:
- case MODE_AMSTRAD1512:
- for (int i = 1; i <= 16; ++i) {
- _curPict[(2 * i)] = _stdPal[n][i].x;
- _curPict[(2 * i) + 1] = _stdPal[n][i].y;
- }
- break;
- case MODE_CGA: {
- nhom pal[16];
- for (int i = 0; i < 16; ++i) {
- pal[i] = _cgaPal[n]._a[i];
- }
-
- if (n < 89)
- palette(_cgaPal[n]._p);
-
- for (int i = 0; i <= 15; ++i)
- displayCGAPattern(i, &_patternArr[pal[i]._id], pal);
- }
- break;
- default:
- break;
- }
-}
-
-/**
- * Engine function - Display a CGA pattern, using a specified palette
- * @remarks Originally called 'outbloc'
- */
-void MortevielleEngine::displayCGAPattern(int n, Pattern *p, nhom *pal) {
- int addr = n * 404 + 0xd700;
-
- WRITE_LE_UINT16(&_curPict[addr], p->_tax);
- WRITE_LE_UINT16(&_curPict[addr + 2], p->_tay);
- addr += 4;
- for (int i = 0; i < p->_tax; ++i) {
- for (int j = 0; j < p->_tay; ++j)
- _curPict[addr + j * p->_tax + i] = pal[n]._hom[p->_des[i + 1][j + 1]];
+ for (int i = 1; i <= 16; ++i) {
+ _curPict[(2 * i)] = _stdPal[n][i].x;
+ _curPict[(2 * i) + 1] = _stdPal[n][i].y;
}
}
@@ -2029,7 +1955,6 @@ void MortevielleEngine::displayCGAPattern(int n, Pattern *p, nhom *pal) {
*/
void MortevielleEngine::loadPalette() {
Common::File f;
- byte b;
if (!f.open("fxx.mor")) {
if (f.open("mfxx.mor"))
@@ -2055,27 +1980,8 @@ void MortevielleEngine::loadPalette() {
if (!f.open("cxx.mor"))
error("Missing file - cxx.mor");
- for (int j = 0; j <= 90; ++j) {
- _cgaPal[j]._p = f.readByte();
- for (int i = 0; i <= 15; ++i) {
- nhom &with = _cgaPal[j]._a[i];
-
- b = f.readByte();
- with._id = (uint)b >> 4;
- with._hom[0] = ((uint)b >> 2) & 3;
- with._hom[1] = b & 3;
- }
- }
+ // Skip CGA Palette and Patterns
- _cgaPal[10]._a[9] = _cgaPal[10]._a[5];
- for (int j = 0; j <= 14; ++j) {
- _patternArr[j]._tax = f.readByte();
- _patternArr[j]._tay = f.readByte();
- for (int i = 1; i <= 20; ++i) {
- for (int k = 1; k <= 20; ++k)
- _patternArr[j]._des[i][k] = f.readByte();
- }
- }
f.close();
}
@@ -2088,8 +1994,8 @@ void MortevielleEngine::loadTexts() {
Common::File ntpFile;
_txxFileFl = false;
- if (getLanguage() == Common::EN_ANY) {
- warning("English version expected - Switching to DAT file");
+ if (!useOriginalData()) {
+ warning("Using improved translation from DAT file");
return;
}
@@ -2211,18 +2117,16 @@ void MortevielleEngine::music() {
* @remarks Originally called 'suite'
*/
void MortevielleEngine::showTitleScreen() {
- hirs();
+ clearScreen();
handleDescriptionText(7, 2035);
_caff = 51;
_text.taffich();
testKeyboard();
- if (_newGraphicalDevice != _currGraphicalDevice)
- _currGraphicalDevice = _newGraphicalDevice;
- hirs();
+ clearScreen();
draw(0, 0);
Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
- _screenSurface.putxy(104 + 72 * _resolutionScaler, 185);
+ _screenSurface.putxy(104 + 72 * kResolutionScaler, 185);
_screenSurface.drawString(cpr, 0);
}
@@ -2243,9 +2147,6 @@ void MortevielleEngine::draw(int x, int y) {
*/
void MortevielleEngine::drawRightFrame() {
setPal(89);
- if (_currGraphicalDevice == MODE_HERCULES)
- _curPict[14] = 15;
-
_mouse.hideMouse();
displayPicture(_rightFramePict, 0, 0);
_mouse.showMouse();
@@ -2255,12 +2156,7 @@ void MortevielleEngine::drawRightFrame() {
* Read the current system time
*/
int MortevielleEngine::readclock() {
- TimeDate dateTime;
- g_system->getTimeAndDate(dateTime);
-
- int m = dateTime.tm_min * 60;
- int h = dateTime.tm_hour * 3600;
- return h + m + dateTime.tm_sec;
+ return (int)(g_system->getMillis() / 1000);
}
/**
@@ -2323,12 +2219,12 @@ void MortevielleEngine::prepareRoom() {
if (_coreVar._faithScore > 65)
_inGameHourDuration -= ((_inGameHourDuration / 3) * 2);
- int newHour = readclock();
- if ((newHour - _currentDayHour) > _inGameHourDuration) {
+ int newTime = readclock();
+ if ((newTime - _currentTime) > _inGameHourDuration) {
bool activeMenu = _menu._menuActive;
_menu.eraseMenu();
- _currentHourCount += ((newHour - _currentDayHour) / _inGameHourDuration);
- _currentDayHour = newHour;
+ _currentHourCount += ((newTime - _currentTime) / _inGameHourDuration);
+ _currentTime = newTime;
switch (_place) {
case GREEN_ROOM:
case DARKBLUE_ROOM:
@@ -2378,13 +2274,14 @@ void MortevielleEngine::prepareRoom() {
_currBitIndex = 0;
if (!_uptodatePresence) {
_uptodatePresence = true;
- _startHour = readclock();
+ _startTime = readclock();
if (getRandomNumber(1, 5) < 5) {
clearVerbBar();
prepareScreenType2();
displayTextInVerbBar(getEngineString(S_HEAR_NOISE));
int rand = (getRandomNumber(0, 4)) - 2;
_soundManager.startSpeech(1, rand, 1);
+ _soundManager.waitSpeech();
clearVerbBar();
}
}
@@ -2395,11 +2292,11 @@ void MortevielleEngine::prepareRoom() {
_menu.drawMenu();
}
}
- _endHour = readclock();
- if ((_uptodatePresence) && ((_endHour - _startHour) > 17)) {
+ _endTime = readclock();
+ if ((_uptodatePresence) && ((_endTime - _startTime) > 17)) {
getPresenceBitIndex(_place);
_uptodatePresence = false;
- _startHour = 0;
+ _startTime = 0;
if ((_coreVar._currPlace > OWN_ROOM) && (_coreVar._currPlace < DINING_ROOM))
_anyone = true;
}
@@ -2417,21 +2314,16 @@ void MortevielleEngine::drawClock() {
const int x = 580;
const int y = 123;
const int rg = 9;
- int hourColor;
_mouse.hideMouse();
_screenSurface.drawRectangle(570, 118, 20, 10);
_screenSurface.drawRectangle(578, 114, 6, 18);
- if ((_currGraphicalDevice == MODE_CGA) || (_currGraphicalDevice == MODE_HERCULES))
- hourColor = 0;
- else
- hourColor = 1;
if (_minute == 0)
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y - rg), hourColor);
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y - rg), 1);
else
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y + rg), hourColor);
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y + rg), 1);
int hour12 = _hour;
if (hour12 > 12)
@@ -2439,7 +2331,7 @@ void MortevielleEngine::drawClock() {
if (hour12 == 0)
hour12 = 12;
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * _resolutionScaler, y + cv[1][hour12 - 1], hourColor);
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * kResolutionScaler, y + cv[1][hour12 - 1], 1);
_mouse.showMouse();
_screenSurface.putxy(568, 154);
@@ -2480,21 +2372,11 @@ Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t
return result;
}
-void MortevielleEngine::hirs() {
- // Note: The original used this to set the graphics mode and clear the screen, both at
- // the start of the game, and whenever the screen need to be cleared. As such, this
- // method is deprecated in favour of clearing the screen
- debugC(1, kMortevielleCore, "TODO: hirs is deprecated in favour of ScreenSurface::clearScreen");
-
- if (_currGraphicalDevice == MODE_TANDY) {
- _screenSurface.fillRect(0, Common::Rect(0, 0, 639, 200));
- _resolutionScaler = 1;
- } else if (_currGraphicalDevice == MODE_CGA) {
- palette(1);
- _resolutionScaler = 1;
- } else
- _resolutionScaler = 2;
-
+/**
+ * Clear Screen
+ * @remarks Originally called 'hirs'
+ */
+void MortevielleEngine::clearScreen() {
_screenSurface.clearScreen();
}
@@ -2511,7 +2393,7 @@ void MortevielleEngine::initCaveOrCellar() {
displayTextInVerbBar(getEngineString(S_SOMEONE_ENTERS));
int rand = (getRandomNumber(0, 4)) - 2;
_soundManager.startSpeech(2, rand, 1);
-
+ _soundManager.waitSpeech();
// The original was doing here a useless loop.
// It has been removed
@@ -2535,12 +2417,6 @@ void MortevielleEngine::displayControlMenu() {
void MortevielleEngine::displayPicture(const byte *pic, int x, int y) {
GfxSurface surface;
surface.decode(pic);
-
- if (_currGraphicalDevice == MODE_HERCULES) {
- _curPict[2] = 0;
- _curPict[32] = 15;
- }
-
_screenSurface.drawPicture(surface, x, y);
}
@@ -2587,14 +2463,8 @@ int MortevielleEngine::getAnimOffset(int frameNum, int animNum) {
* @remarks Originally called 'text1'
*/
void MortevielleEngine::displayTextInDescriptionBar(int x, int y, int nb, int mesgId) {
- int co;
-
- if (_resolutionScaler == 1)
- co = 10;
- else
- co = 6;
Common::String tmpStr = getString(mesgId);
- if ((y == 182) && ((int) tmpStr.size() * co > nb * 6))
+ if ((y == 182) && ((int) tmpStr.size() > nb))
y = 176;
_text.displayStr(tmpStr, x, y, nb, 20, _textColor);
}
@@ -2607,7 +2477,7 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
if ((mesgId > 499) && (mesgId < 563)) {
Common::String tmpStr = getString(mesgId - 501 + kInventoryStringIndex);
- if ((int) tmpStr.size() > ((58 + (_resolutionScaler - 1) * 37) << 1))
+ if ((int) tmpStr.size() > ((58 + (kResolutionScaler - 1) * 37) << 1))
_largestClearScreen = true;
else
_largestClearScreen = false;
@@ -2624,7 +2494,7 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
displayTextInDescriptionBar(8, 182, 103, mesgId);
if ((mesgId == 68) || (mesgId == 69))
_coreVar._availableQuestion[40] = '*';
- if ((mesgId == 104) && (_caff == CELLAR)) {
+ else if ((mesgId == 104) && (_caff == CELLAR)) {
_coreVar._availableQuestion[36] = '*';
if (_coreVar._availableQuestion[39] == '*') {
_coreVar._pctHintFound[3] = '*';
@@ -2709,10 +2579,14 @@ void MortevielleEngine::resetOpenObjects() {
_openObjCount = 0;
}
-void MortevielleEngine::ecr2(Common::String text) {
+/**
+ * Display Text Block
+ * @remarks Originally called 'ecr2'
+ */
+void MortevielleEngine::displayTextBlock(Common::String text) {
// Some dead code was present in the original: removed
_screenSurface.putxy(8, 177);
- int tlig = 59 + (_resolutionScaler - 1) * 36;
+ int tlig = 59 + (kResolutionScaler - 1) * 36;
if ((int)text.size() < tlig)
_screenSurface.drawString(text, 5);
@@ -2749,8 +2623,8 @@ void MortevielleEngine::displayItemInHand(int objId) {
if (objId != 500)
strp = getString(objId - 501 + kInventoryStringIndex);
- _menu.setText(_menu._inventoryMenu[8]._menuId, _menu._inventoryMenu[8]._actionId, strp);
- _menu.disableMenuItem(_menu._inventoryMenu[8]._menuId, _menu._inventoryMenu[8]._actionId);
+ _menu.setText(_menu._inventoryMenu[8], strp);
+ _menu.disableMenuItem(_menu._inventoryMenu[8]);
}
/**
@@ -2877,11 +2751,11 @@ int MortevielleEngine::getPresence(int roomId) {
int retVal = 0;
int rand;
- int p = getPresenceStats(rand, _coreVar._faithScore, roomId);
+ int pres = getPresenceStats(rand, _coreVar._faithScore, roomId);
_place = roomId;
if ((roomId > OWN_ROOM) && (roomId < DINING_ROOM)) {
- if (p != -500) {
- if (rand > p) {
+ if (pres != -500) {
+ if (rand > pres) {
displayAloneText();
retVal = 0;
} else {
@@ -2897,35 +2771,55 @@ int MortevielleEngine::getPresence(int roomId) {
displayAloneText();
else {
int h = 0;
- if (roomId == DINING_ROOM)
- p = getPresenceStatsDiningRoom(h);
- else if (roomId == BUREAU)
- p = getPresenceStatsBureau(h);
- else if (roomId == KITCHEN)
- p = getPresenceStatsKitchen();
- else if ((roomId == ATTIC) || (roomId == CELLAR))
- p = getPresenceStatsAttic();
- else if ((roomId == LANDING) || (roomId == ROOM26))
- p = getPresenceStatsLanding();
- else if (roomId == CHAPEL)
- p = getPresenceStatsChapel(h);
- p += _coreVar._faithScore;
+ switch (roomId) {
+ case DINING_ROOM:
+ pres = getPresenceStatsDiningRoom(h);
+ break;
+ case BUREAU:
+ pres = getPresenceStatsBureau(h);
+ break;
+ case KITCHEN:
+ pres = getPresenceStatsKitchen();
+ break;
+ case ATTIC:
+ case CELLAR:
+ pres = getPresenceStatsAttic();
+ break;
+ case LANDING:
+ case ROOM26:
+ pres = getPresenceStatsLanding();
+ break;
+ case CHAPEL:
+ pres = getPresenceStatsChapel(h);
+ break;
+ }
+ pres += _coreVar._faithScore;
rand = getRandomNumber(1, 100);
- if (rand > p) {
+ if (rand > pres) {
displayAloneText();
retVal = 0;
} else {
- if (roomId == DINING_ROOM)
- p = setPresenceDiningRoom(h);
- else if (roomId == BUREAU)
- p = setPresenceBureau(h);
- else if ((roomId == KITCHEN) || (roomId == ATTIC) || (roomId == CELLAR))
- p = setPresenceKitchen();
- else if ((roomId == LANDING) || (roomId == ROOM26))
- p = setPresenceLanding();
- else if (roomId == CHAPEL)
- p = setPresenceChapel(h);
- retVal = p;
+ switch (roomId) {
+ case DINING_ROOM:
+ pres = setPresenceDiningRoom(h);
+ break;
+ case BUREAU:
+ pres = setPresenceBureau(h);
+ break;
+ case KITCHEN:
+ case ATTIC:
+ case CELLAR:
+ pres = setPresenceKitchen();
+ break;
+ case LANDING:
+ case ROOM26:
+ pres = setPresenceLanding();
+ break;
+ case CHAPEL:
+ pres = setPresenceChapel(h);
+ break;
+ }
+ retVal = pres;
}
}
}
@@ -2938,10 +2832,7 @@ int MortevielleEngine::getPresence(int roomId) {
* @remarks Originally called 'writetp'
*/
void MortevielleEngine::displayQuestionText(Common::String s, int cmd) {
- if (_resolutionScaler == 2)
- _screenSurface.drawString(s, cmd);
- else
- _screenSurface.drawString(copy(s, 1, 25), cmd);
+ _screenSurface.drawString(s, cmd);
}
/**
@@ -2991,18 +2882,27 @@ void MortevielleEngine::drawPicture() {
displayAnimFrame(1, _openObjects[i]);
}
- if (_caff == ATTIC) {
+ switch (_caff) {
+ case ATTIC:
if (_coreVar._atticBallHoleObjectId == 141)
displayAnimFrame(1, 7);
if (_coreVar._atticRodHoleObjectId == 159)
displayAnimFrame(1, 6);
- } else if ((_caff == CELLAR) && (_coreVar._cellarObjectId == 151))
- displayAnimFrame(1, 2);
- else if ((_caff == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId == 143))
- displayAnimFrame(1, 1);
- else if ((_caff == WELL) && (_coreVar._wellObjectId != 0))
- displayAnimFrame(1, 1);
+ break;
+ case CELLAR:
+ if (_coreVar._cellarObjectId == 151)
+ displayAnimFrame(1, 2);
+ break;
+ case SECRET_PASSAGE:
+ if (_coreVar._secretPassageObjectId == 143)
+ displayAnimFrame(1, 1);
+ break;
+ case WELL:
+ if (_coreVar._wellObjectId != 0)
+ displayAnimFrame(1, 1);
+ break;
+ }
}
if (_caff < ROOM26)
@@ -3052,7 +2952,11 @@ void MortevielleEngine::testKey(bool d) {
_mouse.showMouse();
}
-void MortevielleEngine::tlu(int af, int ob) {
+/**
+ * Display Narrative Picture
+ * @remarks Originally called 'tlu'
+ */
+void MortevielleEngine::displayNarrativePicture(int af, int ob) {
_caff = 32;
drawPictureWithText();
handleDescriptionText(6, ob + 4000);
@@ -3118,7 +3022,7 @@ void MortevielleEngine::getReadDescription(int objId) {
case 157:
case 160:
case 161 :
- tlu(_caff, objId);
+ displayNarrativePicture(_caff, objId);
break;
default:
break;
@@ -3151,11 +3055,19 @@ void MortevielleEngine::getSearchDescription(int objId) {
}
}
-void MortevielleEngine::mennor() {
+/**
+ * Menu up
+ * @remarks Originally called 'mennor'
+ */
+void MortevielleEngine::menuUp() {
_menu.menuUp(_currMenu);
}
-void MortevielleEngine::premtet() {
+/**
+ * Draw discussion box
+ * @remarks Originally called 'premtet'
+ */
+void MortevielleEngine::drawDiscussionBox() {
draw(10, 80);
_screenSurface.drawBox(18, 79, 155, 92, 15);
}
@@ -3298,12 +3210,12 @@ void MortevielleEngine::displayStatusArrow() {
return;
if (getMouseClick())
- inRect = (_mouse._pos.x < 256 * _resolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
+ inRect = (_mouse._pos.x < 256 * kResolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
prepareRoom();
} while (!(qust || inRect || _anyone));
if (qust && (touch == '\103'))
- _dialogManager.show(_hintPctMessage, 1);
+ _dialogManager.show(_hintPctMessage);
} while (!((touch == '\73') || ((touch == '\104') && (_x != 0) && (_y != 0)) || (_anyone) || (inRect)));
if (touch == '\73')
@@ -3355,10 +3267,10 @@ void MortevielleEngine::setCoordinates(int sx) {
cy = 1;
do {
cb += 2;
- sx = _tabdon[a + cb] * _resolutionScaler;
+ sx = _tabdon[a + cb] * kResolutionScaler;
sy = _tabdon[(a + cb + 1)];
cb += 2;
- ix = _tabdon[a + cb] * _resolutionScaler;
+ ix = _tabdon[a + cb] * kResolutionScaler;
iy = _tabdon[(a + cb + 1)];
++cy;
} while (!(((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) || (cy > ib)));
@@ -3371,11 +3283,15 @@ void MortevielleEngine::setCoordinates(int sx) {
_crep = 997;
}
-void MortevielleEngine::treg(int objId) {
+/**
+ * Display LOOK Screen
+ * @remarks Originally called 'treg'
+ */
+void MortevielleEngine::displayLookScreen(int objId) {
int mdes = _caff;
_caff = objId;
- if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == OPCODE_SLOOK)) {
+ if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == _menu._opcodeSLook)) {
drawPictureWithText();
if ((_caff > 29) && (_caff < 33))
handleDescriptionText(2, _caff);
@@ -3440,17 +3356,8 @@ int MortevielleEngine::checkLeaveSecretPassage() {
* @remarks Originally called 'fenat'
*/
void MortevielleEngine::displayStatusInDescriptionBar(char stat) {
- int color;
-
_mouse.hideMouse();
- if (_currGraphicalDevice == MODE_CGA)
- color = 2;
- else if (_currGraphicalDevice == MODE_HERCULES)
- color = 1;
- else
- color = 12;
-
- _screenSurface.writeCharacter(Common::Point(306, 193), stat, color);
+ _screenSurface.writeCharacter(Common::Point(306, 193), stat, 12);
_screenSurface.drawBox(300, 191, 16, 8, 15);
_mouse.showMouse();
}
diff --git a/engines/plugins_table.h b/engines/plugins_table.h
index edc94eb0d3..ee7713bb76 100644
--- a/engines/plugins_table.h
+++ b/engines/plugins_table.h
@@ -29,6 +29,9 @@ LINK_PLUGIN(DRASCULA)
#if PLUGIN_ENABLED_STATIC(DREAMWEB)
LINK_PLUGIN(DREAMWEB)
#endif
+#if PLUGIN_ENABLED_STATIC(FULLPIPE)
+LINK_PLUGIN(FULLPIPE)
+#endif
#if PLUGIN_ENABLED_STATIC(GOB)
LINK_PLUGIN(GOB)
#endif
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 09c348f273..883a4d965b 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -105,9 +105,8 @@ static const PlainGameDescriptor s_sciGameTitles[] = {
// === SCI2.1 games ========================================================
{"chest", "Inside the Chest"}, // aka Behind the Developer's Shield
{"gk2", "The Beast Within: A Gabriel Knight Mystery"},
- // TODO: Inside The Chest/Behind the Developer's Shield
{"kq7", "King's Quest VII: The Princeless Bride"},
- // TODO: King's Questions
+ {"kquestions", "King's Questions"},
{"lsl6hires", "Leisure Suit Larry 6: Shape Up or Slip Out!"},
{"mothergoosehires","Mixed-Up Mother Goose Deluxe"},
{"phantasmagoria", "Phantasmagoria"},
@@ -161,6 +160,7 @@ static const GameIdStrToEnum s_gameIdStrToEnum[] = {
{ "kq5", GID_KQ5 },
{ "kq6", GID_KQ6 },
{ "kq7", GID_KQ7 },
+ { "kquestions", GID_KQUESTIONS },
{ "laurabow", GID_LAURABOW },
{ "laurabow2", GID_LAURABOW2 },
{ "lighthouse", GID_LIGHTHOUSE },
@@ -242,6 +242,7 @@ static const OldNewIdTableEntry s_oldNewTable[] = {
// kq5 is the same
// kq6 is the same
{ "kq7cd", "kq7", SCI_VERSION_NONE },
+ { "quizgame-demo", "kquestions", SCI_VERSION_NONE },
{ "mm1", "laurabow", SCI_VERSION_NONE },
{ "cb1", "laurabow", SCI_VERSION_NONE },
{ "lb2", "laurabow2", SCI_VERSION_NONE },
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 7c4638a992..92e77cead9 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -1656,6 +1656,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
AD_LISTEND},
Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ // King's Questions mini-game from the King's Quest Collection
+ // SCI interpreter version 2.000.000
+ {"kquestions", "", {
+ {"resource.000", 0, "9b1cddecd4f0720d83661ba7aed28891", 162697},
+ {"resource.map", 0, "93a2251fa64e729d7a7d2fe56b217c8e", 502},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
+
#endif // ENABLE_SCI32
// Laura Bow - English Amiga
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index 6005ac50be..c26c787fbd 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -467,9 +467,9 @@ bool GameFeatures::autoDetectSci21KernelType() {
// seen it happen in the RAMA demo, thus we can assume that the
// game is using a SCI2.1 table
- // HACK: The Inside the Chest Demo doesn't have sounds at all, but
- // it's using a SCI2 kernel
- if (g_sci->getGameId() == GID_CHEST) {
+ // HACK: The Inside the Chest Demo and King's Questions minigame
+ // don't have sounds at all, but they're using a SCI2 kernel
+ if (g_sci->getGameId() == GID_CHEST || g_sci->getGameId() == GID_KQUESTIONS) {
_sci21KernelType = SCI_VERSION_2;
return true;
}
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 20c5c52178..d4dddb6faf 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -953,10 +953,10 @@ const uint16 qfg1vgaPatchDialogHeader[] = {
// When clicking on the crusher in room 331, Ego approaches him to talk to him,
// an action that is handled by moveToCrusher::changeState in script 331. The
-// scripts set Ego to move close to the crusher, but when Ego is running instead
+// scripts set Ego to move close to the crusher, but when Ego is sneaking instead
// of walking, the target coordinates specified by script 331 are never reached,
// as Ego is making larger steps, and never reaches the required spot. This is an
-// edge case that can occur when Ego is set to run. Normally, when clicking on
+// edge case that can occur when Ego is set to sneak. Normally, when clicking on
// the crusher, ego is supposed to move close to position 79, 165. We change it
// to 85, 165, which is not an edge case thus the freeze is avoided.
// Fixes bug #3585189.
@@ -976,6 +976,25 @@ const uint16 qfg1vgaPatchMoveToCrusher[] = {
PATCH_END
};
+// Same pathfinding bug as above, where Ego is set to move to an impossible
+// spot when sneaking. In GuardsTrumpet::changeState, we change the final
+// location where Ego is moved from 111, 111 to 114, 114. Fixes bug #3604939.
+const byte qfg1vgaSignatureMoveToCastleGate[] = {
+ 7,
+ 0x51, 0x1f, // class MoveTo
+ 0x36, // push
+ 0x39, 0x6f, // pushi 6f (111 - x)
+ 0x3c, // dup (111 - y)
+ 0x7c, // pushSelf
+ 0
+};
+
+const uint16 qfg1vgaPatchMoveToCastleGate[] = {
+ PATCH_ADDTOOFFSET | +3,
+ 0x39, 0x72, // pushi 72 (114 - x)
+ PATCH_END
+};
+
// script, description, magic DWORD, adjust
const SciScriptSignature qfg1vgaSignatures[] = {
{ 215, "fight event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
@@ -983,6 +1002,7 @@ const SciScriptSignature qfg1vgaSignatures[] = {
{ 814, "window text temp space", 1, PATCH_MAGICDWORD(0x3f, 0xba, 0x87, 0x00), 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
{ 814, "dialog header offset", 3, PATCH_MAGICDWORD(0x5b, 0x04, 0x80, 0x36), 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
{ 331, "moving to crusher", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
+ { 41, "moving to castle gate", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
SCI_SIGNATUREENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index 27015d9be4..5327dd1a2e 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -28,12 +28,12 @@
namespace Sci {
-reg_t reg_t::lookForWorkaround(const reg_t right) const {
+reg_t reg_t::lookForWorkaround(const reg_t right, const char *operation) const {
SciTrackOriginReply originReply;
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, arithmeticWorkarounds, &originReply);
if (solution.type == WORKAROUND_NONE)
- error("Invalid arithmetic operation (params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
- PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
+ error("Invalid arithmetic operation (%s - params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
+ operation, PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
originReply.methodName.c_str(), g_sci->getEngineState()->currentRoomNumber(), originReply.scriptNr,
originReply.localCallOffset);
assert(solution.type == WORKAROUND_FAKE);
@@ -55,7 +55,7 @@ reg_t reg_t::operator+(const reg_t right) const {
case SEG_TYPE_DYNMEM:
return make_reg(getSegment(), getOffset() + right.toSint16());
default:
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "addition");
}
} else if (isNumber() && right.isPointer()) {
// Adding a pointer to a number, flip the order
@@ -64,7 +64,7 @@ reg_t reg_t::operator+(const reg_t right) const {
// Normal arithmetics
return make_reg(0, toSint16() + right.toSint16());
} else {
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "addition");
}
}
@@ -82,14 +82,14 @@ reg_t reg_t::operator*(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toSint16() * right.toSint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "multiplication");
}
reg_t reg_t::operator/(const reg_t right) const {
if (isNumber() && right.isNumber() && !right.isNull())
return make_reg(0, toSint16() / right.toSint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "division");
}
reg_t reg_t::operator%(const reg_t right) const {
@@ -109,21 +109,21 @@ reg_t reg_t::operator%(const reg_t right) const {
result += modulo;
return make_reg(0, result);
} else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "modulo");
}
reg_t reg_t::operator>>(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() >> right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "shift right");
}
reg_t reg_t::operator<<(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() << right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "shift left");
}
reg_t reg_t::operator+(int16 right) const {
@@ -140,7 +140,7 @@ uint16 reg_t::requireUint16() const {
else
// The right parameter is NULL_REG because
// we're not comparing *this with anything here.
- return lookForWorkaround(NULL_REG).toUint16();
+ return lookForWorkaround(NULL_REG, "require unsigned number").toUint16();
}
int16 reg_t::requireSint16() const {
@@ -149,28 +149,28 @@ int16 reg_t::requireSint16() const {
else
// The right parameter is NULL_REG because
// we're not comparing *this with anything here.
- return lookForWorkaround(NULL_REG).toSint16();
+ return lookForWorkaround(NULL_REG, "require signed number").toSint16();
}
reg_t reg_t::operator&(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() & right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise AND");
}
reg_t reg_t::operator|(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() | right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise OR");
}
reg_t reg_t::operator^(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() ^ right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise XOR");
}
int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
@@ -184,7 +184,7 @@ int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
} else if (right.pointerComparisonWithInteger(*this)) {
return -1;
} else
- return lookForWorkaround(right).toSint16();
+ return lookForWorkaround(right, "comparison").toSint16();
}
bool reg_t::pointerComparisonWithInteger(const reg_t right) const {
diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h
index 9a7589e9a7..22bd8beaa1 100644
--- a/engines/sci/engine/vm_types.h
+++ b/engines/sci/engine/vm_types.h
@@ -156,7 +156,7 @@ private:
* - a negative number if *this < right
*/
int cmp(const reg_t right, bool treatAsUnsigned) const;
- reg_t lookForWorkaround(const reg_t right) const;
+ reg_t lookForWorkaround(const reg_t right, const char *operation) const;
bool pointerComparisonWithInteger(const reg_t right) const;
};
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 6f0b34b457..154ac8f8b4 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -37,6 +37,7 @@ const SciWorkaroundEntry arithmeticWorkarounds[] = {
{ GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xce0, 0, { WORKAROUND_FAKE, 0 } }, // Same as above, for the Spanish version - bug #3313962
{ GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913
{ GID_GK1, 800,64992, 0, "Fwd", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when Mosely finds Gabriel and Grace near the end of the game, compares the Grooper object with 7
+ { GID_HOYLE4, 700, -1, 1, "Code", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_add: while bidding in Bridge, an object ("Bid") is added to an object in another segment ("hand3")
{ GID_ICEMAN, 199, 977, 0, "Grooper", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_add: While dancing with the girl
{ GID_MOTHERGOOSE256, -1, 999, 0, "Event", "new", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_and: constantly during the game (SCI1 version)
{ GID_MOTHERGOOSE256, -1, 4, 0, "rm004", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when going north and reaching the castle (rooms 4 and 37) - bug #3038228
@@ -50,6 +51,7 @@ const SciWorkaroundEntry arithmeticWorkarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,index, workaround
const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
+ { GID_CAMELOT, 40, 40, 0, "Rm40", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // when looking at the ground at the pool of Siloam - bug #3614968
{ GID_CASTLEBRAIN, 280, 280, 0, "programmer", "dispatchEvent", -1, 0, { WORKAROUND_FAKE, 0xf } }, // pressing 'q' on the computer screen in the robot room, and closing the help dialog that pops up (bug #3039656). Moves the cursor to the view with the ID returned (in this case, the robot hand)
{ GID_CNICK_KQ, -1, 0, 1, "Character", "say", -1, -1, { WORKAROUND_FAKE, 0 } }, // checkers/backgammon, like in hoyle 3 - temps 504 and 505 - bug #3606025
{ GID_CNICK_KQ, -1, 700, 0, "gcWindow", "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when entering the control menu, like in hoyle 3
@@ -74,9 +76,11 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_HOYLE4, -1, 0, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #3039294
{ GID_HOYLE4, 910, 18, 0, NULL, "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // during tutorial - bug #3042756
{ GID_HOYLE4, 910, 910, 0, NULL, "setup", -1, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #3039294
- { GID_HOYLE4, 700, 718, 0, "compete_tree", "doit", -1, 75, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge - bug #3292332
- { GID_HOYLE4, 700, 716, 0, "other1_tree", "doit", -1, 46, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
- { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
+ { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always)
+ { GID_HOYLE4, 700, 710, 1, "BridgeStrategyPlay", "checkSplitTops", -1, 10, { WORKAROUND_FAKE, 0 } }, // while playing bridge, objects LeadReturn_Trump, SecondSeat_Trump, ThirdSeat_Trump and others - bug #3361925
+ { GID_HOYLE4, 700, -1, 1, "BridgeDefense", "think", -1, -1, { WORKAROUND_FAKE, 0 } }, // sometimes while playing bridge, temp var 3, 17 and others, objects LeadReturn_Trump, ThirdSeat_Trump and others
+ { GID_HOYLE4, 700, 730, 1, "BridgeDefense", "beatTheirBest", -1, 3, { WORKAROUND_FAKE, 0 } }, // rarely while playing bridge
+ { GID_HOYLE4, 700, -1, 1, "Code", "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always), temp var 11, 24, 27, 46, 75, objects compete_tree, compwe_tree, other1_tree, b1 - bugs #3292332 and #3361925
{ GID_HOYLE4, 300, 300, 0, "", "export 2", 0x1d4d, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts
{ GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #3292334
{ GID_HOYLE4, 500, 17, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Cribbage (e.g. when the opponent says "Last Card") - bug #3292327
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index af372640da..91c72456a8 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -236,7 +236,9 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
byte *ptr = NULL;
byte *headerPtr = inbuffer + headerPos;
byte *rlePtr = inbuffer + rlePos;
- int16 displaceX, displaceY;
+ // displaceX, displaceY fields are ignored, and may contain garbage
+ // (e.g. pic 261 in Dr. Brain 1 Spanish - bug #3614914)
+ //int16 displaceX, displaceY;
byte priority = _addToFlag ? _priority : 0;
byte clearColor;
bool compression = true;
@@ -251,8 +253,8 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
// Width/height here are always LE, even in Mac versions
width = READ_LE_UINT16(headerPtr + 0);
height = READ_LE_UINT16(headerPtr + 2);
- displaceX = (signed char)headerPtr[4];
- displaceY = (unsigned char)headerPtr[5];
+ //displaceX = (signed char)headerPtr[4];
+ //displaceY = (unsigned char)headerPtr[5];
if (_resourceType == SCI_PICTURE_TYPE_SCI11)
// SCI1.1 uses hardcoded clearcolor for pictures, even if cel header specifies otherwise
clearColor = _screen->getColorWhite();
@@ -262,16 +264,16 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
} else {
width = READ_SCI11ENDIAN_UINT16(headerPtr + 0);
height = READ_SCI11ENDIAN_UINT16(headerPtr + 2);
- displaceX = READ_SCI11ENDIAN_UINT16(headerPtr + 4); // probably signed?!?
- displaceY = READ_SCI11ENDIAN_UINT16(headerPtr + 6); // probably signed?!?
+ //displaceX = READ_SCI11ENDIAN_UINT16(headerPtr + 4); // probably signed?!?
+ //displaceY = READ_SCI11ENDIAN_UINT16(headerPtr + 6); // probably signed?!?
clearColor = headerPtr[8];
if (headerPtr[9] == 0)
compression = false;
}
#endif
- if (displaceX || displaceY)
- error("unsupported embedded cel-data in picture");
+ //if (displaceX || displaceY)
+ // error("unsupported embedded cel-data in picture");
// We will unpack cel-data into a temporary buffer and then plot it to screen
// That needs to be done cause a mirrored picture may be requested
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 3b9844b326..0a75e115fd 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -138,6 +138,7 @@ enum SciGameId {
GID_KQ5,
GID_KQ6,
GID_KQ7,
+ GID_KQUESTIONS,
GID_LAURABOW,
GID_LAURABOW2,
GID_LIGHTHOUSE,
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 5c148a7b57..4e14473921 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1485,7 +1485,7 @@ void ScummEngine::playActorSounds() {
int sound;
for (i = 1; i < _numActors; i++) {
- if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom() && _actors[i]->_sound) {
+ if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom()) {
_currentScript = 0xFF;
if (_game.version == 0) {
sound = v0ActorSounds[i - 1] & 0x3F;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index aaf84c1471..6717ea9b06 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -299,7 +299,11 @@ static const GameSettings gameVariantsTable[] = {
// Changed o_getResourceSize to cover all resource types
{"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"puttzoo", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "", 0, GID_PUTTZOO, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 98.5", 0, GID_PUTTZOO, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 99", 0, GID_PUTTZOO, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 100", 0, GID_PUTTZOO, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added VAR_PLATFORM variable
{"jungle", "", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
@@ -860,6 +864,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttzoo", "Zoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "Putt-Putt Saves the Zoo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "game", kGenHEPC, Common::EN_ANY, Common::kPlatformIOS, 0 },
+ { "puttzoo", "pp3_unlocked", kGenHEPC, Common::EN_ANY, Common::kPlatformWindows, 0 },
{ "SamsFunShop", "SamsFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
{ "SamsFunShop", "Sam's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 4c1fdaf673..1bb4a28f65 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -1769,11 +1769,8 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
// Check whether lights are turned on or not
const bool lightsOn = _vm->isLightOn();
- if (_vm->_game.features & GF_SMALL_HEADER) {
+ if ((_vm->_game.features & GF_SMALL_HEADER) || _vm->_game.version == 8) {
smap_ptr = ptr;
- } else if (_vm->_game.version == 8) {
- // Skip to the BSTR->WRAP->OFFS chunk
- smap_ptr = ptr + 24;
} else {
smap_ptr = _vm->findResource(MKTAG('S','M','A','P'), ptr);
assert(smap_ptr);
@@ -1887,8 +1884,14 @@ bool Gdi::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width,
smapLen = READ_LE_UINT32(smap_ptr);
if (stripnr * 4 + 4 < smapLen)
offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 4);
+ } else if (_vm->_game.version == 8) {
+ smapLen = READ_BE_UINT32(smap_ptr + 4);
+ // Skip to the BSTR->WRAP->OFFS chunk
+ smap_ptr += 24;
+ if (stripnr * 4 + 8 < smapLen)
+ offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
} else {
- smapLen = READ_BE_UINT32(smap_ptr);
+ smapLen = READ_BE_UINT32(smap_ptr + 4);
if (stripnr * 4 + 8 < smapLen)
offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
}
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index b024154c7f..987f74957c 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2148,7 +2148,7 @@ void ScummEngine_v100he::o100_systemOps() {
break;
case 132:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 133:
quitGame();
diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp
index adb2fcac2e..9259e0db2f 100644
--- a/engines/scumm/he/script_v70he.cpp
+++ b/engines/scumm/he/script_v70he.cpp
@@ -309,7 +309,7 @@ void ScummEngine_v70he::o70_systemOps() {
break;
case 160:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 244:
quitGame();
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index f36f5cc130..42bf9a4bb6 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -158,7 +158,7 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- if (ah == NULL || ah->data == NULL)
+ if (!ah)
error("readArray: invalid array %d (%d)", array, readVar(array));
if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
@@ -1199,7 +1199,7 @@ void ScummEngine_v72he::o72_systemOps() {
break;
case 160:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 244:
quitGame();
diff --git a/engines/scumm/insane/insane_enemy.cpp b/engines/scumm/insane/insane_enemy.cpp
index 3876966fd1..d711b63342 100644
--- a/engines/scumm/insane/insane_enemy.cpp
+++ b/engines/scumm/insane/insane_enemy.cpp
@@ -1519,6 +1519,7 @@ void Insane::chooseEnemyWeaponAnim(int32 buttons) {
case INV_BOOT:
case INV_HAND:
case INV_DUST:
+ // fallthrough
default:
switchEnemyWeapon();
}
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 28884d7f78..a377ad3dc4 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -35,6 +35,7 @@ MODULE_OBJS := \
midiparser_ro.o \
object.o \
palette.o \
+ player_ad.o \
player_apple2.o \
player_mac.o \
player_mod.o \
diff --git a/engines/scumm/player_ad.cpp b/engines/scumm/player_ad.cpp
new file mode 100644
index 0000000000..ed368afbf6
--- /dev/null
+++ b/engines/scumm/player_ad.cpp
@@ -0,0 +1,959 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "scumm/player_ad.h"
+#include "scumm/imuse/imuse.h"
+#include "scumm/scumm.h"
+#include "scumm/resource.h"
+
+#include "audio/fmopl.h"
+
+#include "common/textconsole.h"
+#include "common/config-manager.h"
+
+namespace Scumm {
+
+#define AD_CALLBACK_FREQUENCY 472
+
+Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
+ : _vm(scumm), _mixer(mixer), _rate(mixer->getOutputRate()) {
+ _opl2 = OPL::Config::create();
+ if (!_opl2->init(_rate)) {
+ error("Could not initialize OPL2 emulator");
+ }
+
+ _samplesPerCallback = _rate / AD_CALLBACK_FREQUENCY;
+ _samplesPerCallbackRemainder = _rate % AD_CALLBACK_FREQUENCY;
+ _samplesTillCallback = 0;
+ _samplesTillCallbackRemainder = 0;
+
+ memset(_registerBackUpTable, 0, sizeof(_registerBackUpTable));
+ writeReg(0x01, 0x00);
+ writeReg(0xBD, 0x00);
+ writeReg(0x08, 0x00);
+ writeReg(0x01, 0x20);
+
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+ _engineMusicTimer = 0;
+ _soundPlaying = -1;
+
+ _curOffset = 0;
+
+ _sfxTimer = 4;
+ _rndSeed = 1;
+
+ memset(_channels, 0, sizeof(_channels));
+ memset(_sfxResource, 0, sizeof(_sfxResource));
+ memset(_sfxPriority, 0, sizeof(_sfxPriority));
+}
+
+Player_AD::~Player_AD() {
+ _mixer->stopHandle(_soundHandle);
+
+ stopAllSounds();
+ Common::StackLock lock(_mutex);
+ delete _opl2;
+ _opl2 = 0;
+}
+
+void Player_AD::setMusicVolume(int vol) {
+ // HACK: We ignore the parameter and set up the volume specified in the
+ // config manager. This allows us to differentiate between music and sfx
+ // volume changes.
+ setupVolume();
+}
+
+void Player_AD::startSound(int sound) {
+ Common::StackLock lock(_mutex);
+
+ // Query the sound resource
+ const byte *res = _vm->getResourceAddress(rtSound, sound);
+
+ if (res[2] == 0x80) {
+ // Stop the current sounds
+ stopAllSounds();
+
+ // Lock the new music resource
+ _soundPlaying = sound;
+ _vm->_res->lock(rtSound, _soundPlaying);
+
+ // Start the new music resource
+ _resource = res;
+ startMusic();
+ } else {
+ // Only try to start a sfx when no music is playing.
+ if (_soundPlaying == -1) {
+ const byte priority = res[0];
+ const byte channel = res[1];
+
+ // Check for out of bounds access
+ if (channel >= 3) {
+ warning("AdLib sfx resource %d uses channel %d", sound, channel);
+ return;
+ }
+
+ // Check whether the channel is free or the priority of the new
+ // sfx resource is above the old one.
+ if (_channels[channel * 3 + 0].state
+ || _channels[channel * 3 + 1].state
+ || _channels[channel * 3 + 2].state) {
+ if (_sfxPriority[channel] > priority) {
+ return;
+ }
+ }
+
+ // Lock the new resource
+ _sfxResource[channel] = sound;
+ _sfxPriority[channel] = priority;
+ _vm->_res->lock(rtSound, sound);
+
+ // Start the actual sfx resource
+ _resource = res;
+ startSfx();
+ }
+ }
+
+ // Setup the sound volume
+ setupVolume();
+}
+
+void Player_AD::stopSound(int sound) {
+ Common::StackLock lock(_mutex);
+
+ if (sound == _soundPlaying) {
+ stopAllSounds();
+ } else {
+ for (int i = 0; i < 3; ++i) {
+ if (_sfxResource[i] == sound) {
+ if (_channels[i * 3 + 0].state
+ || _channels[i * 3 + 1].state
+ || _channels[i * 3 + 2].state) {
+ // Unlock the sound resource
+ _vm->_res->unlock(rtSound, sound);
+
+ // Stop the actual sfx playback
+ _channels[i * 3 + 0].state = 0;
+ _channels[i * 3 + 1].state = 0;
+ _channels[i * 3 + 2].state = 0;
+ clearChannel(i * 3 + 0);
+ clearChannel(i * 3 + 1);
+ clearChannel(i * 3 + 2);
+ }
+ }
+ }
+ }
+}
+
+void Player_AD::stopAllSounds() {
+ Common::StackLock lock(_mutex);
+
+ // Unlock the music resource if present
+ if (_soundPlaying != -1) {
+ _vm->_res->unlock(rtSound, _soundPlaying);
+ _soundPlaying = -1;
+ }
+
+ // Stop the music playback
+ _curOffset = 0;
+
+ // Unloack all used sfx resources
+ for (int i = 0; i < 3; ++i) {
+ if (_channels[i * 3 + 0].state || _channels[i * 3 + 1].state || _channels[i * 3 + 2].state) {
+ _vm->_res->unlock(rtSound, _sfxResource[i]);
+ }
+ }
+
+ // Reset all the sfx channels
+ for (int i = 0; i < 9; ++i) {
+ _channels[i].state = 0;
+ clearChannel(i);
+ }
+
+ writeReg(0xBD, 0x00);
+}
+
+int Player_AD::getMusicTimer() {
+ return _engineMusicTimer;
+}
+
+int Player_AD::getSoundStatus(int sound) const {
+ return (sound == _soundPlaying);
+}
+
+void Player_AD::saveLoadWithSerializer(Serializer *ser) {
+ Common::StackLock lock(_mutex);
+
+ if (ser->getVersion() < VER(95)) {
+ IMuse *dummyImuse = IMuse::create(_vm->_system, NULL, NULL);
+ dummyImuse->save_or_load(ser, _vm, false);
+ delete dummyImuse;
+ return;
+ }
+
+ // TODO: Be nicer than the original and save the data to continue the
+ // currently played sound resources on load?
+}
+
+int Player_AD::readBuffer(int16 *buffer, const int numSamples) {
+ Common::StackLock lock(_mutex);
+
+ int len = numSamples;
+
+ while (len > 0) {
+ if (!_samplesTillCallback) {
+ // Run the update callback for music or sfx depending on which is
+ // active.
+ if (_curOffset) {
+ updateMusic();
+ } else {
+ updateSfx();
+ }
+
+ _samplesTillCallback = _samplesPerCallback;
+ _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
+ if (_samplesTillCallbackRemainder >= AD_CALLBACK_FREQUENCY) {
+ ++_samplesTillCallback;
+ _samplesTillCallbackRemainder -= AD_CALLBACK_FREQUENCY;
+ }
+ }
+
+ const int samplesToRead = MIN(len, _samplesTillCallback);
+ _opl2->readBuffer(buffer, samplesToRead);
+
+ buffer += samplesToRead;
+ len -= samplesToRead;
+ _samplesTillCallback -= samplesToRead;
+ }
+
+ return numSamples;
+}
+
+void Player_AD::setupVolume() {
+ // Setup the correct volume
+ int soundVolumeMusic = CLIP<int>(ConfMan.getInt("music_volume"), 0, Audio::Mixer::kMaxChannelVolume);
+ int soundVolumeSfx = CLIP<int>(ConfMan.getInt("sfx_volume"), 0, Audio::Mixer::kMaxChannelVolume);
+ if (ConfMan.hasKey("mute")) {
+ if (ConfMan.getBool("mute")) {
+ soundVolumeMusic = 0;
+ soundVolumeSfx = 0;
+ }
+ }
+
+ // In case a music is being played set the music volume. Set the sfx
+ // volume otherwise. This is safe because in the latter case either
+ // sfx are playing or there is no sound being played at all.
+ if (_soundPlaying != -1) {
+ _mixer->setChannelVolume(_soundHandle, soundVolumeMusic);
+ } else {
+ _mixer->setChannelVolume(_soundHandle, soundVolumeSfx);
+ }
+}
+
+void Player_AD::writeReg(int r, int v) {
+ if (r >= 0 && r < ARRAYSIZE(_registerBackUpTable)) {
+ _registerBackUpTable[r] = v;
+ }
+ _opl2->writeReg(r, v);
+}
+
+uint8 Player_AD::readReg(int r) const {
+ if (r >= 0 && r < ARRAYSIZE(_registerBackUpTable)) {
+ return _registerBackUpTable[r];
+ } else {
+ return 0;
+ }
+}
+
+void Player_AD::setupChannel(const uint channel, const byte *instrOffset) {
+ instrOffset += 2;
+ writeReg(0xC0 + channel, *instrOffset++);
+ setupOperator(_operatorOffsetTable[channel * 2 + 0], instrOffset);
+ setupOperator(_operatorOffsetTable[channel * 2 + 1], instrOffset);
+}
+
+void Player_AD::setupOperator(const uint opr, const byte *&instrOffset) {
+ writeReg(0x20 + opr, *instrOffset++);
+ writeReg(0x40 + opr, *instrOffset++);
+ writeReg(0x60 + opr, *instrOffset++);
+ writeReg(0x80 + opr, *instrOffset++);
+ writeReg(0xE0 + opr, *instrOffset++);
+}
+
+const int Player_AD::_operatorOffsetTable[18] = {
+ 0, 3, 1, 4,
+ 2, 5, 8, 11,
+ 9, 12, 10, 13,
+ 16, 19, 17, 20,
+ 18, 21
+};
+
+// Music
+
+void Player_AD::startMusic() {
+ memset(_instrumentOffset, 0, sizeof(_instrumentOffset));
+ memset(_channelLastEvent, 0, sizeof(_channelLastEvent));
+ memset(_channelFrequency, 0, sizeof(_channelFrequency));
+ memset(_channelB0Reg, 0, sizeof(_channelB0Reg));
+
+ _voiceChannels = 0;
+ uint instruments = _resource[10];
+ for (uint i = 0; i < instruments; ++i) {
+ const int instrIndex = _resource[11 + i] - 1;
+ if (0 <= instrIndex && instrIndex < 16) {
+ _instrumentOffset[instrIndex] = i * 16 + 16 + 3;
+ _voiceChannels |= _resource[_instrumentOffset[instrIndex] + 13];
+ }
+ }
+
+ if (_voiceChannels) {
+ _mdvdrState = 0x20;
+ _voiceChannels = 6;
+ } else {
+ _mdvdrState = 0;
+ _voiceChannels = 9;
+ }
+
+ _curOffset = 0x93;
+ // TODO: is this the same for Loom?
+ _nextEventTimer = 40;
+ _engineMusicTimer = 0;
+ _internalMusicTimer = 0;
+ _musicTimer = 0;
+
+ writeReg(0xBD, _mdvdrState);
+
+ const bool isLoom = (_vm->_game.id == GID_LOOM);
+ _timerLimit = isLoom ? 473 : 256;
+ _musicTicks = _resource[3] * (isLoom ? 2 : 1);
+ _loopFlag = (_resource[4] == 0);
+ _musicLoopStart = READ_LE_UINT16(_resource + 5);
+}
+
+void Player_AD::updateMusic() {
+ _musicTimer += _musicTicks;
+ if (_musicTimer < _timerLimit) {
+ return;
+ }
+ _musicTimer -= _timerLimit;
+
+ ++_internalMusicTimer;
+ if (_internalMusicTimer > 120) {
+ _internalMusicTimer = 0;
+ ++_engineMusicTimer;
+ }
+
+ --_nextEventTimer;
+ if (_nextEventTimer) {
+ return;
+ }
+
+ while (true) {
+ uint command = _resource[_curOffset++];
+ if (command == 0xFF) {
+ // META EVENT
+ // Get the command number.
+ command = _resource[_curOffset++];
+ if (command == 47) {
+ // End of track
+ if (_loopFlag) {
+ // In case the track is looping jump to the start.
+ _curOffset = _musicLoopStart;
+ _nextEventTimer = 0;
+ } else {
+ // Otherwise completely stop playback.
+ stopAllSounds();
+ }
+ return;
+ } else if (command == 88) {
+ // This is proposedly a debug information insertion. The CMS
+ // player code handles this differently, but is still using
+ // the same resources...
+ _curOffset += 5;
+ } else if (command == 81) {
+ // Change tempo. This is used exclusively in Loom.
+ const uint timing = _resource[_curOffset + 2] | (_resource[_curOffset + 1] << 8);
+ _musicTicks = 0x73000 / timing;
+ command = _resource[_curOffset++];
+ _curOffset += command;
+ } else {
+ // In case an unknown meta event occurs just skip over the
+ // data by using the length supplied.
+ command = _resource[_curOffset++];
+ _curOffset += command;
+ }
+ } else {
+ if (command >= 0x90) {
+ // NOTE ON
+ // Extract the channel number and save it in command.
+ command -= 0x90;
+
+ const uint instrOffset = _instrumentOffset[command];
+ if (instrOffset) {
+ if (_resource[instrOffset + 13] != 0) {
+ setupRhythm(_resource[instrOffset + 13], instrOffset);
+ } else {
+ int channel = findFreeChannel();
+ if (channel != -1) {
+ noteOff(channel);
+ setupChannel(channel, instrOffset);
+ _channelLastEvent[channel] = command + 0x90;
+ _channelFrequency[channel] = _resource[_curOffset];
+ setupFrequency(channel, _resource[_curOffset]);
+ }
+ }
+ }
+ } else {
+ // NOTE OFF
+ const uint note = _resource[_curOffset];
+ command += 0x10;
+
+ // Find the output channel which plays the note.
+ uint channel = 0xFF;
+ for (uint i = 0; i < _voiceChannels; ++i) {
+ if (_channelFrequency[i] == note && _channelLastEvent[i] == command) {
+ channel = i;
+ break;
+ }
+ }
+
+ if (channel != 0xFF) {
+ // In case a output channel playing the note was found,
+ // stop it.
+ noteOff(channel);
+ } else {
+ // In case there is no such note this will disable the
+ // rhythm instrument played on the channel.
+ command -= 0x90;
+ const uint instrOffset = _instrumentOffset[command];
+ if (instrOffset && _resource[instrOffset + 13] != 0) {
+ const uint rhythmInstr = _resource[instrOffset + 13];
+ if (rhythmInstr < 6) {
+ _mdvdrState &= _mdvdrTable[rhythmInstr] ^ 0xFF;
+ writeReg(0xBD, _mdvdrState);
+ }
+ }
+ }
+ }
+
+ _curOffset += 2;
+ }
+
+ // In case there is a delay till the next event stop handling.
+ if (_resource[_curOffset] != 0) {
+ break;
+ }
+ ++_curOffset;
+ }
+
+ _nextEventTimer = _resource[_curOffset++];
+ if (_nextEventTimer & 0x80) {
+ _nextEventTimer -= 0x80;
+ _nextEventTimer <<= 7;
+ _nextEventTimer |= _resource[_curOffset++];
+ }
+
+ _nextEventTimer >>= (_vm->_game.id == GID_LOOM) ? 2 : 1;
+ if (!_nextEventTimer) {
+ _nextEventTimer = 1;
+ }
+}
+
+void Player_AD::noteOff(uint channel) {
+ _channelLastEvent[channel] = 0;
+ writeReg(0xB0 + channel, _channelB0Reg[channel] & 0xDF);
+}
+
+int Player_AD::findFreeChannel() {
+ for (uint i = 0; i < _voiceChannels; ++i) {
+ if (!_channelLastEvent[i]) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void Player_AD::setupFrequency(uint channel, int8 frequency) {
+ frequency -= 31;
+ if (frequency < 0) {
+ frequency = 0;
+ }
+
+ uint octave = 0;
+ while (frequency >= 12) {
+ frequency -= 12;
+ ++octave;
+ }
+
+ const uint noteFrequency = _noteFrequencies[frequency];
+ octave <<= 2;
+ octave |= noteFrequency >> 8;
+ octave |= 0x20;
+ writeReg(0xA0 + channel, noteFrequency & 0xFF);
+ _channelB0Reg[channel] = octave;
+ writeReg(0xB0 + channel, octave);
+}
+
+void Player_AD::setupRhythm(uint rhythmInstr, uint instrOffset) {
+ if (rhythmInstr == 1) {
+ setupChannel(6, instrOffset);
+ writeReg(0xA6, _resource[instrOffset++]);
+ writeReg(0xB6, _resource[instrOffset] & 0xDF);
+ _mdvdrState |= 0x10;
+ writeReg(0xBD, _mdvdrState);
+ } else if (rhythmInstr < 6) {
+ const byte *secondOperatorOffset = _resource + instrOffset + 8;
+ setupOperator(_rhythmOperatorTable[rhythmInstr], secondOperatorOffset);
+ writeReg(0xA0 + _rhythmChannelTable[rhythmInstr], _resource[instrOffset++]);
+ writeReg(0xB0 + _rhythmChannelTable[rhythmInstr], _resource[instrOffset++] & 0xDF);
+ writeReg(0xC0 + _rhythmChannelTable[rhythmInstr], _resource[instrOffset]);
+ _mdvdrState |= _mdvdrTable[rhythmInstr];
+ writeReg(0xBD, _mdvdrState);
+ }
+}
+
+const uint Player_AD::_noteFrequencies[12] = {
+ 0x200, 0x21E, 0x23F, 0x261,
+ 0x285, 0x2AB, 0x2D4, 0x300,
+ 0x32E, 0x35E, 0x390, 0x3C7
+};
+
+const uint Player_AD::_mdvdrTable[6] = {
+ 0x00, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+const uint Player_AD::_rhythmOperatorTable[6] = {
+ 0x00, 0x00, 0x14, 0x12, 0x15, 0x11
+};
+
+const uint Player_AD::_rhythmChannelTable[6] = {
+ 0x00, 0x00, 0x07, 0x08, 0x08, 0x07
+};
+
+// SFX
+
+void Player_AD::startSfx() {
+ writeReg(0xBD, 0x00);
+
+ // The second byte of the resource defines the logical channel where
+ // the sound effect should be played.
+ const int startChannel = _resource[1] * 3;
+
+ // Clear the channel.
+ _channels[startChannel + 0].state = 0;
+ _channels[startChannel + 1].state = 0;
+ _channels[startChannel + 2].state = 0;
+
+ clearChannel(startChannel + 0);
+ clearChannel(startChannel + 1);
+ clearChannel(startChannel + 2);
+
+ // Set up the first channel to pick up playback.
+ _channels[startChannel].currentOffset = _channels[startChannel].startOffset = _resource + 2;
+ _channels[startChannel].state = 1;
+
+ // Scan for the start of the other channels and set them up if required.
+ int curChannel = startChannel + 1;
+ const byte *bufferPosition = _resource + 2;
+ uint8 command = 0;
+ while ((command = *bufferPosition) != 0xFF) {
+ switch (command) {
+ case 1:
+ // INSTRUMENT DEFINITION
+ bufferPosition += 15;
+ break;
+
+ case 2:
+ // NOTE DEFINITION
+ bufferPosition += 11;
+ break;
+
+ case 0x80:
+ // LOOP
+ bufferPosition += 1;
+ break;
+
+ default:
+ // START OF CHANNEL
+ bufferPosition += 1;
+ _channels[curChannel].currentOffset = bufferPosition;
+ _channels[curChannel].startOffset = bufferPosition;
+ _channels[curChannel].state = 1;
+ ++curChannel;
+ break;
+ }
+ }
+}
+
+void Player_AD::updateSfx() {
+ if (--_sfxTimer) {
+ return;
+ }
+ _sfxTimer = 4;
+
+ for (int i = 0; i <= 9; ++i) {
+ if (!_channels[i].state) {
+ continue;
+ }
+
+ updateChannel(i);
+ }
+}
+
+void Player_AD::clearChannel(int channel) {
+ writeReg(0xA0 + channel, 0x00);
+ writeReg(0xB0 + channel, 0x00);
+}
+
+void Player_AD::updateChannel(int channel) {
+ if (_channels[channel].state == 1) {
+ parseSlot(channel);
+ } else {
+ updateSlot(channel);
+ }
+}
+
+void Player_AD::parseSlot(int channel) {
+ while (true) {
+ const byte *curOffset = _channels[channel].currentOffset;
+
+ switch (*curOffset) {
+ case 1:
+ // INSTRUMENT DEFINITION
+ ++curOffset;
+ _channels[channel].instrumentData[0] = *(curOffset + 0);
+ _channels[channel].instrumentData[1] = *(curOffset + 2);
+ _channels[channel].instrumentData[2] = *(curOffset + 9);
+ _channels[channel].instrumentData[3] = *(curOffset + 8);
+ _channels[channel].instrumentData[4] = *(curOffset + 4);
+ _channels[channel].instrumentData[5] = *(curOffset + 3);
+ _channels[channel].instrumentData[6] = 0;
+
+ setupChannel(channel, curOffset);
+
+ writeReg(0xA0 + channel, *(curOffset + 0));
+ writeReg(0xB0 + channel, *(curOffset + 1) & 0xDF);
+
+ _channels[channel].currentOffset += 15;
+ break;
+
+ case 2:
+ // NOTE DEFINITION
+ ++curOffset;
+ _channels[channel].state = 2;
+ noteOffOn(channel);
+ parseNote(channel, 0, curOffset);
+ parseNote(channel, 1, curOffset);
+ return;
+
+ case 0x80:
+ // LOOP
+ _channels[channel].currentOffset = _channels[channel].startOffset;
+ break;
+
+ default:
+ // START OF CHANNEL
+ // When we encounter a start of another channel while playback
+ // it means that the current channel is finished. Thus, we will
+ // stop it.
+ clearChannel(channel);
+ _channels[channel].state = 0;
+
+ // If no channel of the sound effect is playing anymore, unlock
+ // the resource.
+ channel /= 3;
+ if (!_channels[channel + 0].state
+ && !_channels[channel + 1].state
+ && !_channels[channel + 2].state) {
+ _vm->_res->unlock(rtSound, _sfxResource[channel]);
+ }
+ return;
+ }
+ }
+}
+
+void Player_AD::updateSlot(int channel) {
+ const byte *curOffset = _channels[channel].currentOffset + 1;
+
+ for (int num = 0; num <= 1; ++num, curOffset += 5) {
+ if (!(*curOffset & 0x80)) {
+ continue;
+ }
+
+ const int note = channel * 2 + num;
+ bool updateNote = false;
+
+ if (_notes[note].state == 2) {
+ if (!--_notes[note].sustainTimer) {
+ updateNote = true;
+ }
+ } else {
+ updateNote = processNoteEnvelope(note, _notes[note].instrumentValue);
+
+ if (_notes[note].bias) {
+ writeRegisterSpecial(note, _notes[note].bias - _notes[note].instrumentValue, *curOffset & 0x07);
+ } else {
+ writeRegisterSpecial(note, _notes[note].instrumentValue, *curOffset & 0x07);
+ }
+ }
+
+ if (updateNote) {
+ if (processNote(note, curOffset)) {
+ if (!(*curOffset & 0x08)) {
+ _channels[channel].currentOffset += 11;
+ _channels[channel].state = 1;
+ continue;
+ } else if (*curOffset & 0x10) {
+ noteOffOn(channel);
+ }
+
+ _notes[note].state = -1;
+ processNote(note, curOffset);
+ }
+ }
+
+ if ((*curOffset & 0x20) && !--_notes[note].playTime) {
+ _channels[channel].currentOffset += 11;
+ _channels[channel].state = 1;
+ }
+ }
+}
+
+void Player_AD::parseNote(int channel, int num, const byte *offset) {
+ if (num) {
+ offset += 5;
+ }
+
+ if (*offset & 0x80) {
+ const int note = channel * 2 + num;
+ _notes[note].state = -1;
+ processNote(note, offset);
+ _notes[note].playTime = 0;
+
+ if (*offset & 0x20) {
+ _notes[note].playTime = (*(offset + 4) >> 4) * 118;
+ _notes[note].playTime += (*(offset + 4) & 0x0F) * 8;
+ }
+ }
+}
+
+bool Player_AD::processNote(int note, const byte *offset) {
+ if (++_notes[note].state == 4) {
+ return true;
+ }
+
+ const int instrumentDataOffset = *offset & 0x07;
+ _notes[note].bias = _noteBiasTable[instrumentDataOffset];
+
+ uint8 instrumentDataValue = 0;
+ if (_notes[note].state == 0) {
+ instrumentDataValue = _channels[note / 2].instrumentData[instrumentDataOffset];
+ }
+
+ uint8 noteInstrumentValue = readRegisterSpecial(note, instrumentDataValue, instrumentDataOffset);
+ if (_notes[note].bias) {
+ noteInstrumentValue = _notes[note].bias - noteInstrumentValue;
+ }
+ _notes[note].instrumentValue = noteInstrumentValue;
+
+ if (_notes[note].state == 2) {
+ _notes[note].sustainTimer = _numStepsTable[*(offset + 3) >> 4];
+
+ if (*offset & 0x40) {
+ _notes[note].sustainTimer = (((getRnd() << 8) * _notes[note].sustainTimer) >> 16) + 1;
+ }
+ } else {
+ int timer1, timer2;
+ if (_notes[note].state == 3) {
+ timer1 = *(offset + 3) & 0x0F;
+ timer2 = 0;
+ } else {
+ timer1 = *(offset + _notes[note].state + 1) >> 4;
+ timer2 = *(offset + _notes[note].state + 1) & 0x0F;
+ }
+
+ int adjustValue = ((_noteAdjustTable[timer2] * _noteAdjustScaleTable[instrumentDataOffset]) >> 16) - noteInstrumentValue;
+ setupNoteEnvelopeState(note, _numStepsTable[timer1], adjustValue);
+ }
+
+ return false;
+}
+
+void Player_AD::noteOffOn(int channel) {
+ const uint8 regValue = readReg(0xB0 | channel);
+ writeReg(0xB0 | channel, regValue & 0xDF);
+ writeReg(0xB0 | channel, regValue | 0x20);
+}
+
+void Player_AD::writeRegisterSpecial(int note, uint8 value, int offset) {
+ if (offset == 6) {
+ return;
+ }
+
+ // Division by 2 extracts the channel number out of the note.
+ note /= 2;
+
+ uint8 regNum;
+ if (_useOperatorTable[offset]) {
+ regNum = _operatorOffsetTable[_channelOperatorOffsetTable[offset] + note * 2];
+ } else {
+ regNum = _channelOffsetTable[note];
+ }
+
+ regNum += _baseRegisterTable[offset];
+
+ uint8 regValue = readReg(regNum) & (~_registerMaskTable[offset]);
+ regValue |= value << _registerShiftTable[offset];
+
+ writeReg(regNum, regValue);
+}
+
+uint8 Player_AD::readRegisterSpecial(int note, uint8 defaultValue, int offset) {
+ if (offset == 6) {
+ return 0;
+ }
+
+ // Division by 2 extracts the channel number out of the note.
+ note /= 2;
+
+ uint8 regNum;
+ if (_useOperatorTable[offset]) {
+ regNum = _operatorOffsetTable[_channelOperatorOffsetTable[offset] + note * 2];
+ } else {
+ regNum = _channelOffsetTable[note];
+ }
+
+ regNum += _baseRegisterTable[offset];
+
+ uint8 regValue;
+ if (defaultValue) {
+ regValue = defaultValue;
+ } else {
+ regValue = readReg(regNum);
+ }
+
+ regValue &= _registerMaskTable[offset];
+ regValue >>= _registerShiftTable[offset];
+
+ return regValue;
+}
+
+void Player_AD::setupNoteEnvelopeState(int note, int steps, int adjust) {
+ _notes[note].preIncrease = 0;
+ if (ABS(adjust) > steps) {
+ _notes[note].preIncrease = 1;
+ _notes[note].adjust = adjust / steps;
+ _notes[note].envelope.stepIncrease = ABS(adjust % steps);
+ } else {
+ _notes[note].adjust = adjust;
+ _notes[note].envelope.stepIncrease = ABS(adjust);
+ }
+
+ _notes[note].envelope.step = steps;
+ _notes[note].envelope.stepCounter = 0;
+ _notes[note].envelope.timer = steps;
+}
+
+bool Player_AD::processNoteEnvelope(int note, int &instrumentValue) {
+ if (_notes[note].preIncrease) {
+ instrumentValue += _notes[note].adjust;
+ }
+
+ _notes[note].envelope.stepCounter += _notes[note].envelope.stepIncrease;
+ if (_notes[note].envelope.stepCounter >= _notes[note].envelope.step) {
+ _notes[note].envelope.stepCounter -= _notes[note].envelope.step;
+
+ if (_notes[note].adjust < 0) {
+ --instrumentValue;
+ } else {
+ ++instrumentValue;
+ }
+ }
+
+ if (--_notes[note].envelope.timer) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+uint8 Player_AD::getRnd() {
+ if (_rndSeed & 1) {
+ _rndSeed >>= 1;
+ _rndSeed ^= 0xB8;
+ } else {
+ _rndSeed >>= 1;
+ }
+
+ return _rndSeed;
+}
+
+const uint Player_AD::_noteBiasTable[7] = {
+ 0x00, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x00
+};
+
+const uint Player_AD::_numStepsTable[16] = {
+ 1, 4, 6, 8,
+ 10, 14, 18, 24,
+ 36, 64, 100, 160,
+ 240, 340, 600, 1200
+};
+
+const uint Player_AD::_noteAdjustScaleTable[7] = {
+ 255, 7, 63, 15, 63, 15, 63
+};
+
+const uint Player_AD::_noteAdjustTable[16] = {
+ 0, 4369, 8738, 13107,
+ 17476, 21845, 26214, 30583,
+ 34952, 39321, 43690, 48059,
+ 52428, 46797, 61166, 65535
+};
+
+const bool Player_AD::_useOperatorTable[7] = {
+ false, false, true, true, true, true, false
+};
+
+const uint Player_AD::_channelOffsetTable[11] = {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 8, 7
+};
+
+const uint Player_AD::_channelOperatorOffsetTable[7] = {
+ 0, 0, 1, 1, 0, 0, 0
+};
+
+const uint Player_AD::_baseRegisterTable[7] = {
+ 0xA0, 0xC0, 0x40, 0x20, 0x40, 0x20, 0x00
+};
+
+const uint Player_AD::_registerMaskTable[7] = {
+ 0xFF, 0x0E, 0x3F, 0x0F, 0x3F, 0x0F, 0x00
+};
+
+const uint Player_AD::_registerShiftTable[7] = {
+ 0, 1, 0, 0, 0, 0, 0
+};
+
+} // End of namespace Scumm
diff --git a/engines/scumm/player_ad.h b/engines/scumm/player_ad.h
new file mode 100644
index 0000000000..da6c7177ef
--- /dev/null
+++ b/engines/scumm/player_ad.h
@@ -0,0 +1,190 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCUMM_PLAYER_AD_H
+#define SCUMM_PLAYER_AD_H
+
+#include "scumm/music.h"
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+
+#include "common/mutex.h"
+
+namespace OPL {
+class OPL;
+}
+
+namespace Scumm {
+
+class ScummEngine;
+
+/**
+ * Sound output for v3/v4 AdLib data.
+ */
+class Player_AD : public MusicEngine, public Audio::AudioStream {
+public:
+ Player_AD(ScummEngine *scumm, Audio::Mixer *mixer);
+ virtual ~Player_AD();
+
+ // MusicEngine API
+ virtual void setMusicVolume(int vol);
+ virtual void startSound(int sound);
+ virtual void stopSound(int sound);
+ virtual void stopAllSounds();
+ virtual int getMusicTimer();
+ virtual int getSoundStatus(int sound) const;
+
+ virtual void saveLoadWithSerializer(Serializer *ser);
+
+ // AudioStream API
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+ virtual bool isStereo() const { return false; }
+ virtual bool endOfData() const { return false; }
+ virtual int getRate() const { return _rate; }
+
+private:
+ ScummEngine *const _vm;
+ Common::Mutex _mutex;
+ Audio::Mixer *const _mixer;
+ const int _rate;
+ Audio::SoundHandle _soundHandle;
+ void setupVolume();
+
+ OPL::OPL *_opl2;
+
+ int _samplesPerCallback;
+ int _samplesPerCallbackRemainder;
+ int _samplesTillCallback;
+ int _samplesTillCallbackRemainder;
+
+ int _soundPlaying;
+ int _engineMusicTimer;
+
+ // AdLib register utilities
+ uint8 _registerBackUpTable[256];
+ void writeReg(int r, int v);
+ uint8 readReg(int r) const;
+
+ // Instrument setup
+ void setupChannel(const uint channel, uint instrOffset) {
+ setupChannel(channel, _resource + instrOffset);
+ }
+ void setupChannel(const uint channel, const byte *instrOffset);
+ void setupOperator(const uint opr, const byte *&instrOffset);
+ static const int _operatorOffsetTable[18];
+
+ // Sound data
+ const byte *_resource;
+
+ // Music handling
+ void startMusic();
+ void updateMusic();
+ void noteOff(uint channel);
+ int findFreeChannel();
+ void setupFrequency(uint channel, int8 frequency);
+ void setupRhythm(uint rhythmInstr, uint instrOffset);
+
+ uint _timerLimit;
+ uint _musicTicks;
+ uint _musicTimer;
+ uint _internalMusicTimer;
+ bool _loopFlag;
+ uint _musicLoopStart;
+ uint _instrumentOffset[16];
+ uint _channelLastEvent[9];
+ uint _channelFrequency[9];
+ uint _channelB0Reg[9];
+
+ uint _mdvdrState;
+ uint _voiceChannels;
+
+ uint _curOffset;
+ uint _nextEventTimer;
+
+ static const uint _noteFrequencies[12];
+ static const uint _mdvdrTable[6];
+ static const uint _rhythmOperatorTable[6];
+ static const uint _rhythmChannelTable[6];
+
+ // SFX handling
+ void startSfx();
+ void updateSfx();
+ void clearChannel(int channel);
+ void updateChannel(int channel);
+ void parseSlot(int channel);
+ void updateSlot(int channel);
+ void parseNote(int channel, int num, const byte *offset);
+ bool processNote(int note, const byte *offset);
+ void noteOffOn(int channel);
+ void writeRegisterSpecial(int note, uint8 value, int offset);
+ uint8 readRegisterSpecial(int note, uint8 defaultValue, int offset);
+ void setupNoteEnvelopeState(int note, int steps, int adjust);
+ bool processNoteEnvelope(int note, int &instrumentValue);
+
+ int _sfxTimer;
+
+ int _sfxResource[3];
+ int _sfxPriority[3];
+
+ struct Channel {
+ int state;
+ const byte *currentOffset;
+ const byte *startOffset;
+ uint8 instrumentData[7];
+ } _channels[11];
+
+ uint8 _rndSeed;
+ uint8 getRnd();
+
+ struct Note {
+ int state;
+ int playTime;
+ int sustainTimer;
+ int instrumentValue;
+ int bias;
+ int preIncrease;
+ int adjust;
+
+ struct Envelope {
+ int stepIncrease;
+ int step;
+ int stepCounter;
+ int timer;
+ } envelope;
+ } _notes[22];
+
+ static const uint _noteBiasTable[7];
+ static const uint _numStepsTable[16];
+ static const uint _noteAdjustScaleTable[7];
+ static const uint _noteAdjustTable[16];
+ static const bool _useOperatorTable[7];
+ static const uint _channelOffsetTable[11];
+ static const uint _channelOperatorOffsetTable[7];
+ static const uint _baseRegisterTable[7];
+ static const uint _registerMaskTable[7];
+ static const uint _registerShiftTable[7];
+};
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 7b2ff91ad3..c34be5816d 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 94
+#define CURRENT_VER 95
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index a75e864e7a..6983c51f30 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -394,7 +394,7 @@ ScummEngine_v6::ArrayHeader *ScummEngine_v6::getArray(int array) {
int ScummEngine_v6::readArray(int array, int idx, int base) {
ArrayHeader *ah = getArray(array);
- if (ah == NULL || ah->data == NULL)
+ if (!ah)
error("readArray: invalid array %d (%d)", array, readVar(array));
// WORKAROUND bug #645711. This is clearly a script bug, as this script
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index f5609f1b03..979573c5f5 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sat Aug 3 16:52:02 2013
+ This file was generated by the md5table tool on Thu Aug 15 12:47:39 2013
DO NOT EDIT MANUALLY!
*/
@@ -344,6 +344,7 @@ static const MD5Table md5table[] = {
{ "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "79b05f628586837e7166e82b2279bb50", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine },
+ { "7b4ee071eecadc2d8cd0c3509110825c", "puttzoo", "HE 100", "Remastered", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown },
{ "7c8100e360e8ef05f88069d4cfa0afd1", "puttrace", "HE 99", "Demo", 13108, Common::EN_GRB, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 2a14673855..d1a3de94b8 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -52,6 +52,7 @@
#include "scumm/he/logic_he.h"
#include "scumm/he/sound_he.h"
#include "scumm/object.h"
+#include "scumm/player_ad.h"
#include "scumm/player_nes.h"
#include "scumm/player_sid.h"
#include "scumm/player_pce.h"
@@ -1841,6 +1842,15 @@ void ScummEngine::setupMusic(int midi) {
_musicEngine = _townsPlayer = new Player_Towns_v1(this, _mixer);
if (!_townsPlayer->init())
error("Failed to initialize FM-Towns audio driver");
+ } else if (_game.platform == Common::kPlatformDOS && (_sound->_musicType == MDT_ADLIB) && (_game.id == GID_LOOM || _game.id == GID_INDY3)) {
+ // For Indy3 DOS and Loom DOS we use an implementation of the original
+ // AD player when AdLib is selected. This fixes sound effects in those
+ // games (see for example bug #2027877 "INDY3: Non-Looping Sound
+ // Effects"). The player itself is also used in Monkey Island DOS
+ // EGA/VGA. However, we support multi MIDI for that game and we cannot
+ // support this with the Player_AD code at the moment. The reason here
+ // is that multi MIDI is supported internally by our iMuse output.
+ _musicEngine = new Player_AD(this, _mixer);
} else if (_game.version >= 3 && _game.heversion <= 62) {
MidiDriver *nativeMidiDriver = 0;
MidiDriver *adlibMidiDriver = 0;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index a77c1c0141..ca05c90936 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -240,6 +240,7 @@ enum ScummGameId {
GID_FBEAR,
GID_PUTTMOON,
GID_FUNPACK,
+ GID_PUTTZOO,
GID_FREDDI3,
GID_BIRTHDAYRED,
GID_BIRTHDAYYELLOW,
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 3f6290f8fc..5e5e8045b5 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -1930,7 +1930,6 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) {
// 8 bytes MTrk header
// 7 bytes MIDI tempo sysex
// + some default instruments
- byte *ptr;
if (_game.features & GF_OLD_BUNDLE) {
ad_size -= 4;
_fileHandle->seek(ad_offs + 4, SEEK_SET);
@@ -1938,10 +1937,17 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) {
ad_size -= 6;
_fileHandle->seek(ad_offs, SEEK_SET);
}
- ptr = (byte *) calloc(ad_size, 1);
- _fileHandle->read(ptr, ad_size);
- convertADResource(_res, _game, idx, ptr, ad_size);
- free(ptr);
+ // For games using AD except Indy3 and Loom we are using our iMuse
+ // implementation. See output initialization in
+ // ScummEngine::setupMusic for more information.
+ if (_game.id != GID_INDY3 && _game.id != GID_LOOM) {
+ byte *ptr = (byte *)calloc(ad_size, 1);
+ _fileHandle->read(ptr, ad_size);
+ convertADResource(_res, _game, idx, ptr, ad_size);
+ free(ptr);
+ } else {
+ _fileHandle->read(_res->createResource(rtSound, idx, ad_size), ad_size);
+ }
return 1;
} else if (ro_offs != 0) {
_fileHandle->seek(ro_offs - 2, SEEK_SET);
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 77c7daa0df..9c90d7575d 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -714,6 +714,12 @@ void ScummEngine_v99he::resetScummVars() {
VAR(140) = 0;
#endif
}
+
+ if (_game.id == GID_PUTTZOO && _game.heversion == 100 && _game.platform == Common::kPlatformWindows) {
+ // Specific to Nimbus Games version.
+ VAR(156) = 1;
+ VAR(157) = 0;
+ }
}
#endif
diff --git a/engines/sword25/gfx/microtiles.cpp b/engines/sword25/gfx/microtiles.cpp
index 8dceed5348..18e4a9a1fb 100644
--- a/engines/sword25/gfx/microtiles.cpp
+++ b/engines/sword25/gfx/microtiles.cpp
@@ -119,7 +119,6 @@ RectangleList *MicroTileArray::getRectangles() {
for (y = 0; y < _tilesH; ++y) {
for (x = 0; x < _tilesW; ++x) {
- int start;
int finish = 0;
BoundingBox boundingBox = _tiles[i];
@@ -132,8 +131,6 @@ RectangleList *MicroTileArray::getRectangles() {
y0 = (y * TileSize) + TileY0(boundingBox);
y1 = (y * TileSize) + TileY1(boundingBox);
- start = i;
-
if (TileX1(boundingBox) == TileSize - 1 && x != _tilesW - 1) { // check if the tile continues
while (!finish) {
++x;
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index 590e6c6d81..26e073d407 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -927,17 +927,29 @@ TestExitStatus GFXtests::overlayGraphics() {
Graphics::PixelFormat pf = g_system->getOverlayFormat();
- OverlayColor buffer[50 * 100];
- OverlayColor value = pf.RGBToColor(0, 255, 0);
+ byte *buffer = new byte[50 * 100 * pf.bytesPerPixel];
+ const uint32 value = pf.RGBToColor(0, 255, 0);
- for (int i = 0; i < 50 * 100; i++) {
- buffer[i] = value;
+ if (pf.bytesPerPixel == 2) {
+ uint16 *dst = (uint16 *)buffer;
+ for (int i = 50 * 100; i > 0; --i) {
+ *dst++ = value;
+ }
+ } else if (pf.bytesPerPixel == 4) {
+ uint32 *dst = (uint32 *)buffer;
+ for (int i = 50 * 100; i > 0; --i) {
+ *dst++ = value;
+ }
+ } else {
+ error("GFXtests::overlayGraphics: Unsupported color depth: %d", pf.bytesPerPixel);
}
g_system->showOverlay();
- g_system->copyRectToOverlay(buffer, 200, 270, 175, 100, 50);
+ g_system->copyRectToOverlay(buffer, 100 * pf.bytesPerPixel, 270, 175, 100, 50);
g_system->updateScreen();
+ delete[] buffer;
+
g_system->delayMillis(1000);
g_system->hideOverlay();
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index a945672da2..cc8166f295 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -478,6 +478,26 @@ static const TinselGameDescription gameDescriptions[] = {
},
#endif
+ { // Mac English CD, see tracker #3614864
+ {
+ "dw",
+ "CD",
+ {
+ {"dw.scn", 0, "114643df0d1f1530a0a9c5d4e38917bc", 1268553},
+ {"english.smp", 0, NULL, -1},
+ {NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_CD,
+ GUIO0()
+ },
+ GID_DW1,
+ 0,
+ GF_SCNFILES | GF_ENHANCED_AUDIO_SUPPORT,
+ TINSEL_V1,
+ },
+
{ // Mac multilanguage CD
{
"dw",
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index c5652f0c8d..380f4a3a26 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -73,6 +73,20 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
{
+ // 3 Skulls of the Toltecs English version (alternate)
+ // From bug #3614933
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "a9c9cfef9d05b8f7a5573b626fa4ea87", 337643527),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
+ {
// 3 Skulls of the Toltecs Russian version
{
"toltecs",
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 3aef18f4f0..63f84d25e1 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -678,7 +678,7 @@ void FocusObject::process(Event &event) {
BF_GLOBALS._events.setCursor(BF_GLOBALS._events.getCursor());
if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) &&
- (event.btnState == 3)) {
+ (event.btnState == BTNSHIFT_RIGHT)) {
BF_GLOBALS._events.setCursor(CURSOR_USE);
event.handled = true;
}
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index 95598babc6..f1f00599e0 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -888,6 +888,7 @@ void Scene60::Action1::signal() {
break;
case 4:
remove();
+ break;
case 5:
setDelay(120);
break;
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index 9f1e9ce36e..d26e34ae23 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -2649,7 +2649,7 @@ void Scene160::Action2::signal() {
}
void Scene160::Action2::process(Event &event) {
- if ((event.handled) || (event.eventType == 5))
+ if ((event.handled) || ((event.eventType != EVENT_BUTTON_DOWN) && (event.eventType != EVENT_KEYPRESS)))
return;
if (_actionIndex == 25) {
@@ -3237,7 +3237,7 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.disableControl();
- // Initialise objects
+ // Initialize objects
_door.postInit();
_door.setVisage(190);
_door.setStrip(1);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index abadc4300a..0cf487daa9 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes5.cpp
@@ -1220,7 +1220,7 @@ void Scene560::SafeInset::process(Event &event) {
}
if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) &&
- (event.btnState == 3)) {
+ (event.btnState == BTNSHIFT_RIGHT)) {
BF_GLOBALS._events.setCursor(CURSOR_USE);
event.handled = true;
}
@@ -1459,7 +1459,7 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_lamp.setDetails(Rect(197, 43, 214, 56), 560, 7, 19, 30, 1, NULL);
_item4.setDetails(Rect(121, 18, 156, 54), 560, 8, 20, 31, 1, NULL);
_trophy.setDetails(Rect(259, 52, 275, 63), 560, 10, 22, 33, 1, NULL);
- _watercolours.setDetails(Rect(214, 48, 239, 64), 560, 12, 24, 35, 1, NULL);
+ _waterColors.setDetails(Rect(214, 48, 239, 64), 560, 12, 24, 35, 1, NULL);
_fileCabinets.setDetails(Rect(0, 47, 49, 100), 560, 14, 26, 37, 1, NULL);
_certificate.setDetails(Rect(280, 51, 292, 62), 560, 11, 23, 34, 1, NULL);
_bookcase.setDetails(Rect(176, 0, 319, 103), 560, 9, 21, 32, 1, NULL);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 73d323fc54..56bf20c93b 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.h
+++ b/engines/tsage/blue_force/blueforce_scenes5.h
@@ -225,7 +225,7 @@ public:
NamedObject _object6;
PicturePart _picture1, _picture2, _picture3, _picture4;
Computer _computer;
- NamedHotspot _chair, _lamp, _item4, _trophy, _watercolours, _fileCabinets;
+ NamedHotspot _chair, _lamp, _item4, _trophy, _waterColors, _fileCabinets;
NamedHotspot _certificate, _bookcase, _desk, _carpet, _item12, _office;
ASound _sound1;
bool _field380;
diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp
index 5a60cd7c5e..9a20788b6a 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes8.cpp
@@ -1984,7 +1984,7 @@ void Scene840::BoatKeysInset::process(Event &event) {
CursorType cursorId = BF_GLOBALS._events.getCursor();
BF_GLOBALS._events.setCursor(cursorId);
- if ((event.eventType == EVENT_BUTTON_DOWN) && (cursorId == CURSOR_WALK) && (event.btnState == 3)) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (cursorId == CURSOR_WALK) && (event.btnState == BTNSHIFT_RIGHT)) {
BF_GLOBALS._events.setCursor(CURSOR_USE);
event.handled = true;
}
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index 753a835389..9828ca71d4 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -707,7 +707,7 @@ void StripManager::synchronize(Serializer &s) {
for (int i = 0; i < arrSize; ++i)
_obj44List[i].synchronize(s);
- // Synhcronise script data
+ // Synchronize script data
int scriptSize = _script.size();
s.syncAsUint16LE(scriptSize);
if (s.isLoading())
@@ -754,6 +754,9 @@ void StripManager::remove() {
if (_onEnd)
_onEnd();
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endHandler = NULL;
+
Action::remove();
}
@@ -855,6 +858,11 @@ void StripManager::signal() {
++obj44Idx;
if (_obj44List[obj44Idx]._field16[0]) {
+ // WORKAROUND: The _lookupList isn't always correctly initialized. But it always
+ // seems to be set to the R2_GLOBALS._stripManager_lookupList, so manually set it
+ if (!_lookupList)
+ _lookupList = R2_GLOBALS._stripManager_lookupList;
+
int f16Index = _lookupList[_obj44List[obj44Idx]._field16[0] - 1];
listId = _obj44List[obj44Idx]._field16[f16Index];
@@ -865,13 +873,16 @@ void StripManager::signal() {
choiceStr = (const char *)&_script[0] + _obj44List[obj44Idx]._list[listIdx]._scriptOffset;
} else {
- for (int listIdx = 0; listIdx < OBJ0A_LIST_SIZE; ++listIdx) {
+ for (int listIdx = idx; listIdx < (OBJ0A_LIST_SIZE - 1); ++listIdx) {
obj44._list[listIdx]._id = obj44._list[listIdx + 1]._id;
obj44._list[listIdx]._scriptOffset = obj44._list[listIdx + 1]._scriptOffset;
if (!obj44._list[listIdx + 1]._id)
obj44._list[listIdx]._id = 0;
}
+
+ --idx;
+ continue;
}
}
}
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index 6b4e2963a5..055005808c 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -1179,7 +1179,7 @@ void PaletteRotation::signal() {
int count = _end - _currIndex;
g_system->getPaletteManager()->setPalette((const byte *)&_palette[_currIndex * 3], _start, count);
- if (count2) {
+ if (count2 > 0) {
g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start * 3], _start + count, count2);
}
}
@@ -2111,8 +2111,13 @@ int SceneObject::getFrameCount() {
void SceneObject::animEnded() {
_animateMode = ANIM_MODE_NONE;
- if (_endAction)
- _endAction->signal();
+ if (_endAction) {
+ Action *endAction = _endAction;
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endAction = NULL;
+
+ endAction->signal();
+ }
}
int SceneObject::changeFrame() {
@@ -3262,6 +3267,7 @@ void Player::postInit(SceneObjectList *OwnerList) {
_moveDiff.y = 2;
_effect = 1;
_shade = 0;
+ _linkedActor = NULL;
setObjectWrapper(new SceneObjectWrapper());
setPosition(_characterPos[_characterIndex]);
@@ -3992,7 +3998,7 @@ int WalkRegions::indexOf(const Common::Point &pt, const Common::List<int> *index
}
void WalkRegions::synchronize(Serializer &s) {
- // Synchronise the list of disabled regions as a list of values terminated with a '-1'
+ // Synchronize the list of disabled regions as a list of values terminated with a '-1'
int regionId = 0;
if (s.isLoading()) {
_disabledRegions.clear();
@@ -4242,9 +4248,10 @@ void SceneHandler::process(Event &event) {
// Scan the item list to find one the mouse is within
SynchronizedList<SceneItem *>::iterator i;
for (i = g_globals->_sceneItems.begin(); i != g_globals->_sceneItems.end(); ++i) {
- if ((*i)->contains(event.mousePos)) {
+ SceneItem *item = *i;
+ if (item->contains(event.mousePos)) {
// Pass the action to the item
- bool handled = (*i)->startAction(g_globals->_events.getCursor(), event);
+ bool handled = item->startAction(g_globals->_events.getCursor(), event);
if (!handled)
// Item wasn't handled, keep scanning
continue;
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 5ca531fdb9..ac6ce0bf8e 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -113,7 +113,7 @@ bool EventsClass::getEvent(Event &evt, int eventMask) {
case Common::EVENT_RBUTTONUP:
case Common::EVENT_MBUTTONUP:
evt.eventType = EVENT_BUTTON_UP;
- evt.btnState = 0;
+ evt.btnState = BTNSHIFT_LEFT;
break;
case Common::EVENT_KEYDOWN:
evt.eventType = EVENT_KEYPRESS;
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 5c4fa967e5..3ca54d67a9 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -26,6 +26,7 @@
#include "tsage/ringworld/ringworld_demo.h"
#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/staticres.h"
namespace TsAGE {
@@ -380,6 +381,9 @@ void Ringworld2Globals::reset() {
if (!_scannerDialog)
_scannerDialog = new ScannerDialog();
+ // Default to Quinn as the active character
+ T2_GLOBALS._player._characterIndex = R2_QUINN;
+
// Reset the inventory
R2_INVENTORY.reset();
T2_GLOBALS._uiElements.updateInventory();
@@ -389,7 +393,7 @@ void Ringworld2Globals::reset() {
_scrollFollower = &_player;
// Reset fields
- Common::fill(&_fadePaletteMap[0][0], &_fadePaletteMap[10][256], 0);
+ Common::fill(&_fadePaletteMap[0][0], &_fadePaletteMap[9][256], 0);
Common::fill(&_paletteMap[0], &_paletteMap[4096], 0);
_fadePaletteFlag = false;
@@ -404,25 +408,24 @@ void Ringworld2Globals::reset() {
_v565E7 = 0;
_v565E9 = -5;
_v565EB = 26;
- _v565F5 = 0;
- _v565F6 = 0;
- _v565F8 = 0;
- _v565FA = 0;
+ _foodCount = 0;
+ _rimLocation = 0;
+ _rimTransportLocation = 0;
_v565AE = 0;
- _v56605[0] = 0;
- _v56605[1] = 3;
- _v56605[2] = 5;
- _v56605[3] = 1;
- _v56605[4] = 2;
- _v56605[5] = 5;
- _v56605[6] = 9;
- _v56605[7] = 14;
- _v56605[8] = 15;
- _v56605[9] = 18;
- _v56605[10] = 20;
- _v56605[11] = 25;
- _v56605[12] = 27;
- _v56605[13] = 31;
+ _spillLocation[0] = 0;
+ _spillLocation[1] = 3;
+ _spillLocation[R2_SEEKER] = 5;
+ _spillLocation[3] = 1;
+ _spillLocation[4] = 2;
+ _spillLocation[5] = 5;
+ _spillLocation[6] = 9;
+ _spillLocation[7] = 14;
+ _spillLocation[8] = 15;
+ _spillLocation[9] = 18;
+ _spillLocation[10] = 20;
+ _spillLocation[11] = 25;
+ _spillLocation[12] = 27;
+ _spillLocation[13] = 31;
for (int i = 0; i < 18; i++) {
_v56613[(i * 4) ] = 1;
@@ -449,7 +452,7 @@ void Ringworld2Globals::reset() {
_v56613[(17 * 4) + 1] = 1;
_v566A6 = 3800;
- _v566A3 = 2;
+ _landerSuitNumber = 2;
_v566A4 = 1;
_v566A5 = 0;
_v566A8 = 5;
@@ -475,15 +478,12 @@ void Ringworld2Globals::reset() {
_v5780E = 0;
_v57810 = 0;
_v57C2C = 0;
- _v565EC[0] = 0;
- _v565EC[1] = 27;
- _v565EC[2] = 27;
- _v565EC[3] = 4;
- _v565EC[4] = 4;
+ _s1550PlayerArea[R2_QUINN] = Common::Point(27, 4);
+ _s1550PlayerArea[R2_SEEKER] = Common::Point(27, 4);
Common::fill(&_scannerFrequencies[0], &_scannerFrequencies[MAX_CHARACTERS], 1);
_speechSubtitles = SPEECH_VOICE | SPEECH_TEXT;
_insetUp = 0;
- _frameEdgeColour = 2;
+ _frameEdgeColor = 2;
Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
_stripManager_lookupList[0] = 1;
_stripManager_lookupList[1] = 1;
@@ -496,10 +496,14 @@ void Ringworld2Globals::reset() {
_stripManager_lookupList[10] = 1;
_stripManager_lookupList[11] = 1;
+ // Reset junk/component data in scene 1550
+ Common::copy(&scene1550JunkLocationsDefault[0], &scene1550JunkLocationsDefault[508],
+ &_scene1550JunkLocations[0]);
+
// Reset fields stored in the player class
_player._characterIndex = R2_QUINN;
- _player._characterScene[1] = 100;
- _player._characterScene[2] = 300;
+ _player._characterScene[R2_QUINN] = 100;
+ _player._characterScene[R2_SEEKER] = 300;
_player._characterScene[3] = 300;
}
@@ -519,11 +523,10 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v565E7);
s.syncAsSint16LE(_v565E9);
s.syncAsSint16LE(_v565EB);
- s.syncAsSint16LE(_v565F5);
- s.syncAsSint16LE(_v565F6);
- s.syncAsSint16LE(_v565F8);
- s.syncAsSint16LE(_v565FA);
- s.syncAsSint16LE(_v566A3);
+ s.syncAsSint16LE(_foodCount);
+ s.syncAsSint32LE(_rimLocation);
+ s.syncAsSint16LE(_rimTransportLocation);
+ s.syncAsSint16LE(_landerSuitNumber);
s.syncAsSint16LE(_v566A6);
s.syncAsSint16LE(_v56A93);
s.syncAsSint16LE(_scene1925CurrLevel); // _v56A9C
@@ -539,8 +542,12 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v57C2C);
s.syncAsSint16LE(_speechSubtitles);
- for (i = 0; i < 5; i++)
- s.syncAsByte(_v565EC[i]);
+ byte temp;
+ s.syncAsByte(temp);
+ s.syncAsByte(_s1550PlayerArea[R2_QUINN].x);
+ s.syncAsByte(_s1550PlayerArea[R2_SEEKER].x);
+ s.syncAsByte(_s1550PlayerArea[R2_QUINN].y);
+ s.syncAsByte(_s1550PlayerArea[R2_SEEKER].y);
for (i = 0; i < MAX_CHARACTERS; ++i)
s.syncAsByte(_scannerFrequencies[i]);
@@ -558,7 +565,7 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsByte(_v56AA8);
for (i = 0; i < 14; ++i)
- s.syncAsByte(_v56605[i]);
+ s.syncAsByte(_spillLocation[i]);
for (i = 0; i < 1000; ++i)
s.syncAsByte(_v566AB[i]);
s.syncAsByte(_v56A99);
@@ -566,7 +573,10 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsByte(_stripManager_lookupList[i]);
s.syncAsSint16LE(_insetUp);
- s.syncAsByte(_frameEdgeColour);
+ s.syncAsByte(_frameEdgeColor);
+
+ for (i = 0; i < 508; i += 4)
+ s.syncAsByte(_scene1550JunkLocations[i + 2]);
}
} // end of namespace Ringworld2
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index ed27ff0556..9d4de26b91 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -242,11 +242,6 @@ namespace Ringworld2 {
#define SPEECH_TEXT 1
#define SPEECH_VOICE 2
-#define k5A78C 15
-#define k5A78D 16
-#define k5A790 18
-#define k5A791 17
-
class ScannerDialog;
class Ringworld2Globals: public TsAGE2Globals {
@@ -258,7 +253,7 @@ public:
byte _fadePaletteMap[10][256];
byte _paletteMap[4096];
int _insetUp;
- int _frameEdgeColour; // _v421e
+ int _frameEdgeColor; // _v421e
Rect _v5589E;
Rect _v558B6;
int _v558C2;
@@ -269,18 +264,17 @@ public:
int _v565E7;
int _v565E9;
int _v565EB;
- int _v565F5;
- int _v565F6;
- int _v565F8;
- int _v565FA;
+ int _foodCount;
+ int _rimLocation;
+ int _rimTransportLocation;
int _v5657C;
byte _v565AE;
- byte _v56605[14];
+ byte _spillLocation[14];
int _v56613[76];
byte _v566A4;
byte _v566A5;
int _v566A6;
- byte _v566A3;
+ byte _landerSuitNumber;
byte _v566A8;
byte _v566A9;
byte _v566AA;
@@ -304,9 +298,10 @@ public:
int _v57810;
int _v57C2C;
int _speechSubtitles;
- byte _v565EC[5];
+ Common::Point _s1550PlayerArea[3]; // only used for Quinn and Seeker
byte _scannerFrequencies[4];
byte _stripManager_lookupList[12];
+ byte _scene1550JunkLocations[508];
ScannerDialog *_scannerDialog;
Ringworld2Globals();
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 1815c3d751..2395cc67ed 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -806,20 +806,20 @@ void GfxElement::drawFrame() {
*((byte *)surface.getBasePtr(tempRect.right - 1, tempRect.bottom - 1)) = 0;
// Inner frame border
- surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColour);
- surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColour);
- surface.vLine(tempRect.left + 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColour);
- surface.vLine(tempRect.right - 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColour);
- *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColour;
- *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColour;
- *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColour;
- *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColour;
+ surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
+ surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
+ surface.vLine(tempRect.left + 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor);
+ surface.vLine(tempRect.right - 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor);
+ *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor;
gfxManager.unlockSurface();
gfxManager.getSurface().addDirtyRect(tempRect);
} else {
- // Fill dialog content with specified background colour
+ // Fill dialog content with specified background color
gfxManager.fillRect(tempRect, _colors.background);
--tempRect.bottom; --tempRect.right;
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
index 57fdef6405..663697d94d 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
@@ -234,9 +234,9 @@ void CharacterDialog::show() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
scene->saveCharacter(oldCharacter);
- // Play a transition sound as the character is changed
+ // Play the correctfrequency, if any, of the character being switched to's scanner device
if (R2_GLOBALS._player._characterScene[0] != 300) {
- switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
R2_GLOBALS._sound4.stop();
break;
@@ -256,7 +256,7 @@ void CharacterDialog::show() {
break;
}
} else if (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] > 1) {
- switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -272,8 +272,8 @@ void CharacterDialog::show() {
default:
break;
}
- } else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._scannerFrequencies[1] != 1)) {
- switch (R2_GLOBALS._scannerFrequencies[1]) {
+ } else if ((R2_GLOBALS._player._characterScene[R2_QUINN] == 300) && (R2_GLOBALS._scannerFrequencies[1] != 1)) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -289,12 +289,12 @@ void CharacterDialog::show() {
default:
break;
}
- } else if (R2_GLOBALS._player._characterScene[2] != 300) {
+ } else if (R2_GLOBALS._player._characterScene[R2_SEEKER] != 300) {
R2_GLOBALS._sound4.stop();
} else if (R2_GLOBALS._scannerFrequencies[2] == 1) {
R2_GLOBALS._sound4.stop();
} else {
- switch (R2_GLOBALS._scannerFrequencies[1]) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index f1f9f9fe5a..98e455b41b 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -133,6 +133,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Elevator
return new Scene1530();
case 1550:
+ // Spaceport
return new Scene1550();
case 1575:
return new Scene1575();
@@ -143,16 +144,22 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Miranda being questioned
return new Scene1625();
case 1700:
+ // Rim
return new Scene1700();
case 1750:
+ // Rim Transport Vechile
return new Scene1750();
case 1800:
+ // Rim Lift Exterior
return new Scene1800();
case 1850:
+ // Rim Lift Interior
return new Scene1850();
case 1875:
+ // Rim Lift Computer
return new Scene1875();
case 1900:
+ // Spill Mountains Elevator Exit
return new Scene1900();
case 1925:
return new Scene1925();
@@ -163,49 +170,49 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
/* Scene group #2 */
//
case 2000:
- // Ice Maze
+ // Spill Mountains
return new Scene2000();
case 2350:
- // Ice Maze: Balloon Launch Platform
+ // Spill Mountains: Balloon Launch Platform
return new Scene2350();
case 2400:
- // Ice Maze: Large empty room
+ // Spill Mountains: Large empty room
return new Scene2400();
case 2425:
- // Ice Maze: The Hall of Records
+ // Spill Mountains: The Hall of Records
return new Scene2425();
case 2430:
- // Ice Maze: Bedroom
+ // Spill Mountains: Bedroom
return new Scene2430();
case 2435:
- // Ice Maze: Throne room
+ // Spill Mountains: Throne room
return new Scene2435();
case 2440:
- // Ice Maze: Another bedroom
+ // Spill Mountains: Another bedroom
return new Scene2440();
case 2445:
- // Ice Maze:
+ // Spill Mountains:
return new Scene2445();
case 2450:
- // Ice Maze: Another bedroom
+ // Spill Mountains: Another bedroom
return new Scene2450();
case 2455:
- // Ice Maze: Inside crevasse
+ // Spill Mountains: Inside crevasse
return new Scene2455();
case 2500:
- // Ice Maze: Large Cave
+ // Spill Mountains: Large Cave
return new Scene2500();
case 2525:
- // Ice Maze: Furnace room
+ // Spill Mountains: Furnace room
return new Scene2525();
case 2530:
- // Ice Maze: Well
+ // Spill Mountains: Well
return new Scene2530();
case 2535:
- // Ice Maze: Tannery
+ // Spill Mountains: Tannery
return new Scene2535();
case 2600:
- // Ice Maze: Exit
+ // Spill Mountains: Exit
return new Scene2600();
case 2700:
// Forest Maze
@@ -318,11 +325,10 @@ SceneExt::SceneExt(): Scene() {
for (int i = 0; i < 256; i++)
_field312[i] = 0;
- _field372 = _field37A = 0;
+
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
- _focusObject = NULL;
// WORKAROUND: In the original, playing animations don't reset the global _animationCtr
// counter as scene changes unless the playing animation explicitly finishes. For now,
@@ -331,13 +337,20 @@ SceneExt::SceneExt(): Scene() {
R2_GLOBALS._animationCtr = 0;
}
+void SceneExt::synchronize(Serializer &s) {
+ Scene::synchronize(s);
+
+ s.syncBytes(&_field312[0], 256);
+ _sceneAreas.synchronize(s);
+}
+
void SceneExt::postInit(SceneObjectList *OwnerList) {
Scene::postInit(OwnerList);
// Exclude the bottom area of the screen to allow room for the UI
T2_GLOBALS._interfaceY = UI_INTERFACE_Y;
- // Initialise fields
+ // Initialize fields
_action = NULL;
_field12 = 0;
_sceneMode = 0;
@@ -358,6 +371,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
void SceneExt::remove() {
_sceneAreas.clear();
Scene::remove();
+ R2_GLOBALS._uiElements._active = true;
}
void SceneExt::process(Event &event) {
@@ -382,27 +396,6 @@ void SceneExt::dispatch() {
Scene::dispatch();
}
-void SceneExt::loadScene(int sceneNum) {
- Scene::loadScene(sceneNum);
-
- _v51C34.top = 0;
- _v51C34.bottom = 300;
-
- int prevScene = R2_GLOBALS._sceneManager._previousScene;
- int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
-
- if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50)) ||
- (sceneNumber == 50) || ((prevScene == 205) && (sceneNumber == 100)) ||
- ((prevScene == 180) && (sceneNumber == 100))) {
- // TODO: sub_17875
- R2_GLOBALS._uiElements._active = true;
- R2_GLOBALS._uiElements.show();
- } else {
- // Update the user interface
- R2_GLOBALS._uiElements.updateInventory();
- }
-}
-
bool SceneExt::display(CursorType action, Event &event) {
switch (action) {
case CURSOR_CROSSHAIRS:
@@ -464,7 +457,6 @@ void SceneExt::fadeOut() {
void SceneExt::startStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 1;
scene->_savedPlayerEnabled = R2_GLOBALS._player._enabled;
if (scene->_savedPlayerEnabled) {
@@ -480,7 +472,6 @@ void SceneExt::startStrip() {
void SceneExt::endStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 0;
if (scene->_savedPlayerEnabled) {
R2_GLOBALS._player.enableControl();
@@ -620,7 +611,7 @@ void SceneHandlerExt::postLoad(int priorSceneBeforeLoad, int currentSceneBeforeL
R2_GLOBALS._gfxColors.foreground = 59;
R2_GLOBALS._fontColors.background = 4;
R2_GLOBALS._fontColors.foreground = 15;
- R2_GLOBALS._frameEdgeColour = 2;
+ R2_GLOBALS._frameEdgeColor = 2;
R2_GLOBALS._scenePalette.loadPalette(0);
R2_GLOBALS._scenePalette.setEntry(255, 0xff, 0xff, 0xff);
@@ -664,7 +655,7 @@ void SceneHandlerExt::setupPaletteMaps() {
break;
}
- // Scan for the palette index with the closest matching colour
+ // Scan for the palette index with the closest matching color
int threshold = 769;
int foundIndex = -1;
for (int pIndex2 = 223; pIndex2 >= 0; --pIndex2) {
@@ -970,7 +961,8 @@ void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
R2_GLOBALS._events.setCursor(CURSOR_USE);
// Update the user interface if necessary
- T2_GLOBALS._uiElements.updateInventory();
+ T2_GLOBALS._uiElements.updateInventory(
+ (sceneNumber == R2_GLOBALS._player._characterIndex) ? objectNum : 0);
}
/**
@@ -1324,7 +1316,7 @@ GfxSurface SceneActor::getFrame() {
/*--------------------------------------------------------------------------*/
-SceneArea::SceneArea(): EventHandler() {
+SceneArea::SceneArea(): SceneItem() {
_enabled = true;
_insideArea = false;
_savedCursorNum = CURSOR_NONE;
@@ -1337,8 +1329,8 @@ void SceneArea::synchronize(Serializer &s) {
_bounds.synchronize(s);
s.syncAsSint16LE(_enabled);
s.syncAsSint16LE(_insideArea);
- s.syncAsSint16LE(_cursorNum);
- s.syncAsSint16LE(_savedCursorNum);
+ s.syncAsSint32LE(_cursorNum);
+ s.syncAsSint32LE(_savedCursorNum);
s.syncAsSint16LE(_cursorState);
}
@@ -1428,6 +1420,7 @@ void SceneExit::process(Event &event) {
/*--------------------------------------------------------------------------*/
void SceneAreaObject::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
_object1.remove();
SceneArea::remove();
--R2_GLOBALS._insetUp;
@@ -1437,19 +1430,22 @@ void SceneAreaObject::process(Event &event) {
if (_insetCount == R2_GLOBALS._insetUp) {
CursorType cursor = R2_GLOBALS._events.getCursor();
- if (_bounds.contains(event.mousePos)) {
+ if (_object1._bounds.contains(event.mousePos)) {
// Cursor moving in bounded area
if (cursor == _cursorNum) {
R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
- if (_cursorNum != cursor)
+ if (_cursorNum != cursor) {
// Cursor moved outside bounded area
- R2_GLOBALS._events.setCursor(_savedCursorNum);
-
+ _savedCursorNum = R2_GLOBALS._events.getCursor();
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+
if (event.eventType == EVENT_BUTTON_DOWN) {
- R2_GLOBALS._events.setCursor(_savedCursorNum);
event.handled = true;
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ remove();
}
}
}
@@ -1469,7 +1465,7 @@ void SceneAreaObject::setDetails(int visage, int strip, int frameNumber, const C
}
void SceneAreaObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- ((SceneHotspot *)(this))->setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
+ _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
2, (SceneItem *)NULL);
}
@@ -1881,7 +1877,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
default:
// ANIMPALMODE_CURR_PALETTE
- // Use the closest matching colours in the currently active palette to those specified in the animation
+ // Use the closest matching colors in the currently active palette to those specified in the animation
for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
byte r = _subData._palData[idx * 3];
byte g = _subData._palData[idx * 3 + 1];
@@ -2269,21 +2265,21 @@ void ScannerDialog::Button::reset() {
scanner._obj5.postInit();
scanner._obj5.setup(4, 4, 1);
- scanner._obj5.setPosition(Common::Point(R2_GLOBALS._v565EC[1] + 145,
- R2_GLOBALS._v565EC[3] + 59));
+ scanner._obj5.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_QUINN].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN].y + 59));
scanner._obj5.fixPriority(257);
scanner._obj6.postInit();
scanner._obj6.setup(4, 4, 2);
- scanner._obj6.setPosition(Common::Point(R2_GLOBALS._v565EC[2] + 145,
- R2_GLOBALS._v565EC[4] + 59));
+ scanner._obj6.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_SEEKER].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER].y + 59));
scanner._obj6.fixPriority(257);
break;
case 1700:
case 1800:
- if (R2_GLOBALS._v565F8 < 0 || (R2_GLOBALS._v565F8 == 0 && R2_GLOBALS._v565F6 < 1201))
+ if (R2_GLOBALS._rimLocation < 1201)
scanner._obj4.setup(4, 3, 3);
- else if (R2_GLOBALS._v565F8 > 0 || (R2_GLOBALS._v565F8 == 0 && R2_GLOBALS._v565F6 < 1201))
+ else if (R2_GLOBALS._rimLocation < 1201)
scanner._obj4.setup(4, 3, 4);
else
scanner._obj4.setup(4, 3, 5);
@@ -2416,7 +2412,7 @@ void ScannerDialog::remove() {
switch (R2_GLOBALS._sceneManager._sceneNumber) {
case 1550:
case 1700:
- R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_ARROW : CURSOR_USE);
+ R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
break;
case 3800:
case 3900: {
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index 1b4b7fca1f..c7e36fc5f0 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -42,9 +42,8 @@ public:
static Scene *createScene(int sceneNumber);
};
-class SceneArea: public EventHandler {
+class SceneArea: public SceneItem {
public:
- Rect _bounds;
bool _enabled;
bool _insideArea;
CursorType _cursorNum;
@@ -54,9 +53,12 @@ public:
SceneArea();
void setDetails(const Rect &bounds, CursorType cursor);
+ virtual Common::String getClassName() { return "SceneArea"; }
virtual void synchronize(Serializer &s);
virtual void remove();
virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event) { return false; }
+ virtual void doAction(int action) {}
};
class SceneExit: public SceneArea {
@@ -80,26 +82,21 @@ private:
static void endStrip();
public:
byte _field312[256];
- int _field372;
bool _savedPlayerEnabled;
bool _savedUiEnabled;
bool _savedCanWalk;
- int _field37A;
- SceneObject *_focusObject;
Visage _cursorVisage;
SynchronizedList<EventHandler *> _sceneAreas;
-
- Rect _v51C34;
public:
SceneExt();
virtual Common::String getClassName() { return "SceneExt"; }
+ virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void process(Event &event);
virtual void dispatch();
- virtual void loadScene(int sceneNum);
virtual void refreshBackground(int xAmount, int yAmount);
virtual void saveCharacter(int characterIndex);
virtual void restore() {}
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index 8d35fc7222..40e17b6ed9 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -392,11 +392,11 @@ void Scene100::dispatch() {
*
*--------------------------------------------------------------------------*/
-bool Scene125::Object5::startAction(CursorType action, Event &event) {
+bool Scene125::Food::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE)
return true;
- else
- return SceneActor::startAction(action, event);
+
+ return SceneActor::startAction(action, event);
}
/*--------------------------------------------------------------------------*/
@@ -577,7 +577,7 @@ bool Scene125::DiskSlot::startAction(CursorType action, Event &event) {
Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[1]) {
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[R2_QUINN]) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 126;
scene->setAction(&scene->_sequenceManager, scene, 126, &scene->_infoDisk, NULL);
@@ -619,21 +619,21 @@ void Scene125::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene != 125)
// Save the prior scene to return to when the console is turned off
- R2_GLOBALS._player._oldCharacterScene[1] = R2_GLOBALS._sceneManager._previousScene;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = R2_GLOBALS._sceneManager._previousScene;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[1]) {
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._player._oldCharacterScene[R2_QUINN]) {
_infoDisk.postInit();
_infoDisk.setup(160, 3, 5);
_infoDisk.setPosition(Common::Point(47, 167));
}
- _object6.postInit();
- _object6.setup(162, 1, 1);
- _object6.setPosition(Common::Point(214, 168));
+ _foodDispenser.postInit();
+ _foodDispenser.setup(162, 1, 1);
+ _foodDispenser.setPosition(Common::Point(214, 168));
_diskSlot.setDetails(Rect(27, 145, 81, 159), 126, 9, -1, -1, 1, NULL);
_item3.setDetails(Rect(144, 119, 286, 167), 126, 6, 7, 8, 1, NULL);
@@ -656,8 +656,8 @@ void Scene125::signal() {
_icon4.postInit();
_icon4._sceneRegionId = 5;
- _sceneMode = 2;
setAction(&_sequenceManager, this, 127, &_icon1, &_icon2, &_icon3, &_icon4, &R2_GLOBALS._player, NULL);
+ _sceneMode = 2;
break;
case 2:
_icon1.setup(160, 1, 1);
@@ -698,7 +698,7 @@ void Scene125::signal() {
_icon6._sceneRegionId = 8;
consoleAction(5);
- R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 10:
@@ -781,7 +781,7 @@ void Scene125::signal() {
}
break;
case 125:
- R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldCharacterScene[1]);
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, R2_GLOBALS._player._oldCharacterScene[R2_QUINN]);
R2_GLOBALS._player.enableControl();
break;
case 126:
@@ -883,7 +883,7 @@ void Scene125::consoleAction(int id) {
_icon2.setIcon(23);
break;
case 6:
- R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldCharacterScene[1]);
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldCharacterScene[R2_QUINN]);
break;
case 7:
if (_consoleMode == 11)
@@ -946,7 +946,7 @@ void Scene125::consoleAction(int id) {
break;
case 13:
consoleAction(2);
- if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldCharacterScene[1]) {
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldCharacterScene[R2_QUINN]) {
SceneItem::display2(126, 17);
} else {
R2_GLOBALS._player.disableControl();
@@ -971,14 +971,17 @@ void Scene125::consoleAction(int id) {
case 15:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 3) {
+ if (R2_GLOBALS._foodCount < 3) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 2);
- _object5.setPosition(Common::Point(216, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 2);
+ _food.setPosition(Common::Point(216, UI_INTERFACE_Y));
- R2_GLOBALS._v565F5 += 2;
- } else if (R2_GLOBALS._v565F5 == 3) {
+ R2_GLOBALS._foodCount += 2;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
+ } else if (R2_GLOBALS._foodCount == 3) {
SceneItem::display2(126, 13);
} else {
SceneItem::display2(126, 14);
@@ -987,13 +990,16 @@ void Scene125::consoleAction(int id) {
case 16:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 4) {
+ if (R2_GLOBALS._foodCount < 4) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 3);
- _object5.setPosition(Common::Point(218, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 3);
+ _food.setPosition(Common::Point(218, UI_INTERFACE_Y));
- ++R2_GLOBALS._v565F5;
+ ++R2_GLOBALS._foodCount;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 15);
}
@@ -1001,13 +1007,16 @@ void Scene125::consoleAction(int id) {
case 17:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 4) {
+ if (R2_GLOBALS._foodCount < 4) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 1);
- _object5.setPosition(Common::Point(215, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 1);
+ _food.setPosition(Common::Point(215, UI_INTERFACE_Y));
- ++R2_GLOBALS._v565F5;
+ ++R2_GLOBALS._foodCount;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 16);
}
@@ -1924,7 +1933,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 4;
R2_GLOBALS._gfxColors.background = 3;
R2_GLOBALS._fontColors.background = 3;
- R2_GLOBALS._frameEdgeColour = 3;
+ R2_GLOBALS._frameEdgeColor = 3;
break;
case 1:
@@ -1933,7 +1942,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 25;
R2_GLOBALS._gfxColors.background = 43;
R2_GLOBALS._fontColors.background = 48;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 2:
@@ -1943,7 +1952,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.background = 136;
R2_GLOBALS._fontColors.background = 48;
R2_GLOBALS._fontColors.foreground = 253;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 3:
@@ -1952,7 +1961,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 84;
R2_GLOBALS._gfxColors.background = 118;
R2_GLOBALS._fontColors.background = 47;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 14:
@@ -1962,7 +1971,7 @@ void Scene180::restore() {
R2_GLOBALS._fontColors.foreground = 38;
R2_GLOBALS._gfxColors.foreground = 192;
R2_GLOBALS._gfxColors.background = 30;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
default:
@@ -2026,7 +2035,7 @@ void Scene200::EastExit::changeScene() {
Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 206;
scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
}
@@ -2035,7 +2044,7 @@ void Scene200::WestExit::changeScene() {
Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 208;
scene->setAction(&scene->_sequenceManager, scene, 208, &R2_GLOBALS._player, NULL);
}
@@ -2480,14 +2489,13 @@ void Scene205::handleText() {
*--------------------------------------------------------------------------*/
Scene250::Button::Button(): SceneActor() {
- _floorNumber = _v2 = 0;
+ _floorNumber = 0;
}
void Scene250::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_floorNumber);
- s.syncAsSint16LE(_v2);
}
bool Scene250::Button::startAction(CursorType action, Event &event) {
@@ -2495,7 +2503,7 @@ bool Scene250::Button::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (scene->_field414) {
+ if (scene->_destButtonY) {
SceneItem::display2(250, 15);
} else {
switch (_floorNumber) {
@@ -2546,7 +2554,6 @@ bool Scene250::Button::startAction(CursorType action, Event &event) {
void Scene250::Button::setFloor(int floorNumber) {
SceneActor::postInit();
_floorNumber = floorNumber;
- _v2 = 0;
if (_floorNumber <= 9) {
SceneObject::setup(250, 1, 4);
@@ -2571,17 +2578,18 @@ void Scene250::Button::setFloor(int floorNumber) {
/*--------------------------------------------------------------------------*/
Scene250::Scene250(): SceneExt() {
- _field412 = _field414 = _field416 = _field418 = _field41A = 0;
+ _currButtonY = _destButtonY = _elevatorSpeed = 0;
+ _skippingFl = _skippableFl = false;
}
void Scene250::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
+ s.syncAsSint16LE(_currButtonY);
+ s.syncAsSint16LE(_destButtonY);
+ s.syncAsSint16LE(_elevatorSpeed);
+ s.syncAsSint16LE(_skippableFl);
+ s.syncAsSint16LE(_skippingFl);
}
void Scene250::postInit(SceneObjectList *OwnerList) {
@@ -2623,28 +2631,28 @@ void Scene250::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._sceneManager._previousScene) {
case 200:
- _field412 = 55;
+ _currButtonY = 55;
break;
case 300:
- _field412 = 43;
+ _currButtonY = 43;
break;
case 700:
- _field412 = 139;
+ _currButtonY = 139;
break;
case 850:
- _field412 = 91;
+ _currButtonY = 91;
break;
default:
R2_GLOBALS._sceneManager._previousScene = 200;
- _field412 = 55;
+ _currButtonY = 55;
break;
}
- _currentFloor.setPosition(Common::Point(111, _field412));
+ _currentFloor.setPosition(Common::Point(111, _currButtonY));
}
void Scene250::signal() {
- if (_field41A)
+ if (_skippingFl)
_sceneMode = 20;
switch (_sceneMode) {
@@ -2655,20 +2663,24 @@ void Scene250::signal() {
R2_GLOBALS._player.setPosition(Common::Point(261, 185));
ADD_MOVER(R2_GLOBALS._player, 261, 15);
- _field416 = 0;
+ _elevatorSpeed = 0;
_sceneMode = 2;
break;
case 2:
- _sceneMode = ((_field414 - 12) == _field412) ? 4 : 3;
+ if (_destButtonY - 12 == _currButtonY)
+ _sceneMode = 4;
+ else
+ _sceneMode = 3;
+
signal();
break;
case 3:
_currentFloor.setPosition(Common::Point(111, _currentFloor._position.y + 12));
- _field412 += 12;
+ _currButtonY += 12;
R2_GLOBALS._player.setPosition(Common::Point(261, 185));
ADD_MOVER(R2_GLOBALS._player, 261, 15);
- if ((_field414 - 12) == _field412)
+ if ((_destButtonY - 12) == _currButtonY)
_sceneMode = 4;
break;
case 4:
@@ -2690,12 +2702,12 @@ void Scene250::signal() {
R2_GLOBALS._player.setup(250, 1, 2);
R2_GLOBALS._player.setPosition(Common::Point(261, 15));
ADD_MOVER(R2_GLOBALS._player, 261, 185);
- _field416 = 0;
+ _elevatorSpeed = 0;
_sceneMode = 7;
break;
case 7:
- _field418 = 1;
- if ((_field414 + 12) == _field412)
+ _skippableFl = true;
+ if ((_destButtonY + 12) == _currButtonY)
_sceneMode = 9;
else
_sceneMode = 8;
@@ -2703,11 +2715,11 @@ void Scene250::signal() {
break;
case 8:
_currentFloor.setPosition(Common::Point(111, _currentFloor._position.y - 12));
- _field412 -= 12;
+ _currButtonY -= 12;
R2_GLOBALS._player.setPosition(Common::Point(261, 15));
ADD_MOVER(R2_GLOBALS._player, 261, 185);
- if ((_field414 + 12) == _field412)
+ if ((_destButtonY + 12) == _currButtonY)
_sceneMode = 9;
break;
case 9:
@@ -2723,7 +2735,7 @@ void Scene250::signal() {
break;
case 20:
// Handle changing scene
- switch (_field414) {
+ switch (_destButtonY) {
case 55:
R2_GLOBALS._sceneManager.changeScene(200);
break;
@@ -2746,12 +2758,13 @@ void Scene250::signal() {
}
void Scene250::changeFloor(int floorNumber) {
- _field414 = (floorNumber - 1) * 12 + 43;
- _button1.setPosition(Common::Point(111, _field414));
+ _destButtonY = (floorNumber - 1) * 12 + 43;
+ _button1.setPosition(Common::Point(111, _destButtonY));
_button1.show();
- _sceneMode = (_field412 >= _field414) ? 6 : 1;
- if (_field414 == _field412)
+ _skippableFl = true;
+ _sceneMode = (_currButtonY >= _destButtonY) ? 6 : 1;
+ if (_destButtonY == _currButtonY)
_sceneMode = 20;
signal();
@@ -2759,8 +2772,8 @@ void Scene250::changeFloor(int floorNumber) {
void Scene250::process(Event &event) {
if (!event.handled) {
- if (((event.eventType == EVENT_KEYPRESS) || (event.btnState != 0)) && _field418) {
- _field41A = 1;
+ if (((event.eventType == EVENT_KEYPRESS) || (event.btnState == BTNSHIFT_RIGHT)) && _skippableFl) {
+ _skippingFl = true;
event.handled = true;
}
@@ -2771,14 +2784,14 @@ void Scene250::process(Event &event) {
void Scene250::dispatch() {
SceneExt::dispatch();
- if (((_sceneMode == 2) || (_sceneMode == 7)) && (_field416 < 100)) {
- ++_field416;
- R2_GLOBALS._player._moveDiff.y = _field416 / 5;
+ if (((_sceneMode == 2) || (_sceneMode == 7)) && (_elevatorSpeed < 100)) {
+ ++_elevatorSpeed;
+ R2_GLOBALS._player._moveDiff.y = _elevatorSpeed / 5;
}
if (((_sceneMode == 5) || (_sceneMode == 10)) && (R2_GLOBALS._player._moveDiff.y > 4)) {
- --_field416;
- R2_GLOBALS._player._moveDiff.y = _field416 / 7 + 3;
+ --_elevatorSpeed;
+ R2_GLOBALS._player._moveDiff.y = (_elevatorSpeed / 7) + 3;
}
}
@@ -3142,7 +3155,7 @@ bool Scene300::Doorway::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) &&
- (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)) {
+ (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_SEEKER] == 500)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 301;
scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL);
@@ -3266,7 +3279,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_miranda.setAction(&_action3);
_miranda.setDetails(300, 39, 40, 41, 1, (SceneItem *)NULL);
- if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_SEEKER] == 300) || (R2_GLOBALS._player._characterScene[R2_SEEKER] == 325)) {
_seeker.postInit();
_seeker.setVisage(302);
_seeker.setPosition(Common::Point(158, 108));
@@ -3288,7 +3301,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_miranda.setAction(&_action3);
_miranda.setDetails(300, 39, 40, 41, 1, (SceneItem *)NULL);
- if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == 300) || (R2_GLOBALS._player._characterScene[R2_QUINN] == 325)) {
_quinn.postInit();
_quinn.setup(302, 3, 1);
_quinn.setPosition(Common::Point(271, 150));
@@ -3304,7 +3317,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
break;
case 3:
- if ((R2_GLOBALS._player._characterScene[2] == 300) || (R2_GLOBALS._player._characterScene[2] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_SEEKER] == 300) || (R2_GLOBALS._player._characterScene[R2_SEEKER] == 325)) {
_seeker.postInit();
_seeker.setVisage(302);
_seeker.setPosition(Common::Point(158, 108));
@@ -3313,7 +3326,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_seeker.setDetails(300, 42, 43, 44, 1, (SceneItem *)NULL);
}
- if ((R2_GLOBALS._player._characterScene[1] == 300) || (R2_GLOBALS._player._characterScene[1] == 325)) {
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == 300) || (R2_GLOBALS._player._characterScene[R2_QUINN] == 325)) {
_quinn.postInit();
_quinn.setup(302, 3, 1);
_quinn.setPosition(Common::Point(271, 150));
@@ -3559,7 +3572,7 @@ void Scene300::signal() {
break;
case 16:
- if (_stripManager._field2E8 == 1) {
+ if (_stripManager._exitMode == 1) {
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._sceneManager.changeScene(1000);
} else {
@@ -3644,7 +3657,7 @@ void Scene300::signal() {
break;
case 316:
- R2_GLOBALS._player._characterScene[2] = 500;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 500;
_seeker.remove();
R2_GLOBALS._player.enableControl(CURSOR_CROSSHAIRS);
break;
@@ -4813,6 +4826,11 @@ void Scene400::dispatch() {
*
*--------------------------------------------------------------------------*/
+Scene500::PanelDialog::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
+}
+
bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
@@ -4835,17 +4853,18 @@ bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
-bool Scene500::Object2::startAction(CursorType action, Event &event) {
+bool Scene500::Seeker::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
if (action == CURSOR_TALK) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1101 : 1103;
} else {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1102 : 1105;
}
+ scene->_sceneMode = 524;
scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
return true;
} else {
@@ -4853,7 +4872,7 @@ bool Scene500::Object2::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Object3::startAction(CursorType action, Event &event) {
+bool Scene500::Suit::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -4864,20 +4883,20 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
case CURSOR_USE:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if ((_strip != 3) && (_strip != 7))
- SceneItem::display2(500, _strip);
+ SceneItem::display2(500, _strip + 25);
else if (R2_GLOBALS.getFlag(26)) {
R2_GLOBALS._player.disableControl();
scene->_stripNumber = 1103;
scene->_sceneMode = 524;
- scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 512, &R2_GLOBALS._player, NULL);
} else if (!R2_GLOBALS.getFlag(28))
SceneItem::display2(500, 41);
- else if (!R2_GLOBALS.getFlag(40))
+ else if (!R2_GLOBALS.getFlag(25))
SceneItem::display2(500, 40);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 512;
- scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, &scene->_object3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 512, &R2_GLOBALS._player, &scene->_suit, NULL);
R2_GLOBALS.setFlag(26);
}
} else {
@@ -4893,7 +4912,7 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 515;
- scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_object3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_suit, NULL);
R2_GLOBALS.setFlag(28);
}
return true;
@@ -4903,12 +4922,7 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
return true;
default:
- if (action < R2_LAST_INVENT) {
- SceneItem::display2(500, action);
- return true;
- } else {
- return SceneActor::startAction(action, event);
- }
+ return SceneActor::startAction(action, event);
}
}
@@ -4976,7 +4990,7 @@ bool Scene500::AirLock::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = (R2_GLOBALS._player._characterIndex == R2_QUINN) ? 521 : 522;
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
- &scene->_object2, &scene->_airLock, NULL);
+ &scene->_seeker, &scene->_airLock, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -5045,7 +5059,36 @@ bool Scene500::Locker2::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Object::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+void Scene500::PanelDialog::setDetails(int visage, int strip, int frameNumber,
+ const Common::Point &pt) {
+ SceneAreaObject::setDetails(visage, strip, frameNumber, pt);
+ SceneAreaObject::setDetails(500, 43, 32, 45);
+
+ _button1.setupButton(1);
+ _button2.setupButton(2);
+ _button3.setupButton(3);
+}
+
+void Scene500::PanelDialog::remove() {
+ Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.remove(&_button1);
+ scene->_sceneAreas.remove(&_button2);
+ scene->_sceneAreas.remove(&_button3);
+
+ _button1.remove();
+ _button2.remove();
+ _button3.remove();
+
+ SceneAreaObject::remove();
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 511;
+ scene->setAction(&scene->_sequenceManager1, scene, 511, &R2_GLOBALS._player, NULL);
+}
+
+bool Scene500::PanelDialog::Button::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
return false;
} else {
@@ -5053,6 +5096,119 @@ bool Scene500::Object::startAction(CursorType action, Event &event) {
}
}
+void Scene500::PanelDialog::Button::setupButton(int buttonId) {
+ _buttonId = buttonId;
+ _buttonDown = false;
+ SceneActor::postInit();
+ setup(500, 7, 1);
+ fixPriority(251);
+
+ switch (_buttonId) {
+ case 1:
+ setPosition(Common::Point(139, 78));
+ break;
+ case 2:
+ setPosition(Common::Point(139, 96));
+ break;
+ case 3:
+ setPosition(Common::Point(139, 114));
+ break;
+ default:
+ break;
+ }
+
+ Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.push_front(this);
+}
+
+void Scene500::PanelDialog::Button::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_buttonDown);
+}
+
+void Scene500::PanelDialog::Button::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) &&
+ (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
+ _bounds.contains(event.mousePos) && !_buttonDown) {
+ _buttonDown = true;
+ event.handled = true;
+ setFrame(2);
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _buttonDown) {
+ setFrame(1);
+ _buttonDown = false;
+ event.handled = true;
+
+ doButtonPress();
+ }
+}
+
+void Scene500::PanelDialog::Button::doButtonPress() {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS.getFlag(28)) {
+ SceneItem::display2(500, 48);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = _buttonId;
+
+ switch (_buttonId) {
+ case 1:
+ if (--R2_GLOBALS._landerSuitNumber == 0)
+ R2_GLOBALS._landerSuitNumber = 3;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 5;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_object1.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 2:
+ if (++R2_GLOBALS._landerSuitNumber == 4)
+ R2_GLOBALS._v566A4 = 1;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 6;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_object1.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 3:
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 509;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_suit.postInit();
+ scene->_suit.hide();
+ scene->_suit._effect = 1;
+ scene->_suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ scene->_suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 1);
+
+ scene->setAction(&scene->_sequenceManager1, scene, 508,
+ &R2_GLOBALS._player, &scene->_object1, &scene->_suit,
+ &scene->_object8, NULL);
+ R2_GLOBALS.setFlag(35);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
/*--------------------------------------------------------------------------*/
void Scene500::postInit(SceneObjectList *OwnerList) {
@@ -5071,23 +5227,23 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._walkRegions.disableRegion(1);
- _object2.postInit();
- _object2._effect = 1;
- _object2.setup(1505, 1, 1);
- _object2._moveDiff.x = 5;
- _object2.setPosition(Common::Point(42, 151));
- _object2.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
+ _seeker.postInit();
+ _seeker._effect = 1;
+ _seeker.setup(1505, 1, 1);
+ _seeker._moveDiff.x = 5;
+ _seeker.setPosition(Common::Point(42, 151));
+ _seeker.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
} else if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
- _object2.postInit();
- _object2._effect = 1;
- _object2.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
- _object2.setPosition(Common::Point(42, 151));
+ _seeker.postInit();
+ _seeker._effect = 1;
+ _seeker.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
+ _seeker.setPosition(Common::Point(42, 151));
R2_GLOBALS._walkRegions.disableRegion(1);
R2_GLOBALS._walkRegions.disableRegion(2);
R2_GLOBALS._walkRegions.disableRegion(3);
- _object2.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
+ _seeker.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
}
}
@@ -5167,16 +5323,16 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
} else {
_object8.setup(500, 8, 7);
- _object3.postInit();
- _object3._effect = 1;
- _object3.setPosition(Common::Point(247, 52));
- _object3.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ _suit.postInit();
+ _suit._effect = 1;
+ _suit.setPosition(Common::Point(247, 52));
+ _suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
if (!R2_GLOBALS.getFlag(26)) {
if (R2_GLOBALS.getFlag(28))
- _object3.setup(502, 7, 2);
+ _suit.setup(502, 7, 2);
else
- _object3.setup(502, R2_GLOBALS._v566A3 + 2, 7);
+ _suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 7);
}
}
@@ -5222,7 +5378,7 @@ void Scene500::signal() {
_object1.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 6:
@@ -5231,7 +5387,7 @@ void Scene500::signal() {
_object1.animate(ANIM_MODE_5, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 7:
@@ -5239,14 +5395,14 @@ void Scene500::signal() {
_object8.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 500:
R2_GLOBALS._sceneManager.changeScene(700);
break;
case 501:
- if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) {
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 500) {
_stripNumber = 1100;
_sceneMode = 523;
setAction(&_sequenceManager1, this, 523, &R2_GLOBALS._player, NULL);
@@ -5277,7 +5433,7 @@ void Scene500::signal() {
break;
case 506:
case 518:
- R2_GLOBALS.setFlag(11);
+ R2_GLOBALS.setFlag(12);
R2_GLOBALS._player.enableControl();
break;
case 507:
@@ -5287,12 +5443,12 @@ void Scene500::signal() {
break;
case 509:
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 510:
R2_GLOBALS._player.enableControl();
- _area1.setDetails(500, 6, 1, Common::Point(160, 120));
+ _panelDialog.setDetails(500, 6, 1, Common::Point(160, 120));
R2_GLOBALS._player.enableControl();
break;
case 513:
@@ -5391,22 +5547,22 @@ bool Scene600::Item4::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
scene->_object1.setup2(603, 3, 1, 239, 54, 10, 0);
- scene->_actor3.postInit();
- scene->_actor2.postInit();
+ scene->_stasisField.postInit();
+ scene->_computer.postInit();
scene->_sceneMode = 612;
- scene->setAction(&scene->_sequenceManager1, scene, 612, &scene->_actor3, &scene->_actor2, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 612, &scene->_stasisField, &scene->_computer, &R2_GLOBALS._player, NULL);
return true;
}
-void Scene600::Actor4::signal() {
+void Scene600::Smoke::signal() {
Common::Point pt(177 + R2_GLOBALS._randomSource.getRandomNumber(5),
108 + R2_GLOBALS._randomSource.getRandomNumber(3));
NpcMover *mover = new NpcMover();
addMover(mover, &pt, this);
}
-bool Scene600::Actor4::startAction(CursorType action, Event &event) {
+bool Scene600::Smoke::startAction(CursorType action, Event &event) {
if (action >= CURSOR_WALK)
// Only action cursors
return SceneActor::startAction(action, event);
@@ -5414,7 +5570,7 @@ bool Scene600::Actor4::startAction(CursorType action, Event &event) {
return false;
}
-GfxSurface Scene600::Actor4::getFrame() {
+GfxSurface Scene600::Smoke::getFrame() {
GfxSurface frame = SceneActor::getFrame();
if (_effect) {
@@ -5435,7 +5591,8 @@ GfxSurface Scene600::Actor4::getFrame() {
}
bool Scene600::Doorway::startAction(CursorType action, Event &event) {
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START))
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
if (action != CURSOR_USE)
@@ -5478,16 +5635,17 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
if (action < CURSOR_WALK) {
switch (action) {
case R2_COM_SCANNER:
+ // If laser is destroyed
if (R2_GLOBALS.getFlag(6)) {
if (R2_GLOBALS.getFlag(8)) {
SceneItem::display(600, 29, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
return true;
} else {
R2_GLOBALS._player.disableControl();
- scene->_actor8.postInit();
- scene->_actor8.setDetails(600, 20, -1, -1, 4, &scene->_laser);
+ scene->_scanner.postInit();
+ scene->_scanner.setDetails(600, 20, -1, -1, 4, &scene->_laser);
scene->_sceneMode = 607;
- scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_scanner, NULL);
return true;
}
} else {
@@ -5503,21 +5661,22 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
scene->_aerosol.postInit();
scene->_aerosol.setDetails(600, 27, -1, -1, 5, &scene->_laser);
- scene->_actor4.postInit();
- scene->_actor4.setup(601, 3, 1);
- scene->_actor4._effect = 3;
- scene->_actor4._moveDiff = Common::Point(1, 1);
- scene->_actor4._moveRate = 2;
- scene->_actor4._numFrames = 3;
- scene->_actor4.setDetails(600, 24, 25, 26, 5, &scene->_aerosol);
+ scene->_smoke.postInit();
+ scene->_smoke.setup(601, 3, 1);
+ scene->_smoke._effect = 3;
+ scene->_smoke._moveDiff = Common::Point(1, 1);
+ scene->_smoke._moveRate = 2;
+ scene->_smoke._numFrames = 3;
+ scene->_smoke.setDetails(600, 24, 25, 26, 5, &scene->_aerosol);
scene->_sceneMode = 605;
- scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_aerosol, &scene->_actor4, &scene->_doorway, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_aerosol, &scene->_smoke, &scene->_doorway, NULL);
return true;
}
break;
case R2_CLAMP:
+ // If cloud is active
if (R2_GLOBALS.getFlag(5)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 606;
@@ -5547,9 +5706,11 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
bool Scene600::Aerosol::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
- } else if (action == CURSOR_USE) {
+
+ if (action == CURSOR_USE) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 614;
scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_aerosol, NULL);
@@ -5574,17 +5735,17 @@ void Scene600::synchronize(Serializer &s) {
s.syncAsByte(_pixelMap[i]);
}
-bool Scene600::Actor8::startAction(CursorType action, Event &event) {
+bool Scene600::Scanner::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(9) == 600)) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 615;
- scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_actor8, NULL);
- } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(9) == 600) && (R2_GLOBALS._scannerFrequencies[1] == 2) && (!R2_GLOBALS.getFlag(8))){
+ scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_scanner, NULL);
+ } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600) && (R2_GLOBALS._scannerFrequencies[1] == 2) && (!R2_GLOBALS.getFlag(8))){
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 608;
- scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_smoke, NULL);
} else {
return SceneActor::startAction(action, event);
}
@@ -5599,7 +5760,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.enableRegion(3);
_field412 = 0;
- // Initialise pixel map for the obscuring effect
+ // Initialize pixel map for the obscuring effect
ScenePalette &pal = R2_GLOBALS._scenePalette;
uint r, g, b;
for (int i = 0; i < 256; ++i) {
@@ -5618,11 +5779,11 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_laser.postInit();
_laser.setPosition(Common::Point(246, 41));
- if (R2_INVENTORY.getObjectScene(9) == 600) {
- _actor8.postInit();
- _actor8.setup(602, 5, 1);
- _actor8.setPosition(Common::Point(246, 41));
- _actor8.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600) {
+ _scanner.postInit();
+ _scanner.setup(602, 5, 1);
+ _scanner.setPosition(Common::Point(246, 41));
+ _scanner.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
switch (R2_GLOBALS._scannerFrequencies[1] - 2) {
case 0:
R2_GLOBALS._sound4.play(45);
@@ -5658,7 +5819,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_object1.setup2(603, 1, 1, 244, 50, 10, 0);
if (R2_GLOBALS.getFlag(5)) {
- if (R2_INVENTORY.getObjectScene(12) == 600) {
+ if (R2_INVENTORY.getObjectScene(R2_AEROSOL) == 600) {
_aerosol.postInit();
_aerosol.setup(602, 2, 2);
_aerosol.setPosition(Common::Point(189, 95));
@@ -5667,23 +5828,25 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS.getFlag(8)) {
if (R2_GLOBALS.getFlag(9)) {
- _actor2.postInit();
- _actor2.setup(603, 2, 1);
- _actor2.setPosition(Common::Point(233, 45));
- _actor2.animate(ANIM_MODE_2, NULL);_actor2.fixPriority(11);
+ // Computer is active
+ _computer.postInit();
+ _computer.setup(603, 2, 1);
+ _computer.setPosition(Common::Point(233, 45));
+ _computer.animate(ANIM_MODE_2, NULL);
+ _computer.fixPriority(11);
}
} else {
- _actor4.postInit();
- _actor4.setup(601, 1, 1);
- _actor4.setPosition(Common::Point(180, 110));
- _actor4._moveDiff = Common::Point(1, 1);
- _actor4._moveRate = 2;
- _actor4._numFrames = 3;
- _actor4.animate(ANIM_MODE_2, NULL);
- _actor4.fixPriority(130);
- _actor4._effect = 3;
- _actor4.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
- _actor4.signal();
+ _smoke.postInit();
+ _smoke.setup(601, 1, 1);
+ _smoke.setPosition(Common::Point(180, 110));
+ _smoke._moveDiff = Common::Point(1, 1);
+ _smoke._moveRate = 2;
+ _smoke._numFrames = 3;
+ _smoke.animate(ANIM_MODE_2, NULL);
+ _smoke.fixPriority(130);
+ _smoke._effect = 3;
+ _smoke.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
+ _smoke.signal();
}
}
@@ -5727,7 +5890,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
}
void Scene600::remove() {
- if (R2_INVENTORY.getObjectScene(9) == 600)
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600)
R2_GLOBALS._sound4.fadeOut2(NULL);
SceneExt::remove();
}
@@ -5742,6 +5905,7 @@ void Scene600::signal() {
R2_GLOBALS._sceneManager.changeScene(700);
break;
case 605:
+ // After cloud is active
R2_GLOBALS._player.enableControl();
R2_GLOBALS._walkRegions.enableRegion(6);
R2_GLOBALS._walkRegions.enableRegion(7);
@@ -5751,42 +5915,48 @@ void Scene600::signal() {
R2_INVENTORY.setObjectScene(R2_AEROSOL, 600);
R2_GLOBALS.setFlag(5);
- _actor4._effect = 3;
- _actor4.signal();
+ _smoke._effect = 3;
+ _smoke.signal();
break;
case 606:
- R2_INVENTORY.setObjectScene(15, 600);
+ // After Clamp is put on laser
+ R2_INVENTORY.setObjectScene(R2_CLAMP, 600);
R2_GLOBALS._player.enableControl();
break;
case 607:
- R2_INVENTORY.setObjectScene(9, 600);
+ // After scanner is put on laser
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 600);
R2_GLOBALS._player.enableControl();
break;
case 608:
+ // deactivate cloud
R2_GLOBALS.setFlag(8);
- _actor4.remove();
+ _smoke.remove();
R2_GLOBALS._walkRegions.disableRegion(6);
R2_GLOBALS._walkRegions.disableRegion(9);
R2_GLOBALS._walkRegions.disableRegion(10);
R2_GLOBALS._player.enableControl();
break;
case 612:
+ // Deactivate stasis field
R2_GLOBALS.setFlag(9);
- _actor3.remove();
+ _stasisField.remove();
R2_GLOBALS._sceneItems.remove(&_item4);
- _actor2.setDetails(600, 21, -1, 23, 4, &_item4);
+ _computer.setDetails(600, 21, -1, 23, 4, &_item4);
_background.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
case 614:
+ // Pick up Aerosol
R2_GLOBALS._player.enableControl();
_aerosol.remove();
- R2_INVENTORY.setObjectScene(12, 1);
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 1);
R2_GLOBALS._walkRegions.disableRegion(7);
break;
case 615:
- _actor8.remove();
- R2_INVENTORY.setObjectScene(9, 1);
+ // Pick up Com Scanner
+ _scanner.remove();
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 1);
R2_GLOBALS._player.enableControl();
break;
default:
@@ -5842,7 +6012,7 @@ void Scene600::dispatch() {
_aSound1.play(40);
Scene::dispatch();
- if ((_actor4._strip == 3) && (_actor4._frame == 3)) {
+ if ((_smoke._strip == 3) && (_smoke._frame == 3)) {
_actor1.setStrip(4);
_actor1.setFrame(1);
}
@@ -5868,26 +6038,26 @@ bool Scene700::Item11::startAction(CursorType action, Event &event) {
return NamedHotspot::startAction(action, event);
}
-bool Scene700::Item12::startAction(CursorType action, Event &event) {
+bool Scene700::HandGrip::startAction(CursorType action, Event &event) {
Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case R2_CABLE_HARNESS:
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
- scene->_actor5.setup(701, 3, 2);
- scene->_actor5.setPosition(Common::Point(243, 98));
- scene->_actor5.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
- scene->_actor5.hide();
+ scene->_cable.postInit();
+ scene->_cable.setup(701, 3, 2);
+ scene->_cable.setPosition(Common::Point(243, 98));
+ scene->_cable.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
+ scene->_cable.hide();
scene->_sceneMode = 20;
break;
case R2_ATTRACTOR_CABLE_HARNESS:
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
- scene->_actor5.setup(701, 2, 8);
- scene->_actor5.setPosition(Common::Point(243, 98));
- scene->_actor5.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
- scene->_actor5.hide();
+ scene->_cable.postInit();
+ scene->_cable.setup(701, 2, 8);
+ scene->_cable.setPosition(Common::Point(243, 98));
+ scene->_cable.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
+ scene->_cable.hide();
scene->_sceneMode = 21;
break;
default:
@@ -5895,7 +6065,7 @@ bool Scene700::Item12::startAction(CursorType action, Event &event) {
break;
}
- scene->setAction(&scene->_sequenceManager, scene, 707, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 707, &R2_GLOBALS._player, &scene->_cable, NULL);
return true;
}
@@ -5947,7 +6117,7 @@ bool Scene700::Actor4::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor5::startAction(CursorType action, Event &event) {
+bool Scene700::Cable::startAction(CursorType action, Event &event) {
Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -5981,9 +6151,9 @@ bool Scene700::Actor5::startAction(CursorType action, Event &event) {
break;
case R2_ATTRACTOR_UNIT:
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) {
+ if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 700) {
scene->_sceneMode = 706;
- scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_cable, NULL);
} else {
scene->_sceneMode = 15;
Common::Point pt(_position.x - 12, _position.y + 1);
@@ -6065,20 +6235,20 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor9.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
- _actor5.postInit();
- _actor5.fixPriority(10);
+ _cable.postInit();
+ _cable.fixPriority(10);
switch (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS)) {
case 0:
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
- _actor5.setup(701, 3, 2);
- _actor5.setPosition(Common::Point(243, 98));
- _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 3, 2);
+ _cable.setPosition(Common::Point(243, 98));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
case 700:
- _actor5.setup(701, 3, 1);
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
- _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 3, 1);
+ _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6088,22 +6258,22 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
- _actor5.setup(701, 2, 1);
+ _cable.setup(701, 2, 1);
else
- _actor5.setup(701, 2, 8);
- _actor5.setPosition(Common::Point(243, 98));
- _actor5.fixPriority(77);
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 2, 8);
+ _cable.setPosition(Common::Point(243, 98));
+ _cable.fixPriority(77);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
case 700:
- _actor5.setup(701, 1, 8);
+ _cable.setup(701, 1, 8);
if (R2_GLOBALS._v565E7 == 0) {
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
} else {
- _actor5.setup(701, 1, 1);
- _actor5.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
+ _cable.setup(701, 1, 1);
+ _cable.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
}
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6118,7 +6288,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor4.setPosition(Common::Point(454, 117));
_actor4.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
- _item12.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
+ _handGrip.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
_item6.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
_item2.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
_item3.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
@@ -6223,7 +6393,7 @@ void Scene700::signal() {
break;
case 11:
_sceneMode = 12;
- _actor5.remove();
+ _cable.remove();
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
case 12:
@@ -6248,13 +6418,13 @@ void Scene700::signal() {
break;
case 16:
_sceneMode = 17;
- _actor5.setup(701, 1, 8);
- _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- if ((R2_GLOBALS._v565E5 != 0) && (_actor5._position.x == _actor1._position.x + 1) && (_actor5._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
- _actor5.animate(ANIM_MODE_6, NULL);
- Common::Point pt(_actor5._position.x, _actor1._position.y + 120);
+ _cable.setup(701, 1, 8);
+ _cable.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
+ if ((R2_GLOBALS._v565E5 != 0) && (_cable._position.x == _actor1._position.x + 1) && (_cable._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
+ _cable.animate(ANIM_MODE_6, NULL);
+ Common::Point pt(_cable._position.x, _actor1._position.y + 120);
NpcMover *mover = new NpcMover();
- _actor5.addMover(mover, &pt, NULL);
+ _cable.addMover(mover, &pt, NULL);
R2_GLOBALS._v565E7 = 1;
}
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
@@ -6274,9 +6444,9 @@ void Scene700::signal() {
R2_GLOBALS._player.enableControl();
break;
case 21:
- _actor5.fixPriority(77);
+ _cable.fixPriority(77);
if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
- _actor5.animate(ANIM_MODE_6, NULL);
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
@@ -6291,10 +6461,10 @@ void Scene700::signal() {
R2_GLOBALS._sceneManager.changeScene(900);
break;
case 706:
- _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- _actor5.fixPriority(77);
+ _cable.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
+ _cable.fixPriority(77);
if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
- _actor5.animate(ANIM_MODE_6, NULL);
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h
index bc30743aca..df0b4d8fc6 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -102,7 +102,7 @@ public:
class Scene125: public SceneExt {
/* Objects */
- class Object5: public SceneActor {
+ class Food: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -136,7 +136,7 @@ public:
ASoundExt _sound1;
NamedHotspot _background, _item2, _item3;
DiskSlot _diskSlot;
- SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _infoDisk;
+ SceneActor _object1, _object2, _object3, _object4, _food, _foodDispenser, _infoDisk;
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
SequenceManager _sequenceManager;
SceneText _sceneText;
@@ -310,7 +310,7 @@ public:
class Scene250: public SceneExt {
class Button: public SceneActor {
public:
- int _floorNumber, _v2;
+ int _floorNumber;
Button();
void setFloor(int floorNumber);
@@ -318,7 +318,8 @@ class Scene250: public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412, _field414, _field416, _field418, _field41A;
+ int _currButtonY, _destButtonY, _elevatorSpeed;
+ bool _skippingFl, _skippableFl;
NamedHotspot _background, _item2, _item3, _item4;
Button _button1, _currentFloor;
Button _floor1, _floor2, _floor3, _floor4, _floor5;
@@ -524,6 +525,31 @@ public:
};
class Scene500: public SceneExt {
+ /* Dialogs */
+ class PanelDialog: public SceneAreaObject {
+ class Button: public SceneActor {
+ private:
+ int _buttonId;
+ bool _buttonDown;
+
+ void doButtonPress();
+ public:
+ Button();
+ virtual Common::String getClassName() { return "Scene500_Button"; }
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ virtual void synchronize(Serializer &s);
+
+ void setupButton(int buttonId);
+ };
+ public:
+ Button _button1, _button2, _button3;
+
+ virtual Common::String getClassName() { return "Scene500_PanelWindow"; }
+ virtual void remove();
+ void setDetails(int visage, int strip, int frameNumber, const Common::Point &pt);
+ };
+
/* Items */
class ControlPanel: public SceneHotspot {
public:
@@ -531,11 +557,11 @@ class Scene500: public SceneExt {
};
/* Objects */
- class Object2: public SceneActor {
+ class Seeker: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object3: public SceneActor {
+ class Suit: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -570,20 +596,16 @@ class Scene500: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object: public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
public:
int _stripNumber;
byte _buffer[2710];
- SpeakerSeeker _seekerSpeaker;
- SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker500 _seekerSpeaker;
+ SpeakerQuinn500 _quinnSpeaker;
SceneHotspot _background, _item2;
ControlPanel _controlPanel;
SceneActor _object1;
- Object2 _object2;
- Object3 _object3;
+ Seeker _seeker;
+ Suit _suit;
Doorway _doorway;
OxygenTanks _tanks1, _tanks2;
AirLock _airLock;
@@ -592,8 +614,7 @@ public:
SonicStunner _sonicStunner;
Locker1 _locker1;
Locker2 _locker2;
- SceneAreaObject _area1;
- Object _obj1, _obj2, _obj3;
+ PanelDialog _panelDialog;
ASoundExt _sound1;
SequenceManager _sequenceManager1, _sequenceManager2;
public:
@@ -622,7 +643,7 @@ class Scene600 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Smoke : public SceneActor {
public:
virtual void signal();
virtual bool startAction(CursorType action, Event &event);
@@ -640,7 +661,7 @@ class Scene600 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class Scanner : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -653,13 +674,13 @@ public:
CompartmentHotspot _item5;
BackgroundSceneObject _object1;
SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
+ SceneActor _computer;
+ SceneActor _stasisField;
+ Smoke _smoke;
Doorway _doorway;
Laser _laser;
Aerosol _aerosol;
- Actor8 _actor8;
+ Scanner _scanner;
ASoundExt _aSound1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -679,7 +700,7 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item12 : public NamedHotspot {
+ class HandGrip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -696,7 +717,7 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Cable : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -716,12 +737,12 @@ public:
NamedHotspot _item9;
NamedHotspot _item10;
Item11 _item11;
- Item12 _item12;
+ HandGrip _handGrip;
SceneActor _actor1;
Actor2 _actor2;
Actor3 _actor3;
Actor4 _actor4;
- Actor5 _actor5;
+ Cable _cable;
Actor6 _actor6;
Actor6 _actor7;
Actor6 _actor8;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
index 6ea53d0852..0941f09677 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -5,7 +5,7 @@
* 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
+ * modify it under the terms of the GNU GenWeral Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
@@ -38,7 +38,8 @@ Scene1000::Scene1000(): SceneExt() {
R2_GLOBALS._sceneManager._hasPalette = false;
R2_GLOBALS._uiElements._active = false;
_gameTextSpeaker._displayMode = 9;
- _fieldD2E = 0;
+ _forceCheckAnimationFl = false;
+ _animCounter = 0;
}
void Scene1000::postInit(SceneObjectList *OwnerList) {
@@ -115,7 +116,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, 0);
for (int percent = 0; percent < 100; percent += 5)
@@ -140,7 +141,7 @@ void Scene1000::signal() {
R2_GLOBALS._player.setPosition(Common::Point(160, 100));
R2_GLOBALS._player.show();
- _field412 = 0;
+ _animCounter = 0;
_stripManager.start(29, this);
break;
@@ -148,7 +149,7 @@ void Scene1000::signal() {
if (R2_GLOBALS._speechSubtitles & SPEECH_TEXT) {
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else {
- if (++_field412 < 3)
+ if (++_animCounter < 3)
_sceneMode = 2;
setAction(&_sequenceManager1, this, 2, &R2_GLOBALS._player, NULL);
@@ -173,7 +174,7 @@ void Scene1000::signal() {
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -203,7 +204,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -225,7 +226,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -245,7 +246,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -270,7 +271,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -296,7 +297,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -318,7 +319,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -345,7 +346,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -370,7 +371,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -393,7 +394,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -411,7 +412,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -438,7 +439,7 @@ void Scene1000::signal() {
R2_GLOBALS._sceneManager._hasPalette = false;
_animationPlayer.dispatch();
- _fieldD2E = 1;
+ _forceCheckAnimationFl = true;
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -454,9 +455,9 @@ void Scene1000::signal() {
}
void Scene1000::dispatch() {
- if (_fieldD2E) {
+ if (_forceCheckAnimationFl) {
if (_animationPlayer.isCompleted()) {
- _fieldD2E = 0;
+ _forceCheckAnimationFl = false;
_animationPlayer.close();
_animationPlayer.remove();
@@ -661,18 +662,18 @@ void Scene1020::dispatch() {
*
*--------------------------------------------------------------------------*/
Scene1100::Scene1100() {
- _field412 = 0;
- _field414 = 0;
+ _nextStripNum = 0;
+ _paletteRefreshStatus = 0;
}
void Scene1100::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_nextStripNum);
+ s.syncAsSint16LE(_paletteRefreshStatus);
}
-bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
+bool Scene1100::Seeker::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if (action != CURSOR_TALK)
@@ -680,24 +681,24 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
if (R2_GLOBALS.getFlag(52)) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
- scene->_field412 = 327;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ scene->_nextStripNum = 327;
else
- scene->_field412 = 328;
+ scene->_nextStripNum = 328;
scene->_sceneMode = 53;
scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 55;
if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(329, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(330, scene, R2_GLOBALS._stripManager_lookupList);
} else {
++R2_GLOBALS._v565AE;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(304, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(308, scene, R2_GLOBALS._stripManager_lookupList);
@@ -706,7 +707,7 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
+bool Scene1100::Trooper::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -714,7 +715,7 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
if (_visage == 1105) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1114;
- scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_trooper, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -725,21 +726,21 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
case R2_PHOTON_STUNNER:
if (_visage == 1105) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_sceneMode = 1112;
- scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_trooper, NULL);
} else {
scene->_sceneMode = 1115;
- scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_trooper, NULL);
}
return true;
} else if (_strip == 2) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1113;
- if (R2_GLOBALS._player._characterIndex == 1) {
- scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_trooper, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_trooper, NULL);
}
return true;
} else {
@@ -752,11 +753,11 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
}
}
-bool Scene1100::Actor18::startAction(CursorType action, Event &event) {
+bool Scene1100::Chief::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) {
- scene->_field412 = 0;
+ scene->_nextStripNum = 0;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 53;
scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
@@ -778,7 +779,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._v5589E.right = 200;
}
- if (R2_GLOBALS._player._characterScene[1] == 1100)
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 1100)
R2_GLOBALS._sceneManager._previousScene = 1100;
if (R2_GLOBALS._sceneManager._previousScene == -1) {
@@ -814,38 +815,38 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.stop();
if (R2_GLOBALS._sceneManager._previousScene == 300) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._player._characterIndex = R2_QUINN;
- R2_GLOBALS._player._characterScene[1] = 1100;
- R2_GLOBALS._player._characterScene[2] = 1100;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1100;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1100;
_actor2.setPosition(Common::Point(150, 30));
R2_GLOBALS._sound1.play(93);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor16.postInit();
- _actor16.hide();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _seeker.postInit();
+ _seeker.hide();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _seeker.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
else
- _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor18.postInit();
- _actor18.setup(1113, 3, 1);
- _actor18.setPosition(Common::Point(181, 125));
- _actor18.fixPriority(110);
+ _chief.postInit();
+ _chief.setup(1113, 3, 1);
+ _chief.setPosition(Common::Point(181, 125));
+ _chief.fixPriority(110);
if (R2_GLOBALS.getFlag(54))
- _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
else
- _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
- _actor17.postInit();
- _actor17.setup(1105, 3, 1);
- _actor17.setPosition(Common::Point(312, 165));
- _actor17._numFrames = 5;
- _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+ _trooper.postInit();
+ _trooper.setup(1105, 3, 1);
+ _trooper.setPosition(Common::Point(312, 165));
+ _trooper._numFrames = 5;
+ _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
_actor1.postInit();
_actor1.setup(1512, 1, 1);
@@ -859,7 +860,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS._sceneManager._previousScene == 1000) {
_actor2.setPosition(Common::Point(50, 30));
- _field414 = 0;
+ _paletteRefreshStatus = 0;
_palette1.loadPalette(1101);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
@@ -872,25 +873,25 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveRate = 30;
R2_GLOBALS._player._moveDiff = Common::Point(16, 2);
- _object1.setup2(1104, 2, 1, 175, 125, 102, 1);
+ _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, 1);
_object2.setup2(1102, 5, 1, 216, 167, 1, 0);
- _actor12.postInit();
- _actor12.setup(1113, 2, 1);
- _actor12.setPosition(Common::Point(67, 151));
- _actor12.fixPriority(255);
+ _leftImpacts.postInit();
+ _leftImpacts.setup(1113, 2, 1);
+ _leftImpacts.setPosition(Common::Point(67, 151));
+ _leftImpacts.fixPriority(255);
- _actor3.postInit();
- _actor3.setup(1102, 6, 1);
- _actor3._moveRate = 30;
- _actor3._moveDiff.x = 2;
+ _shipFormation.postInit();
+ _shipFormation.setup(1102, 6, 1);
+ _shipFormation._moveRate = 30;
+ _shipFormation._moveDiff.x = 2;
- _actor4.postInit();
- _actor4.setup(1102, 6, 2);
- _actor4._moveRate = 30;
- _actor4._moveDiff.x = 2;
- _actor4._effect = 5;
- _actor4._field9C = _field312;
+ _shipFormationShadow.postInit();
+ _shipFormationShadow.setup(1102, 6, 2);
+ _shipFormationShadow._moveRate = 30;
+ _shipFormationShadow._moveDiff.x = 2;
+ _shipFormationShadow._effect = 5;
+ _shipFormationShadow._field9C = _field312;
R2_GLOBALS._sound1.play(86);
@@ -907,66 +908,66 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- _actor16.postInit();
+ _seeker.postInit();
if (R2_GLOBALS.getFlag(52)) {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(19, 7, 1);
- _actor16.setup(29, 6, 1);
+ _seeker.setup(29, 6, 1);
} else {
R2_GLOBALS._player.setup(29, 7, 1);
- _actor16.setup(19, 6, 1);
+ _seeker.setup(19, 6, 1);
}
R2_GLOBALS._player.setPosition(Common::Point(140, 124));
- _actor16.setPosition(Common::Point(237, 134));
+ _seeker.setPosition(Common::Point(237, 134));
R2_GLOBALS._player.enableControl();
} else {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1107, 2, 1);
- _actor16.setup(1107, 4, 1);
+ _seeker.setup(1107, 4, 1);
R2_GLOBALS._player.setPosition(Common::Point(247, 169));
- _actor16.setPosition(Common::Point(213, 169));
+ _seeker.setPosition(Common::Point(213, 169));
} else {
R2_GLOBALS._player.setup(1107, 4, 1);
- _actor16.setup(1107, 2, 1);
+ _seeker.setup(1107, 2, 1);
R2_GLOBALS._player.setPosition(Common::Point(213, 169));
- _actor16.setPosition(Common::Point(247, 169));
+ _seeker.setPosition(Common::Point(247, 169));
}
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
}
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _seeker.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
else
- _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor18.postInit();
- _actor18.setup(1113, 3, 1);
- _actor18.setPosition(Common::Point(181, 125));
- _actor18.fixPriority(110);
+ _chief.postInit();
+ _chief.setup(1113, 3, 1);
+ _chief.setPosition(Common::Point(181, 125));
+ _chief.fixPriority(110);
if (R2_GLOBALS.getFlag(54))
- _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
else
- _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
if (!R2_GLOBALS.getFlag(52)) {
- _actor17.postInit();
+ _trooper.postInit();
if (R2_GLOBALS.getFlag(53))
- _actor17.setup(1106, 2, 4);
+ _trooper.setup(1106, 2, 4);
else
- _actor17.setup(1105, 4, 4);
+ _trooper.setup(1105, 4, 4);
- _actor17.setPosition(Common::Point(17, 54));
- _actor17._numFrames = 5;
+ _trooper.setPosition(Common::Point(17, 54));
+ _trooper._numFrames = 5;
if (R2_GLOBALS.getFlag(53))
- _actor17.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
+ _trooper.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
else
- _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+ _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
- _actor17.fixPriority(200);
+ _trooper.fixPriority(200);
}
_actor1.postInit();
_actor1.setup(1512, 1, 1);
@@ -992,30 +993,30 @@ void Scene1100::remove() {
void Scene1100::signal() {
switch (_sceneMode++) {
case 0:
- _actor3.setPosition(Common::Point(350, 20));
+ _shipFormation.setPosition(Common::Point(350, 20));
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
break;
case 1:{
Common::Point pt(-150, 20);
NpcMover *mover = new NpcMover();
- _actor3.addMover(mover, &pt, this);
- _actor4.setPosition(Common::Point(350, 55));
+ _shipFormation.addMover(mover, &pt, this);
+ _shipFormationShadow.setPosition(Common::Point(350, 55));
Common::Point pt2(-150, 55);
NpcMover *mover2 = new NpcMover();
- _actor4.addMover(mover2, &pt2, NULL);
+ _shipFormationShadow.addMover(mover2, &pt2, NULL);
}
break;
case 2:
- _actor3.remove();
- _actor4.remove();
- _actor5.postInit();
- _actor6.postInit();
- _actor7.postInit();
- _actor8.postInit();
- _actor9.postInit();
- _actor10.postInit();
- setAction(&_sequenceManager1, this, 1102, &_actor5, &_actor6, &_actor7, &_actor8, &_actor9, &_actor10, NULL);
+ _shipFormation.remove();
+ _shipFormationShadow.remove();
+ _shotImpact1.postInit();
+ _shotImpact2.postInit();
+ _shotImpact3.postInit();
+ _shotImpact4.postInit();
+ _shotImpact5.postInit();
+ _laserShot.postInit();
+ setAction(&_sequenceManager1, this, 1102, &_shotImpact1, &_shotImpact2, &_shotImpact3, &_shotImpact4, &_shotImpact5, &_laserShot, NULL);
break;
case 3: {
R2_GLOBALS._sound2.play(84);
@@ -1026,26 +1027,26 @@ void Scene1100::signal() {
}
break;
case 4:
- _actor18.postInit();
- _actor18.show();
- setAction(&_sequenceManager1, this, 1101, &_actor18, &_actor10, NULL);
+ _chief.postInit();
+ _chief.show();
+ setAction(&_sequenceManager1, this, 1101, &_chief, &_laserShot, NULL);
break;
case 5:
- _actor13.postInit();
- _actor13._effect = 6;
- _actor13.setup(1103, 3, 1);
- _actor13._moveRate = 30;
+ _runningGuy1.postInit();
+ _runningGuy1._effect = 6;
+ _runningGuy1.setup(1103, 3, 1);
+ _runningGuy1._moveRate = 30;
- _actor14.postInit();
- _actor14._effect = 6;
- _actor14.setup(1103, 4, 1);
- _actor4._moveRate = 25;
+ _runningGuy2.postInit();
+ _runningGuy2._effect = 6;
+ _runningGuy2.setup(1103, 4, 1);
+ _runningGuy2._moveRate = 25;
- _actor13.setAction(&_sequenceManager2, this, 1109, &_actor13, &_actor14, NULL);
+ _runningGuy1.setAction(&_sequenceManager2, this, 1109, &_runningGuy1, &_runningGuy2, NULL);
break;
case 6: {
- _actor13.remove();
- _actor14.remove();
+ _runningGuy1.remove();
+ _runningGuy2.remove();
R2_GLOBALS._player.setPosition(Common::Point(-50, 136));
R2_GLOBALS._sound2.play(84);
Common::Point pt(350, 236);
@@ -1054,29 +1055,30 @@ void Scene1100::signal() {
}
break;
case 7:
- setAction(&_sequenceManager1, this, 1103, &_actor18, &_actor10);
+ setAction(&_sequenceManager1, this, 1103, &_chief, &_laserShot, NULL);
break;
case 8:
R2_GLOBALS._player._effect = 0;
- _actor11.postInit();
- setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_actor10, &_actor11, &_actor18, NULL);
+ _animation.postInit();
+ setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_laserShot, &_animation, &_chief, NULL);
break;
case 9:
- _object1.copySceneToBackground();
+ _rightLandslide.copySceneToBackground();
- _actor15.postInit();
- _actor15.setup(1103, 2, 1);
- _actor15._moveRate = 30;
- _actor15.setAction(&_sequenceManager3, this, 1107, &_actor15, NULL);
+ _runningGuy3.postInit();
+ _runningGuy3.setup(1103, 2, 1);
+ _runningGuy3._moveRate = 30;
+ _runningGuy3.setAction(&_sequenceManager3, this, 1107, &_runningGuy3, NULL);
break;
case 10:
- _actor13.postInit();
- _actor13.setup(1103, 1, 1);
- _actor13._moveRate = 15;
- _actor13.setAction(&_sequenceManager2, this, 1108, &_actor13, NULL);
+ _runningGuy1.postInit();
+ _runningGuy1.setup(1103, 1, 1);
+ _runningGuy1._moveRate = 15;
+ _runningGuy1.setAction(&_sequenceManager2, this, 1108, &_runningGuy1, NULL);
break;
case 11: {
- setAction(&_sequenceManager1, this, 1106, &_actor11, &_actor10, &_actor12, NULL);
+ setAction(&_sequenceManager1, this, 1106, &_animation, &_laserShot, &_leftImpacts, NULL);
+
R2_GLOBALS._player._effect = 5;
R2_GLOBALS._player.setup(1102, 3, 2);
R2_GLOBALS._player.setPosition(Common::Point(-50, 131));
@@ -1090,19 +1092,19 @@ void Scene1100::signal() {
// Really nothing
break;
case 13:
- _actor17.postInit();
- R2_GLOBALS._scrollFollower = &_actor17;
+ _trooper.postInit();
+ R2_GLOBALS._scrollFollower = &_trooper;
- _actor11.setup(1100, 2, 1);
- _actor11.setPosition(Common::Point(408, 121));
+ _animation.setup(1100, 2, 1);
+ _animation.setPosition(Common::Point(408, 121));
- _actor10.setup(1100, 3, 5);
- _actor10.setPosition(Common::Point(409, 121));
+ _laserShot.setup(1100, 3, 5);
+ _laserShot.setPosition(Common::Point(409, 121));
- setAction(&_sequenceManager1, this, 1104, &_actor17, NULL);
+ setAction(&_sequenceManager1, this, 1104, &_trooper, NULL);
break;
case 14:
- setAction(&_sequenceManager1, this, 1100, &_actor11, &_actor10, NULL);
+ setAction(&_sequenceManager1, this, 1100, &_animation, &_laserShot, NULL);
break;
case 15:
R2_GLOBALS._sceneManager.changeScene(1000);
@@ -1115,14 +1117,14 @@ void Scene1100::signal() {
break;
case 21: {
R2_GLOBALS._sound2.play(92);
- _actor17.animate(ANIM_MODE_5, NULL);
+ _trooper.animate(ANIM_MODE_5, NULL);
Common::Point pt(187, 45);
NpcMover *mover = new NpcMover();
_actor1.addMover(mover, &pt, this);
}
break;
case 22:
- setAction(&_sequenceManager1, this, 1110, &_actor16, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 1110, &_seeker, &R2_GLOBALS._player, NULL);
break;
case 23:
R2_GLOBALS._player.disableControl();
@@ -1136,74 +1138,77 @@ void Scene1100::signal() {
break;
case 25:
R2_GLOBALS._player.disableControl();
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
R2_GLOBALS._sound1.play(95);
- setAction(&_sequenceManager1, this, 1111, &_actor17, &R2_GLOBALS._player, &_actor16, NULL);
+ setAction(&_sequenceManager1, this, 1111, &_trooper, &R2_GLOBALS._player, &_seeker, NULL);
break;
case 26:
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(302, this);
break;
case 27:
R2_GLOBALS._player.disableControl();
- setAction(&_sequenceManager1, this, 1120, &_actor16, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 1120, &_seeker, &R2_GLOBALS._player, NULL);
break;
case 28:
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(303, this);
break;
+ case 29:
+ case 50:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
case 51:
R2_GLOBALS.setFlag(53);
- _actor17.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
- // No break on purpose
- case 50:
- // No break on purpose
- case 29:
+ _trooper.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
+
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
case 52:
R2_GLOBALS._sound1.play(98);
R2_GLOBALS.setFlag(52);
R2_GLOBALS._player.disableControl();
_sceneMode = 1116;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
setAction(&_sequenceManager1, this, 1116, &R2_GLOBALS._player, NULL);
- _actor16.setAction(&_sequenceManager2, NULL, 1123, &_actor16, NULL);
+ _seeker.setAction(&_sequenceManager2, NULL, 1123, &_seeker, NULL);
} else {
setAction(&_sequenceManager1, this, 1124, &R2_GLOBALS._player, NULL);
- _actor16.setAction(&_sequenceManager2, NULL, 1117, &_actor16, NULL);
+ _seeker.setAction(&_sequenceManager2, NULL, 1117, &_seeker, NULL);
}
break;
case 53:
_sceneMode = 54;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (_field412 == 0) {
+ if (_nextStripNum == 0) {
R2_GLOBALS.setFlag(55);
if (R2_GLOBALS.getFlag(55)) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(318, this);
else
_stripManager.start(323, this);
} else {
// This part is totally useless as flag 55 has been set right before the check
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(317, this);
else
_stripManager.start(322, this);
}
} else {
- _stripManager.start3(_field412, this, _stripManager._lookupList);
+ _stripManager.start3(_nextStripNum, this, _stripManager._lookupList);
}
break;
case 54:
- if (_stripManager._field2E8 == 1) {
+ if (_stripManager._exitMode == 1) {
R2_GLOBALS._player.disableControl();
_sceneMode = 1125;
- setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_actor16, NULL);
+ setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_seeker, NULL);
} else
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
@@ -1212,8 +1217,8 @@ void Scene1100::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 99:
- R2_GLOBALS._player._characterScene[1] = 300;
- R2_GLOBALS._player._characterScene[2] = 300;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 300;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 300;
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._sceneManager.changeScene(300);
break;
@@ -1244,9 +1249,9 @@ void Scene1100::signal() {
break;
case 1116:
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
break;
case 1125: {
_sceneMode = 99;
@@ -1265,37 +1270,37 @@ void Scene1100::signal() {
}
void Scene1100::dispatch() {
- if ((g_globals->_sceneObjects->contains(&_actor10)) && (_actor10._visage == 1102) && (_actor10._strip == 4) && (_actor10._frame == 1) && (_actor10._flags & OBJFLAG_HIDING)) {
- if (_field414 == 1) {
- _field414 = 2;
+ if ((g_globals->_sceneObjects->contains(&_laserShot)) && (_laserShot._visage == 1102) && (_laserShot._strip == 4) && (_laserShot._frame == 1) && (_laserShot._flags & OBJFLAG_HIDING)) {
+ if (_paletteRefreshStatus == 1) {
+ _paletteRefreshStatus = 2;
R2_GLOBALS._scenePalette.refresh();
}
} else {
- if (_field414 == 2)
+ if (_paletteRefreshStatus == 2)
R2_GLOBALS._scenePalette.refresh();
- _field414 = 1;
+ _paletteRefreshStatus = 1;
}
Scene::dispatch();
- if (R2_GLOBALS._player._bounds.contains(_actor13._position))
- _actor13._shade = 3;
+ if (R2_GLOBALS._player._bounds.contains(_runningGuy1._position))
+ _runningGuy1._shade = 3;
else
- _actor13._shade = 0;
+ _runningGuy1._shade = 0;
- if (R2_GLOBALS._player._bounds.contains(_actor14._position))
- _actor14._shade = 3;
+ if (R2_GLOBALS._player._bounds.contains(_runningGuy2._position))
+ _runningGuy2._shade = 3;
else
- _actor14._shade = 0;
+ _runningGuy2._shade = 0;
- if (R2_GLOBALS._player._bounds.contains(_actor15._position))
- _actor15._shade = 3;
+ if (R2_GLOBALS._player._bounds.contains(_runningGuy3._position))
+ _runningGuy3._shade = 3;
else
- _actor15._shade = 0;
+ _runningGuy3._shade = 0;
}
void Scene1100::saveCharacter(int characterIndex) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
}
@@ -5973,7 +5978,8 @@ void Scene1337::subCF31D() {
if ((_arrunkObj1337[1]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[1]._arr3[0]._field34))) {
subC340B(&_arrunkObj1337[1]._arr1[tmpVal], &_arrunkObj1337[1]._arr2[i]);
found = true;
- }
+ break;
+ }
}
}
@@ -5983,8 +5989,10 @@ void Scene1337::subCF31D() {
tmpVal = subC274D(1);
int tmpVal2 = subC331B(1);
- if ((tmpVal != -1) && ( tmpVal2 != -1))
+ if ((tmpVal != -1) && ( tmpVal2 != -1)) {
subC358E(&_arrunkObj1337[1]._arr1[tmpVal], tmpVal2);
+ found = true;
+ }
if (found)
return;
@@ -7008,7 +7016,7 @@ void Scene1500::signal() {
}
break;
case 24:
- R2_GLOBALS._sceneManager.changeScene(300);
+ R2_GLOBALS._sceneManager.changeScene(1550);
break;
default:
break;
@@ -7169,21 +7177,22 @@ void Scene1530::dispatch() {
}
/*--------------------------------------------------------------------------
- * Scene 1550 -
+ * Scene 1550 - Spaceport
*
*--------------------------------------------------------------------------*/
-Scene1550::UnkObj15501::UnkObj15501() {
- _fieldA4 = _fieldA6 = 0;
+
+Scene1550::Junk::Junk() {
+ _fieldA4 = _junkNumber = 0;
}
-void Scene1550::UnkObj15501::synchronize(Serializer &s) {
+void Scene1550::Junk::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_junkNumber);
}
-bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
+bool Scene1550::Junk::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -7236,36 +7245,36 @@ bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
}
}
-Scene1550::UnkObj15502::UnkObj15502() {
- _fieldA4 = 0;
+Scene1550::ShipComponent::ShipComponent() {
+ _componentId = 0;
}
-void Scene1550::UnkObj15502::synchronize(Serializer &s) {
+void Scene1550::ShipComponent::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_componentId);
}
-bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
+bool Scene1550::ShipComponent::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if (_fieldA4 == 8) {
+ if (_componentId == 8) {
scene->_field412 = 1;
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1576;
else
scene->_sceneMode = 1584;
- // strcpy(scene->_arrUnkObj15502[7]._actorName, 'hatch');
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[7], NULL);
+ // strcpy(scene->_shipComponents[7]._actorName, 'hatch');
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[7], NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case CURSOR_LOOK:
- if (_fieldA4 == 8)
+ if (_componentId == 8)
SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
else if (_frame == 1)
SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
@@ -7275,92 +7284,92 @@ bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
break;
case R2_FUEL_CELL:
scene->_field412 = 1;
- if (_fieldA4 == 6) {
+ if (_componentId == 6) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1574;
else
scene->_sceneMode = 1582;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[5], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[5], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GYROSCOPE:
scene->_field412 = 1;
- if (_fieldA4 == 3) {
+ if (_componentId == 3) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1571;
else
scene->_sceneMode = 1581;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[2], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[2], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GUIDANCE_MODULE:
scene->_field412 = 1;
- if (_fieldA4 == 1) {
+ if (_componentId == 1) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1569;
else
scene->_sceneMode = 1579;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[0], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[0], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_THRUSTER_VALVE:
scene->_field412 = 1;
- if (_fieldA4 == 4) {
+ if (_componentId == 4) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1572;
- scene->_actor1.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[3], &scene->_actor1, NULL);
+ scene->_landingStrut.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[3], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_RADAR_MECHANISM:
scene->_field412 = 1;
- if (_fieldA4 == 2) {
+ if (_componentId == 2) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1570;
else
scene->_sceneMode = 1580;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[1], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[1], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_IGNITOR:
scene->_field412 = 1;
- if (_fieldA4 == 5) {
+ if (_componentId == 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1573;
- scene->_actor1.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[4], &scene->_actor1, NULL);
+ scene->_landingStrut.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[4], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_BATTERY:
scene->_field412 = 1;
- if (_fieldA4 == 7) {
+ if (_componentId == 7) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1575;
else
scene->_sceneMode = 1583;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[6], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[6], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
@@ -7371,47 +7380,48 @@ bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
}
}
-void Scene1550::UnkObj15502::subA5CDF(int strip) {
- _fieldA4 = strip;
+void Scene1550::ShipComponent::setupShipComponent(int componentId) {
+ _componentId = componentId;
postInit();
- setup(1517, _fieldA4, 1);
- switch (_fieldA4 - 1) {
- case 0:
+ setup(1517, _componentId, 1);
+
+ switch (_componentId) {
+ case 1:
if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
setFrame(5);
setPosition(Common::Point(287, 85));
break;
- case 1:
+ case 2:
if (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0)
setFrame(5);
setPosition(Common::Point(248, 100));
break;
- case 2:
- if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 0)
+ case 3:
+ if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 0)
setFrame(5);
setPosition(Common::Point(217, 85));
break;
- case 3:
- if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE))
+ case 4:
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 0)
setFrame(5);
setPosition(Common::Point(161, 121));
break;
- case 4:
- if (R2_INVENTORY.getObjectScene(R2_IGNITOR))
+ case 5:
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 0)
setFrame(5);
setPosition(Common::Point(117, 121));
break;
- case 5:
- if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL))
+ case 6:
+ if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) == 0)
setFrame(5);
setPosition(Common::Point(111, 85));
break;
- case 6:
- if (R2_INVENTORY.getObjectScene(R2_BATTERY))
+ case 7:
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 0)
setFrame(5);
setPosition(Common::Point(95, 84));
break;
- case 7: {
+ case 8: {
setup(1516, 1, 1);
setPosition(Common::Point(201, 45));
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
@@ -7424,6 +7434,9 @@ void Scene1550::UnkObj15502::subA5CDF(int strip) {
default:
break;
}
+
+ fixPriority(92);
+ setDetails(1550, 70, -1, -1, 2, (SceneItem *)NULL);
}
Scene1550::UnkObj15503::UnkObj15503() {
@@ -7510,19 +7523,16 @@ void Scene1550::UnkArea1550::process(Event &event) {
if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
- warning("TODO: _cursorState = ???");
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
remove();
}
}
@@ -7570,26 +7580,30 @@ void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum
_areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
}
-bool Scene1550::Hotspot1::startAction(CursorType action, Event &event) {
+bool Scene1550::WorkingShip::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
bool Scene1550::Hotspot3::startAction(CursorType action, Event &event) {
// Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
- assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ assert ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS._player._characterIndex == R2_SEEKER));
// The original contains a debug message when CURSOR_TALK is used.
// This part is totally useless, we could remove it (and the entire function as well)
if (action == CURSOR_TALK)
- warning("Location: %d/%d - %d", R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex], R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2], k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]);
+ warning("Location: %d/%d - %d",
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x,
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y,
+ scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30)] +
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x);
return SceneHotspot::startAction(action, event);
}
-bool Scene1550::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1550::Wreckage::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1550::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1550::Companion::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
@@ -7607,7 +7621,7 @@ bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1552;
else
scene->_sceneMode = 1588;
@@ -7624,7 +7638,7 @@ bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
scene->_sceneMode = 50;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start(518, scene);
else
scene->_stripManager.start(520, scene);
@@ -7645,7 +7659,7 @@ bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1555;
else
scene->_sceneMode = 1589;
@@ -7661,7 +7675,7 @@ bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1586;
else
scene->_sceneMode = 1587;
@@ -7676,7 +7690,7 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1585;
scene->setAction(&scene->_sequenceManager1, scene, 1585, &R2_GLOBALS._player, NULL);
@@ -7756,23 +7770,26 @@ void Scene1550::synchronize(Serializer &s) {
}
void Scene1550::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11))
+ // Exiting the intact spaceship
loadScene(1234);
else
+ // Normal scene entry
loadScene(1550);
+ SceneExt::postInit();
scalePalette(65, 65, 65);
setZoomPercents(30, 75, 170, 100);
_field417 = 1550;
_field419 = 0;
- SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS.setFlag(R2_ATTRACTOR_CABLE_HARNESS);
+ R2_GLOBALS.setFlag(16);
- if ((R2_GLOBALS._player._characterScene[1] != 1550) && (R2_GLOBALS._player._characterScene[1] != 1580)) {
- R2_GLOBALS._player._characterScene[1] = 1550;
- R2_GLOBALS._player._characterScene[2] = 1550;
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] != 1550) && (R2_GLOBALS._player._characterScene[R2_QUINN] != 1580)) {
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1550;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1550;
}
_stripManager.setColors(60, 255);
@@ -7783,14 +7800,15 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player._effect = 6;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setup(1500, 3, 1);
else
R2_GLOBALS._player.setup(1505, 3, 1);
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11))
R2_GLOBALS._player.setPosition(Common::Point(157, 135));
else
R2_GLOBALS._player.setPosition(Common::Point(160, 100));
@@ -7799,7 +7817,7 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
_field414 = 0;
- _actor7.changeZoom(-1);
+ _companion.changeZoom(-1);
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._sceneManager._previousScene) {
@@ -7814,21 +7832,22 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(105);
break;
case 1580:
+ // Leaving intact ship
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1580) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
_field412 = 1;
- _actor1.postInit();
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[7].hide();
- if (R2_GLOBALS._player._characterIndex == 1)
+ _landingStrut.postInit();
+ _shipComponents[7].setupShipComponent(8);
+ _shipComponents[7].hide();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 1577;
else
_sceneMode = 1578;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_arrUnkObj15502[7], NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_landingStrut, &_shipComponents[7], NULL);
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
} else {
R2_GLOBALS._player.enableControl();
@@ -7838,29 +7857,29 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
break;
}
- subA2B2F();
+ enterArea();
- _item1.setDetails(16, 1550, 10, -1, -1);
+ _shipHull.setDetails(16, 1550, 10, -1, -1);
_item2.setDetails(24, 1550, 10, -1, -1);
_item3.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
_sceneMode = 70;
- if (!R2_GLOBALS._sceneObjects->contains(&_actor7))
- _actor7.postInit();
+ if (!R2_GLOBALS._sceneObjects->contains(&_companion))
+ _companion.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor7.setVisage(1505);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(1505);
else
- _actor7.setVisage(1500);
+ _companion.setVisage(1500);
- _actor7.changeZoom(77);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.changeZoom(77);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
assert(_field419 >= 1550);
R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
- setAction(&_sequenceManager1, this, 1590, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1590, &_companion, NULL);
} else if ((_sceneMode != 1577) && (_sceneMode != 1578))
R2_GLOBALS._player.enableControl();
}
@@ -7876,7 +7895,7 @@ void Scene1550::signal() {
case 7:
_field412 = 0;
R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 20:
// No break on purpose
@@ -7917,14 +7936,14 @@ void Scene1550::signal() {
break;
case 40: {
_sceneMode = 41;
- Common::Point pt(_arrUnkObj15501[0]._position.x, _arrUnkObj15501[0]._position.y + 20);
+ Common::Point pt(_junk[0]._position.x, _junk[0]._position.y + 20);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 41:
_sceneMode = 42;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1502, 8, 1);
} else {
R2_GLOBALS._player.changeZoom(R2_GLOBALS._player._percent + 14);
@@ -7932,37 +7951,42 @@ void Scene1550::signal() {
}
R2_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
- case 42:
+
+ case 42: {
_sceneMode = 43;
- warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
- switch (_arrUnkObj15501[0]._frame - 1) {
- case 0:
- R2_INVENTORY.setObjectScene(26, R2_GLOBALS._player._characterIndex);
- break;
+ int junkRegionIndex = R2_GLOBALS._scene1550JunkLocations[_junk[0]._junkNumber + 3];
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[junkRegionIndex]);
+
+ switch (_junk[0]._frame) {
case 1:
- R2_INVENTORY.setObjectScene(17, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, R2_GLOBALS._player._characterIndex);
break;
case 2:
- R2_INVENTORY.setObjectScene(22, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_FUEL_CELL, R2_GLOBALS._player._characterIndex);
break;
case 3:
- R2_INVENTORY.setObjectScene(25, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, R2_GLOBALS._player._characterIndex);
break;
case 4:
- R2_INVENTORY.setObjectScene(45, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, R2_GLOBALS._player._characterIndex);
break;
case 5:
- R2_INVENTORY.setObjectScene(28, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_BATTERY, R2_GLOBALS._player._characterIndex);
+ break;
+ case 6:
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
break;
default:
break;
}
- _arrUnkObj15501[0].remove();
+
+ _junk[0].remove();
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
+ }
case 43:
- warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
- if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._scene1550JunkLocations[_junk[0]._junkNumber + 2] = 0;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setVisage(1500);
else {
R2_GLOBALS._player.changeZoom(-1);
@@ -7976,29 +8000,29 @@ void Scene1550::signal() {
warning("STUB: sub_1D227()");
++_sceneMode;
setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
- if (g_globals->_sceneObjects->contains(&_actor7))
+ if (g_globals->_sceneObjects->contains(&_companion))
signal();
else {
- _actor7.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor7.setVisage(1505);
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(1505);
else
- _actor7.setVisage(1500);
- _actor7.changeZoom(77);
- _actor7.setAction(&_sequenceManager2, this, 1590, &_actor7, NULL);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setVisage(1500);
+ _companion.changeZoom(77);
+ _companion.setAction(&_sequenceManager2, this, 1590, &_companion, NULL);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
break;
case 51:
++_sceneMode;
break;
case 52:
- _actor7.changeZoom(-1);
+ _companion.changeZoom(-1);
_sceneMode = 1592;
- if (R2_GLOBALS._player._characterIndex == 1)
- setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
else
- setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
break;
case 61:
R2_GLOBALS._player.enableControl(CURSOR_USE);
@@ -8013,9 +8037,8 @@ void Scene1550::signal() {
}
break;
case 70:
- R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
- R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
- R2_GLOBALS._v565EC[0] = 1;
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
+ //R2_GLOBALS._s1550PlayerAreas[0] = 1;
_sceneMode = 60;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(500, this);
@@ -8026,13 +8049,13 @@ void Scene1550::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(499 + R2_GLOBALS._v565AE, this);
else
_stripManager.start(502 + R2_GLOBALS._v565AE, this);
@@ -8042,13 +8065,13 @@ void Scene1550::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._v565AE >= 4) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(563 + R2_GLOBALS._v565AE, this);
else
_stripManager.start(567 + R2_GLOBALS._v565AE, this);
@@ -8112,7 +8135,7 @@ void Scene1550::signal() {
// No break on purpose
case 1579:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8120,7 +8143,7 @@ void Scene1550::signal() {
// No break on purpose
case 1580:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8128,19 +8151,19 @@ void Scene1550::signal() {
// No break on purpose
case 1581:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1572:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1573:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_IGNITOR, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8148,7 +8171,7 @@ void Scene1550::signal() {
// No break on purpose
case 1582:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_FUEL_CELL, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8156,7 +8179,7 @@ void Scene1550::signal() {
// No break on purpose
case 1583:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_BATTERY, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8170,7 +8193,7 @@ void Scene1550::signal() {
// No break on purpose
case 1578:
_sceneMode = 0;
- _actor1.remove();
+ _landingStrut.remove();
_field412 = 0;
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.enableControl();
@@ -8183,19 +8206,17 @@ void Scene1550::signal() {
// No break on purpose
case 1587:
R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
- _actor1.remove();
+ _landingStrut.remove();
_field412 = 0;
R2_GLOBALS._player.enableControl();
break;
case 1592:
_actor9.remove();
R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1);
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
- R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
} else {
- R2_GLOBALS._v565EC[1] = R2_GLOBALS._v565EC[2];
- R2_GLOBALS._v565EC[3] = R2_GLOBALS._v565EC[4];
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN] = R2_GLOBALS._s1550PlayerArea[R2_SEEKER];
}
R2_GLOBALS._player.enableControl();
break;
@@ -8227,11 +8248,11 @@ void Scene1550::dispatch() {
Scene::dispatch();
// Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
- assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ assert ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS._player._characterIndex == R2_SEEKER));
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 15) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 16)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 15) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 16)) {
R2_GLOBALS._player._shade = 0;
- // Original game contains a switch based on an uninitialised variable.
+ // Original game contains a switch based on an uninitialized variable.
// Until we understand what should really happen there, this code is unused on purpose
int missingVariable = 0;
switch (missingVariable) {
@@ -8263,12 +8284,13 @@ void Scene1550::dispatch() {
case 0:
// No break on purpose
case 5:
+ // Exiting the top of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 1;
_field412 = 1;
- --R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ --R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
- subA2B2F();
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 108) * 172) / 100), 145));
if (R2_GLOBALS._player._position.x < 160) {
@@ -8286,12 +8308,13 @@ void Scene1550::dispatch() {
}
break;
case 1:
+ // Exiting the bottom of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 3;
_field412 = 1;
- ++R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
- subA2B2F();
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 172) * 108) / 100), 19));
if (R2_GLOBALS._player._position.x < 160) {
@@ -8309,14 +8332,15 @@ void Scene1550::dispatch() {
}
break;
case 2:
+ // Exiting the right of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 5;
_field412 = 1;
- ++R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
- subA2B2F();
+ enterArea();
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
if (R2_GLOBALS._player._position.y >= 85) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y + 20);
@@ -8336,16 +8360,20 @@ void Scene1550::dispatch() {
}
break;
case 3:
+ // Exiting to the left of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 7;
_field412 = 1;
- --R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 24) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
+ --R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
+
+ enterArea();
+
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 24) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11)) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y / 2));
Common::Point pt(265, 29);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ } else if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
if (R2_GLOBALS._player._position.y >= 85) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y + 20);
@@ -8370,7 +8398,7 @@ void Scene1550::dispatch() {
}
void Scene1550::saveCharacter(int characterIndex) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
@@ -8560,7 +8588,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
}
-void Scene1550::subA2B2F() {
+void Scene1550::enterArea() {
Rect tmpRect;
_field419 = 0;
_field415 = 0;
@@ -8568,19 +8596,19 @@ void Scene1550::subA2B2F() {
tmpRect = R2_GLOBALS._v5589E;
_actor14.remove();
- _actor17.remove();
- _actor15.remove();
- _actor19.remove();
+ _westWall.remove();
+ _northWall.remove();
+ _southWall.remove();
_actor16.remove();
- _actor18.remove();
+ _eastWall.remove();
for (int i = 0; i < 8; ++i)
- _arrUnkObj15501[i].remove();
+ _junk[i].remove();
- _actor6.remove();
+ _wreckage.remove();
for (int i = 0; i < 8; ++i)
- _arrUnkObj15502[i].remove();
+ _shipComponents[i].remove();
_actor8.remove();
_actor9.remove();
@@ -8589,18 +8617,19 @@ void Scene1550::subA2B2F() {
_actor11.remove();
if ((_sceneMode != 1577) && (_sceneMode != 1578))
- _actor1.remove();
+ _landingStrut.remove();
_actor2.remove();
- _actor7.remove();
+ _companion.remove();
_actor13.remove();
_actor5.remove();
_actor12.remove();
_actor4.remove();
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2]) {
+ // Set up of special walk regions for certain areas
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y) {
case 0:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 3:
R2_GLOBALS._walkRegions.load(1554);
_field419 = 1554;
@@ -8616,7 +8645,7 @@ void Scene1550::subA2B2F() {
case 3:
// No break on purpose
case 4:
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 23) || (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex])) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 23) || (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x)) {
if (!R2_GLOBALS.getFlag(16)) {
R2_GLOBALS._walkRegions.load(1559);
_field419 = 1559;
@@ -8624,7 +8653,7 @@ void Scene1550::subA2B2F() {
}
break;
case 7:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 10:
R2_GLOBALS._walkRegions.load(1555);
_field419 = 1555;
@@ -8638,7 +8667,7 @@ void Scene1550::subA2B2F() {
}
break;
case 11:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 24:
R2_GLOBALS._walkRegions.load(1558);
_field419 = 1558;
@@ -8652,7 +8681,7 @@ void Scene1550::subA2B2F() {
}
break;
case 16:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 2:
R2_GLOBALS._walkRegions.load(1552);
_field419 = 1552;
@@ -8675,12 +8704,12 @@ void Scene1550::subA2B2F() {
int varA = 0;
if (!R2_GLOBALS.getFlag(16)) {
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] - 2) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y - 2) {
case 0:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 22) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 22) {
case 0:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.subA4D14(6, 0);
break;
case 1:
// No break on purpose
@@ -8693,7 +8722,7 @@ void Scene1550::subA2B2F() {
break;
case 5:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.subA4D14(6, 0);
break;
default:
break;
@@ -8702,14 +8731,14 @@ void Scene1550::subA2B2F() {
case 1:
// No break on purpose
case 2:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _actor15.subA4D14(9, 0);
+ _northWall.subA4D14(9, 0);
break;
case 1:
varA = 1552;
- _actor15.subA4D14(10, 0);
+ _northWall.subA4D14(10, 0);
break;
case 2:
// No break on purpose
@@ -8722,25 +8751,25 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1552;
- _actor15.subA4D14(7, 0);
+ _northWall.subA4D14(7, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(8, 0);
+ _northWall.subA4D14(8, 0);
break;
default:
break;
}
break;
case 3:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _actor15.subA4D14(4, 0);
+ _northWall.subA4D14(4, 0);
break;
case 1:
varA = 1550;
- _actor15.subA4D14(3, 0);
+ _northWall.subA4D14(3, 0);
break;
case 2:
// No break on purpose
@@ -8753,11 +8782,11 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1550;
- _actor15.subA4D14(2, 0);
+ _northWall.subA4D14(2, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(1, 0);
+ _northWall.subA4D14(1, 0);
break;
default:
break;
@@ -8766,21 +8795,22 @@ void Scene1550::subA2B2F() {
default:
break;
}
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 0) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] <= 29) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] >= 20) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 7)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 0) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x <= 29) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x >= 20) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 7)) {
R2_GLOBALS.setFlag(16);
R2_GLOBALS._sceneManager.changeScene(1500);
}
}
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
- if (R2_GLOBALS._sceneManager._sceneNumber != 1234) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11)) {
+ if (_screenNumber != 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1234);
R2_GLOBALS._sceneManager._hasPalette = false;
_field414 = 0;
}
} else {
- if (R2_GLOBALS._sceneManager._sceneNumber == 1234) {
+ if (_screenNumber == 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1550);
R2_GLOBALS._sceneManager._hasPalette = false;
@@ -8828,71 +8858,75 @@ void Scene1550::subA2B2F() {
}
}
- switch (k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ // Scene setup dependent on the type of cell specified in the scene map
+ switch (scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30) +
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x]) {
case 0:
+ // Standard cell
if (_field419 == 0) {
R2_GLOBALS._walkRegions.load(1550);
_field419 = 1550;
}
break;
case 1:
+ // North end of the spaceport
if (_field419 == 0) {
R2_GLOBALS._walkRegions.load(1560);
_field419 = 1560;
}
_actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
break;
case 2:
R2_GLOBALS._walkRegions.load(1561);
_field419 = 1561;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
- _actor15.subA4D14(1, 3);
+ _westWall.subA4D14(2, 2);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
break;
case 3:
R2_GLOBALS._walkRegions.load(1562);
_field419 = 1562;
_actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _eastWall.subA4D14(2, 6);
break;
case 4:
R2_GLOBALS._walkRegions.load(1563);
_field419 = 1563;
- _actor15.subA4D14(2, 3);
+ _northWall.subA4D14(2, 3);
break;
case 5:
R2_GLOBALS._walkRegions.load(1564);
_field419 = 1564;
- _actor19.subA4D14(2, 4);
+ _southWall.subA4D14(2, 4);
break;
case 6:
R2_GLOBALS._walkRegions.load(1565);
_field419 = 1565;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(3, 3);
+ _westWall.subA4D14(1, 2);
+ _northWall.subA4D14(3, 3);
break;
case 7:
R2_GLOBALS._walkRegions.load(1566);
_field419 = 1566;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(2, 4);
+ _westWall.subA4D14(1, 2);
+ _northWall.subA4D14(2, 4);
break;
case 8:
R2_GLOBALS._walkRegions.load(1567);
_field419 = 1567;
- _actor17.subA4D14(5, 2);
+ _westWall.subA4D14(5, 2);
break;
case 9:
R2_GLOBALS._walkRegions.load(1568);
_field419 = 1568;
- _actor17.subA4D14(4, 2);
+ _westWall.subA4D14(4, 2);
break;
case 10:
R2_GLOBALS._walkRegions.load(1569);
@@ -8903,56 +8937,57 @@ void Scene1550::subA2B2F() {
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
+ _westWall.subA4D14(1, 2);
break;
case 12:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _eastWall.subA4D14(1, 6);
break;
case 13:
R2_GLOBALS._walkRegions.load(1572);
_field419 = 1572;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor19.subA4D14(1, 4);
+ _westWall.subA4D14(1, 2);
+ _southWall.subA4D14(1, 4);
break;
case 14:
R2_GLOBALS._walkRegions.load(1573);
_field419 = 1573;
- _actor19.subA4D14(1, 4);
+ _southWall.subA4D14(1, 4);
_actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _eastWall.subA4D14(1, 6);
break;
case 15:
+ // South wall
R2_GLOBALS._walkRegions.load(1574);
_field419 = 1574;
- _actor19.subA4D14(1, 4);
+ _southWall.subA4D14(1, 4);
break;
case 16:
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
+ _westWall.subA4D14(2, 2);
break;
case 17:
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(3, 2);
+ _westWall.subA4D14(3, 2);
break;
case 18:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _eastWall.subA4D14(2, 6);
break;
case 19:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(3, 6);
+ _eastWall.subA4D14(3, 6);
break;
default:
break;
@@ -8960,24 +8995,27 @@ void Scene1550::subA2B2F() {
int di = 0;
int tmpIdx = 0;
- // Original game was checking "i < 129" but it was clearly a bug as it's out of bounds
- for (int i = 0; i < 129 * 4; i += 4) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k562CC[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k562CC[i + 1]) && (k562CC[i + 2] != 0)) {
- tmpIdx = k562CC[i + 3];
- _arrUnkObj15501[di].postInit();
- _arrUnkObj15501[di]._effect = 6;
- _arrUnkObj15501[di]._shade = 0;
- _arrUnkObj15501[di]._fieldA4 = tmpIdx;
- _arrUnkObj15501[di]._fieldA6 = i;
- _arrUnkObj15501[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
- if (k562CC[i + 2] == 41) {
- _arrUnkObj15501[di].changeZoom(-1);
- _arrUnkObj15501[di].setPosition(Common::Point(150, 70));
- _arrUnkObj15501[di].setup(1562, 1, 1);
- R2_GLOBALS._walkRegions.enableRegion(k5A78C);
- R2_GLOBALS._walkRegions.enableRegion(k5A78D);
- R2_GLOBALS._walkRegions.enableRegion(k5A790);
- R2_GLOBALS._walkRegions.enableRegion(k5A791);
+ for (int i = 0; i < 127 * 4; i += 4) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == R2_GLOBALS._scene1550JunkLocations[i]) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == R2_GLOBALS._scene1550JunkLocations[i + 1]) &&
+ (R2_GLOBALS._scene1550JunkLocations[i + 2] != 0)) {
+ tmpIdx = R2_GLOBALS._scene1550JunkLocations[i + 3];
+ _junk[di].postInit();
+ _junk[di]._effect = 6;
+ _junk[di]._shade = 0;
+ _junk[di]._fieldA4 = tmpIdx;
+ _junk[di]._junkNumber = i;
+ _junk[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] == 41) {
+ _junk[di].changeZoom(-1);
+ _junk[di].setPosition(Common::Point(150, 70));
+ _junk[di].setup(1562, 1, 1);
+
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[2]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[3]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[6]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[7]);
+
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1550) {
_actor9.postInit();
_actor9.setup(1562, 3, 1);
@@ -8986,35 +9024,36 @@ void Scene1550::subA2B2F() {
_actor9.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
}
} else {
- if (k562CC[i + 2] > 40) {
- _arrUnkObj15501[di].changeZoom(100);
- _arrUnkObj15501[di].setup(1561, 1, k562CC[i + 2] - 40);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] > 40) {
+ _junk[di].changeZoom(100);
+ _junk[di].setup(1561, 1, R2_GLOBALS._scene1550JunkLocations[i + 2] - 40);
} else {
- _arrUnkObj15501[di].changeZoom(-1);
- _arrUnkObj15501[di].setup(1552, ((k562CC[i + 2] - 1) / 5) + 1, ((k562CC[i + 2] - 1) % 5) + 1);
+ _junk[di].changeZoom(-1);
+ _junk[di].setup(1552, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) / 5) + 1, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) % 5) + 1);
}
- _arrUnkObj15501[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
- if (k5A78A[tmpIdx] != 0)
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[tmpIdx]);
+ _junk[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
+ if (scene1550JunkRegions[tmpIdx] != 0)
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[tmpIdx]);
di++;
}
}
}
for (int i = 0; i < 15 * 3; i++) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k5A79B[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k5A79B[i + 1])) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == k5A79B[i])
+ && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == k5A79B[i + 1])) {
tmpIdx = k5A79B[i + 2];
switch (tmpIdx - 1) {
case 0:
if (!R2_GLOBALS.getFlag(16)) {
- _actor1.postInit();
- if (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 3)
- _actor1.setup(1555, 2, 1);
+ _landingStrut.postInit();
+ if (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 3)
+ _landingStrut.setup(1555, 2, 1);
else
- _actor1.setup(1555, 1, 1);
- _actor1.setPosition(Common::Point(150, 100));
- _actor1.fixPriority(92);
- _actor1.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
+ _landingStrut.setup(1555, 1, 1);
+ _landingStrut.setPosition(Common::Point(150, 100));
+ _landingStrut.fixPriority(92);
+ _landingStrut.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
}
break;
case 1:
@@ -9053,20 +9092,20 @@ void Scene1550::subA2B2F() {
_actor4.setPosition(Common::Point(172, 48));
_actor4.fixPriority(169);
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[15]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[15]);
break;
case 2:
- _actor6.postInit();
- _actor6.setup(1550, 1, 1);
- _actor6.setPosition(Common::Point(259, 55));
- _actor6.fixPriority(133);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 1, 2);
- _actor1.setPosition(Common::Point(259, 133));
- _actor1.fixPriority(105);
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 1, 1);
+ _wreckage.setPosition(Common::Point(259, 55));
+ _wreckage.fixPriority(133);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 1, 2);
+ _landingStrut.setPosition(Common::Point(259, 133));
+ _landingStrut.fixPriority(105);
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 1550) {
_actor10.postInit();
_actor10.setup(1550, 7, 2);
@@ -9076,16 +9115,16 @@ void Scene1550::subA2B2F() {
}
break;
case 3:
- _actor6.postInit();
- _actor6.setup(1550, 1, 4);
- _actor6.setPosition(Common::Point(76, 131));
- _actor6.fixPriority(10);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 1, 3);
- _actor1.setPosition(Common::Point(76, 64));
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 1, 4);
+ _wreckage.setPosition(Common::Point(76, 131));
+ _wreckage.fixPriority(10);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 1, 3);
+ _landingStrut.setPosition(Common::Point(76, 64));
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1550) {
_actor11.postInit();
_actor11.setup(1504, 4, 1);
@@ -9104,48 +9143,48 @@ void Scene1550::subA2B2F() {
}
break;
case 4:
- _actor6.postInit();
- _actor6.setup(1550, 2, 4);
- _actor6.setPosition(Common::Point(243, 131));
- _actor6.fixPriority(10);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 2, 3);
- _actor1.setPosition(Common::Point(243, 64));
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 2, 4);
+ _wreckage.setPosition(Common::Point(243, 131));
+ _wreckage.fixPriority(10);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 2, 3);
+ _landingStrut.setPosition(Common::Point(243, 64));
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
case 5:
- _actor6.postInit();
- _actor6.setup(1550, 2, 1);
- _actor6.setPosition(Common::Point(60, 55));
- _actor6.fixPriority(133);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 2, 2);
- _actor1.setPosition(Common::Point(60, 133));
- _actor1.fixPriority(106);
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 2, 1);
+ _wreckage.setPosition(Common::Point(60, 55));
+ _wreckage.fixPriority(133);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 2, 2);
+ _landingStrut.setPosition(Common::Point(60, 133));
+ _landingStrut.fixPriority(106);
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
case 6:
- _actor6.postInit();
- _actor6.setup(1550, 3, 1);
- _actor6.setPosition(Common::Point(281, 132));
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 3, 1);
+ _wreckage.setPosition(Common::Point(281, 132));
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
break;
case 7:
- _actor6.postInit();
- _actor6.setup(1550, 3, 2);
- _actor6.setPosition(Common::Point(57, 96));
- _actor6.fixPriority(70);
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 3, 3);
- _actor1.setPosition(Common::Point(145, 88));
- _actor1.fixPriority(55);
- _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 3, 2);
+ _wreckage.setPosition(Common::Point(57, 96));
+ _wreckage.fixPriority(70);
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 3, 3);
+ _landingStrut.setPosition(Common::Point(145, 88));
+ _landingStrut.fixPriority(55);
+ _landingStrut.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
_actor2.postInit();
_actor2.setup(1550, 3, 4);
@@ -9159,17 +9198,17 @@ void Scene1550::subA2B2F() {
_actor3.fixPriority(45);
break;
case 8:
- _actor6.postInit();
- _actor6.setup(1550, 4, 2);
- _actor6.setPosition(Common::Point(262, 96));
- _actor6.fixPriority(70);
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 4, 3);
- _actor1.setPosition(Common::Point(174, 88));
- _actor1.fixPriority(55);
- _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 4, 2);
+ _wreckage.setPosition(Common::Point(262, 96));
+ _wreckage.fixPriority(70);
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 4, 3);
+ _landingStrut.setPosition(Common::Point(174, 88));
+ _landingStrut.fixPriority(55);
+ _landingStrut.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
_actor2.postInit();
_actor2.setup(1550, 4, 4);
@@ -9183,55 +9222,56 @@ void Scene1550::subA2B2F() {
_actor3.fixPriority(45);
break;
case 9:
- _actor6.postInit();
- _actor6.setup(1550, 4, 1);
- _actor6.setPosition(Common::Point(38, 132));
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 4, 1);
+ _wreckage.setPosition(Common::Point(38, 132));
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
break;
case 11:
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[0].subA5CDF(1);
- _arrUnkObj15502[1].subA5CDF(2);
- _arrUnkObj15502[2].subA5CDF(3);
- _arrUnkObj15502[3].subA5CDF(4);
- _arrUnkObj15502[4].subA5CDF(5);
- _arrUnkObj15502[5].subA5CDF(6);
- _arrUnkObj15502[6].subA5CDF(7);
+ // Intact ship
+ _shipComponents[7].setupShipComponent(8);
+ _shipComponents[0].setupShipComponent(1);
+ _shipComponents[1].setupShipComponent(2);
+ _shipComponents[2].setupShipComponent(3);
+ _shipComponents[3].setupShipComponent(4);
+ _shipComponents[4].setupShipComponent(5);
+ _shipComponents[5].setupShipComponent(6);
+ _shipComponents[6].setupShipComponent(7);
default:
break;
}
}
}
- if ((R2_GLOBALS._v565EC[1] == R2_GLOBALS._v565EC[2]) && (R2_GLOBALS._v565EC[3] == R2_GLOBALS._v565EC[4])) {
- _actor7.postInit();
- _actor7._effect = 7;
- _actor7.changeZoom(-1);
+ if (R2_GLOBALS._s1550PlayerArea[R2_QUINN] == R2_GLOBALS._s1550PlayerArea[R2_SEEKER]) {
+ _companion.postInit();
+ _companion._effect = 7;
+ _companion.changeZoom(-1);
assert((_field419 >= 1550) && (_field419 <= 2008));
R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
- _actor7.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
- if (R2_GLOBALS._player._characterIndex == 1) {
- if (R2_GLOBALS._player._characterScene[2] == 1580) {
- _actor7.setup(1516, 3, 17);
- _actor7.setPosition(Common::Point(272, 94));
- _actor7.fixPriority(91);
- _actor7.changeZoom(100);
- _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ _companion.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 1580) {
+ _companion.setup(1516, 3, 17);
+ _companion.setPosition(Common::Point(272, 94));
+ _companion.fixPriority(91);
+ _companion.changeZoom(100);
+ _companion.setDetails(1550, -1, -1, -1, 5, &_shipComponents[7]);
} else {
- _actor7.setup(1505, 6, 1);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setup(1505, 6, 1);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
} else {
- if (R2_GLOBALS._player._characterScene[1] == 1580) {
- _actor7.setup(1516, 2, 14);
- _actor7.setPosition(Common::Point(276, 97));
- _actor7.fixPriority(91);
- _actor7.changeZoom(100);
- _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 1580) {
+ _companion.setup(1516, 2, 14);
+ _companion.setPosition(Common::Point(276, 97));
+ _companion.fixPriority(91);
+ _companion.changeZoom(100);
+ _companion.setDetails(1550, -1, -1, -1, 5, &_shipComponents[7]);
} else {
- _actor7.setup(1500, 6, 1);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setup(1500, 6, 1);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
}
}
@@ -9636,7 +9676,7 @@ bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_JOYSTICK) {
- R2_INVENTORY.setObjectScene(26, 1580);
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1580);
R2_GLOBALS._sceneItems.remove(&scene->_item1);
scene->_actor2.postInit();
scene->_actor2.setup(1580, 1, 4);
@@ -9655,7 +9695,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_DIAGNOSTICS_DISPLAY) {
- R2_INVENTORY.setObjectScene(28, 1580);
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, 1580);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._sceneItems.remove(&scene->_item2);
@@ -9664,7 +9704,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
scene->_actor3.setPosition(Common::Point(124, 108));
scene->_actor3.fixPriority(10);
- if (R2_INVENTORY.getObjectScene(26) == 1580)
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580)
scene->_actor3.setDetails(1550, 14, -1, -1, 5, &scene->_actor2);
else
scene->_actor3.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
@@ -9684,15 +9724,15 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
}
bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
- if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(28) == 1580)
- && (R2_INVENTORY.getObjectScene(17) == 0) && (R2_INVENTORY.getObjectScene(22) == 0)
- && (R2_INVENTORY.getObjectScene(25) == 0) && (R2_INVENTORY.getObjectScene(18) == 0)
- && (R2_INVENTORY.getObjectScene(23) == 0) && (R2_INVENTORY.getObjectScene(27) == 0)) {
+ if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580)
+ && (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) == 0) && (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0) && (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 0) && (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 0)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 31;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start(536, scene);
else
scene->_stripManager.start(537, scene);
@@ -9704,10 +9744,10 @@ bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
}
bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(51) == 1580)) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
- R2_INVENTORY.setObjectScene(51, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_BROKEN_DISPLAY, R2_GLOBALS._player._characterIndex);
scene->_item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
scene->_actor1.remove();
remove();
@@ -9750,8 +9790,8 @@ bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_INVENTORY.setObjectScene(23, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 1);
remove();
return true;
}
@@ -9782,8 +9822,8 @@ bool Scene1580::Actor7::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_INVENTORY.setObjectScene(27, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_INVENTORY.setObjectScene(R2_IGNITOR, 1);
remove();
return true;
}
@@ -9823,7 +9863,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(26) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580) {
_actor2.postInit();
_actor2.setup(1580, 1, 4);
_actor2.setPosition(Common::Point(159, 163));
@@ -9832,7 +9872,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_item1.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
}
- if (R2_INVENTORY.getObjectScene(51) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580) {
_actor3.postInit();
_actor3.setup(1580, 1, 1);
_actor3.setPosition(Common::Point(124, 108));
@@ -9843,7 +9883,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor1.setup(1580, 1, 3);
_actor1.setPosition(Common::Point(124, 96));
_actor1.fixPriority(20);
- } else if (R2_INVENTORY.getObjectScene(28) == 1580) {
+ } else if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580) {
_actor3.postInit();
_actor3.setup(1580, 1, 1);
_actor3.setPosition(Common::Point(124, 108));
@@ -9861,7 +9901,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
}
_actor4.postInit();
- if (R2_INVENTORY.getObjectScene(58) == 0) {
+ if (R2_GLOBALS.getFlag(58) == 0) {
_actor4.setup(1580, 5, 1);
_actor4.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
} else {
@@ -9876,8 +9916,8 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor5.setPosition(Common::Point(291, 147));
_actor5.fixPriority(100);
_actor5.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
-
- if (R2_INVENTORY.getObjectScene(23) == 1580) {
+
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 1580) {
_actor6.postInit();
_actor6.setup(1580, 6, 2);
_actor6.setPosition(Common::Point(222, 108));
@@ -9885,7 +9925,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor6.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
}
- if (R2_INVENTORY.getObjectScene(27) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 1580) {
_actor7.postInit();
_actor7.setup(1580, 6, 1);
_actor7.setPosition(Common::Point(195, 108));
@@ -9894,11 +9934,9 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1580;
R2_GLOBALS._player.hide();
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
_item3.setDetails(Rect(0, 0, 320, 200), 1550, 50, -1, -1, 1, NULL);
-
}
void Scene1580::signal() {
@@ -9910,49 +9948,49 @@ void Scene1580::signal() {
_actor1.setup(1580, 1, 2);
_actor1.setPosition(Common::Point(124, 94));
- if (R2_INVENTORY.getObjectScene(18) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) != 0) {
_arrActor[0].postInit();
_arrActor[0].setup(1580, 2, 1);
_arrActor[0].setPosition(Common::Point(138, 56));
}
- if (R2_INVENTORY.getObjectScene(25) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) != 0) {
_arrActor[1].postInit();
_arrActor[1].setup(1580, 2, 2);
_arrActor[1].setPosition(Common::Point(140, 66));
}
- if (R2_INVENTORY.getObjectScene(27) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) != 0) {
_arrActor[2].postInit();
_arrActor[2].setup(1580, 2, 3);
_arrActor[2].setPosition(Common::Point(142, 85));
}
- if (R2_INVENTORY.getObjectScene(23) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) != 0) {
_arrActor[3].postInit();
_arrActor[3].setup(1580, 2, 4);
_arrActor[3].setPosition(Common::Point(142, 92));
}
- if (R2_INVENTORY.getObjectScene(22) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) != 0) {
_arrActor[4].postInit();
_arrActor[4].setup(1580, 2, 5);
_arrActor[4].setPosition(Common::Point(108, 54));
}
- if (R2_INVENTORY.getObjectScene(26) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) != 1580) {
_arrActor[5].postInit();
_arrActor[5].setup(1580, 2, 6);
_arrActor[5].setPosition(Common::Point(110, 64));
}
- if (R2_INVENTORY.getObjectScene(45) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) != 0) {
_arrActor[6].postInit();
_arrActor[6].setup(1580, 2, 7);
_arrActor[6].setPosition(Common::Point(108, 80));
}
- if (R2_INVENTORY.getObjectScene(17) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) != 0) {
_arrActor[7].postInit();
_arrActor[7].setup(1580, 2, 8);
_arrActor[7].setPosition(Common::Point(111, 92));
@@ -9978,17 +10016,8 @@ void Scene1580::signal() {
* Scene 1625 - Miranda being questioned
*
*--------------------------------------------------------------------------*/
-Scene1625::Scene1625() {
- _field412 = 0;
-}
-void Scene1625::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
-}
-
-bool Scene1625::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1625::Wire::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -9997,10 +10026,20 @@ bool Scene1625::Actor7::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1631;
scene->_actor3.postInit();
- scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_actor3, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_actor3, &scene->_wire, NULL);
return true;
}
+Scene1625::Scene1625() {
+ _field412 = 0;
+}
+
+void Scene1625::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+}
+
void Scene1625::postInit(SceneObjectList *OwnerList) {
loadScene(1625);
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
@@ -10011,23 +10050,24 @@ void Scene1625::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_soldierSpeaker);
R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
- _actor7.postInit();
- _actor7.setup(1626, 2, 1);
- _actor7.setPosition(Common::Point(206, 133));
- _actor7.setDetails(1625, 0, -1, -1, 1, (SceneItem *) NULL);
+ _wire.postInit();
+ _wire.setup(1626, 2, 1);
+ _wire.setPosition(Common::Point(206, 133));
+ _wire.setDetails(1625, 0, -1, -1, 1, (SceneItem *) NULL);
_actor5.postInit();
_actor5.setup(1625, 8, 1);
_actor5.setPosition(Common::Point(190, 131));
_actor5.setDetails(1625, 6, -1, 2, 1, (SceneItem *) NULL);
- if (R2_GLOBALS._player._oldCharacterScene[3] == 1625) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 1625) {
if (!R2_GLOBALS.getFlag(83)) {
- _actor4.postInit();
- _actor4.setup(1626, 4, 1);
- _actor4.setPosition(Common::Point(96, 166));
- _actor4.setDetails(1625, -1, -1, -1, 1, (SceneItem *) NULL);
+ _glass.postInit();
+ _glass.setup(1626, 4, 1);
+ _glass.setPosition(Common::Point(96, 166));
+ _glass.setDetails(1625, -1, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
@@ -10044,8 +10084,8 @@ void Scene1625::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(245);
_item1.setDetails(Rect(0, 0, 320, 200), 1625, 12, -1, -1, 1, NULL);
- R2_GLOBALS._player._oldCharacterScene[3] = 1625;
- R2_GLOBALS._player._characterScene[3] = 1625;
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1625;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 1625;
}
void Scene1625::remove() {
@@ -10057,70 +10097,69 @@ void Scene1625::signal() {
switch (_sceneMode) {
case 10:
R2_GLOBALS._player.disableControl();
- _actor4.postInit();
- _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ _glass.postInit();
+ _glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1626;
- setAction(&_sequenceManager, this, 1626, &_actor2, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1626, &_tealHead, &_glass, NULL);
break;
case 12:
- // TODO: check if OK_BTN_STRING is required
MessageDialog::show(DONE_MSG, OK_BTN_STRING);
break;
case 14:
- _actor2.postInit();
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
+ _tealHead.postInit();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(831, this);
break;
case 99:
R2_GLOBALS._player.disableControl();
- switch (_stripManager._field2E8) {
- case 0:
+ switch (_stripManager._exitMode) {
+ case 1:
_sceneMode = 1627;
- setAction(&_sequenceManager, this, 1627, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1627, &_actor3, &_glass, NULL);
break;
- case 1:
+ case 2:
_sceneMode = 1629;
- setAction(&_sequenceManager, this, 1629, &_actor2, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1629, &_tealHead, &_actor5, NULL);
break;
- case 3:
- R2_GLOBALS._player._oldCharacterScene[3] = 3150;
- R2_GLOBALS._player._characterScene[3] = 3150;
+ case 4:
+ R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3150;
+ R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3150;
R2_GLOBALS._player._characterIndex = R2_QUINN;
- R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[1]);
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[R2_QUINN]);
break;
- case 4:
+ case 5:
_sceneMode = 1628;
- _actor2.remove();
- setAction(&_sequenceManager, this, 1628, &_actor3, &_actor4, NULL);
+ _tealHead.remove();
+ setAction(&_sequenceManager, this, 1628, &_actor3, &_glass, NULL);
break;
- case 5:
- _actor4.postInit();
- _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ case 6:
+ _glass.postInit();
+ _glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1632;
- setAction(&_sequenceManager, this, 1632, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1632, &_glass, NULL);
break;
- case 6:
+ case 7:
_sceneMode = 1633;
- setAction(&_sequenceManager, this, 1633, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 1633, &_glass, NULL);
break;
- case 7:
+ case 8:
_sceneMode = 1635;
setAction(&_sequenceManager, this, 1635, &_actor3, &_actor5, NULL);
break;
- case 8:
- _actor4.postInit();
- _actor4.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
+ case 9:
+ _glass.postInit();
+ _glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1634;
setAction(&_sequenceManager, this, 1634, &_actor3, &_actor5, NULL);
break;
- case 2:
+ case 3:
// No break on purpose
default:
_sceneMode = 1630;
- _actor2.postInit();
+ _tealHead.remove();
setAction(&_sequenceManager, this, 1630, &_actor1, &_actor6, NULL);
break;
}
@@ -10128,17 +10167,17 @@ void Scene1625::signal() {
_stripManager._field2E8 = 0;
break;
case 1625:
- _actor2.postInit();
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
+ _tealHead.postInit();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
_sceneMode = 10;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(800, this);
break;
case 1626:
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
- _actor2.show();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
+ _tealHead.show();
_actor3.postInit();
_actor3.setup(1627, 3, 1);
@@ -10159,9 +10198,9 @@ void Scene1625::signal() {
break;
case 1628:
R2_GLOBALS.setFlag(83);
- _actor2.postInit();
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
+ _tealHead.postInit();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
_actor3.setup(1627, 3, 1);
_actor3.setPosition(Common::Point(196, 65));
@@ -10172,9 +10211,9 @@ void Scene1625::signal() {
_stripManager.start(834, this);
break;
case 1629:
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
- _actor2.show();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
+ _tealHead.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -10189,30 +10228,29 @@ void Scene1625::signal() {
_actor3.setPosition(Common::Point(196, 65));
_actor3.show();
- _actor7.remove();
+ _wire.remove();
_actor1.postInit();
_actor1.fixPriority(10);
_actor6.postInit();
- warning("_actor6._actorName = \"arm\";");
- R2_INVENTORY.setObjectScene(40, 3);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3);
_sceneMode = 14;
setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
break;
case 1632:
- _actor2.setup(1627, 1, 1);
- _actor2.setPosition(Common::Point(68, 68));
- _actor2.show();
+ _tealHead.setup(1627, 1, 1);
+ _tealHead.setPosition(Common::Point(68, 68));
+ _tealHead.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(835, this);
break;
case 1633:
- _actor4.remove();
+ _glass.remove();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(818, this);
@@ -10244,9 +10282,10 @@ void Scene1625::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 1700 -
+ * Scene 1700 - Rim
*
*--------------------------------------------------------------------------*/
+
Scene1700::Scene1700() {
_field77A = 0;
_field77C = 0;
@@ -10265,7 +10304,7 @@ bool Scene1700::Item2::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene1700::Actor11::startAction(CursorType action, Event &event) {
+bool Scene1700::RimTransport::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -10293,7 +10332,7 @@ bool Scene1700::Actor12::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1700::Exit1::changeScene() {
+void Scene1700::NorthExit::changeScene() {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -10305,7 +10344,7 @@ void Scene1700::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1700::Exit2::changeScene() {
+void Scene1700::SouthExit::changeScene() {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -10317,7 +10356,7 @@ void Scene1700::Exit2::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1700::Exit3::changeScene() {
+void Scene1700::WestExit::changeScene() {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -10329,20 +10368,20 @@ void Scene1700::Exit3::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1700::subAF3F8() {
+void Scene1700::enterArea() {
Rect tmpRect;
R2_GLOBALS._walkRegions.load(1700);
- _actor3.remove();
- _actor4.remove();
- _actor5.remove();
- _actor6.remove();
- _actor7.remove();
- _actor8.remove();
- _actor11.remove();
-
+ _slabWest.remove();
+ _slabEast.remove();
+ _slabShadowWest.remove();
+ _slabShadowEast.remove();
+ _westPlatform.remove();
+ _rimTransportDoor.remove();
+ _rimTransport.remove();
+
if (_sceneMode != 40) {
- _actor9.remove();
+ _ledgeHopper.remove();
_actor10.remove();
}
@@ -10358,68 +10397,72 @@ void Scene1700::subAF3F8() {
warning("set_pane_p(_paneNumber);");
- if ((_sceneMode != 40) && (R2_GLOBALS._v565F6 != 0)){
- _actor9.postInit();
- _actor9.setup(1701, 1, 1);
- _actor9.setPosition(Common::Point(220, 137));
- _actor9.setDetails(1700, 6, -1, -1, 2, (SceneItem *) NULL);
+ if (_sceneMode != 40 && R2_GLOBALS._rimLocation == 0) {
+ // Crashed ledge hopper
+ _ledgeHopper.postInit();
+ _ledgeHopper.setup(1701, 1, 1);
+ _ledgeHopper.setPosition(Common::Point(220, 137));
+ _ledgeHopper.setDetails(1700, 6, -1, -1, 2, (SceneItem *) NULL);
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(12);
}
- if ((R2_GLOBALS._v565F6 + 2) % 4 == 0) {
- _actor3.postInit();
- _actor3.setup(1700, 1, 1);
- _actor3.setPosition(Common::Point(222, 82));
- _actor3.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
+ if ((R2_GLOBALS._rimLocation + 2) % 4 == 0) {
+ // The slabs forming the bottom of the regular rings the rim transport travels through
+ _slabWest.postInit();
+ _slabWest.setup(1700, 1, 1);
+ _slabWest.setPosition(Common::Point(222, 82));
+ _slabWest.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5.setup(1700, 2, 1);
- _actor5.setPosition(Common::Point(177, 82));
- _actor5.fixPriority(0);
+ _slabShadowWest.postInit();
+ _slabShadowWest.setup(1700, 2, 1);
+ _slabShadowWest.setPosition(Common::Point(177, 82));
+ _slabShadowWest.fixPriority(0);
- _actor6.postInit();
- _actor6.setup(1700, 2, 2);
- _actor6.setPosition(Common::Point(332, 96));
- _actor6.fixPriority(0);
+ _slabShadowEast.postInit();
+ _slabShadowEast.setup(1700, 2, 2);
+ _slabShadowEast.setPosition(Common::Point(332, 96));
+ _slabShadowEast.fixPriority(0);
- _actor4.postInit();
- _actor4.setup(1700, 1, 2);
- _actor4.setPosition(Common::Point(424, 84));
+ _slabEast.postInit();
+ _slabEast.setup(1700, 1, 2);
+ _slabEast.setPosition(Common::Point(424, 84));
R2_GLOBALS._walkRegions.enableRegion(11);
}
- if ((R2_GLOBALS._v565F6 + 399) % 800 == 0) {
- _actor7.postInit();
- _actor7.setup(1700, 3, 2);
- _actor7.setPosition(Common::Point(51, 141));
- _actor7.fixPriority(0);
- _actor7.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
+ if ((R2_GLOBALS._rimLocation + 399) % 800 == 0) {
+ // Enable west exit to lift
+ _westPlatform.postInit();
+ _westPlatform.setup(1700, 3, 2);
+ _westPlatform.setPosition(Common::Point(51, 141));
+ _westPlatform.fixPriority(0);
+ _westPlatform.setDetails(100, -1, -1, -1, 2, (SceneItem *) NULL);
- _exit3._enabled = true;
+ _westExit._enabled = true;
} else {
R2_GLOBALS._walkRegions.enableRegion(1);
- _exit3._enabled = false;
+ _westExit._enabled = false;
}
- if ( ((!R2_GLOBALS.getFlag(15)) && ((R2_GLOBALS._v565F6 == 25) || (R2_GLOBALS._v565F6 == -3)))
- || ((R2_GLOBALS.getFlag(15)) && (R2_GLOBALS._v565F6 == R2_GLOBALS._v565FA))
+ if ( ((!R2_GLOBALS.getFlag(15)) && ((R2_GLOBALS._rimLocation == 25) || (R2_GLOBALS._rimLocation == -3)))
+ || ((R2_GLOBALS.getFlag(15)) && (R2_GLOBALS._rimLocation == R2_GLOBALS._rimTransportLocation))
) {
- R2_GLOBALS._v565FA = R2_GLOBALS._v565F6;
+ // Rim transport vechile located
+ R2_GLOBALS._rimTransportLocation = R2_GLOBALS._rimLocation;
if (!R2_GLOBALS.getFlag(15))
_field77C = 1;
- _actor11.postInit();
- _actor11.setup(1700, 3, 1);
- _actor11.setPosition(Common::Point(338, 150));
- _actor11.setDetails(1700, 9, -1, -1, 2, (SceneItem *) NULL);
- _actor11.fixPriority(15);
+ _rimTransport.postInit();
+ _rimTransport.setup(1700, 3, 1);
+ _rimTransport.setPosition(Common::Point(338, 150));
+ _rimTransport.setDetails(1700, 9, -1, -1, 2, (SceneItem *) NULL);
+ _rimTransport.fixPriority(15);
- _actor8.postInit();
- _actor8.setup(1700, 4, 1);
- _actor8.setPosition(Common::Point(312, 106));
- _actor8.fixPriority(130);
+ _rimTransportDoor.postInit();
+ _rimTransportDoor.setup(1700, 4, 1);
+ _rimTransportDoor.setPosition(Common::Point(312, 106));
+ _rimTransportDoor.fixPriority(130);
}
}
@@ -10433,12 +10476,9 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
- _field77A = 0;
- _field77C = 0;
-
- _exit1.setDetails(Rect(94, 0, 319, 12), EXITCURSOR_N, 1700);
- _exit2.setDetails(Rect(0, 161, 319, 168), EXITCURSOR_S, 1700);
- _exit3.setDetails(Rect(0, 0, 2, 138), EXITCURSOR_W, 1800);
+ _northExit.setDetails(Rect(94, 0, 319, 12), EXITCURSOR_N, 1700);
+ _southExit.setDetails(Rect(0, 161, 319, 168), EXITCURSOR_S, 1700);
+ _westExit.setDetails(Rect(0, 0, 12, 138), EXITCURSOR_W, 1800);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setPosition(Common::Point(0, 0));
@@ -10503,14 +10543,14 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
warning("_actor10._actorName = \"hatch\";");
_actor10.hide();
- _actor9.postInit();
- _actor9.setup(1701, 1, 1);
- _actor9.setPosition(Common::Point(220, 137));
- _actor9.setDetails(1700, 6, -1, -1, 1, (SceneItem *) NULL);
+ _ledgeHopper.postInit();
+ _ledgeHopper.setup(1701, 1, 1);
+ _ledgeHopper.setPosition(Common::Point(220, 137));
+ _ledgeHopper.setDetails(1700, 6, -1, -1, 1, (SceneItem *) NULL);
_actor1.hide();
_actor2.hide();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(539, this);
_sceneMode = 40;
break;
@@ -10557,13 +10597,13 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
break;
}
- R2_GLOBALS._player._characterScene[1] = 1700;
- R2_GLOBALS._player._characterScene[2] = 1700;
- R2_GLOBALS._player._oldCharacterScene[1] = 1700;
- R2_GLOBALS._player._oldCharacterScene[2] = 1700;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1700;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1700;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1700;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1700;
R2_GLOBALS._v558B6.set(20, 0, 320, 200);
- subAF3F8();
+ enterArea();
_item1.setDetails(1, 1700, 3, -1, -1);
_item2.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
}
@@ -10577,9 +10617,9 @@ void Scene1700::signal() {
switch (_sceneMode) {
case 1: {
_sceneMode = 3;
- if ((R2_GLOBALS._v565F6 < 2400) && (R2_GLOBALS._v565F6 >= 0))
- ++R2_GLOBALS._v565F6;
- subAF3F8();
+ if (R2_GLOBALS._rimLocation < 2400)
+ ++R2_GLOBALS._rimLocation;
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point(235 - (((((235 - R2_GLOBALS._player._position.x) * 100) / 103) * 167) / 100), 170));
Common::Point pt(R2_GLOBALS._player._position.x, 160);
NpcMover *mover = new NpcMover();
@@ -10602,9 +10642,9 @@ void Scene1700::signal() {
break;
case 2: {
_sceneMode = 3;
- if ((R2_GLOBALS._v565F6 > -2400) && (R2_GLOBALS._v565F6 < 0))
- R2_GLOBALS._v565F6--;
- subAF3F8();
+ if (R2_GLOBALS._rimLocation > -2400)
+ --R2_GLOBALS._rimLocation;
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point(235 - (((((235 - R2_GLOBALS._player._position.x) * 100) / 167) * 103) / 100), 0));
Common::Point pt(R2_GLOBALS._player._position.x, 10);
NpcMover *mover = new NpcMover();
@@ -10627,12 +10667,12 @@ void Scene1700::signal() {
break;
case 3:
if (_field77C == 0) {
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
R2_GLOBALS.setFlag(15);
_field77C = 0;
_sceneMode = 31;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(542, this);
else
@@ -10644,10 +10684,10 @@ void Scene1700::signal() {
Common::Point pt(271, 90);
PlayerMover *mover = new PlayerMover();
_actor12.addMover(mover, &pt, NULL);
- if (R2_GLOBALS._player._characterIndex == 1)
- setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_actor8, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_rimTransportDoor, NULL);
else
- setAction(&_sequenceManager, this, 1701, &R2_GLOBALS._player, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1701, &R2_GLOBALS._player, &_rimTransportDoor, NULL);
}
break;
case 5:
@@ -10661,13 +10701,13 @@ void Scene1700::signal() {
R2_GLOBALS._player._strip = 1;
_actor12.setObjectWrapper(new SceneObjectWrapper());
_actor12._strip = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._walkRegions.enableRegion(14);
break;
case 8:
R2_GLOBALS._player._strip = 2;
_actor12._strip = 1;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._walkRegions.enableRegion(12);
break;
case 30:
@@ -10686,7 +10726,7 @@ void Scene1700::signal() {
case 40:
R2_GLOBALS._player.disableControl();
_sceneMode = 1704;
- setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_actor9, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_ledgeHopper, &_actor1, &_actor2, NULL);
break;
case 50:
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -10702,7 +10742,7 @@ void Scene1700::signal() {
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(12);
R2_GLOBALS._player.fixPriority(-1);
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
R2_GLOBALS._player.enableControl();
@@ -10711,162 +10751,171 @@ void Scene1700::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1750 -
+ * Scene 1750 - Maintaiance Vechile
*
*--------------------------------------------------------------------------*/
-Scene1750::Actor4::Actor4() {
- _fieldA4 = 0;
- _fieldA6 = 0;
- _fieldA8 = 0;
- _fieldAA = 0;
- _fieldAC = 0;
- _fieldAE = 0;
+
+Scene1750::Button::Button() {
+ _buttonId = 0;
}
-void Scene1750::Actor4::synchronize(Serializer &s) {
+void Scene1750::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
- s.syncAsSint16LE(_fieldA8);
- s.syncAsSint16LE(_fieldAA);
- s.syncAsSint16LE(_fieldAC);
- s.syncAsSint16LE(_fieldAE);
+ s.syncAsSint16LE(_buttonId);
}
-Scene1750::Actor5::Actor5() {
- _fieldA4 = 0;
-}
+bool Scene1750::Button::startAction(CursorType action, Event &event) {
+ if (action != CURSOR_USE)
+ return SceneActor::startAction(action, event);
-void Scene1750::Actor5::synchronize(Serializer &s) {
- SceneActor::synchronize(s);
+ Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
- s.syncAsSint16LE(_fieldA4);
+ switch (_buttonId) {
+ case 1:
+ // Forward button
+ show();
+ scene->_backwardButton.hide();
+ if (scene->_speed < 0)
+ scene->_speed = -scene->_speed;
+ scene->_direction = 1;
+ break;
+ case 2:
+ // Backwards button
+ show();
+ scene->_forwardButton.hide();
+ if (scene->_speed > 0)
+ scene->_speed = -scene->_speed;
+ scene->_direction = -1;
+ break;
+ case 3:
+ // Exit button
+ if (scene->_rotation->_idxChange == 0) {
+ show();
+ R2_GLOBALS._sceneManager.changeScene(1700);
+ } else {
+ scene->_speed = 0;
+ scene->_speedSlider._moveRate = 20;
+ scene->_forwardButton._moveDiff.y = 1;
+ Common::Point pt(286, 143);
+ NpcMover *mover = new NpcMover();
+ scene->_speedSlider.addMover(mover, &pt, NULL);
+ }
+ default:
+ break;
+ }
+
+ return true;
}
-Scene1750::Scene1750() {
- _field412 = 0;
- _field413 = 0;
- _field415 = 0;
- _field417 = 0;
- _field419 = 0;
- _field41B = 0;
- _field41D = 0;
+/*------------------------------------------------------------------------*/
+
+Scene1750::SpeedSlider::SpeedSlider() {
+ _incrAmount = 0;
+ _xp = 0;
+ _ys = 0;
+ _height = 0;
+ _thumbHeight = 0;
+ _mouseDown = false;
}
-void Scene1750::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
- SYNC_POINTER(_rotation);
+void Scene1750::SpeedSlider::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field413);
- s.syncAsSint16LE(_field415);
- s.syncAsSint16LE(_field417);
- s.syncAsSint16LE(_field419);
- s.syncAsSint16LE(_field41B);
- s.syncAsSint16LE(_field41D);
+ s.syncAsSint16LE(_incrAmount);
+ s.syncAsSint16LE(_xp);
+ s.syncAsSint16LE(_ys);
+ s.syncAsSint16LE(_height);
+ s.syncAsSint16LE(_thumbHeight);
+ s.syncAsSint16LE(_mouseDown);
}
-void Scene1750::Actor4::subB1A76(int arg1, int arg2, int arg3, int arg4, int arg5) {
- _fieldA4 = arg1;
- _fieldAE = 0;
- _fieldA6 = arg2;
- _fieldA8 = arg3;
- _fieldAA = arg4;
- _fieldAC = arg5;
+void Scene1750::SpeedSlider::setupSlider(int incrAmount, int xp, int ys, int height, int thumbHeight) {
+ _mouseDown = false;
+ _incrAmount = incrAmount;
+ _xp = xp;
+ _ys = ys;
+ _height = height;
+ _thumbHeight = thumbHeight;
postInit();
setup(1750, 1, 1);
fixPriority(255);
- setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * (arg1 - 1)) / (_fieldAC - 1))));
+ setPosition(Common::Point(_xp, _ys + ((_height * (incrAmount - 1)) / (_thumbHeight - 1))));
}
-void Scene1750::Actor4::subB1B27() {
+void Scene1750::SpeedSlider::calculateSlider() {
Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
- int tmpVar = (_fieldAA / (_fieldAC - 1)) / 2;
- int tmpVar2 = ((_position.y - _fieldA8 + tmpVar) * _fieldAC) / (_fieldAA + 2 * tmpVar);
+ int tmpVar = (_height / (_thumbHeight - 1)) / 2;
+ int tmpVar2 = ((_position.y - _ys + tmpVar) * _thumbHeight) / (_height + 2 * tmpVar);
- setPosition(Common::Point(_fieldA6, _fieldA8 + ((_fieldAA * tmpVar2) / (_fieldAC - 1))));
- scene->_field415 = scene->_field412 * tmpVar2;
+ setPosition(Common::Point(_xp, _ys + ((_height * tmpVar2) / (_thumbHeight - 1))));
+ scene->_speed = scene->_direction * tmpVar2;
}
-void Scene1750::Actor4::remove() {
+void Scene1750::SpeedSlider::remove() {
// Function kept to match IDA. Could be removed.
SceneActor::remove();
}
-void Scene1750::Actor4::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) {
- _fieldAE = 1;
+void Scene1750::SpeedSlider::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
+ (_bounds.contains(event.mousePos))) {
+ _mouseDown = true;
event.eventType = EVENT_NONE;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldAE != 0)) {
- _fieldAE = 0;
+ if ((event.eventType == EVENT_BUTTON_UP) && _mouseDown) {
+ _mouseDown = false;
event.handled = true;
addMover(NULL);
- subB1B27();
+ calculateSlider();
}
- if (_fieldAE != 0) {
+ if (_mouseDown) {
event.handled = true;
- if (event.mousePos.y >= _fieldA8) {
- if (_fieldA8 + _fieldAA >= event.mousePos.y)
- setPosition(Common::Point(_fieldA6, event.mousePos.y));
+ if (event.mousePos.y >= _ys) {
+ if (_ys + _height >= event.mousePos.y)
+ setPosition(Common::Point(_xp, event.mousePos.y));
else
- setPosition(Common::Point(_fieldA6, _fieldA8 + _fieldAA));
+ setPosition(Common::Point(_xp, _ys + _height));
} else {
- setPosition(Common::Point(_fieldA6, _fieldA8));
+ setPosition(Common::Point(_xp, _ys));
}
}
}
-bool Scene1750::Actor4::startAction(CursorType action, Event &event) {
+bool Scene1750::SpeedSlider::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE)
return SceneActor::startAction(action, event);
return false;
}
-bool Scene1750::Actor5::startAction(CursorType action, Event &event) {
- if (action != CURSOR_USE)
- return SceneActor::startAction(action, event);
+/*------------------------------------------------------------------------*/
- Scene1750 *scene = (Scene1750 *)R2_GLOBALS._sceneManager._scene;
+Scene1750::Scene1750() {
+ _direction = 0;
+ _field413 = 0;
+ _speed = 0;
+ _field417 = 0;
+ _field419 = 0;
+ _field41B = 0;
+ _field41D = 0;
+}
- switch (_fieldA4) {
- case 1:
- show();
- scene->_actor6.hide();
- if (scene->_field415 < 0)
- scene->_field415 ^= 0xFFFE;
- scene->_field412 = 1;
- break;
- case 2:
- show();
- scene->_actor5.hide();
- if (scene->_field415 > 0)
- scene->_field415 ^= 0xFFFE;
- scene->_field412 = -1;
- break;
- case 3:
- if (scene->_rotation->_idxChange == 0) {
- show();
- R2_GLOBALS._sceneManager.changeScene(1700);
- } else {
- scene->_field415 = 0;
- scene->_actor4._moveRate = 20;
- scene->_actor5._moveDiff.y = 1;
- Common::Point pt(286, 143);
- NpcMover *mover = new NpcMover();
- scene->_actor4.addMover(mover, &pt, NULL);
- }
- default:
- break;
- }
+void Scene1750::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
- return true;
+ s.syncAsSint16LE(_direction);
+ s.syncAsSint16LE(_field413);
+ s.syncAsSint16LE(_speed);
+ s.syncAsSint16LE(_field417);
+ s.syncAsSint16LE(_field419);
+ s.syncAsSint16LE(_field41B);
+ s.syncAsSint16LE(_field41D);
}
void Scene1750::postInit(SceneObjectList *OwnerList) {
@@ -10876,17 +10925,17 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._v5589E.set(0, 0, 320, 200);
SceneExt::postInit();
- R2_GLOBALS._player._characterScene[1] = 1750;
- R2_GLOBALS._player._characterScene[2] = 1750;
- R2_GLOBALS._player._oldCharacterScene[1] = 1750;
- R2_GLOBALS._player._oldCharacterScene[2] = 1750;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1750;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1750;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1750;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1750;
_rotation = R2_GLOBALS._scenePalette.addRotation(224, 254, 1);
_rotation->setDelay(0);
_rotation->_idxChange = 0;
_rotation->_countdown = 2;
- switch ((R2_GLOBALS._v565F6 + 2) % 4) {
+ switch ((R2_GLOBALS._rimLocation + 2) % 4) {
case 0:
_rotation->_currIndex = 247;
break;
@@ -10932,7 +10981,7 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
_actor1.postInit();
_actor1.setup(1750, 2, 1);
- _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._v565F6 % 800) * 4) - 1440));
+ _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
_actor1.fixPriority(8);
_actor2.postInit();
@@ -10947,51 +10996,49 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
else
_actor2.setPosition(Common::Point(148, (tmpVar * 7) + 122));
- _actor4.subB1A76(1, 286, 143, 41, 15);
- _actor4.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL);
-
- _actor5.postInit();
- _actor5._fieldA4 = 1;
- _actor5.setup(1750, 1, 2);
- _actor5.setPosition(Common::Point(192, 140));
- _actor5.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
-
- _actor6.postInit();
- _actor6._fieldA4 = 2;
- _actor6.setup(1750, 1, 3);
- _actor6.setPosition(Common::Point(192, 163));
- _actor6.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
- _actor6.hide();
-
- _actor7.postInit();
- _actor7._fieldA4 = 3;
- _actor7.setup(1750, 1, 5);
- _actor7.setPosition(Common::Point(230, 183));
- _actor7.setDetails(1750, 27, 1, -1, 1, (SceneItem *) NULL);
-
- _field412 = 1;
+ _speedSlider.setupSlider(1, 286, 143, 41, 15);
+ _speedSlider.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL);
+
+ _forwardButton.postInit();
+ _forwardButton._buttonId = 1;
+ _forwardButton.setup(1750, 1, 2);
+ _forwardButton.setPosition(Common::Point(192, 140));
+ _forwardButton.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
+
+ _backwardButton.postInit();
+ _backwardButton._buttonId = 2;
+ _backwardButton.setup(1750, 1, 3);
+ _backwardButton.setPosition(Common::Point(192, 163));
+ _backwardButton.setDetails(1750, 18, 1, -1, 1, (SceneItem *) NULL);
+ _backwardButton.hide();
+
+ _exitButton.postInit();
+ _exitButton._buttonId = 3;
+ _exitButton.setup(1750, 1, 5);
+ _exitButton.setPosition(Common::Point(230, 183));
+ _exitButton.setDetails(1750, 27, 1, -1, 1, (SceneItem *) NULL);
+
+ _direction = 1; // Forward by default
_field417 = 0;
_field413 = 0;
- _field415 = 0;
+ _speed = 0;
_field419 = ((_rotation->_currIndex - 218) / 4) % 4;
- _item2.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
- _item3.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL);
- _item4.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL);
- _item5.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 1750, 6, 1, -1, 1, NULL);
+ _redLights.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
+ _greenLights.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL);
+ _frontView.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL);
+ _rearView.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1750, 6, 1, -1, 1, NULL);
}
void Scene1750::remove() {
- _rotation->remove();
-
- if (R2_GLOBALS._v565F6 == 2400)
- R2_GLOBALS._v565F6 = 2399;
+ if (R2_GLOBALS._rimLocation == 2400)
+ R2_GLOBALS._rimLocation = 2399;
- if (R2_GLOBALS._v565F6 == -2400)
- R2_GLOBALS._v565F6 = -2399;
+ if (R2_GLOBALS._rimLocation == -2400)
+ R2_GLOBALS._rimLocation = -2399;
- R2_GLOBALS._v565FA = R2_GLOBALS._v565F6;
+ R2_GLOBALS._rimTransportLocation = R2_GLOBALS._rimLocation;
SceneExt::remove();
R2_GLOBALS._sound1.fadeOut2(NULL);
@@ -11007,26 +11054,95 @@ void Scene1750::signal() {
void Scene1750::process(Event &event) {
Scene::process(event);
if (!event.handled)
- _actor4.process(event);
+ _speedSlider.process(event);
}
-void Scene1750::dispatch() {}
+void Scene1750::dispatch() {
+ if (_rotation) {
+ if (!_field417 && (_speed != _field413)) {
+ if (_field413 >= _speed)
+ --_field413;
+ else
+ ++_field413;
+
+ _field417 = 21 - ABS(_field413);
+ }
+
+ if (_field417 == 1) {
+ if (_field413 == 0) {
+ _actor3.show();
+ _rotation->_idxChange = 0;
+ } else {
+ if (_rotation->_idxChange == 0)
+ _actor3.hide();
+
+ if (_field413 < -12) {
+ _rotation->setDelay(15 - ABS(_field413));
+ _rotation->_idxChange = -2;
+ } else if (_field413 < 0) {
+ _rotation->setDelay(10 - ABS(_field413));
+ _rotation->_idxChange = -1;
+ } else if (_field413 < 11) {
+ _rotation->setDelay(10 - _field413);
+ _rotation->_idxChange = 1;
+ } else {
+ _rotation->setDelay(15 - _field413);
+ _rotation->_idxChange = 2;
+ }
+ }
+ }
+
+ if (_field417)
+ --_field417;
+
+ _field41B = _field419;
+ _field419 = ((_rotation->_currIndex - 218) / 4) / 4;
+
+ if ((_field41B + 1) == _field419 || (_field41B - 3) == _field419) {
+ if (R2_GLOBALS._rimLocation < 2400) {
+ ++R2_GLOBALS._rimLocation;
+ }
+ }
+
+ if ((_field41B - 1) == _field419 || (_field41B + 3) == _field419) {
+ if (R2_GLOBALS._rimLocation > -2400) {
+ --R2_GLOBALS._rimLocation;
+ }
+ }
+
+ if (_rotation->_currIndex != _field41D) {
+ _field41D = _rotation->_currIndex;
+ _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) +
+ ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
+ }
+ }
+
+ int v = ABS(_actor1._position.y - 158) / 100;
+ if (v < 8) {
+ _actor2.show();
+ _actor2.setPosition(Common::Point((_actor1._position.y <= 158) ? 137 : 148,
+ v * 7 + 122));
+ } else {
+ _actor2.hide();
+ }
+}
/*--------------------------------------------------------------------------
- * Scene 1800 -
+ * Scene 1800 - Rim Lift Exterior
*
*--------------------------------------------------------------------------*/
+
Scene1800::Scene1800() {
- _field412 = 0;
+ _locationMode = 0;
}
void Scene1800::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_locationMode);
}
-bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
+bool Scene1800::Background::startAction(CursorType action, Event &event) {
if ((action != R2_COM_SCANNER) && (action != R2_COM_SCANNER_2))
return false;
@@ -11035,7 +11151,7 @@ bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- if (R2_GLOBALS._v565F6 == 1201) {
+ if (R2_GLOBALS._rimLocation == 1201) {
scene->_stripManager.start(548, this);
} else if (R2_GLOBALS.getFlag(66)) {
return false;
@@ -11043,7 +11159,7 @@ bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
scene->_stripManager.start(546, this);
}
} else {
- if (R2_GLOBALS._v565F6 == 1201) {
+ if (R2_GLOBALS._rimLocation == 1201) {
scene->_stripManager.start(549, this);
} else if (R2_GLOBALS.getFlag(66)) {
return false;
@@ -11056,7 +11172,7 @@ bool Scene1800::Hotspot5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1800::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1800::Lever::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -11072,31 +11188,34 @@ bool Scene1800::Actor6::startAction(CursorType action, Event &event) {
if (_frame == 1) {
R2_GLOBALS.setFlag(64);
scene->_sceneMode = 1810;
- scene->setAction(&scene->_sequenceManager, scene, 1810, &R2_GLOBALS._player, &scene->_actor6, &scene->_actor4, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1810, &R2_GLOBALS._player, &scene->_lever, &scene->_leftStaircase, &scene->_rightStaircase, NULL);
} else {
R2_GLOBALS.clearFlag(64);
scene->_sceneMode = 1811;
- scene->setAction(&scene->_sequenceManager, scene, 1811, &R2_GLOBALS._player, &scene->_actor6, &scene->_actor4, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1811, &R2_GLOBALS._player, &scene->_lever, &scene->_leftStaircase, &scene->_rightStaircase, NULL);
}
return true;
}
-bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1800::Doors::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ // Seeker trying to force open the door
R2_GLOBALS._player.disableControl();
- if (scene->_field412 >= 2) {
+ if (scene->_locationMode >= 2) {
if (R2_GLOBALS.getFlag(14)) {
+ // Allow door to close
scene->_sceneMode = 1809;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
+ // Force open door
scene->_sceneMode = 1808;
- scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.setFlag(14);
}
} else {
@@ -11106,6 +11225,7 @@ bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
} else if (R2_GLOBALS.getFlag(14)) {
return SceneActor::startAction(action, event);
} else {
+ // Quinn trying to force open doors
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1812;
scene->setAction(&scene->_sequenceManager, scene, 1812, &R2_GLOBALS._player, NULL);
@@ -11114,40 +11234,40 @@ bool Scene1800::Actor7::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1800::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1800::PassengerDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
if (_position.x < 160) {
- if (scene->_actor4._frame == 1) {
+ if (scene->_leftStaircase._frame == 1) {
return SceneActor::startAction(action, event);
} else {
R2_GLOBALS.setFlag(29);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(14)) {
- scene->_sceneMode = 1804;
- scene->setAction(&scene->_sequenceManager, scene, 1804, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor8, NULL);
- } else {
scene->_sceneMode = 1;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1804;
+ scene->setAction(&scene->_sequenceManager, scene, 1804, &R2_GLOBALS._player, &scene->_companion, &scene->_leftDoor, NULL);
}
} else {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 1;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
scene->_sceneMode = 1805;
- scene->setAction(&scene->_sequenceManager, scene, 1805, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1805, &R2_GLOBALS._player, &scene->_companion, &scene->_leftDoor, NULL);
}
}
}
} else {
- if (scene->_actor4._frame == 1) {
+ if (scene->_leftStaircase._frame == 1) {
return SceneActor::startAction(action, event);
} else {
R2_GLOBALS.clearFlag(29);
@@ -11155,20 +11275,20 @@ bool Scene1800::Actor8::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
scene->_sceneMode = 1806;
- scene->setAction(&scene->_sequenceManager, scene, 1806, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor9, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1806, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
}
} else {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
scene->_sceneMode = 1807;
- scene->setAction(&scene->_sequenceManager, scene, 1807, &R2_GLOBALS._player, &scene->_actor2, &scene->_actor9, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1807, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
}
}
}
@@ -11186,16 +11306,16 @@ void Scene1800::Exit1::changeScene() {
if (R2_GLOBALS.getFlag(14)) {
scene->_sceneMode = 3;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
else
- scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_actor2, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
R2_GLOBALS.clearFlag(14);
} else {
scene->_sceneMode = 1802;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_companion, NULL);
else
- scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 1802, &R2_GLOBALS._player, &scene->_companion, NULL);
}
}
@@ -11207,95 +11327,98 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_seekerSpeaker);
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS._v565F6 = 1201;
+ R2_GLOBALS._rimLocation = 1201;
- if (R2_GLOBALS._v565F6 == 1201)
- _field412 = 2;
+ // Set the mode based on whether this is the "correct" lift or not
+ if (R2_GLOBALS._rimLocation == 1201)
+ _locationMode = 2;
else
- _field412 = 0;
+ _locationMode = 0;
scalePalette(65, 65, 65);
_exit1.setDetails(Rect(0, 160, 319, 168), EXITCURSOR_S, 1800);
- _item5.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
-
- _actor6.postInit();
- _actor6.setup(1801, 4, 1);
- _actor6.setPosition(Common::Point(170, 24));
- _actor6.setDetails(1800, 13, 14, 15, 1, (SceneItem *) NULL);
-
- _actor7.postInit();
- _actor7.setup(1801, 3, 1);
- _actor7.setPosition(Common::Point(160, 139));
- _actor7.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
-
- _actor8.postInit();
- _actor8.setup(1800, 1, 1);
- _actor8.setPosition(Common::Point(110, 78));
- _actor8.fixPriority(135);
- _actor8.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
-
- _actor9.postInit();
- _actor9.setup(1800, 2, 1);
- _actor9.setPosition(Common::Point(209, 78));
- _actor9.fixPriority(135);
- _actor9.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
-
- _actor4.postInit();
- if ((_field412 != 1) && (_field412 != 3) && (!R2_GLOBALS.getFlag(64)))
- _actor4.setup(1801, 2, 1);
+ _background.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
+
+ _lever.postInit();
+ _lever.setup(1801, 4, 1);
+ _lever.setPosition(Common::Point(170, 124));
+ _lever.setDetails(1800, 13, 14, 15, 1, (SceneItem *) NULL);
+
+ _doors.postInit();
+ _doors.setup(1801, 3, 1);
+ _doors.setPosition(Common::Point(160, 139));
+ _doors.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
+
+ _leftDoor.postInit();
+ _leftDoor.setup(1800, 1, 1);
+ _leftDoor.setPosition(Common::Point(110, 78));
+ _leftDoor.fixPriority(135);
+ _leftDoor.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
+
+ _rightDoor.postInit();
+ _rightDoor.setup(1800, 2, 1);
+ _rightDoor.setPosition(Common::Point(209, 78));
+ _rightDoor.fixPriority(135);
+ _rightDoor.setDetails(1800, 20, -1, -1, 1, (SceneItem *) NULL);
+
+ _leftStaircase.postInit();
+ if ((_locationMode != 1) && (_locationMode != 3) && (!R2_GLOBALS.getFlag(64)))
+ _leftStaircase.setup(1801, 2, 1);
else
- _actor4.setup(1801, 2, 10);
- _actor4.setPosition(Common::Point(76, 142));
- _actor4.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
+ _leftStaircase.setup(1801, 2, 10);
+ _leftStaircase.setPosition(Common::Point(76, 142));
+ _leftStaircase.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- if ((_field412 != 1) && (_field412 != 3) && (!R2_GLOBALS.getFlag(64)))
- _actor5.setup(1801, 1, 1);
+ _rightStaircase.postInit();
+ if ((_locationMode != 1) && (_locationMode != 3) && (!R2_GLOBALS.getFlag(64)))
+ _rightStaircase.setup(1801, 1, 1);
else
- _actor5.setup(1801, 1, 10);
- _actor5.setPosition(Common::Point(243, 142));
- _actor5.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
+ _rightStaircase.setup(1801, 1, 10);
+ _rightStaircase.setPosition(Common::Point(243, 142));
+ _rightStaircase.setDetails(1800, 3, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ // Standard Quinn setup
+ R2_GLOBALS._player.setVisage(1503);
+ R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
+ } else {
+ // Seeker setup dependent on whether he's holding the doors or not
if (R2_GLOBALS.getFlag(14)) {
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
R2_GLOBALS._player.setObjectWrapper(NULL);
R2_GLOBALS._player.setup(1801, 5, 12);
R2_GLOBALS._player.setPosition(Common::Point(160, 139));
R2_GLOBALS._walkRegions.enableRegion(9);
- _actor7.hide();
+ _doors.hide();
} else {
R2_GLOBALS._player.setVisage(1507);
}
R2_GLOBALS._player._moveDiff = Common::Point(4, 2);
- } else {
- R2_GLOBALS._player.setVisage(1503);
- R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
}
- _actor2.postInit();
- _actor2.animate(ANIM_MODE_1, NULL);
- _actor2.setObjectWrapper(new SceneObjectWrapper());
+ _companion.postInit();
+ _companion.animate(ANIM_MODE_1, NULL);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(14)) {
- _actor2.animate(ANIM_MODE_NONE, NULL);
- _actor2.setObjectWrapper(NULL);
- _actor2.setup(1801, 5, 12);
+ _companion.animate(ANIM_MODE_NONE, NULL);
+ _companion.setObjectWrapper(NULL);
+ _companion.setup(1801, 5, 12);
R2_GLOBALS._walkRegions.enableRegion(9);
- _actor7.hide();
+ _doors.hide();
} else {
- _actor2.setup(1507, 1, 1);
- _actor2.setPosition(Common::Point(180, 160));
+ _companion.setup(1507, 1, 1);
+ _companion.setPosition(Common::Point(180, 160));
}
- _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
- _actor2._moveDiff = Common::Point(4, 2);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _companion._moveDiff = Common::Point(4, 2);
} else {
- _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor2.setVisage(1503);
- _actor2._moveDiff = Common::Point(2, 2);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _companion.setVisage(1503);
+ _companion._moveDiff = Common::Point(2, 2);
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1800) {
@@ -11303,11 +11426,11 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(114, 150));
R2_GLOBALS._player.setStrip(5);
if (R2_GLOBALS.getFlag(14)) {
- _actor2.setPosition(Common::Point(160, 139));
+ _companion.setPosition(Common::Point(160, 139));
R2_GLOBALS._walkRegions.enableRegion(8);
} else {
- _actor2.setPosition(Common::Point(209, 150));
- _actor2.setStrip(6);
+ _companion.setPosition(Common::Point(209, 150));
+ _companion.setStrip(6);
R2_GLOBALS._walkRegions.enableRegion(8);
}
} else {
@@ -11318,18 +11441,18 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(209, 150));
R2_GLOBALS._player.setStrip(6);
}
- _actor2.setPosition(Common::Point(114, 150));
- _actor2.setStrip(5);
+ _companion.setPosition(Common::Point(114, 150));
+ _companion.setStrip(5);
R2_GLOBALS._walkRegions.enableRegion(10);
R2_GLOBALS._walkRegions.enableRegion(11);
}
} else {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setPosition(Common::Point(140, 160));
- _actor2.setPosition(Common::Point(180, 160));
+ _companion.setPosition(Common::Point(180, 160));
} else {
R2_GLOBALS._player.setPosition(Common::Point(180, 160));
- _actor2.setPosition(Common::Point(140, 160));
+ _companion.setPosition(Common::Point(140, 160));
}
}
@@ -11355,10 +11478,10 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
_actor3._effect = 5;
_actor3._field9C = _field312;
- _actor2._linkedActor = &_actor3;
+ _companion._linkedActor = &_actor3;
- R2_GLOBALS._player._characterScene[1] = 1800;
- R2_GLOBALS._player._characterScene[2] = 1800;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1800;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1800;
_item2.setDetails(Rect(128, 95, 190, 135), 1800, 10, -1, -1, 1, NULL);
_item1.setDetails(Rect(95, 3, 223, 135), 1800, 0, -1, -1, 1, NULL);
@@ -11380,32 +11503,32 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS.getFlag(29)) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1814;
- setAction(&_sequenceManager, this, 1814, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1814, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
} else {
_sceneMode = 1815;
- setAction(&_sequenceManager, this, 1815, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1815, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
} else {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1816;
- setAction(&_sequenceManager, this, 1816, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1816, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
_sceneMode = 1817;
- setAction(&_sequenceManager, this, 1817, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1817, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
}
}
} else {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1800;
- setAction(&_sequenceManager, this, 1800, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1800, &R2_GLOBALS._player, &_companion, NULL);
} else {
_sceneMode = 1801;
- setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_companion, NULL);
}
}
- R2_GLOBALS._player._oldCharacterScene[1] = 1800;
- R2_GLOBALS._player._oldCharacterScene[2] = 1800;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1800;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1800;
}
void Scene1800::signal() {
@@ -11413,27 +11536,27 @@ void Scene1800::signal() {
case 1:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1804;
- setAction(&_sequenceManager, this, 1804, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1804, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
} else {
_sceneMode = 1805;
- setAction(&_sequenceManager, this, 1805, &R2_GLOBALS._player, &_actor2, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 1805, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
break;
case 2:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_sceneMode = 1806;
- setAction(&_sequenceManager, this, 1806, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1806, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
_sceneMode = 1807;
- setAction(&_sequenceManager, this, 1807, &R2_GLOBALS._player, &_actor2, &_actor9, NULL);
+ setAction(&_sequenceManager, this, 1807, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
}
break;
case 3:
_sceneMode = 1802;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- setAction(&_sequenceManager, this, 1802, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1802, &R2_GLOBALS._player, &_companion, NULL);
else
- setAction(&_sequenceManager, this, 1803, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1803, &R2_GLOBALS._player, &_companion, NULL);
break;
case 10:
// No break on purpose
@@ -11503,7 +11626,7 @@ void Scene1800::signal() {
break;
case 1808:
_sceneMode = 12;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(553, this);
break;
case 1812:
@@ -11537,18 +11660,11 @@ void Scene1800::saveCharacter(int characterIndex) {
}
/*--------------------------------------------------------------------------
- * Scene 1850 -
+ * Scene 1850 - Rim Lift Interior
*
*--------------------------------------------------------------------------*/
-Scene1850::Scene1850() {
- warning("STUBBED: Scene1850()");
-}
-
-void Scene1850::synchronize(Serializer &s) {
- warning("STUBBED: Scene1850::synchronize()");
-}
-bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
+bool Scene1850::Button::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
@@ -11566,9 +11682,9 @@ bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32))
- scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_robot, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_robot, NULL);
R2_GLOBALS.clearFlag(30);
} else {
@@ -11583,21 +11699,21 @@ bool Scene1850::Hotspot2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
+bool Scene1850::Robot::startAction(CursorType action, Event &event) {
Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if ((R2_GLOBALS._player._characterIndex != R2_SEEKER) || (R2_GLOBALS.getFlag(33)) || (R2_GLOBALS.getFlag(30)))
+ if ((R2_GLOBALS._player._characterIndex != R2_SEEKER) || R2_GLOBALS.getFlag(33) || R2_GLOBALS.getFlag(30))
return SceneActor::startAction(action, event);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1857;
if (R2_GLOBALS.getFlag(32))
- scene->setAction(&scene->_sequenceManager1, scene, 1858, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1858, &R2_GLOBALS._player, &scene->_robot, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 1857, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1857, &R2_GLOBALS._player, &scene->_robot, NULL);
R2_GLOBALS.setFlag(30);
return true;
@@ -11616,7 +11732,7 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 30;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
scene->_stripManager.start(558, scene);
return true;
@@ -11636,8 +11752,8 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
return true;
} else if (R2_GLOBALS.getFlag(70)) {
R2_GLOBALS._player.disableControl();
- scene->_sceneMode = 30;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ scene->_sceneMode = 20;
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
scene->_stripManager.start(557, scene);
R2_GLOBALS.setFlag(69);
@@ -11653,7 +11769,7 @@ bool Scene1850::Actor5::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1878;
- scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player, &scene->_actor5, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player, &scene->_robot, &scene->_actor2, NULL);
}
return true;
@@ -11693,23 +11809,23 @@ bool Scene1850::Actor6::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32)) {
- scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1860, &R2_GLOBALS._player, &scene->_robot, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1859, &R2_GLOBALS._player, &scene->_robot, NULL);
}
} else {
scene->_sceneMode = 11;
if (_position.x >= 160) {
- scene->setAction(&scene->_sequenceManager1, scene, 1866, &R2_GLOBALS._player, &scene->_actor7, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1866, &R2_GLOBALS._player, &scene->_rightDoor, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1865, &R2_GLOBALS._player, &scene->_actor6, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1865, &R2_GLOBALS._player, &scene->_leftDoor, NULL);
}
}
return true;
}
-bool Scene1850::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1850::DisplayScreen::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (_position.y != 120))
return SceneHotspot::startAction(action, event);
@@ -11727,6 +11843,28 @@ bool Scene1850::Actor8::startAction(CursorType action, Event &event) {
return true;
}
+/*------------------------------------------------------------------------*/
+
+Scene1850::Scene1850() {
+ _field412 = 0;
+ _field414 = 0;
+ _field416 = 0;
+ _field418 = 0;
+ _field41E = 0;
+}
+
+void Scene1850::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41E);
+ s.syncAsSint16LE(_field41A.x);
+ s.syncAsSint16LE(_field41A.y);
+}
+
void Scene1850::postInit(SceneObjectList *OwnerList) {
loadScene(1850);
@@ -11755,62 +11893,62 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
_field41E = 0;
_field41A = Common::Point(0, 0);
- R2_GLOBALS._player._characterScene[1] = 1850;
- R2_GLOBALS._player._characterScene[2] = 1850;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1850;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1850;
- _item2.setDetails(Rect(101, 56, 111, 63), 1850, 19, -1, -1, 1, NULL);
+ _button.setDetails(Rect(101, 56, 111, 63), 1850, 19, -1, -1, 1, NULL);
- _actor6.postInit();
- _actor6.setup(1850, 3, 1);
- _actor6.setPosition(Common::Point(66, 102));
- _actor6.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
+ _leftDoor.postInit();
+ _leftDoor.setup(1850, 3, 1);
+ _leftDoor.setPosition(Common::Point(66, 102));
+ _leftDoor.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
- _actor7.postInit();
- _actor7.setup(1850, 2, 1);
- _actor7.setPosition(Common::Point(253, 102));
- _actor7.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
+ _rightDoor.postInit();
+ _rightDoor.setup(1850, 2, 1);
+ _rightDoor.setPosition(Common::Point(253, 102));
+ _rightDoor.setDetails(1850, 22, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._walkRegions.enableRegion(1);
- _actor5.postInit();
+ _robot.postInit();
if (R2_GLOBALS.getFlag(34)) {
R2_GLOBALS._walkRegions.enableRegion(2);
- _actor5.setup(1851, 4, 3);
+ _robot.setup(1851, 4, 3);
} else if (R2_GLOBALS.getFlag(30)) {
- _actor5.setup(1851, 2, 2);
+ _robot.setup(1851, 2, 2);
} else {
R2_GLOBALS._walkRegions.enableRegion(5);
if (R2_GLOBALS.getFlag(33)) {
R2_GLOBALS._walkRegions.enableRegion(2);
- _actor5.setup(1851, 1, 3);
+ _robot.setup(1851, 1, 3);
} else {
- _actor5.setup(1851, 2, 1);
+ _robot.setup(1851, 2, 1);
}
}
- _actor5.setPosition(Common::Point(219, 130));
- _actor5.fixPriority(114);
- _actor5.setDetails(1850, -1, -1, -1, 1, (SceneItem *) NULL);
+ _robot.setPosition(Common::Point(219, 130));
+ _robot.fixPriority(114);
+ _robot.setDetails(1850, -1, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._player.postInit();
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
} else {
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1850) {
R2_GLOBALS._player._effect = 6;
- _actor1._effect = 6;
+ _companion._effect = 6;
if (R2_GLOBALS.getFlag(31)) {
R2_GLOBALS._player._shade = 0;
- _actor1._shade = 0;
+ _companion._shade = 0;
} else {
R2_GLOBALS._player._shade = 6;
- _actor1._shade = 6;
+ _companion._shade = 6;
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
@@ -11824,7 +11962,7 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
_actor2.setPosition(Common::Point(179, 113));
- if ((_actor5._strip == 1) && (_actor5._frame == 3)){
+ if ((_robot._strip == 1) && (_robot._frame == 3)){
_actor2.hide();
}
@@ -11834,7 +11972,7 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(32)) {
R2_GLOBALS._player.setVisage(1511);
- _actor1.setVisage(1508);
+ _companion.setVisage(1508);
_actor3.postInit();
_actor3.setup(1853, 3, 1);
@@ -11873,12 +12011,12 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
}
} else {
R2_GLOBALS._player.setVisage(1500);
- _actor1.setVisage(1505);
+ _companion.setVisage(1505);
}
} else { // Not Quinn
if (R2_GLOBALS.getFlag(32)) {
R2_GLOBALS._player.setVisage(1508);
- _actor1.setVisage(1511);
+ _companion.setVisage(1511);
_actor3.postInit();
_actor3.setup(1853, 3, 1);
@@ -11917,7 +12055,7 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
}
} else {
R2_GLOBALS._player.setVisage(1505);
- _actor1.setVisage(1500);
+ _companion.setVisage(1500);
}
}
@@ -11925,25 +12063,25 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.setPosition(Common::Point(80, 114));
- _actor1.animate(ANIM_MODE_1, NULL);
- _actor1.setObjectWrapper(new SceneObjectWrapper());
- _actor1.setStrip(3);
- _actor1.setPosition(Common::Point(180, 96));
+ _companion.animate(ANIM_MODE_1, NULL);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
+ _companion.setStrip(3);
+ _companion.setPosition(Common::Point(180, 96));
if (R2_GLOBALS.getFlag(30)) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.animate(ANIM_MODE_NONE, NULL);
- _actor1.setObjectWrapper(NULL);
+ _companion.animate(ANIM_MODE_NONE, NULL);
+ _companion.setObjectWrapper(NULL);
if (R2_GLOBALS.getFlag(32)) {
- _actor1.setup(1854, 1, 3);
+ _companion.setup(1854, 1, 3);
} else {
- _actor1.setup(1854, 2, 3);
+ _companion.setup(1854, 2, 3);
}
- _actor1.setPosition(Common::Point(164, 106));
+ _companion.setPosition(Common::Point(164, 106));
} else {
- _actor1.animate(ANIM_MODE_NONE, NULL);
- _actor1.setObjectWrapper(NULL);
+ _companion.animate(ANIM_MODE_NONE, NULL);
+ _companion.setObjectWrapper(NULL);
if (R2_GLOBALS.getFlag(32)) {
R2_GLOBALS._player.setup(1854, 1, 3);
} else {
@@ -11957,57 +12095,57 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
} else { // R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 1850
R2_GLOBALS._player._effect = 1;
- _actor1._effect = 1;
+ _companion._effect = 1;
R2_GLOBALS._player.disableControl();
_sceneMode = 10;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(29)) {
- setAction(&_sequenceManager1, this, 1863, &R2_GLOBALS._player, &_actor1, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1863, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
- setAction(&_sequenceManager1, this, 1861, &R2_GLOBALS._player, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 1861, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
} else {
if (R2_GLOBALS.getFlag(29)) {
- setAction(&_sequenceManager1, this, 1864, &R2_GLOBALS._player, &_actor1, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1864, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
- setAction(&_sequenceManager1, this, 1862, &R2_GLOBALS._player, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 1862, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
}
}
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _actor1._moveDiff = Common::Point(5, 3);
+ _companion._moveDiff = Common::Point(5, 3);
} else {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- _actor1._moveDiff = Common::Point(3, 2);
+ _companion._moveDiff = Common::Point(3, 2);
}
- _actor8.postInit();
- _actor8.setup(1850, 1, 1);
+ _displayScreen.postInit();
+ _displayScreen.setup(1850, 1, 1);
if (R2_GLOBALS.getFlag(62)) {
- _actor8.setPosition(Common::Point(159, 120));
+ _displayScreen.setPosition(Common::Point(159, 120));
} else {
- _actor8.setPosition(Common::Point(159, 184));
+ _displayScreen.setPosition(Common::Point(159, 184));
}
- _actor8.fixPriority(113);
+ _displayScreen.fixPriority(113);
if (R2_GLOBALS.getFlag(34)) {
- _actor8.setDetails(1850, 25, -1, -1, 4, &_actor5);
+ _displayScreen.setDetails(1850, 25, -1, -1, 4, &_robot);
} else {
- _actor8.setDetails(1850, 25, -1, -1, 2, (SceneItem *) NULL);
+ _displayScreen.setDetails(1850, 25, -1, -1, 2, (SceneItem *) NULL);
}
if (!R2_GLOBALS.getFlag(62)) {
- _actor8.hide();
+ _displayScreen.hide();
}
- _item1.setDetails(Rect(0, 0, 320, 200), 1850, 16, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1850, 16, -1, -1, 1, NULL);
- R2_GLOBALS._player._oldCharacterScene[1] = 1850;
- R2_GLOBALS._player._oldCharacterScene[2] = 1850;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1850;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1850;
}
void Scene1850::remove() {
@@ -12026,8 +12164,8 @@ void Scene1850::signal() {
R2_GLOBALS._player._effect = 6;
R2_GLOBALS._player._shade = 6;
- _actor1._effect = 6;
- _actor1._shade = 6;
+ _companion._effect = 6;
+ _companion._shade = 6;
R2_GLOBALS._walkRegions.enableRegion(5);
@@ -12049,7 +12187,7 @@ void Scene1850::signal() {
break;
case 16:
_sceneMode = 1870;
- setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_actor1, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_companion, &_actor3, &_actor4, NULL);
break;
case 20:
R2_GLOBALS._player.enableControl(CURSOR_TALK);
@@ -12057,7 +12195,7 @@ void Scene1850::signal() {
case 21:
R2_GLOBALS._player.disableControl();
_sceneMode = 1877;
- setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_actor1, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_companion, &_robot, NULL);
break;
case 30:
R2_GLOBALS._player.disableControl();
@@ -12079,14 +12217,14 @@ void Scene1850::signal() {
_field418 = 1;
if (R2_GLOBALS.getFlag(30)) {
- _actor8.setAction(&_sequenceManager2, NULL, 1867, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, NULL, 1867, &_displayScreen, NULL);
} else if (R2_GLOBALS.getFlag(34)) {
if (R2_GLOBALS.getFlag(62)) {
R2_GLOBALS.clearFlag(62);
- _actor8.setAction(&_sequenceManager2, this, 1851, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1851, &_displayScreen, NULL);
} else {
R2_GLOBALS.setFlag(62);
- _actor8.setAction(&_sequenceManager2, this, 1850, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1850, &_displayScreen, NULL);
}
} else if (R2_GLOBALS.getFlag(33)) {
R2_GLOBALS.setFlag(62);
@@ -12094,13 +12232,13 @@ void Scene1850::signal() {
R2_GLOBALS._walkRegions.enableRegion(2);
_actor2.postInit();
- _actor2.setDetails(1850, 6, -1, -1, 5, &_actor5);
+ _actor2.setDetails(1850, 6, -1, -1, 5, &_robot);
_sceneMode = 1879;
- _actor8.setAction(&_sequenceManager2, this, 1879, &_actor5, &_actor8, &_actor2, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1879, &_robot, &_displayScreen, &_actor2, NULL);
} else {
- _actor8.setAction(&_sequenceManager2, NULL, 1867, &_actor8, NULL);
+ _displayScreen.setAction(&_sequenceManager2, NULL, 1867, &_displayScreen, NULL);
}
if (R2_GLOBALS.getFlag(34))
@@ -12149,7 +12287,7 @@ void Scene1850::signal() {
case 1858:
R2_GLOBALS._player.disableControl();
_sceneMode = 1859;
- setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_robot, NULL);
R2_GLOBALS.clearFlag(30);
break;
case 1859:
@@ -12179,12 +12317,11 @@ void Scene1850::signal() {
break;
case 2:
_sceneMode = 11;
- setAction(&_sequenceManager1, this, 1865, &R2_GLOBALS._player, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 1865, &R2_GLOBALS._player, &_leftDoor, NULL);
break;
case 3:
- warning("_field41E == 3");
_sceneMode = 11;
- setAction(&_sequenceManager1, this, 1866, &R2_GLOBALS._player, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1866, &R2_GLOBALS._player, &_rightDoor, NULL);
break;
default:
break;
@@ -12234,7 +12371,7 @@ void Scene1850::signal() {
R2_GLOBALS.clearFlag(30);
_sceneMode = 15;
setAction(&_sequenceManager1, this, 1869, &R2_GLOBALS._player, &_actor3, NULL);
- setAction(&_sequenceManager2, this, 1868, &_actor1, &_actor4, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1868, &_companion, &_actor4, NULL);
break;
case 1878:
R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1850);
@@ -12265,9 +12402,9 @@ void Scene1850::process(Event &event) {
R2_GLOBALS._player.disableControl();
_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32)) {
- setAction(&_sequenceManager1, this, 1860, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1860, &R2_GLOBALS._player, &_robot, NULL);
} else {
- setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_robot, NULL);
}
R2_GLOBALS.clearFlag(32);
event.handled = true;
@@ -12289,8 +12426,8 @@ void Scene1850::dispatch() {
}
R2_GLOBALS._player._flags |= OBJFLAG_PANES;
- _actor1._shade = R2_GLOBALS._player._shade;
- _actor1._flags |= OBJFLAG_PANES;
+ _companion._shade = R2_GLOBALS._player._shade;
+ _companion._flags |= OBJFLAG_PANES;
_actor3._shade = R2_GLOBALS._player._shade;
_actor3._flags |= OBJFLAG_PANES;
@@ -12300,46 +12437,47 @@ void Scene1850::dispatch() {
}
if (R2_GLOBALS.getFlag(32)) {
- _actor3.setPosition(Common::Point(_actor8._position.x - 37, _actor8._position.y - 71));
- _actor4.setPosition(Common::Point(_actor8._position.x - 20, _actor8._position.y - 73));
+ _actor3.setPosition(Common::Point(_displayScreen._position.x - 37, _displayScreen._position.y - 71));
+ _actor4.setPosition(Common::Point(_displayScreen._position.x - 20, _displayScreen._position.y - 73));
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
- _actor2.setPosition(Common::Point(_actor8._position.x + 20, _actor8._position.y - 71));
+ _actor2.setPosition(Common::Point(_displayScreen._position.x + 20, _displayScreen._position.y - 71));
}
Scene::dispatch();
}
/*--------------------------------------------------------------------------
- * Scene 1875 -
+ * Scene 1875 - Rim Lift Computer
*
*--------------------------------------------------------------------------*/
-Scene1875::Actor1875::Actor1875() {
- _fieldA4 = 0;
- _fieldA6 = 0;
+
+Scene1875::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
}
-void Scene1875::Actor1875::synchronize(Serializer &s) {
+void Scene1875::Button::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_buttonDown);
}
-void Scene1875::Actor1875::subB84AB() {
+void Scene1875::Button::doButtonPress() {
Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._sound1.play(227);
int newFrameNumber;
- switch (_fieldA4) {
+ switch (_buttonId) {
case 3:
- if ((scene->_actor1._frame == 1) && (scene->_actor4._strip == 2)) {
+ if ((scene->_actor1._frame == 1) && (scene->_button1._strip == 2)) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
scene->_sceneMode = 10;
- scene->_stripManager.start(576, this);
+ scene->_stripManager.start(576, scene);
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1890;
@@ -12364,32 +12502,32 @@ void Scene1875::Actor1875::subB84AB() {
}
}
-void Scene1875::Actor1875::subB8271(int indx) {
+void Scene1875::Button::initButton(int buttonId) {
postInit();
- _fieldA4 = indx;
- _fieldA6 = 0;
+ _buttonId = buttonId;
+ _buttonDown = false;
setVisage(1855);
- if (_fieldA4 == 1)
+ if (_buttonId == 1)
setStrip(2);
else
setStrip(1);
- setFrame(_fieldA4);
- switch (_fieldA4 - 1) {
- case 0:
+ setFrame(_buttonId);
+ switch (_buttonId) {
+ case 1:
setPosition(Common::Point(20, 144));
break;
- case 1:
+ case 2:
setPosition(Common::Point(82, 144));
break;
- case 2:
+ case 3:
setPosition(Common::Point(136, 144));
break;
- case 3:
+ case 4:
setPosition(Common::Point(237, 144));
break;
- case 4:
+ case 5:
setPosition(Common::Point(299, 144));
break;
default:
@@ -12399,36 +12537,37 @@ void Scene1875::Actor1875::subB8271(int indx) {
setDetails(1875, 6, 1, -1, 2, (SceneItem *) NULL);
}
-void Scene1875::Actor1875::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) || (event.handled))
+void Scene1875::Button::process(Event &event) {
+ if (!R2_GLOBALS._player._uiEnabled || event.handled)
return;
Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_STEPPING_DISKS) && (_bounds.contains(event.mousePos)) && (_fieldA6 == 0)) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
+ && (_bounds.contains(event.mousePos)) && !_buttonDown) {
setStrip(2);
- switch (_fieldA4) {
+ switch (_buttonId) {
case 1:
R2_GLOBALS._sound2.play(227);
- scene->_actor5.setStrip(1);
+ scene->_button2.setStrip(1);
break;
case 2:
R2_GLOBALS._sound2.play(227);
- scene->_actor4.setStrip(1);
+ scene->_button1.setStrip(1);
break;
default:
break;
}
- _fieldA6 = 1;
+ _buttonDown = true;
event.handled = true;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldA6 != 0)) {
- if ((_fieldA4 == 3) || (_fieldA4 == 4) || (_fieldA4 == 5)) {
+ if ((event.eventType == EVENT_BUTTON_UP) && _buttonDown) {
+ if ((_buttonId == 3) || (_buttonId == 4) || (_buttonId == 5)) {
setStrip(1);
- subB84AB();
+ doButtonPress();
}
- _fieldA6 = 0;
+ _buttonDown = false;
event.handled = true;
}
}
@@ -12437,32 +12576,36 @@ void Scene1875::postInit(SceneObjectList *OwnerList) {
loadScene(1875);
SceneExt::postInit();
- R2_GLOBALS._player._characterScene[1] = 1875;
- R2_GLOBALS._player._characterScene[2] = 1875;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1875;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1875;
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
- _actor4.subB8271(1);
- _actor5.subB8271(2);
- _actor6.subB8271(3);
- _actor7.subB8271(4);
- _actor8.subB8271(5);
+ _button1.initButton(1);
+ _button2.initButton(2);
+ _button3.initButton(3);
+ _button4.initButton(4);
+ _button5.initButton(5);
_actor1.postInit();
_actor1.setup(1855, 4, 1);
_actor1.setPosition(Common::Point(160, 116));
R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+
if (R2_GLOBALS._sceneManager._previousScene == 1625) {
R2_GLOBALS._sound1.play(122);
R2_GLOBALS._player.disableControl();
_sceneMode = 11;
_actor2.postInit();
setAction(&_sequenceManager, this, 1892, &_actor2, NULL);
- } else if (R2_GLOBALS._sceneManager._previousScene == 3150) {
- R2_GLOBALS._sound1.play(116);
} else {
+ if (R2_GLOBALS._sceneManager._previousScene == 3150) {
+ R2_GLOBALS._sound1.play(116);
+ }
+
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
}
@@ -12470,10 +12613,10 @@ void Scene1875::postInit(SceneObjectList *OwnerList) {
_item2.setDetails(Rect(43, 14, 275, 122), 1875, 9, 1, -1, 1, NULL);
_item1.setDetails(Rect(0, 0, 320, 200), 1875, 3, -1, -1, 1, NULL);
- R2_GLOBALS._player._characterScene[1] = 1875;
- R2_GLOBALS._player._characterScene[2] = 1875;
- R2_GLOBALS._player._oldCharacterScene[1] = 1875;
- R2_GLOBALS._player._oldCharacterScene[2] = 1875;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 1875;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1875;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1875;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1875;
}
void Scene1875::signal() {
@@ -12512,18 +12655,19 @@ void Scene1875::signal() {
void Scene1875::process(Event &event) {
Scene::process(event);
- _actor4.process(event);
- _actor5.process(event);
- _actor6.process(event);
- _actor7.process(event);
- _actor8.process(event);
+ _button1.process(event);
+ _button2.process(event);
+ _button3.process(event);
+ _button4.process(event);
+ _button5.process(event);
}
/*--------------------------------------------------------------------------
- * Scene 1900 -
+ * Scene 1900 - Spill Mountains Elevator Exit
*
*--------------------------------------------------------------------------*/
-bool Scene1900::Actor2::startAction(CursorType action, Event &event) {
+
+bool Scene1900::LiftDoor::startAction(CursorType action, Event &event) {
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
if (action != CURSOR_USE)
@@ -12540,17 +12684,17 @@ bool Scene1900::Actor2::startAction(CursorType action, Event &event) {
if (_position.x >= 160) {
scene->_sceneMode = 1905;
- scene->setAction(&scene->_sequenceManager1, scene, 1905, &R2_GLOBALS._player, &scene->_actor3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1905, &R2_GLOBALS._player, &scene->_rightDoor, NULL);
} else {
R2_GLOBALS.setFlag(29);
scene->_sceneMode = 1904;
- scene->setAction(&scene->_sequenceManager1, scene, 1904, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1904, &R2_GLOBALS._player, &scene->_leftDoor, NULL);
}
return true;
}
-void Scene1900::Exit1::changeScene() {
+void Scene1900::WestExit::changeScene() {
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
@@ -12561,7 +12705,7 @@ void Scene1900::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene1900::Exit2::changeScene() {
+void Scene1900::EastExit::changeScene() {
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
@@ -12581,7 +12725,7 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS._sceneManager._previousScene = 1925;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
- R2_GLOBALS._player._oldCharacterScene[2] = 1925;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1925;
}
if (R2_GLOBALS._sceneManager._previousScene != 1875)
@@ -12591,11 +12735,11 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
_stripManager.setFontNumber(3);
_stripManager.addSpeaker(&_seekerSpeaker);
- _exit1.setDetails(Rect(0, 105, 14, 145), R2_COM_SCANNER, 2000);
- _exit1.setDest(Common::Point(14, 135));
+ _westExit.setDetails(Rect(0, 105, 14, 145), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(14, 135));
- _exit2.setDetails(Rect(305, 105, 320, 145), R2_SPENT_POWER_CAPSULE, 2000);
- _exit2.setDest(Common::Point(315, 135));
+ _eastExit.setDetails(Rect(305, 105, 320, 145), EXITCURSOR_E, 2000);
+ _eastExit.setDest(Common::Point(315, 135));
R2_GLOBALS._player.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -12612,24 +12756,24 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene != 1925)
R2_GLOBALS.clearFlag(29);
- _actor2.postInit();
- _actor2.setup(1901, 1, 1);
- _actor2.setPosition(Common::Point(95, 109));
- _actor2.fixPriority(100);
+ _leftDoor.postInit();
+ _leftDoor.setup(1901, 1, 1);
+ _leftDoor.setPosition(Common::Point(95, 109));
+ _leftDoor.fixPriority(100);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor2.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
+ _leftDoor.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
else
- _actor2.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
+ _leftDoor.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
- _actor3.postInit();
- _actor3.setup(1901, 2, 1);
- _actor3.setPosition(Common::Point(225, 109));
- _actor3.fixPriority(100);
+ _rightDoor.postInit();
+ _rightDoor.setup(1901, 2, 1);
+ _rightDoor.setPosition(Common::Point(225, 109));
+ _rightDoor.fixPriority(100);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor3.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
+ _rightDoor.setDetails(1900, 0, 1, 2, 1, (SceneItem *) NULL);
else
- _actor3.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
+ _rightDoor.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
if (R2_GLOBALS._sceneManager._previousScene != 1875) {
_object1.postInit();
@@ -12647,26 +12791,26 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
_actor1.postInit();
_sceneMode = 20;
- R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 1901, &R2_GLOBALS._player, &_actor2, NULL);
- _actor1.setAction(&_sequenceManager2, this, 1900, &_actor1, &_actor3, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 1901, &R2_GLOBALS._player, &_leftDoor, NULL);
+ _actor1.setAction(&_sequenceManager2, this, 1900, &_actor1, &_rightDoor, NULL);
} else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1925) {
if (R2_GLOBALS.getFlag(29)) {
R2_GLOBALS.clearFlag(29);
- _actor2.hide();
+ _leftDoor.hide();
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.setPosition(Common::Point(90, 106));
_sceneMode = 1906;
- setAction(&_sequenceManager1, this, 1906, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, 1906, &R2_GLOBALS._player, &_leftDoor, NULL);
} else {
- _actor3.hide();
+ _rightDoor.hide();
R2_GLOBALS._player.setStrip(5);
R2_GLOBALS._player.setPosition(Common::Point(230, 106));
_sceneMode = 1907;
- setAction(&_sequenceManager1, this, 1907, &R2_GLOBALS._player, &_actor3, NULL);
+ setAction(&_sequenceManager1, this, 1907, &R2_GLOBALS._player, &_rightDoor, NULL);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor1.postInit();
_actor1.setPosition(Common::Point(30, 110));
R2_GLOBALS._walkRegions.enableRegion(1);
@@ -12674,21 +12818,23 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
_actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
- } else if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- _actor1.setPosition(Common::Point(30, 110));
- R2_GLOBALS._walkRegions.enableRegion(1);
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 3, 1);
- _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
- } else {
- _actor1.setup(2008, 3, 1);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _actor1.postInit();
+ _actor1.setPosition(Common::Point(30, 110));
+ R2_GLOBALS._walkRegions.enableRegion(1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _actor1.setup(20, 3, 1);
+ _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ } else {
+ _actor1.setup(2008, 3, 1);
+ _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ }
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- if (R2_GLOBALS._v56605[1] == 5) {
+ if (R2_GLOBALS._spillLocation[R2_QUINN] == 5) {
_sceneMode = 1902;
setAction(&_sequenceManager1, this, 1902, &R2_GLOBALS._player, NULL);
} else {
@@ -12696,7 +12842,7 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 1903, &R2_GLOBALS._player, NULL);
}
} else {
- if (R2_GLOBALS._v56605[2] == 5) {
+ if (R2_GLOBALS._spillLocation[R2_SEEKER] == 5) {
_sceneMode = 1908;
setAction(&_sequenceManager1, this, 1908, &R2_GLOBALS._player, NULL);
} else {
@@ -12711,8 +12857,8 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
}
- _item2.setDetails(Rect(77, 2, 240, 103), 1900, 6, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 1900, 3, -1, -1, 1, NULL);
+ _elevator.setDetails(Rect(77, 2, 240, 103), 1900, 6, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1900, 3, -1, -1, 1, NULL);
}
void Scene1900::remove() {
@@ -12723,16 +12869,16 @@ void Scene1900::remove() {
void Scene1900::signal() {
switch (_sceneMode) {
case 10:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 5;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 5;
R2_GLOBALS._sceneManager.changeScene(2000);
break;
case 11:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 6;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 6;
R2_GLOBALS._sceneManager.changeScene(2000);
break;
case 20:
++_sceneMode;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(1300, this);
break;
case 21:
@@ -12755,10 +12901,10 @@ void Scene1900::signal() {
R2_GLOBALS._sceneManager.changeScene(1925);
break;
case 1910:
- R2_INVENTORY.setObjectScene(22, 2535);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2535);
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
- R2_GLOBALS._player._oldCharacterScene[1] = 1900;
- R2_GLOBALS._player._oldCharacterScene[2] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1900;
R2_GLOBALS._sceneManager.changeScene(2450);
break;
case 1906:
@@ -12985,7 +13131,7 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(220);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._player._characterScene[2] = 1925;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1925;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
switch (R2_GLOBALS._scene1925CurrLevel) {
case -2:
@@ -13044,7 +13190,7 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
void Scene1925::remove() {
R2_GLOBALS._sound1.fadeOut2(NULL);
- R2_GLOBALS._player._oldCharacterScene[2] = 1925;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1925;
SceneExt::remove();
}
@@ -13252,7 +13398,7 @@ void Scene1945::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- R2_GLOBALS._player._characterScene[2] = 1945;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 1945;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
_exitUp.setDetails(Rect(128, 0, 186, 10), EXITCURSOR_N, 1945);
@@ -13505,7 +13651,6 @@ void Scene1950::Area1::remove() {
_areaActor.remove();
SceneArea::remove();
R2_GLOBALS._insetUp--;
- //
if (!R2_GLOBALS.getFlag(37))
R2_GLOBALS._sound2.play(278);
@@ -13525,7 +13670,7 @@ void Scene1950::Area1::remove() {
}
void Scene1950::Area1::process(Event &event) {
-// This is a copy of Scene1200::LaserPanel::process
+ // This is a copy of Scene1200::LaserPanel::process
if (_field20 != R2_GLOBALS._insetUp)
return;
@@ -13533,19 +13678,16 @@ void Scene1950::Area1::process(Event &event) {
if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
- warning("TODO: _cursorState = ???");
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
remove();
}
}
@@ -13606,14 +13748,14 @@ bool Scene1950::Actor2::startAction(CursorType action, Event &event) {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(31, 0);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 0);
scene->_sceneMode = 1958;
scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_actor2, NULL);
return true;
}
bool Scene1950::Actor3::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(35) != 1950))
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) != 1950))
return SceneActor::startAction(action, event);
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
@@ -13882,7 +14024,7 @@ void Scene1950::Exit6::changeScene() {
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
R2_GLOBALS._v566A5 = 5;
if (R2_GLOBALS._v566A4 == 2) {
- if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(34) == 2) && (R2_INVENTORY.getObjectScene(35) == 2)) {
+ if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 2) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)) {
scene->_sceneMode = 1961;
Common::Point pt(-20, 160);
NpcMover *mover = new NpcMover();
@@ -13890,7 +14032,7 @@ void Scene1950::Exit6::changeScene() {
} else {
if (!R2_GLOBALS.getFlag(36))
SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- if ((R2_INVENTORY.getObjectScene(34) == 1950) || (R2_INVENTORY.getObjectScene(35) == 1950))
+ if ((R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 1950))
SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
scene->_sceneMode = 0;
Common::Point pt(30, 160);
@@ -14201,7 +14343,7 @@ void Scene1950::subBDC1E() {
switch (R2_GLOBALS._v566A4 - 1) {
case 0:
_exit7._enabled = true;
- if ((R2_INVENTORY.getObjectScene(31) == 0) && (R2_INVENTORY.getObjectScene(34) == 1950))
+ if ((R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950))
_exit8._enabled = true;
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(3);
@@ -14719,7 +14861,7 @@ void Scene1950::subBE59B() {
_field416 = 1;
}
}
- if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(31) != 0)) {
+ if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
_actor2.postInit();
_actor2.setVisage(1948);
_actor2.setStrip(3);
@@ -14755,7 +14897,7 @@ void Scene1950::subBE59B() {
_item2.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
- if (R2_INVENTORY.getObjectScene(34) == 1950) {
+ if (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) {
_actor5.postInit();
_actor5.setVisage(1970);
_actor5.setStrip(1);
@@ -14786,7 +14928,7 @@ void Scene1950::subBE59B() {
_actor3.setPosition(Common::Point(76, 94));
_actor3.fixPriority(25);
_actor3.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
- if (R2_INVENTORY.getObjectScene(35) == 2)
+ if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)
_actor3.setFrame(2);
else
_actor3.setFrame(1);
@@ -14805,7 +14947,7 @@ void Scene1950::subBE59B() {
switch (R2_GLOBALS._v566A5) {
case 0:
_sceneMode = 1950;
- if (R2_INVENTORY.getObjectScene(31) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) {
R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
} else {
@@ -15020,8 +15162,8 @@ void Scene1950::postInit(SceneObjectList *OwnerList) {
_exit8.setDest(Common::Point(268, 149));
R2_GLOBALS._player.postInit();
- if ( (R2_INVENTORY.getObjectScene(32) == 0) && (R2_INVENTORY.getObjectScene(33) == 0)
- && (R2_INVENTORY.getObjectScene(46) == 0) && (!R2_GLOBALS.getFlag(36)) )
+ if ( (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 0) && (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_SOAKED_FACEMASK) == 0) && (!R2_GLOBALS.getFlag(36)) )
R2_GLOBALS._player.setVisage(22);
else
R2_GLOBALS._player.setVisage(20);
@@ -15124,7 +15266,7 @@ void Scene1950::signal() {
_exit8._enabled = true;
break;
case 1959:
- R2_INVENTORY.setObjectScene(46, 0);
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 0);
R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
_exit8._enabled = true;
@@ -15155,7 +15297,7 @@ void Scene1950::signal() {
_actor5.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
case 1967: {
_sceneMode = 0;
- R2_INVENTORY.setObjectScene(34, 2);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 2);
_actor5.remove();
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
@@ -15170,7 +15312,7 @@ void Scene1950::signal() {
break;
case 1968:
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(35, 2);
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2);
_actor3.setFrame(2);
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
@@ -15190,7 +15332,7 @@ void Scene1950::process(Event &event) {
&& (R2_GLOBALS._player._uiEnabled)
&& (R2_GLOBALS._events.getCursor() == R2_LIGHT_BULB)
&& (R2_GLOBALS._player._bounds.contains(event.mousePos))
- && (R2_INVENTORY.getObjectScene(31) == 0)) {
+ && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)) {
event.handled = true;
R2_GLOBALS._player.disableControl();
_exit7._enabled = false;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index 23ebb2c276..82895c7ab0 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -46,8 +46,8 @@ public:
SpeakerGameText _gameTextSpeaker;
AnimationPlayer _animationPlayer;
- int _field412;
- int _fieldD2E;
+ int _animCounter;
+ bool _forceCheckAnimationFl;
public:
Scene1000();
@@ -75,21 +75,21 @@ public:
};
class Scene1100 : public SceneExt {
- class Actor16 : public SceneActor {
+ class Seeker : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor17 : public SceneActor {
+ class Trooper : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor18 : public SceneActor {
+ class Chief : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412, _field414;
+ int _nextStripNum, _paletteRefreshStatus;
SpeakerSeeker1100 _seekerSpeaker;
SpeakerQuinn1100 _quinnSpeaker;
SpeakerChief1100 _chiefSpeaker;
@@ -103,24 +103,24 @@ public:
NamedHotspot _item7;
SceneActor _actor1;
SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
- SceneActor _actor12;
- SceneActor _actor13;
- SceneActor _actor14;
- SceneActor _actor15;
- BackgroundSceneObject _object1;
+ SceneActor _shipFormation;
+ SceneActor _shipFormationShadow;
+ SceneActor _shotImpact1;
+ SceneActor _shotImpact2;
+ SceneActor _shotImpact3;
+ SceneActor _shotImpact4;
+ SceneActor _shotImpact5;
+ SceneActor _laserShot;
+ SceneActor _animation;
+ SceneActor _leftImpacts;
+ SceneActor _runningGuy1;
+ SceneActor _runningGuy2;
+ SceneActor _runningGuy3;
+ BackgroundSceneObject _rightLandslide;
BackgroundSceneObject _object2;
- Actor16 _actor16;
- Actor17 _actor17;
- Actor18 _actor18;
+ Seeker _seeker;
+ Trooper _trooper;
+ Chief _chief;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
SequenceManager _sequenceManager3;
@@ -427,26 +427,26 @@ class Scene1550 : public SceneExt {
void subA4D14(int frameNumber, int strip);
};
- class UnkObj15501 : public SceneActor {
+ class Junk : public SceneActor {
public:
int _fieldA4;
- int _fieldA6;
+ int _junkNumber;
- UnkObj15501();
+ Junk();
void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
- class UnkObj15502 : public SceneActor {
+ class ShipComponent : public SceneActor {
public:
- int _fieldA4;
+ int _componentId;
- UnkObj15502();
+ ShipComponent();
void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
- void subA5CDF(int strip);
+ void setupShipComponent(int componentId);
};
class UnkObj15503 : public SceneActor {
@@ -472,7 +472,7 @@ class Scene1550 : public SceneExt {
virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
- class Hotspot1 : public NamedHotspot {
+ class WorkingShip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -482,12 +482,12 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Wreckage : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Companion : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -522,7 +522,7 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor14 : public SceneActor1550 {
+ class Wall : public SceneActor1550 {
// Nothing specific found in the original
// TODO: check if it's an useless class
};
@@ -530,30 +530,30 @@ class Scene1550 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- Hotspot1 _item1;
- Hotspot1 _item2;
+ WorkingShip _shipHull;
+ WorkingShip _item2;
Hotspot3 _item3;
- SceneActor _actor1;
+ SceneActor _landingStrut;
SceneActor _actor2;
SceneActor _actor3;
SceneActor _actor4;
SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
+ Wreckage _wreckage;
+ Companion _companion;
Actor8 _actor8;
Actor9 _actor9;
Actor10 _actor10;
Actor11 _actor11;
Actor12 _actor12;
Actor13 _actor13;
- UnkObj15501 _arrUnkObj15501[8];
- Actor14 _actor14;
- Actor14 _actor15;
- Actor14 _actor16;
- Actor14 _actor17;
- Actor14 _actor18;
- Actor14 _actor19;
- UnkObj15502 _arrUnkObj15502[8];
+ Junk _junk[8];
+ Wall _actor14;
+ Wall _northWall; // Is also reused for landing strip
+ Wall _actor16;
+ Wall _westWall; // Is also reused for left hand space
+ Wall _eastWall;
+ Wall _southWall;
+ ShipComponent _shipComponents[8];
UnkArea1550 _unkArea1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -566,7 +566,7 @@ public:
Scene1550();
void synchronize(Serializer &s);
- void subA2B2F();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
@@ -687,7 +687,7 @@ public:
};
class Scene1625 : public SceneExt {
- class Actor7 : public SceneActor {
+ class Wire : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -698,12 +698,12 @@ public:
SpeakerSoldier1625 _soldierSpeaker;
NamedHotspot _item1;
SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _tealHead;
SceneActor _actor3;
- SceneActor _actor4;
+ SceneActor _glass;
SceneActor _actor5;
SceneActor _actor6;
- Actor7 _actor7;
+ Wire _wire;
SequenceManager _sequenceManager;
Scene1625();
@@ -721,7 +721,7 @@ class Scene1700 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor11 : public SceneActor {
+ class RimTransport : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -730,15 +730,15 @@ class Scene1700 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -749,19 +749,19 @@ public:
Item2 _item2;
SceneActor _actor1;
SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
+ SceneActor _slabWest;
+ SceneActor _slabEast;
+ SceneActor _slabShadowWest;
+ SceneActor _slabShadowEast;
+ SceneActor _westPlatform;
+ SceneActor _rimTransportDoor;
+ SceneActor _ledgeHopper;
SceneActor _actor10;
- Actor11 _actor11;
+ RimTransport _rimTransport;
Actor12 _actor12;
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
+ NorthExit _northExit;
+ SouthExit _southExit;
+ WestExit _westExit;
SequenceManager _sequenceManager;
int _field77A;
@@ -769,7 +769,7 @@ public:
Scene1700();
void synchronize(Serializer &s);
- void subAF3F8();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
@@ -777,54 +777,54 @@ public:
};
class Scene1750 : public SceneExt {
- class Actor4 : public SceneActor {
+ class SpeedSlider : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
- int _fieldA8;
- int _fieldAA;
- int _fieldAC;
- int _fieldAE;
+ int _incrAmount;
+ int _xp;
+ int _ys;
+ int _height;
+ int _thumbHeight;
+ bool _mouseDown;
- Actor4();
+ SpeedSlider();
virtual void synchronize(Serializer &s);
- void subB1A76(int arg1, int arg2, int arg3, int arg4, int arg5);
- void subB1B27();
+ void setupSlider(int incrAmount, int xp, int ys, int height, int thumbHeight);
+ void calculateSlider();
virtual void remove();
virtual void process(Event &event);
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Button : public SceneActor {
public:
- int _fieldA4;
+ int _buttonId;
- Actor5();
+ Button();
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
+ NamedHotspot _background;
+ NamedHotspot _redLights;
+ NamedHotspot _greenLights;
+ NamedHotspot _frontView;
+ NamedHotspot _rearView;
SceneActor _actor1;
SceneActor _actor2;
SceneActor _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor5 _actor6;
- Actor5 _actor7;
+ SpeedSlider _speedSlider;
+ Button _forwardButton;
+ Button _backwardButton;
+ Button _exitButton;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
- int _field412;
+ int _direction;
int _field413;
- int _field415;
+ int _speed;
int _field417;
int _field419;
int _field41B;
@@ -841,20 +841,20 @@ public:
};
class Scene1800 : public SceneExt {
- class Hotspot5 : public NamedHotspot {
+ class Background : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Lever : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Doors : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class PassengerDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -864,23 +864,23 @@ class Scene1800 : public SceneExt {
virtual void changeScene();
};
public:
- int _field412;
+ int _locationMode;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
NamedHotspot _item1;
NamedHotspot _item2;
NamedHotspot _item3;
NamedHotspot _item4;
- Hotspot5 _item5;
+ Background _background;
SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _companion;
SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
- Actor8 _actor9;
+ SceneActor _leftStaircase;
+ SceneActor _rightStaircase;
+ Lever _lever;
+ Doors _doors;
+ PassengerDoor _leftDoor;
+ PassengerDoor _rightDoor;
Exit1 _exit1;
SequenceManager _sequenceManager;
@@ -893,12 +893,12 @@ public:
};
class Scene1850 : public SceneExt {
- class Hotspot2 : public NamedHotspot {
+ class Button : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Robot : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -906,7 +906,7 @@ class Scene1850 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class DisplayScreen : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -921,16 +921,16 @@ public:
ScenePalette _palette1;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- Hotspot2 _item2;
- SceneActor _actor1;
+ NamedHotspot _background;
+ Button _button;
+ SceneActor _companion;
SceneActor _actor2;
SceneActor _actor3;
SceneActor _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor6 _actor7;
- Actor8 _actor8;
+ Robot _robot;
+ Actor6 _leftDoor;
+ Actor6 _rightDoor;
+ DisplayScreen _displayScreen;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -945,15 +945,16 @@ public:
};
class Scene1875 : public SceneExt {
- class Actor1875 : public SceneActor {
+ class Button : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
+ int _buttonId;
+ bool _buttonDown;
- Actor1875();
- void subB84AB();
- void subB8271(int indx);
+ Button();
+ void doButtonPress();
+ void initButton(int buttonId);
+ virtual Common::String getClassName() { return "Scene1875_Button"; }
void synchronize(Serializer &s);
virtual void process(Event &event);
};
@@ -965,11 +966,11 @@ public:
SceneActor _actor1;
SceneActor _actor2;
SceneActor _actor3;
- Actor1875 _actor4;
- Actor1875 _actor5;
- Actor1875 _actor6;
- Actor1875 _actor7;
- Actor1875 _actor8;
+ Button _button1;
+ Button _button2;
+ Button _button3;
+ Button _button4;
+ Button _button5;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -978,30 +979,29 @@ public:
};
class Scene1900 : public SceneExt {
- class Actor2 : public SceneActor {
+ class LiftDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
SpeakerSeeker1900 _seekerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
+ NamedHotspot _background;
+ NamedHotspot _elevator;
SceneActor _actor1;
BackgroundSceneObject _object1;
BackgroundSceneObject _object2;
- Actor2 _actor2;
- Actor2 _actor3;
- Exit1 _exit1;
- Exit2 _exit2;
+ LiftDoor _leftDoor, _rightDoor;
+ WestExit _westExit;
+ EastExit _eastExit;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index 9246c4b6a4..443f68bc1f 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -30,17 +30,19 @@ namespace TsAGE {
namespace Ringworld2 {
/*--------------------------------------------------------------------------
- * Scene 2000 - Ice Maze
+ * Scene 2000 - Spill Mountains
*
*--------------------------------------------------------------------------*/
+
void Scene2000::initPlayer() {
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
switch (_mazePlayerMode) {
case 0:
R2_GLOBALS._player.setStrip(5);
- if (_exit1._enabled) {
- if (_exit2._enabled)
+ if (_westExit._enabled) {
+ if (_eastExit._enabled)
R2_GLOBALS._player.setPosition(Common::Point(140, 129));
else
R2_GLOBALS._player.setPosition(Common::Point(20, 129));
@@ -129,11 +131,11 @@ void Scene2000::initPlayer() {
break;
}
for (int i = 0; i < 11; i++) {
- if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == R2_GLOBALS._v56605[3 + i])
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == R2_GLOBALS._spillLocation[3 + i])
_objList1[i].show();
}
- if ((R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) && (R2_GLOBALS._v56605[1] == R2_GLOBALS._v56605[2])) {
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) && (R2_GLOBALS._spillLocation[R2_QUINN] == R2_GLOBALS._spillLocation[R2_SEEKER])) {
_object1.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_object1.setup(20, 5, 1);
@@ -142,8 +144,8 @@ void Scene2000::initPlayer() {
_object1.setup(2008, 5, 1);
_object1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- if (_exit1._enabled) {
- if (_exit2._enabled)
+ if (_westExit._enabled) {
+ if (_eastExit._enabled)
_object1.setPosition(Common::Point(180, 128));
else
_object1.setPosition(Common::Point(75, 128));
@@ -153,53 +155,53 @@ void Scene2000::initPlayer() {
}
void Scene2000::initExits() {
- _exit1._enabled = true;
- _exit2._enabled = true;
- _exit3._enabled = false;
- _exit4._enabled = false;
- _exit5._enabled = false;
-
- _exit1._insideArea = false;
- _exit2._insideArea = false;
- _exit3._insideArea = false;
- _exit4._insideArea = false;
- _exit5._insideArea = false;
-
- _exit1._moving = false;
- _exit2._moving = false;
- _exit3._moving = false;
- _exit4._moving = false;
- _exit5._moving = false;
+ _westExit._enabled = true;
+ _eastExit._enabled = true;
+ _southExit._enabled = false;
+ _northExit._enabled = false;
+ _doorExit._enabled = false;
+
+ _westExit._insideArea = false;
+ _eastExit._insideArea = false;
+ _southExit._insideArea = false;
+ _northExit._insideArea = false;
+ _doorExit._insideArea = false;
+
+ _westExit._moving = false;
+ _eastExit._moving = false;
+ _southExit._moving = false;
+ _northExit._moving = false;
+ _doorExit._moving = false;
for (int i = 0; i < 11; i++)
_objList1[i].hide();
_object1.remove();
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 3:
case 10:
case 16:
case 21:
- _exit5._enabled = true;
- _exit5._bounds.set(61, 68, 90, 125);
- _exit5.setDest(Common::Point(92, 129));
- _exit5._cursorNum = EXITCURSOR_W;
+ _doorExit._enabled = true;
+ _doorExit._bounds.set(61, 68, 90, 125);
+ _doorExit.setDest(Common::Point(92, 129));
+ _doorExit._cursorNum = EXITCURSOR_W;
break;
case 4:
case 12:
case 25:
case 34:
- _exit5._enabled = true;
- _exit5._bounds.set(230, 68, 259, 125);
- _exit5.setDest(Common::Point(244, 129));
- _exit5._cursorNum = EXITCURSOR_E;
+ _doorExit._enabled = true;
+ _doorExit._bounds.set(230, 68, 259, 125);
+ _doorExit.setDest(Common::Point(244, 129));
+ _doorExit._cursorNum = EXITCURSOR_E;
break;
default:
break;
}
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] - 1) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
case 6:
case 13:
@@ -207,7 +209,7 @@ void Scene2000::initExits() {
case 22:
case 27:
case 30:
- _exit1._enabled = false;
+ _westExit._enabled = false;
loadScene(2225);
R2_GLOBALS._walkRegions.load(2225);
if (!_exitingFlag)
@@ -216,10 +218,10 @@ void Scene2000::initExits() {
break;
case 1:
case 19:
- _exit3._enabled = true;
- _exit3._bounds.set(71, 130, 154, 168);
- _exit3.setDest(Common::Point(94, 129));
- _exit3._cursorNum = EXITCURSOR_SE;
+ _southExit._enabled = true;
+ _southExit._bounds.set(71, 130, 154, 168);
+ _southExit.setDest(Common::Point(94, 129));
+ _southExit._cursorNum = EXITCURSOR_SE;
loadScene(2300);
if (!_exitingFlag)
_mazePlayerMode = 0;
@@ -283,8 +285,8 @@ void Scene2000::initExits() {
case 21:
case 26:
loadScene(2200);
- R2_GLOBALS._walkRegions.load(2000);
- _exit2._enabled = false;
+ R2_GLOBALS._walkRegions.load(2200);
+ _eastExit._enabled = false;
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1900)
_mazePlayerMode = 2;
else if (!_exitingFlag)
@@ -294,10 +296,10 @@ void Scene2000::initExits() {
break;
case 7:
case 29:
- _exit4._enabled = true;
- _exit4._bounds.set(138, 83, 211, 125);
- _exit4.setDest(Common::Point(129, 188));
- _exit4._cursorNum = EXITCURSOR_NW;
+ _northExit._enabled = true;
+ _northExit._bounds.set(138, 83, 211, 125);
+ _northExit.setDest(Common::Point(188, 129));
+ _northExit._cursorNum = EXITCURSOR_NW;
loadScene(2250);
R2_GLOBALS._walkRegions.load(2000);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2500)
@@ -309,10 +311,10 @@ void Scene2000::initExits() {
break;
case 10:
case 25:
- _exit3._enabled = true;
- _exit3._bounds.set(78, 130, 148, 168);
- _exit3.setDest(Common::Point(100, 129));
- _exit3._cursorNum = EXITCURSOR_SE;
+ _southExit._enabled = true;
+ _southExit._bounds.set(78, 130, 148, 168);
+ _southExit.setDest(Common::Point(100, 129));
+ _southExit._cursorNum = EXITCURSOR_SE;
loadScene(2075);
R2_GLOBALS._walkRegions.load(2000);
if (!_exitingFlag)
@@ -320,10 +322,10 @@ void Scene2000::initExits() {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
break;
case 14:
- _exit3._enabled = true;
- _exit3._bounds.set(160, 130, 248, 168);
- _exit3.setDest(Common::Point(225, 129));
- _exit3._cursorNum = EXITCURSOR_SW;
+ _southExit._enabled = true;
+ _southExit._bounds.set(160, 130, 248, 168);
+ _southExit.setDest(Common::Point(225, 129));
+ _southExit._cursorNum = EXITCURSOR_SW;
loadScene(2325);
R2_GLOBALS._walkRegions.load(2000);
if (!_exitingFlag)
@@ -332,10 +334,10 @@ void Scene2000::initExits() {
break;
case 16:
case 31:
- _exit4._enabled = true;
- _exit4._bounds.set(122, 83, 207, 125);
- _exit4.setDest(Common::Point(210, 129));
- _exit4._cursorNum = EXITCURSOR_NW;
+ _northExit._enabled = true;
+ _northExit._bounds.set(122, 83, 207, 125);
+ _northExit.setDest(Common::Point(210, 129));
+ _northExit._cursorNum = EXITCURSOR_NW;
loadScene(2125);
R2_GLOBALS._walkRegions.load(2000);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2400)
@@ -346,10 +348,10 @@ void Scene2000::initExits() {
R2_GLOBALS._sceneManager._previousScene = 2000;
break;
case 23:
- _exit4._enabled = true;
- _exit4._bounds.set(108, 83, 128, 184);
- _exit4.setDest(Common::Point(135, 129));
- _exit4._cursorNum = CURSOR_INVALID;
+ _northExit._enabled = true;
+ _northExit._bounds.set(108, 83, 128, 184);
+ _northExit.setDest(Common::Point(135, 129));
+ _northExit._cursorNum = CURSOR_INVALID;
loadScene(2275);
R2_GLOBALS._walkRegions.load(2000);
if (!_exitingFlag)
@@ -357,10 +359,10 @@ void Scene2000::initExits() {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2000;
break;
case 28:
- _exit3._enabled = true;
- _exit3._bounds.set(171, 130, 241, 168);
- _exit3.setDest(Common::Point(218, 129));
- _exit3._cursorNum = EXITCURSOR_SW;
+ _southExit._enabled = true;
+ _southExit._bounds.set(171, 130, 241, 168);
+ _southExit.setDest(Common::Point(218, 129));
+ _southExit._cursorNum = EXITCURSOR_SW;
loadScene(2050);
R2_GLOBALS._walkRegions.load(2000);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2350)
@@ -396,34 +398,34 @@ void Scene2000::Action1::signal() {
}
case 1:
scene->_objList1[_state].setPosition(Common::Point(340, 127));
- --R2_GLOBALS._v56605[4 + _state];
+ --R2_GLOBALS._spillLocation[4 + _state];
_actionIndex = 0;
switch (_state - 1) {
case 0:
- if (R2_GLOBALS._v56605[4] == 1)
+ if (R2_GLOBALS._spillLocation[4] == 1)
_actionIndex = 10;
break;
case 2:
- if (R2_GLOBALS._v56605[6] == 7)
+ if (R2_GLOBALS._spillLocation[6] == 7)
_actionIndex = 10;
break;
case 4:
- if (R2_GLOBALS._v56605[8] == 14)
+ if (R2_GLOBALS._spillLocation[8] == 14)
_actionIndex = 10;
break;
case 6:
- if (R2_GLOBALS._v56605[10] == 19)
+ if (R2_GLOBALS._spillLocation[10] == 19)
_actionIndex = 10;
break;
case 7:
- if (R2_GLOBALS._v56605[11] == 23)
+ if (R2_GLOBALS._spillLocation[11] == 23)
_actionIndex = 10;
break;
default:
break;
}
- if (R2_GLOBALS._v56605[3 + _state] == R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex])
+ if (R2_GLOBALS._spillLocation[3 + _state] == R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex])
scene->_objList1[_state].show();
else
scene->_objList1[_state].hide();
@@ -439,34 +441,34 @@ void Scene2000::Action1::signal() {
}
case 6:
scene->_objList1[_state].setPosition(Common::Point(-20, 127));
- ++R2_GLOBALS._v56605[3 + _state];
+ ++R2_GLOBALS._spillLocation[3 + _state];
_actionIndex = 5;
switch (_state - 1) {
case 0:
- if (R2_GLOBALS._v56605[4] == 5)
+ if (R2_GLOBALS._spillLocation[4] == 5)
_actionIndex = 15;
break;
case 2:
- if (R2_GLOBALS._v56605[6] == 13)
+ if (R2_GLOBALS._spillLocation[6] == 13)
_actionIndex = 15;
break;
case 4:
- if (R2_GLOBALS._v56605[8] == 16)
+ if (R2_GLOBALS._spillLocation[8] == 16)
_actionIndex = 15;
break;
case 6:
- if (R2_GLOBALS._v56605[10] == 22)
+ if (R2_GLOBALS._spillLocation[10] == 22)
_actionIndex = 15;
break;
case 7:
- if (R2_GLOBALS._v56605[11] == 27)
+ if (R2_GLOBALS._spillLocation[11] == 27)
_actionIndex = 15;
break;
default:
break;
}
- if (R2_GLOBALS._v56605[3 + _state] == R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex])
+ if (R2_GLOBALS._spillLocation[3 + _state] == R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex])
scene->_objList1[_state].show();
else
scene->_objList1[_state].hide();
@@ -498,7 +500,7 @@ void Scene2000::Action1::signal() {
signal();
break;
case 15:
- if ((R2_GLOBALS._v56605[3 + _state] == 13) || (R2_GLOBALS._v56605[3 + _state] == 22) || (R2_GLOBALS._v56605[3 + _state] == 27)) {
+ if ((R2_GLOBALS._spillLocation[3 + _state] == 13) || (R2_GLOBALS._spillLocation[3 + _state] == 22) || (R2_GLOBALS._spillLocation[3 + _state] == 27)) {
Common::Point pt(30, 127);
NpcMover *mover = new NpcMover();
scene->_objList1[_state].addMover(mover, &pt, this);
@@ -534,26 +536,24 @@ void Scene2000::Action1::signal() {
}
}
-void Scene2000::Exit1::changeScene() {
+void Scene2000::WestExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 10;
Common::Point pt(-10, 129);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, scene);
-
- scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
}
-void Scene2000::Exit2::changeScene() {
+void Scene2000::EastExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 11;
@@ -562,38 +562,38 @@ void Scene2000::Exit2::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
}
-void Scene2000::Exit3::changeScene() {
+void Scene2000::SouthExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 12;
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 2:
scene->_mazePlayerMode = 4;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 8;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 8;
break;
case 11:
scene->_mazePlayerMode = 6;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 17;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 17;
break;
case 15:
scene->_mazePlayerMode = 8;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 24;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 24;
break;
case 20:
scene->_mazePlayerMode = 4;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 30;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 30;
break;
case 26:
scene->_mazePlayerMode = 6;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 32;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 32;
break;
case 29:
scene->_mazePlayerMode = 11;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 29;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 29;
break;
default:
break;
@@ -631,34 +631,34 @@ void Scene2000::Exit3::changeScene() {
}
}
-void Scene2000::Exit4::changeScene() {
+void Scene2000::NorthExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
scene->_exitingFlag = true;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 13;
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 8:
scene->_mazePlayerMode = 5;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 2;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 2;
break;
case 17:
scene->_mazePlayerMode = 7;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 11;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 11;
break;
case 24:
scene->_mazePlayerMode = 9;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 15;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 15;
break;
case 30:
scene->_mazePlayerMode = 5;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 20;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 20;
break;
case 32:
scene->_mazePlayerMode = 7;
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 26;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 26;
break;
default:
break;
@@ -688,14 +688,14 @@ void Scene2000::Exit4::changeScene() {
}
}
-void Scene2000::Exit5::changeScene() {
+void Scene2000::DoorExit::changeScene() {
Scene2000 *scene = (Scene2000 *)R2_GLOBALS._sceneManager._scene;
- scene->_sceneMode = 0;
+ _enabled = false;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 14;
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 3:
scene->_mazePlayerMode = 1;
if (R2_GLOBALS._player._characterIndex == 1)
@@ -758,9 +758,9 @@ void Scene2000::Exit5::changeScene() {
}
Scene2000::Scene2000(): SceneExt() {
- if (R2_GLOBALS._sceneManager._previousScene != -1) {
- R2_GLOBALS._v56605[1] = 21;
- R2_GLOBALS._v56605[2] = 21;
+ if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ R2_GLOBALS._spillLocation[R2_QUINN] = 21;
+ R2_GLOBALS._spillLocation[R2_SEEKER] = 21;
}
if ((R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex]
!= R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex])
@@ -769,19 +769,20 @@ Scene2000::Scene2000(): SceneExt() {
}
_exitingFlag = false;
+ _mazePlayerMode = 0;
}
void Scene2000::postInit(SceneObjectList *OwnerList) {
- _exit1.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2000);
- _exit1.setDest(Common::Point(14, 129));
- _exit2.setDetails(Rect(305, 100, 320, 140), EXITCURSOR_E, 2000);
- _exit2.setDest(Common::Point(315, 129));
- _exit3.setDetails(Rect(71, 130, 154, 168), EXITCURSOR_S, 2000);
- _exit3.setDest(Common::Point(94, 129));
- _exit4.setDetails(Rect(138, 83, 211, 125), EXITCURSOR_N, 2000);
- _exit4.setDest(Common::Point(188, 128));
- _exit5.setDetails(Rect(61, 68, 90, 125), EXITCURSOR_W, 2000);
- _exit5.setDest(Common::Point(92, 129));
+ _westExit.setDetails(Rect(0, 100, 14, 140), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(14, 129));
+ _eastExit.setDetails(Rect(305, 100, 320, 140), EXITCURSOR_E, 2000);
+ _eastExit.setDest(Common::Point(315, 129));
+ _southExit.setDetails(Rect(71, 130, 154, 168), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(94, 129));
+ _northExit.setDetails(Rect(138, 83, 211, 125), EXITCURSOR_N, 2000);
+ _northExit.setDest(Common::Point(188, 129));
+ _doorExit.setDetails(Rect(61, 68, 90, 125), EXITCURSOR_W, 2000);
+ _doorExit.setDest(Common::Point(92, 129));
R2_GLOBALS._sound1.play(200);
initExits();
@@ -858,39 +859,39 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
_objList1[i].hide();
switch (i - 1) {
case 0:
- if (R2_GLOBALS._v56605[3 + i] == 1)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 5)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 1)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 5)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 2:
- if (R2_GLOBALS._v56605[3 + i] == 7)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 13)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 7)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 13)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 4:
- if (R2_GLOBALS._v56605[3 + i] == 14)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 16)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 14)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 16)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 6:
- if (R2_GLOBALS._v56605[3 + i] == 19)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 22)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 19)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 22)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
case 8:
- if (R2_GLOBALS._v56605[3 + i] == 23)
- ++R2_GLOBALS._v56605[3 + i];
- else if (R2_GLOBALS._v56605[3 + i] == 27)
- --R2_GLOBALS._v56605[3 + i];
+ if (R2_GLOBALS._spillLocation[3 + i] == 23)
+ ++R2_GLOBALS._spillLocation[3 + i];
+ else if (R2_GLOBALS._spillLocation[3 + i] == 27)
+ --R2_GLOBALS._spillLocation[3 + i];
break;
default:
break;
}
- switch (R2_GLOBALS._v56605[3 + i] - 1) {
+ switch (R2_GLOBALS._spillLocation[3 + i] - 1) {
case 0:
case 6:
case 13:
@@ -925,6 +926,7 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
}
void Scene2000::remove() {
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._sound1.fadeOut(NULL);
SceneExt::remove();
}
@@ -932,17 +934,19 @@ void Scene2000::remove() {
void Scene2000::signal() {
switch (_sceneMode) {
case 10:
- if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == 6)
+ // Leaving left-hand side of scene
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == 6)
g_globals->_sceneManager.changeScene(1900);
else {
_mazePlayerMode = 1;
- --R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex];
+ --R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex];
initExits();
initPlayer();
}
break;
case 11:
- switch (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex]) {
+ // Leaving right-hand side of scene
+ switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 5:
g_globals->_sceneManager.changeScene(1900);
break;
@@ -954,7 +958,7 @@ void Scene2000::signal() {
break;
default:
_mazePlayerMode = 2;
- ++R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex];
initExits();
initPlayer();
break;
@@ -962,6 +966,7 @@ void Scene2000::signal() {
break;
case 12:
case 13:
+ // Top/bottom scene exits
initExits();
initPlayer();
break;
@@ -1025,6 +1030,12 @@ void Scene2000::process(Event &event) {
void Scene2000::synchronize(Serializer &s) {
SceneExt::synchronize(s);
+ // Synchronise active walk regions
+ int regionsId = R2_GLOBALS._walkRegions._resNum;
+ s.syncAsUint16LE(regionsId);
+ if (s.isLoading())
+ R2_GLOBALS._walkRegions.load(regionsId);
+
s.syncAsByte(_exitingFlag);
s.syncAsSint16LE(_mazePlayerMode);
}
@@ -1084,7 +1095,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS._player._characterScene[2] = 2350;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2350;
_exitUp.setDetails(Rect(25, 83, 93, 125), EXITCURSOR_NW, 2350);
_exitUp.setDest(Common::Point(80, 129));
@@ -1102,7 +1113,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor2.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor2.setup(20, 5, 1);
@@ -1116,7 +1127,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
_actor3.postInit();
_actor4.postInit();
- if (R2_INVENTORY.getObjectScene(20) == 2350) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2350) {
_actor3.hide();
_actor4.hide();
} else {
@@ -1133,7 +1144,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
- if (R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] == 34) {
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == 34) {
if (R2_GLOBALS._player._characterIndex == 1)
_sceneMode = 2351;
else
@@ -1163,11 +1174,11 @@ void Scene2350::remove() {
void Scene2350::signal() {
switch (_sceneMode) {
case 11:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 34;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 34;
g_globals->_sceneManager.changeScene(2000);
break;
case 12:
- R2_GLOBALS._v56605[R2_GLOBALS._player._characterIndex] = 29;
+ R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] = 29;
g_globals->_sceneManager.changeScene(2000);
break;
case 20:
@@ -1176,12 +1187,12 @@ void Scene2350::signal() {
break;
case 21:
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(36, 1);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 1);
_sceneMode = 2354;
setAction(&_sequenceManager, this, 2354, &R2_GLOBALS._player, NULL);
break;
case 2354:
- R2_INVENTORY.setObjectScene(20, 2350);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2350);
g_globals->_sceneManager.changeScene(2900);
break;
case 2355:
@@ -1207,7 +1218,7 @@ void Scene2350::process(Event &event) {
}
/*--------------------------------------------------------------------------
- * Scene 2400 - Ice Maze: Large empty room
+ * Scene 2400 - Spill Mountains: Large empty room
*
*--------------------------------------------------------------------------*/
void Scene2400::Exit1::changeScene() {
@@ -1243,7 +1254,7 @@ void Scene2400::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._v56605[1] == 16) {
+ if (R2_GLOBALS._spillLocation[R2_QUINN] == 16) {
_sceneMode = 2400;
setAction(&_sequenceManager, this, 2400, &R2_GLOBALS._player, NULL);
} else {
@@ -1255,11 +1266,11 @@ void Scene2400::postInit(SceneObjectList *OwnerList) {
void Scene2400::signal() {
switch (_sceneMode) {
case 10:
- R2_GLOBALS._v56605[1] = 16;
+ R2_GLOBALS._spillLocation[R2_QUINN] = 16;
g_globals->_sceneManager.changeScene(2000);
break;
case 11:
- R2_GLOBALS._v56605[1] = 17;
+ R2_GLOBALS._spillLocation[R2_QUINN] = 17;
g_globals->_sceneManager.changeScene(2000);
break;
default:
@@ -1269,7 +1280,7 @@ void Scene2400::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2425 - Ice Maze:
+ * Scene 2425 - Spill Mountains:
*
*--------------------------------------------------------------------------*/
@@ -1364,7 +1375,7 @@ void Scene2425::Exit1::changeScene() {
Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 11;
@@ -1395,7 +1406,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor2.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor2.setup(20, 5, 1);
@@ -1484,7 +1495,7 @@ void Scene2425::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2430 - Ice Maze: Bedroom
+ * Scene 2430 - Spill Mountains: Bedroom
*
*--------------------------------------------------------------------------*/
@@ -1520,7 +1531,7 @@ void Scene2430::Exit1::changeScene() {
Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 0;
- R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 11;
Common::Point pt(108, 200);
@@ -1534,7 +1545,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(37) == 2430) {
+ if (R2_INVENTORY.getObjectScene(R2_GUNPOWDER) == 2430) {
_actor2.postInit();
_actor2.setup(2435, 1, 5);
_actor2.setPosition(Common::Point(205, 119));
@@ -1542,7 +1553,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
_actor2.setDetails(2430, 51, -1, 53, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(50) == 2435) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2435) {
_actor3.postInit();
_actor3.setup(2435, 1, 1);
_actor3.setPosition(Common::Point(31, 65));
@@ -1560,7 +1571,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(100, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor1.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor1.setup(20, 5, 1);
@@ -1623,14 +1634,15 @@ void Scene2430::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2435 - Ice Maze: Throne room
+ * Scene 2435 - Spill Mountains: Throne room
*
*--------------------------------------------------------------------------*/
-bool Scene2435::Actor1::startAction(CursorType action, Event &event) {
+
+bool Scene2435::Companion::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene2435::Actor2::startAction(CursorType action, Event &event) {
+bool Scene2435::Astor::startAction(CursorType action, Event &event) {
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -1671,7 +1683,7 @@ void Scene2435::Exit1::changeScene() {
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._events.setCursor(R2_NEGATOR_GUN);
+ R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 11;
Common::Point pt(175, 200);
@@ -1689,36 +1701,38 @@ void Scene2435::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_pharishaSpeaker);
_exit1.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(175, 160));
- _actor2.postInit();
- _actor2.setup(2005, 3, 1);
- _actor2.setPosition(Common::Point(219, 106));
- _actor2.setDetails(2001, 25, 26, -1, 1, (SceneItem *)NULL);
+ _astor.postInit();
+ _astor.setup(2005, 3, 1);
+ _astor.setPosition(Common::Point(219, 106));
+ _astor.setDetails(2001, 25, 26, -1, 1, (SceneItem *)NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- if (R2_GLOBALS._player._characterIndex == 1) {
+
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setVisage(2008);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
} else {
R2_GLOBALS._player.setVisage(20);
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- R2_GLOBALS._player.setPosition(Common::Point(715, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ R2_GLOBALS._player.setPosition(Common::Point(175, 200));
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(107, 145));
+ _companion.setPosition(Common::Point(107, 145));
R2_GLOBALS._walkRegions.enableRegion(2);
}
- _item2.setDetails(Rect(52, 44, 96, 82), 2430, 3, -1, 5, 1, NULL);
- _item3.setDetails(Rect(117, 36, 161, 74), 2430, 3, -1, 5, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _leftWindow.setDetails(Rect(52, 44, 96, 82), 2430, 3, -1, 5, 1, NULL);
+ _rightWindow.setDetails(Rect(117, 36, 161, 74), 2430, 3, -1, 5, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
_sceneMode = 10;
@@ -1736,7 +1750,7 @@ void Scene2435::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
}
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2435;
- R2_GLOBALS._v56605[1 + R2_GLOBALS._player._characterIndex] = 12;
+ R2_GLOBALS._spillLocation[1 + R2_GLOBALS._player._characterIndex] = 12;
}
void Scene2435::remove() {
@@ -1753,21 +1767,21 @@ void Scene2435::signal() {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
case 30:
- R2_GLOBALS._player._characterScene[1] = 2435;
- R2_GLOBALS._player._characterScene[2] = 2435;
- R2_GLOBALS._player._oldCharacterScene[1] = 2435;
- R2_GLOBALS._player._oldCharacterScene[2] = 2435;
- R2_GLOBALS._v56605[1] = 12;
- R2_GLOBALS._v56605[2] = 12;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 2435;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2435;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 2435;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2435;
+ R2_GLOBALS._spillLocation[R2_QUINN] = 12;
+ R2_GLOBALS._spillLocation[R2_SEEKER] = 12;
R2_GLOBALS.setFlag(81);
_sceneMode = 2436;
R2_GLOBALS._player.setStrip(7);
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == 1)
- _actor1.setVisage(20);
+ _companion.setVisage(20);
else
- _actor1.setVisage(2008);
- setAction(&_sequenceManager, this, 2436, &_actor1, NULL);
+ _companion.setVisage(2008);
+ setAction(&_sequenceManager, this, 2436, &_companion, NULL);
break;
case 2436:
R2_GLOBALS._walkRegions.enableRegion(2);
@@ -1781,7 +1795,7 @@ void Scene2435::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2440 - Ice Maze: Another bedroom
+ * Scene 2440 - Spill Mountains: Another bedroom
*
*--------------------------------------------------------------------------*/
@@ -1820,7 +1834,7 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
// Fix exit cursor, the original was using NW
_exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
_exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(49) == 2440) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2440) {
_actor2.postInit();
_actor2.setup(2435, 1, 1);
_actor2.setPosition(Common::Point(94, 80));
@@ -1839,7 +1853,7 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
R2_GLOBALS._player.setPosition(Common::Point(210, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor1.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor1.setup(20, 5, 1);
@@ -1885,7 +1899,7 @@ void Scene2440::signal() {
break;
case 2440:
_actor2.remove();
- R2_INVENTORY.setObjectScene(49, 2);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2);
// No break on purpose
default:
R2_GLOBALS._player.enableControl();
@@ -1894,7 +1908,7 @@ void Scene2440::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2445 - Ice Maze:
+ * Scene 2445 - Spill Mountains:
*
*--------------------------------------------------------------------------*/
void Scene2445::postInit(SceneObjectList *OwnerList) {
@@ -1912,23 +1926,23 @@ void Scene2445::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2450 - Ice Maze: Another bedroom
+ * Scene 2450 - Spill Mountains: Another bedroom
*
*--------------------------------------------------------------------------*/
-bool Scene2450::Actor2::startAction(CursorType action, Event &event) {
+bool Scene2450::Parker::startAction(CursorType action, Event &event) {
Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == 1)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2452;
- scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_parker, NULL);
return true;
}
return SceneActor::startAction(action, event);
}
-bool Scene2450::Actor3::startAction(CursorType action, Event &event) {
+bool Scene2450::CareTaker::startAction(CursorType action, Event &event) {
Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
if (action == CURSOR_TALK) {
@@ -1942,7 +1956,8 @@ bool Scene2450::Actor3::startAction(CursorType action, Event &event) {
else
scene->_stripManager.start(700 + (R2_GLOBALS._v565AE * 2), scene);
}
- return true;} else {
+ return true;
+ } else {
return SceneActor::startAction(action, event);
}
}
@@ -1973,8 +1988,8 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(200);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS._sceneManager._previousScene = 1900;
- R2_GLOBALS._player._oldCharacterScene[1] = 1900;
- R2_GLOBALS._player._oldCharacterScene[2] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1900;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1900;
}
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
@@ -1986,11 +2001,11 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
}
if (!R2_GLOBALS.getFlag(61)) {
- _actor2.postInit();
- _actor2.setVisage(2009);
- _actor2.setPosition(Common::Point(190, 119));
- _actor2.fixPriority(50);
- _actor2.setDetails(2450, 0, -1, -1, 1, (SceneItem *)NULL);
+ _parker.postInit();
+ _parker.setVisage(2009);
+ _parker.setPosition(Common::Point(190, 119));
+ _parker.fixPriority(50);
+ _parker.setDetails(2450, 0, -1, -1, 1, (SceneItem *)NULL);
}
R2_GLOBALS._player.postInit();
@@ -1998,10 +2013,10 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
case 1900:
R2_GLOBALS._v565AE = 0;
- R2_GLOBALS._player._characterScene[1] = 2450;
- R2_GLOBALS._player._characterScene[2] = 2450;
- R2_GLOBALS._player._oldCharacterScene[1] = 2450;
- R2_GLOBALS._player._oldCharacterScene[2] = 2450;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 2450;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2450;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 2450;
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2450;
R2_GLOBALS._player.setup(2450, 1, 1);
R2_GLOBALS._player.setPosition(Common::Point(126, 101));
setAction(&_sequenceManager, this, 2450, &R2_GLOBALS._player, NULL);
@@ -2009,24 +2024,24 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
case 2000:
_sceneMode = 2451;
if (R2_GLOBALS._player._characterIndex == 1) {
- if (R2_GLOBALS._player._characterScene[2] == 2450) {
- _actor1.postInit();
- _actor1.setup(20, 6, 1);
- _actor1.setPosition(Common::Point(240, 120));
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 2450) {
+ _companion.postInit();
+ _companion.setup(20, 6, 1);
+ _companion.setPosition(Common::Point(240, 120));
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
}
setAction(&_sequenceManager, this, 2451, &R2_GLOBALS._player, NULL);
} else {
- R2_GLOBALS._player._oldCharacterScene[2] = 2450;
- R2_GLOBALS._player._characterScene[2] = 2450;
- if (R2_GLOBALS._player._characterScene[1] == 2450) {
- _actor1.postInit();
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2450;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2450;
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 2450) {
+ _companion.postInit();
if (R2_GLOBALS.getFlag(61))
- _actor1.setup(2008, 6, 1);
+ _companion.setup(2008, 6, 1);
else
- _actor1.setup(10, 6, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
- _actor1.setPosition(Common::Point(106, 111));
+ _companion.setup(10, 6, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setPosition(Common::Point(106, 111));
}
setAction(&_sequenceManager, this, 2456, &R2_GLOBALS._player, NULL);
}
@@ -2042,22 +2057,22 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(106, 111));
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
if (R2_GLOBALS.getFlag(72)) {
- if (R2_GLOBALS._player._characterScene[2] == 2450) {
- _actor1.postInit();
- _actor1.setup(20, 6, 1);
- _actor1.setPosition(Common::Point(240, 120));
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 2450) {
+ _companion.postInit();
+ _companion.setup(20, 6, 1);
+ _companion.setPosition(Common::Point(240, 120));
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
}
} else {
- _actor1.postInit();
- _actor1.setup(20, 8, 1);
- _actor1.setPosition(Common::Point(93, 158));
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.postInit();
+ _companion.setup(20, 8, 1);
+ _companion.setPosition(Common::Point(93, 158));
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
- _actor3.postInit();
- _actor3.setup(2001, 7, 1);
- _actor3.setPosition(Common::Point(34, 153));
- _actor3.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
+ _careTaker.postInit();
+ _careTaker.setup(2001, 7, 1);
+ _careTaker.setPosition(Common::Point(34, 153));
+ _careTaker.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
_exit1._enabled = false;
}
@@ -2067,30 +2082,30 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setPosition(Common::Point(93, 158));
if (R2_GLOBALS.getFlag(72)) {
- if (R2_GLOBALS._player._characterScene[1] == 2450) {
- _actor1.postInit();
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == 2450) {
+ _companion.postInit();
if (R2_GLOBALS.getFlag(61)) {
- _actor1.setup(2008, 6, 1);
+ _companion.setup(2008, 6, 1);
} else {
- _actor1.setup(10, 6, 1);
+ _companion.setup(10, 6, 1);
}
- _actor1.setPosition(Common::Point(106, 111));
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setPosition(Common::Point(106, 111));
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
} else {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS.getFlag(61)) {
- _actor1.setup(2008, 6, 1);
+ _companion.setup(2008, 6, 1);
} else {
- _actor1.setup(10, 6, 1);
+ _companion.setup(10, 6, 1);
}
- _actor1.setPosition(Common::Point(106, 111));
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setPosition(Common::Point(106, 111));
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
- _actor3.postInit();
- _actor3.setup(2001, 7, 1);
- _actor3.setPosition(Common::Point(34, 153));
- _actor3.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
+ _careTaker.postInit();
+ _careTaker.setup(2001, 7, 1);
+ _careTaker.setPosition(Common::Point(34, 153));
+ _careTaker.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
_exit1._enabled = false;
}
@@ -2117,9 +2132,9 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
break;
}
- _item2.setDetails(Rect(174, 4, 199, 123), 2430, 30, 31, 32, 1, NULL);
- _item3.setDetails(Rect(67, 73, 207, 121), 2430, 36, -1, 38, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _post.setDetails(Rect(174, 4, 199, 123), 2430, 30, 31, 32, 1, NULL);
+ _bedspread.setDetails(Rect(67, 73, 207, 121), 2430, 36, -1, 38, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
}
void Scene2450::remove() {
@@ -2137,7 +2152,7 @@ void Scene2450::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._v565AE = 4;
_sceneMode = 2454;
- setAction(&_sequenceManager, this, 2454, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 2454, &_careTaker, NULL);
} else {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
if (R2_GLOBALS._v565AE < 4)
@@ -2147,7 +2162,7 @@ void Scene2450::signal() {
case 30:
R2_GLOBALS._player.disableControl();
_sceneMode = 2455;
- setAction(&_sequenceManager, this, 2455, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2455, &_companion, NULL);
break;
case 31:
R2_GLOBALS.setFlag(61);
@@ -2158,7 +2173,7 @@ void Scene2450::signal() {
break;
case 2452:
R2_GLOBALS.setFlag(61);
- _actor2.remove();
+ _parker.remove();
R2_GLOBALS._player.enableControl();
if (!R2_GLOBALS.getFlag(72)) {
R2_GLOBALS._player.setStrip(6);
@@ -2173,38 +2188,38 @@ void Scene2450::signal() {
case 2454:
_exit1._enabled = true;
R2_GLOBALS.setFlag(72);
- _actor3.remove();
+ _careTaker.remove();
if (R2_GLOBALS.getFlag(61)) {
g_globals->_sceneManager.changeScene(2435);
} else {
_sceneMode = 31;
- if (R2_GLOBALS._player._characterIndex == 1) {
- setAction(&_sequenceManager, this, 2452, &R2_GLOBALS._player, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ setAction(&_sequenceManager, this, 2452, &R2_GLOBALS._player, &_parker, NULL);
} else {
- setAction(&_sequenceManager, this, 2452, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 2452, &_companion, &_parker, NULL);
}
}
break;
case 2455:
- R2_GLOBALS._player._oldCharacterScene[2] = 2450;
- R2_GLOBALS._player._characterScene[2] = 2000;
- R2_GLOBALS._v56605[2] = 3;
- _actor1.remove();
+ R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 2450;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 2000;
+ R2_GLOBALS._spillLocation[R2_SEEKER] = 3;
+ _companion.remove();
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
break;
default:
- _actor1.postInit();
- _actor1.setDetails(9002, 0, 4, 3, 2, (SceneItem *)NULL);
- _actor3.postInit();
- _actor3.setDetails(2001, 40, -1, -1, 2, (SceneItem *)NULL);
+ _companion.postInit();
+ _companion.setDetails(9002, 0, 4, 3, 2, (SceneItem *)NULL);
+ _careTaker.postInit();
+ _careTaker.setDetails(2001, 40, -1, -1, 2, (SceneItem *)NULL);
_sceneMode = 2453;
- setAction(&_sequenceManager, this, 2453, &_actor3, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 2453, &_careTaker, &_companion, NULL);
break;
}
}
/*--------------------------------------------------------------------------
- * Scene 2455 - Ice Maze: Inside crevasse
+ * Scene 2455 - Spill Mountains: Inside crevasse
*
*--------------------------------------------------------------------------*/
@@ -2212,7 +2227,7 @@ bool Scene2455::Actor1::startAction(CursorType action, Event &event) {
Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_GLASS_DOME) {
- if ((R2_INVENTORY.getObjectScene(49) == 2455) || (R2_INVENTORY.getObjectScene(50) == 2455)) {
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2458;
scene->_actor2._lookLineNum = 9;
@@ -2232,7 +2247,7 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
switch (action) {
case R2_ALCOHOL_LAMP_2:
- if (R2_INVENTORY.getObjectScene(50) != 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) {
R2_GLOBALS._player.disableControl();
scene->_actor1.postInit();
scene->_actor1.setup(2456, 3, 3);
@@ -2244,7 +2259,7 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
}
break;
case R2_ALCOHOL_LAMP_3:
- if (R2_INVENTORY.getObjectScene(49) != 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455) {
R2_GLOBALS._player.disableControl();
scene->_actor1.postInit();
scene->_actor1.setup(2456, 3, 3);
@@ -2290,15 +2305,15 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(29, 2);
- R2_INVENTORY.setObjectScene(50, 2);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2);
}
R2_GLOBALS._sound1.play(200);
_exit1.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
- if ((R2_INVENTORY.getObjectScene(50) == 2455) || (R2_INVENTORY.getObjectScene(49) == 2455)) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455)) {
_actor1.postInit();
_actor1.setup(2456, 3, 3);
_actor1.setPosition(Common::Point(162, 165));
@@ -2312,11 +2327,11 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
_actor2.postInit();
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
_actor2.setup(2456, 3, 2);
_actor2.setDetails(2455, 9, 1, -1, 1, (SceneItem *)NULL);
} else {
- if ((R2_INVENTORY.getObjectScene(50) != 2455) && (R2_INVENTORY.getObjectScene(49) != 2455))
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) && (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455))
_actor2.setup(2455, 1, 1);
else
_actor2.setup(2456, 1, 1);
@@ -2324,7 +2339,7 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
_actor2.setPosition(Common::Point(162, 165));
_actor2.fixPriority(20);
- if (R2_INVENTORY.getObjectScene(29) != 2455)
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) != 2455)
_actor2.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._player.postInit();
@@ -2356,23 +2371,23 @@ void Scene2455::signal() {
g_globals->_sceneManager.changeScene(2425);
break;
case 11:
- R2_INVENTORY.setObjectScene(49, 2455);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 12:
- R2_INVENTORY.setObjectScene(50, 2455);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 2458:
- R2_INVENTORY.setObjectScene(29, 2455);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 2459:
_actor3.remove();
- R2_INVENTORY.setObjectScene(31, 2);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 2);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
@@ -2384,7 +2399,7 @@ void Scene2455::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2500 - Ice Maze: Large Cave
+ * Scene 2500 - Spill Mountains: Large Cave
*
*--------------------------------------------------------------------------*/
@@ -2429,7 +2444,7 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor1.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor1.setup(21, 3, 1);
@@ -2542,7 +2557,7 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
- if (R2_INVENTORY.getObjectScene(29) == 2525) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2525) {
_actor3.postInit();
_actor3.setup(2435, 1, 2);
_actor3.setPosition(Common::Point(78, 155));
@@ -2567,7 +2582,7 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
}
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor1.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor1.setup(20, 5, 1);
@@ -2615,7 +2630,7 @@ void Scene2525::signal() {
break;
case 2525:
_actor3.remove();
- R2_INVENTORY.setObjectScene(29, 2);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
R2_GLOBALS._player.enableControl();
break;
case 2526:
@@ -2629,7 +2644,7 @@ void Scene2525::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2530 - Ice Maze: Well
+ * Scene 2530 - Spill Mountains: Well
*
*--------------------------------------------------------------------------*/
bool Scene2530::Actor2::startAction(CursorType action, Event &event) {
@@ -2698,7 +2713,7 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(33) == 2530) {
+ if (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 2530) {
_actor2.postInit();
_actor2.setup(2435, 1, 3);
_actor2.setPosition(Common::Point(299, 80));
@@ -2728,7 +2743,7 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(100, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
_actor1.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
_actor1.setup(20, 5, 1);
@@ -2766,7 +2781,7 @@ void Scene2530::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2530:
- R2_INVENTORY.setObjectScene(33, 2);
+ R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 2);
_actor2.remove();
break;
case 2531:
@@ -2786,25 +2801,22 @@ void Scene2530::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2535 - Ice Maze: Tannery
+ * Scene 2535 - Spill Mountains: Tannery
*
*--------------------------------------------------------------------------*/
-bool Scene2535::Actor3::startAction(CursorType action, Event &event) {
+bool Scene2535::RebreatherTank::startAction(CursorType action, Event &event) {
Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
- scene->_sceneMode = 2536;
- scene->setAction(&scene->_sequenceManager, scene, 2536, &R2_GLOBALS._player, &scene->_actor3, NULL);
- } else {
- scene->_sceneMode = 2537;
- scene->setAction(&scene->_sequenceManager, scene, 2537, &R2_GLOBALS._player, &scene->_actor3, NULL);
- }
+
+ scene->_sceneMode = (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) ? 2536 : 2537;
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_rebreatherTank, NULL);
} else {
SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
}
@@ -2812,7 +2824,7 @@ bool Scene2535::Actor3::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene2535::Actor4::startAction(CursorType action, Event &event) {
+bool Scene2535::TannerMask::startAction(CursorType action, Event &event) {
Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
if (action != CURSOR_USE)
@@ -2821,7 +2833,7 @@ bool Scene2535::Actor4::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterIndex == 2) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2535;
- scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_tannerMask, NULL);
} else {
SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
}
@@ -2846,40 +2858,40 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS.setFlag(73);
- R2_INVENTORY.setObjectScene(20, 2535);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2535);
}
_exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(32) == 2535) {
- _actor4.postInit();
- _actor4.setup(2435, 1, 4);
- _actor4.setPosition(Common::Point(47, 74));
- _actor4.fixPriority(74);
- _actor4.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
+ if (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 2535) {
+ _tannerMask.postInit();
+ _tannerMask.setup(2435, 1, 4);
+ _tannerMask.setPosition(Common::Point(47, 74));
+ _tannerMask.fixPriority(74);
+ _tannerMask.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
- _actor3.postInit();
- _actor3.setup(2535, 3, 1);
- _actor3.setPosition(Common::Point(203, 131));
- _actor3.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) {
+ _rebreatherTank.postInit();
+ _rebreatherTank.setup(2535, 3, 1);
+ _rebreatherTank.setPosition(Common::Point(203, 131));
+ _rebreatherTank.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
R2_GLOBALS._walkRegions.enableRegion(6);
}
- if ((R2_INVENTORY.getObjectScene(20) == 0) && (R2_GLOBALS.getFlag(73))) {
- _actor3.postInit();
- _actor3.setup(2536, 1, 2);
- _actor3.setPosition(Common::Point(164, 133));
- _actor3.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
+ if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 0) && (R2_GLOBALS.getFlag(73))) {
+ _rebreatherTank.postInit();
+ _rebreatherTank.setup(2536, 1, 2);
+ _rebreatherTank.setPosition(Common::Point(164, 133));
+ _rebreatherTank.setDetails(3, 20, -1, -1, 1, (SceneItem *)NULL);
}
if (R2_GLOBALS.getFlag(73)) {
- _actor2.postInit();
- _actor2.setup(2536, 1, 1);
- _actor2.setPosition(Common::Point(160, 130));
- _actor2.fixPriority(122);
- _actor2.setDetails(2535, 37, -1, -1, 1, (SceneItem *)NULL);
+ _rope.postInit();
+ _rope.setup(2536, 1, 1);
+ _rope.setPosition(Common::Point(160, 130));
+ _rope.fixPriority(122);
+ _rope.setDetails(2535, 37, -1, -1, 1, (SceneItem *)NULL);
}
R2_GLOBALS._player.postInit();
@@ -2893,26 +2905,26 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(210, 200));
- if (R2_GLOBALS._player._characterScene[1] == R2_GLOBALS._player._characterScene[2]) {
- _actor1.postInit();
+ if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == 1) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(245, 115));
+ _companion.setPosition(Common::Point(245, 115));
R2_GLOBALS._walkRegions.enableRegion(2);
}
- _item2.setDetails(Rect(96, 3, 215, 33), 2535, 3, 6, 5, 1, NULL);
- _item3.setDetails(Rect(4, 43, 40, 101), 2535, 6, 7, 8, 1, NULL);
- _item4.setDetails(Rect(55, 13, 140, 89), 2535, 6, 7, 8, 1, NULL);
- _item5.setDetails(Rect(144, 23, 216, 76), 2535, 6, 7, 8, 1, NULL);
- _item6.setDetails(Rect(227, 8, 307, 99), 2535, 6, 7, 8, 1, NULL);
- _item7.setDetails(Rect(116, 111, 201, 132), 2535, 18, 19, 20, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2535, 0, 1, -1, 1, NULL);
+ _roof.setDetails(Rect(96, 3, 215, 33), 2535, 3, 6, 5, 1, NULL);
+ _skin1.setDetails(Rect(4, 43, 40, 101), 2535, 6, 7, 8, 1, NULL);
+ _skin2.setDetails(Rect(55, 13, 140, 89), 2535, 6, 7, 8, 1, NULL);
+ _skin3.setDetails(Rect(144, 23, 216, 76), 2535, 6, 7, 8, 1, NULL);
+ _skin4.setDetails(Rect(227, 8, 307, 99), 2535, 6, 7, 8, 1, NULL);
+ _depression.setDetails(Rect(116, 111, 201, 132), 2535, 18, 19, 20, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2535, 0, 1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
@@ -2933,32 +2945,31 @@ void Scene2535::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2535:
- R2_INVENTORY.setObjectScene(32, 2);
- _actor4.remove();
+ R2_INVENTORY.setObjectScene(R2_TANNER_MASK, 2);
+ _tannerMask.remove();
R2_GLOBALS._player.enableControl();
break;
case 2536:
- R2_INVENTORY.setObjectScene(20, 0);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 0);
R2_GLOBALS._walkRegions.disableRegion(6);
if (!R2_GLOBALS.getFlag(73)) {
- _actor3.remove();
+ _rebreatherTank.remove();
R2_GLOBALS._player.enableControl();
} else {
_sceneMode = 20;
- _actor3.show();
- _actor3.setup(2536, 1, 2);
- _actor3.setDetails(3, 20, -1, -1, 3, (SceneItem *)NULL);
- _actor3.setPosition(Common::Point(164, 150));
- _actor3.fixPriority(130);
- _actor3._moveDiff.y = 1;
- Common::Point pt(164, 133);
- PlayerMover *mover = new PlayerMover();
- _actor3.addMover(mover, &pt, this);
+ _rebreatherTank.show();
+ _rebreatherTank.setup(2536, 1, 2);
+ _rebreatherTank.setDetails(3, 20, -1, -1, 3, (SceneItem *)NULL);
+ _rebreatherTank.setPosition(Common::Point(164, 150));
+ _rebreatherTank.fixPriority(130);
+
+ _rebreatherTank._moveDiff.y = 1;
+ ADD_MOVER(_rebreatherTank, 164, 133);
}
break;
case 2537:
- _actor3.remove();
- R2_INVENTORY.setObjectScene(20, 1);
+ _rebreatherTank.remove();
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
R2_GLOBALS._player.enableControl();
break;
case 20:
@@ -2970,7 +2981,7 @@ void Scene2535::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2600 - Ice Maze: Exit
+ * Scene 2600 - Spill Mountains: Exit
*
*--------------------------------------------------------------------------*/
Scene2600::Scene2600(): SceneExt() {
@@ -3056,7 +3067,7 @@ void Scene2700::Action4::signal() {
void Scene2700::Area1::process(Event &event) {
SceneArea::process(event);
- if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
@@ -3106,7 +3117,7 @@ void Scene2700::Area1::process(Event &event) {
void Scene2700::Area2::process(Event &event) {
SceneArea::process(event);
- if ((event.eventType == 1) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
@@ -3211,7 +3222,7 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(36) == 0)
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0)
R2_GLOBALS._sound1.changeSound(234);
if (R2_GLOBALS._sceneManager._previousScene == 2750) {
@@ -3452,7 +3463,7 @@ void Scene2700::signal() {
}
break;
case 11:
- R2_INVENTORY.setObjectScene(36, 0);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 0);
R2_GLOBALS._player.disableControl();
_field412 = 0;
_sceneMode = 2700;
@@ -3854,7 +3865,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
_rect2.set(130, 142, 210, 167);
_rect3.set(-1, 137, 290, 147);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.changeSound(235);
_actor2.postInit();
_actor2.setup(2751, 1, 1);
@@ -3929,7 +3940,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_nejSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
_actor1.postInit();
_actor1.setup(2752, 5, 1);
_actor1.animate(ANIM_MODE_NONE, NULL);
@@ -3943,7 +3954,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._sceneManager._previousScene == 2700) {
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._player.setVisage(2752);
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
@@ -4448,7 +4459,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_nejSpeaker);
_stripManager.addSpeaker(&_guardSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.fadeSound(237);
if (R2_GLOBALS.getFlag(47)) {
_item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
@@ -4469,7 +4480,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2800, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS.getFlag(47)) {
R2_GLOBALS._player.setVisage(3110);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h
index feceaa1537..04b849f070 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.h
@@ -45,23 +45,23 @@ class Scene2000 : public SceneExt {
virtual void signal();
};
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit5 : public SceneExit {
+ class DoorExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -72,11 +72,11 @@ public:
NamedHotspot _item1;
SceneActor _object1;
SceneActor _objList1[11];
- Exit1 _exit1;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
- Exit5 _exit5;
+ WestExit _westExit;
+ EastExit _eastExit;
+ SouthExit _southExit;
+ NorthExit _northExit;
+ DoorExit _doorExit;
Action1 _action1, _action2, _action3, _action4, _action5;
SequenceManager _sequenceManager;
@@ -230,11 +230,11 @@ public:
};
class Scene2435 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Astor : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
@@ -247,11 +247,11 @@ public:
SpeakerQuinn2435 _quinnSpeaker;
SpeakerSeeker2435 _seekerSpeaker;
SpeakerPharisha2435 _pharishaSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- Actor1 _actor1;
- Actor2 _actor2;
+ NamedHotspot _background;
+ NamedHotspot _leftWindow;
+ NamedHotspot _rightWindow;
+ Companion _companion;
+ Astor _astor;
Exit1 _exit1;
SequenceManager _sequenceManager;
@@ -301,11 +301,11 @@ public:
};
class Scene2450 : public SceneExt {
- class Actor2 : public SceneActor {
+ class Parker : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class CareTaker : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
@@ -318,12 +318,12 @@ public:
SpeakerQuinn2450 _quinnSpeaker;
SpeakerSeeker2450 _seekerSpeaker;
SpeakerCaretaker2450 _caretakerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
+ NamedHotspot _background;
+ NamedHotspot _post;
+ NamedHotspot _bedspread;
+ SceneActor _companion;
+ Parker _parker;
+ CareTaker _careTaker;
Exit1 _exit1;
SequenceManager _sequenceManager;
@@ -447,11 +447,11 @@ public:
};
class Scene2535 : public SceneExt {
- class Actor3 : public SceneActor {
+ class RebreatherTank : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class TannerMask : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
@@ -461,17 +461,17 @@ class Scene2535 : public SceneExt {
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- SceneActor _actor1;
- SceneActor _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
+ NamedHotspot _background;
+ NamedHotspot _roof;
+ NamedHotspot _skin1;
+ NamedHotspot _skin2;
+ NamedHotspot _skin3;
+ NamedHotspot _skin4;
+ NamedHotspot _depression;
+ SceneActor _companion;
+ SceneActor _rope;
+ RebreatherTank _rebreatherTank;
+ TannerMask _tannerMask;
Exit1 _exit1;
SequenceManager _sequenceManager;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
index 6af2a0cad4..3c9a36c646 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -58,7 +58,7 @@ bool Scene3100::Guard::startAction(CursorType action, Event &event) {
void Scene3100::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 1000) {
- if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100) {
loadScene(3101);
R2_GLOBALS._uiElements._active = false;
} else {
@@ -89,7 +89,7 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
_field412 = 0;
if (R2_GLOBALS._sceneManager._previousScene == 1000) {
- if (R2_GLOBALS._player._oldCharacterScene[1] == 3100) {
+ if (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100) {
_sceneMode = 3102;
_actor3.postInit();
_actor4.postInit();
@@ -153,7 +153,7 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(243);
}
- R2_GLOBALS._player._oldCharacterScene[1] = 3100;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 3100;
}
void Scene3100::remove() {
@@ -178,7 +178,7 @@ void Scene3100::signal() {
R2_GLOBALS._sceneManager.changeScene(1000);
break;
case 3102:
- R2_GLOBALS._player._oldCharacterScene[1] = 1000;
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1000;
R2_GLOBALS._sceneManager.changeScene(1000);
break;
default:
@@ -378,7 +378,7 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_INVENTORY.getObjectScene(47) != 3150)
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150)
return SceneHotspot::startAction(action, event);
R2_GLOBALS._player.disableControl();
@@ -386,7 +386,7 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3154, &R2_GLOBALS._player, &scene->_actor3, NULL);
return true;
case R2_SUPERCONDUCTOR_WIRE:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_GLOBALS.getFlag(75))) {
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_GLOBALS.getFlag(75))) {
R2_GLOBALS._player.disableControl();
scene->_actor3.postInit();
scene->_actor3._effect = 3;
@@ -417,7 +417,7 @@ bool Scene3150::Item6::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_actor4, NULL);
return true;
case R2_FOOD_TRAY:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_INVENTORY.getObjectScene(40) == 3150) && (R2_GLOBALS.getFlag(75))) {
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) && (R2_GLOBALS.getFlag(75))) {
scene->_actor5.postInit();
scene->_actor5._effect = 6;
scene->_actor5._shade = 3;
@@ -535,8 +535,8 @@ void Scene3150::Exit2::changeScene() {
void Scene3150::postInit(SceneObjectList *OwnerList) {
loadScene(3150);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(35, 2000);
- R2_GLOBALS._player._oldCharacterScene[1] = 3100;
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2000);
+ R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 3100;
R2_GLOBALS._player._oldCharacterScene[3] = 0;
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
}
@@ -583,7 +583,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_actor7.fixPriority(50);
_actor7.setDetails(3150, 17, -1, 19, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(41) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_PILLOW) == 3150) {
_actor4.postInit();
if (R2_GLOBALS.getFlag(75)) {
if (R2_GLOBALS.getFlag(76)) {
@@ -608,13 +608,13 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
}
}
- if (R2_INVENTORY.getObjectScene(47) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) == 3150) {
_actor3.postInit();
_actor3.setup(3152, 7, 1);
_actor3.setPosition(Common::Point(73, 83));
}
- if (R2_INVENTORY.getObjectScene(40) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) {
_actor3.postInit();
_actor3.setup(3152, 7, 3);
_actor3.setPosition(Common::Point(70, 55));
@@ -623,7 +623,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_actor3._shade = 5;
}
- if (R2_INVENTORY.getObjectScene(42) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_FOOD_TRAY) == 3150) {
_actor5.postInit();
if (R2_GLOBALS.getFlag(77)) {
_actor5.setup(3152, 7, 8);
@@ -675,7 +675,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
break;
}
default:
- if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(35) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
+ if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2000) && (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100)) {
++R2_GLOBALS._v56AA0;
_sceneMode = 3156;
_actor1.postInit();
@@ -713,7 +713,7 @@ void Scene3150::signal() {
break;
case 3151:
_actor1.remove();
- R2_INVENTORY.setObjectScene(41, 3);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3);
R2_GLOBALS._player.enableControl();
break;
case 3153:
@@ -726,37 +726,37 @@ void Scene3150::signal() {
break;
case 3154:
_actor3.remove();
- R2_INVENTORY.setObjectScene(47, 3);
+ R2_INVENTORY.setObjectScene(R2_LIGHT_BULB, 3);
R2_GLOBALS._player.enableControl();
break;
case 3155:
- R2_INVENTORY.setObjectScene(40, 3150);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3156:
_actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
- R2_INVENTORY.setObjectScene(42, 3150);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3157:
_actor5.remove();
- R2_INVENTORY.setObjectScene(42, 3);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3);
R2_GLOBALS._player.enableControl();
break;
case 3158:
R2_GLOBALS.setFlag(75);
- R2_INVENTORY.setObjectScene(41, 3150);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3150);
_actor4.fixPriority(110);
_actor4.setDetails(3150, 13, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._player.enableControl();
break;
case 3159:
R2_GLOBALS.setFlag(77);
- R2_INVENTORY.setObjectScene(42, 3150);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3160:
- R2_INVENTORY.setObjectScene(52, 3150);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3150);
R2_GLOBALS.setFlag(80);
R2_GLOBALS._sceneManager.changeScene(1200);
break;
@@ -1407,7 +1407,7 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
_actor13.setPosition(Common::Point(40, 106));
_actor13.setDetails(3260, 18, 1, -1, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(52) == 3260) {
+ if (R2_INVENTORY.getObjectScene(R2_TOOLBOX) == 3260) {
_actor14.postInit();
_actor14.setup(3260, 7, 1);
_actor14.setPosition(Common::Point(202, 66));
@@ -1524,8 +1524,8 @@ void Scene3260::signal() {
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(52, 3);
- R2_INVENTORY.setObjectScene(43, 3);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3);
+ R2_INVENTORY.setObjectScene(R2_LASER_HACKSAW, 3);
setAction(&_sequenceManager, this, 3273, &R2_GLOBALS._player, &_actor14, NULL);
break;
case 3273:
@@ -1957,8 +1957,8 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_webbsterSpeaker);
- R2_GLOBALS._player._characterScene[1] = 3375;
- R2_GLOBALS._player._characterScene[2] = 3375;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3375;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3375;
R2_GLOBALS._player._characterScene[3] = 3375;
setZoomPercents(126, 55, 200, 167);
@@ -2292,8 +2292,8 @@ void Scene3385::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_webbsterSpeaker);
- R2_GLOBALS._player._characterScene[1] = 3385;
- R2_GLOBALS._player._characterScene[2] = 3385;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3385;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3385;
R2_GLOBALS._player._characterScene[3] = 3385;
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -2512,8 +2512,8 @@ void Scene3395::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_mirandaSpeaker);
_stripManager.addSpeaker(&_webbsterSpeaker);
- R2_GLOBALS._player._characterScene[1] = 3395;
- R2_GLOBALS._player._characterScene[2] = 3395;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3395;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3395;
R2_GLOBALS._player._characterScene[3] = 3395;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -2669,8 +2669,8 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_tealSpeaker);
setZoomPercents(51, 46, 180, 200);
- R2_GLOBALS._player._characterScene[1] = 3400;
- R2_GLOBALS._player._characterScene[2] = 3400;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3400;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3400;
R2_GLOBALS._player._characterScene[3] = 3400;
_actor7.postInit();
@@ -2771,7 +2771,7 @@ void Scene3400::signal() {
_actor2.setStrip(6);
_actor3.setStrip(3);
_actor4.setStrip(1);
- R2_INVENTORY.setObjectScene(34, 0);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 0);
_stripManager.start(3307, this);
if (R2_GLOBALS._player._characterIndex == 2) {
_sceneMode = 3400;
@@ -3577,8 +3577,8 @@ void Scene3500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._v5589E.set(0, 0, 320, 200);
R2_GLOBALS._sound1.play(305);
R2_GLOBALS._player._characterIndex = R2_QUINN;
- R2_GLOBALS._player._characterScene[1] = 3500;
- R2_GLOBALS._player._characterScene[2] = 3500;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3500;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3500;
R2_GLOBALS._player._characterScene[3] = 3500;
_field1284 = 0;
_field1282 = 0;
@@ -4377,8 +4377,8 @@ void Scene3600::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_protectorSpeaker);
setZoomPercents(142, 80, 167, 105);
- R2_GLOBALS._player._characterScene[1] = 3600;
- R2_GLOBALS._player._characterScene[2] = 3600;
+ R2_GLOBALS._player._characterScene[R2_QUINN] = 3600;
+ R2_GLOBALS._player._characterScene[R2_SEEKER] = 3600;
R2_GLOBALS._player._characterScene[3] = 3600;
_item2.setDetails(33, 3600, 6, -1, -1);
@@ -5319,7 +5319,7 @@ void Scene3800::signal() {
}
void Scene3800::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == 1) && (_rect1.contains(event.mousePos))) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN) && (_rect1.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
case R2_NEGATOR_GUN:
@@ -5582,7 +5582,7 @@ void Scene3900::signal() {
}
void Scene3900::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == 1) && (_rect1.contains(event.mousePos))) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN) && (_rect1.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
case R2_NEGATOR_GUN:
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp
index cd2ff669ff..e908fb4412 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.cpp
+++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp
@@ -204,13 +204,12 @@ void VisualSpeaker::setText(const Common::String &msg) {
_sceneText._textMode = _textMode;
_sceneText.setup(s);
- //_sceneText.clone();
-
_sceneText.setPosition(_textPos);
_sceneText.fixPriority(256);
// If subtitles are turned off, don't show the text
- if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) &&
+ !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
_sceneText.hide();
}
@@ -360,7 +359,7 @@ void SpeakerChief1100::proc15() {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor18;
+ _object2 = &scene->_chief;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1042,7 +1041,7 @@ void SpeakerPharisha2435::proc15() {
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_astor;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1180,6 +1179,7 @@ void SpeakerQuinn300::proc15() {
if (R2_GLOBALS._player._characterIndex == 3) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_quinn;
}
@@ -1220,6 +1220,51 @@ void SpeakerQuinn300::proc15() {
}
}
+void SpeakerQuinn500::proc15() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 500);
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+
+ _object1.postInit();
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ switch (_object2->_visage) {
+ case 10:
+ _object1.setup(4021, (v == 1) ? 5 : 7, 1);
+ break;
+
+ case 1500:
+ _object1.setup(4021, (v == 1) ? 1 : 3, 1);
+ break;
+
+ default:
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
void SpeakerQuinn1100::proc15() {
int v = _speakerMode;
@@ -1230,8 +1275,9 @@ void SpeakerQuinn1100::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1100);
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor16;
+ _object2 = &scene->_seeker;
}
_object2->hide();
@@ -1275,8 +1321,9 @@ void SpeakerQuinn2435::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -1301,8 +1348,9 @@ void SpeakerQuinn2450::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -1948,9 +1996,9 @@ void SpeakerSeeker300::proc15() {
int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_object2 = &R2_GLOBALS._player;
- } else {
+ } else {assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_seeker;
}
@@ -1980,6 +2028,43 @@ void SpeakerSeeker300::proc15() {
}
}
+void SpeakerSeeker500::proc15() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 500);
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ if (v == 1)
+ _object1.setup(4041, 3, 1);
+ else
+ _object1.setup(4041, 1, 1);
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
void SpeakerSeeker1100::proc15() {
int v = _speakerMode;
@@ -1990,8 +2075,9 @@ void SpeakerSeeker1100::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1100);
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor16;
+ _object2 = &scene->_seeker;
}
_object2->hide();
@@ -2046,6 +2132,7 @@ void SpeakerSeeker1900::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1900);
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -2076,8 +2163,9 @@ void SpeakerSeeker2435::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -2102,8 +2190,9 @@ void SpeakerSeeker2450::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2450);
Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -2492,9 +2581,9 @@ void SpeakerSocko3200::proc15() {
// Classes related to SOLDIER
//----------------------------------------------------------------------------
-SpeakerSoldier::SpeakerSoldier(int colour) {
+SpeakerSoldier::SpeakerSoldier(int color) {
_speakerName = "SOLDIER";
- _color1 = colour;
+ _color1 = color;
_color2 = 0;
_speakerMode = 0;
_textWidth = 300;
@@ -2577,7 +2666,7 @@ void SpeakerTeal1625::proc15() {
if (!_object2) {
Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor2;
+ _object2 = &scene->_tealHead;
_object2->hide();
_object1.postInit();
@@ -2788,9 +2877,9 @@ void SpeakerTomko3245::proc15() {
// Classes related to WEBBSTER
//----------------------------------------------------------------------------
-SpeakerWebbster::SpeakerWebbster(int colour) {
+SpeakerWebbster::SpeakerWebbster(int color) {
_speakerName = "WEBBSTER";
- _color1 = colour;
+ _color1 = color;
_color2 = 0;
_speakerMode = 0;
_textWidth = 300;
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h
index 532e02576c..4dfb500f2d 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.h
+++ b/engines/tsage/ringworld2/ringworld2_speakers.h
@@ -282,6 +282,12 @@ public:
virtual void proc15();
};
+class SpeakerQuinn500 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn500"; }
+ virtual void proc15();
+};
+
class SpeakerQuinn1100 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn1100"; }
@@ -420,6 +426,12 @@ public:
virtual void proc15();
};
+class SpeakerSeeker500 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker500"; }
+ virtual void proc15();
+};
+
class SpeakerSeeker1100 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1100"; }
@@ -504,7 +516,7 @@ public:
class SpeakerSoldier : public VisualSpeaker {
public:
- SpeakerSoldier(int colour);
+ SpeakerSoldier(int color);
virtual Common::String getClassName() { return "SpeakerSoldier"; }
};
@@ -579,7 +591,7 @@ public:
class SpeakerWebbster : public VisualSpeaker {
public:
- SpeakerWebbster(int colour);
+ SpeakerWebbster(int color);
virtual Common::String getClassName() { return "SpeakerWebbster"; }
};
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index a273ec2a0b..db38862365 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -244,7 +244,7 @@ char const *const USE_INTERCEPTOR = "Do you want to use your interceptor card?";
char const *const USE_DOUBLE_AGENT = "Do you want to use your double agent?";
char const *const NEED_INSTRUCTIONS = "Do you want instructions?";
char const *const WRONG_ANSWER_MSG = "Wrong respond value sent.";
-const byte k562CC[] = {
+const byte scene1550JunkLocationsDefault[] = {
20, 7, 41, 6,
3, 6, 42, 11,
10, 15, 43, 6,
@@ -374,7 +374,7 @@ const byte k562CC[] = {
28, 18, 21, 1
};
-const byte k5A4D6[] = {
+const byte scene1550AreaMap[] = {
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18,
17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
@@ -409,7 +409,7 @@ const byte k5A76D[] = {
3, 3, 3, 7, 3, 7, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3
};
-const byte k5A78A[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
+const byte scene1550JunkRegions[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
const byte k5A79B[] = {
23, 3, 1,
23, 4, 1,
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index e3daf73333..8c21147191 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -199,13 +199,13 @@ extern char const *const NEED_INSTRUCTIONS;
extern char const *const WRONG_ANSWER_MSG;
// Scene 1550 arrays of constants
-extern const byte k562CC[];
-extern const byte k5A4D6[];
+extern const byte scene1550JunkLocationsDefault[];
+extern const byte scene1550AreaMap[];
extern const byte k5A72E[];
extern const byte k5A73F[];
extern const byte k5A750[];
extern const byte k5A76D[];
-extern const byte k5A78A[];
+extern const byte scene1550JunkRegions[];
extern const byte k5A79B[];
extern const byte k5A7F6[];
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index c0ebb804d2..09cc2fd56d 100644
--- a/engines/tsage/user_interface.cpp
+++ b/engines/tsage/user_interface.cpp
@@ -454,7 +454,7 @@ void UIElements::add(UIElement *obj) {
/**
* Handles updating the visual inventory in the user interface
*/
-void UIElements::updateInventory() {
+void UIElements::updateInventory(int objectNumber) {
switch (g_vm->getGameID()) {
case GType_BlueForce:
// Update the score
@@ -483,6 +483,17 @@ void UIElements::updateInventory() {
else if (_slotStart > (lastPage - 1))
_slotStart = 0;
+ // Handle changing the page, if necessary, to ensure an optionally supplied
+ // object number will be on-screen
+ if (objectNumber != 0) {
+ for (uint idx = 0; idx < _itemList.size(); ++idx) {
+ if (_itemList[idx] == objectNumber) {
+ _slotStart = idx / 4;
+ break;
+ }
+ }
+ }
+
// Handle refreshing slot graphics
UIInventorySlot *slotList[4] = { &_slot1, &_slot2, &_slot3, &_slot4 };
diff --git a/engines/tsage/user_interface.h b/engines/tsage/user_interface.h
index 0fbfc5a00f..d06dccd9a4 100644
--- a/engines/tsage/user_interface.h
+++ b/engines/tsage/user_interface.h
@@ -137,7 +137,7 @@ public:
virtual void process(Event &event);
void setup(const Common::Point &pt);
- void updateInventory();
+ void updateInventory(int objectNumber = 0);
void addScore(int amount);
void scrollInventory(bool isLeft);
diff --git a/engines/wintermute/ad/ad_region.cpp b/engines/wintermute/ad/ad_region.cpp
index 444ada2433..bc9ac903c6 100644
--- a/engines/wintermute/ad/ad_region.cpp
+++ b/engines/wintermute/ad/ad_region.cpp
@@ -404,7 +404,7 @@ bool AdRegion::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alpha));
persistMgr->transfer(TMEMBER(_blocked));
persistMgr->transfer(TMEMBER(_decoration));
- persistMgr->transfer(TMEMBER(_zoom));
+ persistMgr->transferFloat(TMEMBER(_zoom));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_rot_level.cpp b/engines/wintermute/ad/ad_rot_level.cpp
index b11fad96d7..d925b0d57a 100644
--- a/engines/wintermute/ad/ad_rot_level.cpp
+++ b/engines/wintermute/ad/ad_rot_level.cpp
@@ -153,7 +153,7 @@ bool AdRotLevel::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_rotation));
+ persistMgr->transferFloat(TMEMBER(_rotation));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_scale_level.cpp b/engines/wintermute/ad/ad_scale_level.cpp
index 9cf7bfa600..59e6d57787 100644
--- a/engines/wintermute/ad/ad_scale_level.cpp
+++ b/engines/wintermute/ad/ad_scale_level.cpp
@@ -154,7 +154,7 @@ bool AdScaleLevel::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferFloat(TMEMBER(_scale));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_waypoint_group.cpp b/engines/wintermute/ad/ad_waypoint_group.cpp
index cb754516b3..cc7982cb9d 100644
--- a/engines/wintermute/ad/ad_waypoint_group.cpp
+++ b/engines/wintermute/ad/ad_waypoint_group.cpp
@@ -196,7 +196,7 @@ bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_active));
persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
+ persistMgr->transferFloat(TMEMBER(_lastMimicScale));
persistMgr->transfer(TMEMBER(_lastMimicX));
persistMgr->transfer(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index 5b88dab90e..b2c05d271d 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -3068,8 +3068,8 @@ bool BaseGame::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_offsetX));
persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_offsetPercentX));
- persistMgr->transfer(TMEMBER(_offsetPercentY));
+ persistMgr->transferFloat(TMEMBER(_offsetPercentX));
+ persistMgr->transferFloat(TMEMBER(_offsetPercentY));
persistMgr->transfer(TMEMBER(_origInteractive));
persistMgr->transfer(TMEMBER_INT(_origState));
diff --git a/engines/wintermute/base/base_object.cpp b/engines/wintermute/base/base_object.cpp
index 9d5548be0f..ea754f8f23 100644
--- a/engines/wintermute/base/base_object.cpp
+++ b/engines/wintermute/base/base_object.cpp
@@ -968,9 +968,9 @@ bool BaseObject::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_movable));
persistMgr->transfer(TMEMBER(_posX));
persistMgr->transfer(TMEMBER(_posY));
- persistMgr->transfer(TMEMBER(_relativeScale));
+ persistMgr->transferFloat(TMEMBER(_relativeScale));
persistMgr->transfer(TMEMBER(_rotatable));
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferFloat(TMEMBER(_scale));
persistMgr->transferPtr(TMEMBER_PTR(_sFX));
persistMgr->transfer(TMEMBER(_sFXStart));
persistMgr->transfer(TMEMBER(_sFXVolume));
@@ -982,21 +982,21 @@ bool BaseObject::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_soundEvent));
persistMgr->transfer(TMEMBER(_zoomable));
- persistMgr->transfer(TMEMBER(_scaleX));
- persistMgr->transfer(TMEMBER(_scaleY));
+ persistMgr->transferFloat(TMEMBER(_scaleX));
+ persistMgr->transferFloat(TMEMBER(_scaleY));
- persistMgr->transfer(TMEMBER(_rotate));
+ persistMgr->transferFloat(TMEMBER(_rotate));
persistMgr->transfer(TMEMBER(_rotateValid));
- persistMgr->transfer(TMEMBER(_relativeRotate));
+ persistMgr->transferFloat(TMEMBER(_relativeRotate));
persistMgr->transfer(TMEMBER(_saveState));
persistMgr->transfer(TMEMBER(_nonIntMouseEvents));
persistMgr->transfer(TMEMBER_INT(_sFXType));
- persistMgr->transfer(TMEMBER(_sFXParam1));
- persistMgr->transfer(TMEMBER(_sFXParam2));
- persistMgr->transfer(TMEMBER(_sFXParam3));
- persistMgr->transfer(TMEMBER(_sFXParam4));
+ persistMgr->transferFloat(TMEMBER(_sFXParam1));
+ persistMgr->transferFloat(TMEMBER(_sFXParam2));
+ persistMgr->transferFloat(TMEMBER(_sFXParam3));
+ persistMgr->transferFloat(TMEMBER(_sFXParam4));
persistMgr->transfer(TMEMBER_INT(_blendMode));
diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp
index 6f0f7e289f..e5542d96b7 100644
--- a/engines/wintermute/base/base_persistence_manager.cpp
+++ b/engines/wintermute/base/base_persistence_manager.cpp
@@ -465,44 +465,53 @@ uint32 BasePersistenceManager::getDWORD() {
//////////////////////////////////////////////////////////////////////////
-void BasePersistenceManager::putString(const Common::String &val) {
- if (!val.size()) {
- putString("(null)");
- } else {
- _saveStream->writeUint32LE(val.size());
- _saveStream->writeString(val);
+void BasePersistenceManager::putString(const char *val) {
+ if (!val) {
+ _saveStream->writeUint32LE(0);
+ return;
}
-}
-
-Common::String BasePersistenceManager::getStringObj() {
- uint32 len = _loadStream->readUint32LE();
- char *ret = new char[len + 1];
- _loadStream->read(ret, len);
- ret[len] = '\0';
- Common::String retString = ret;
- delete[] ret;
+ uint32 len = strlen(val);
- if (retString == "(null)") {
- retString = "";
- }
+ _saveStream->writeUint32LE(len + 1);
+ _saveStream->write(val, len);
+}
- return retString;
+Common::String BasePersistenceManager::getStringObj() {
+ return getString();
}
//////////////////////////////////////////////////////////////////////////
char *BasePersistenceManager::getString() {
uint32 len = _loadStream->readUint32LE();
- char *ret = new char[len + 1];
- _loadStream->read(ret, len);
- ret[len] = '\0';
- if (!strcmp(ret, "(null)")) {
- delete[] ret;
- return nullptr;
+ if (checkVersion(1,2,2)) {
+ // Version 1.2.2 and above: len == strlen() + 1, NULL has len == 0
+
+ if (len == 0)
+ return nullptr;
+
+ char *ret = new char[len];
+ _loadStream->read(ret, len - 1);
+ ret[len - 1] = '\0';
+
+ return ret;
+
} else {
+
+ // Version 1.2.1 and older: NULL strings are represented as "(null)"
+ char *ret = new char[len + 1];
+ _loadStream->read(ret, len);
+ ret[len] = '\0';
+
+ if (!strcmp(ret, "(null)")) {
+ delete[] ret;
+ return nullptr;
+ }
+
return ret;
}
+
}
bool BasePersistenceManager::putTimeDate(const TimeDate &t) {
@@ -536,8 +545,7 @@ void BasePersistenceManager::putFloat(float val) {
int exponent = 0;
float significand = frexp(val, &exponent);
Common::String str = Common::String::format("FS%f", significand);
- _saveStream->writeUint32LE(str.size());
- _saveStream->writeString(str);
+ putString(str.c_str());
_saveStream->writeSint32LE(exponent);
}
@@ -559,8 +567,7 @@ void BasePersistenceManager::putDouble(double val) {
int exponent = 0;
double significand = frexp(val, &exponent);
Common::String str = Common::String::format("DS%f", significand);
- _saveStream->writeUint32LE(str.size());
- _saveStream->writeString(str);
+ putString(str.c_str());
_saveStream->writeSint32LE(exponent);
}
@@ -637,7 +644,7 @@ bool BasePersistenceManager::transfer(const char *name, uint32 *val) {
//////////////////////////////////////////////////////////////////////////
// float
-bool BasePersistenceManager::transfer(const char *name, float *val) {
+bool BasePersistenceManager::transferFloat(const char *name, float *val) {
if (_saving) {
putFloat(*val);
if (_saveStream->err()) {
@@ -711,7 +718,7 @@ bool BasePersistenceManager::transfer(const char *name, const char **val) {
// Common::String
bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
if (_saving) {
- putString(*val);
+ putString(val->c_str());
return STATUS_OK;
} else {
char *str = getString();
diff --git a/engines/wintermute/base/base_persistence_manager.h b/engines/wintermute/base/base_persistence_manager.h
index 6949bfe278..3c0587b362 100644
--- a/engines/wintermute/base/base_persistence_manager.h
+++ b/engines/wintermute/base/base_persistence_manager.h
@@ -52,7 +52,7 @@ public:
void putDWORD(uint32 val);
char *getString();
Common::String getStringObj();
- void putString(const Common::String &val);
+ void putString(const char *val);
float getFloat();
void putFloat(float val);
double getDouble();
@@ -76,7 +76,7 @@ public:
bool transferPtr(const char *name, void *val);
bool transfer(const char *name, int32 *val);
bool transfer(const char *name, uint32 *val);
- bool transfer(const char *name, float *val);
+ bool transferFloat(const char *name, float *val);
bool transfer(const char *name, double *val);
bool transfer(const char *name, bool *val);
bool transfer(const char *name, byte *val);
diff --git a/engines/wintermute/base/base_region.cpp b/engines/wintermute/base/base_region.cpp
index 61e9deefb3..36036a1f18 100644
--- a/engines/wintermute/base/base_region.cpp
+++ b/engines/wintermute/base/base_region.cpp
@@ -432,7 +432,7 @@ bool BaseRegion::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_active));
persistMgr->transfer(TMEMBER(_editorSelectedPoint));
- persistMgr->transfer(TMEMBER(_lastMimicScale));
+ persistMgr->transferFloat(TMEMBER(_lastMimicScale));
persistMgr->transfer(TMEMBER(_lastMimicX));
persistMgr->transfer(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index 3059a69047..b6f372f377 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -272,7 +272,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
Graphics::Surface *surface = new Graphics::Surface();
if (_deletableFont) { // We actually have a TTF
- surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat());
} else { // We are using a fallback, they can't do 32bpp
surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
}
@@ -285,7 +285,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
}
BaseSurface *retSurface = _gameRef->_renderer->createSurface();
- Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ Graphics::Surface *convertedSurface = surface->convertTo(_gameRef->_renderer->getPixelFormat());
retSurface->putSurface(*convertedSurface, true);
convertedSurface->free();
surface->free();
@@ -559,7 +559,7 @@ bool BaseFontTT::initFont() {
}
if (file) {
- _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72).
+ _deletableFont = Graphics::loadTTFFont(*file, _fontHeight, 96); // Use the same dpi as WME (96 vs 72).
_font = _deletableFont;
BaseFileManager::getEngineInstance()->closeFile(file);
file = nullptr;
diff --git a/engines/wintermute/base/gfx/base_renderer.h b/engines/wintermute/base/gfx/base_renderer.h
index 31dc2a022d..b6615bc8fc 100644
--- a/engines/wintermute/base/gfx/base_renderer.h
+++ b/engines/wintermute/base/gfx/base_renderer.h
@@ -84,7 +84,7 @@ public:
* @param a the alpha component to fade too.
* @param rect the portion of the screen to fade (if nullptr, the entire screen will be faded).
*/
- virtual void fadeToColor(byte r, byte g, byte b, byte a, Common::Rect *rect = nullptr) = 0;
+ virtual void fadeToColor(byte r, byte g, byte b, byte a) = 0;
virtual bool drawLine(int x1, int y1, int x2, int y2, uint32 color); // Unused outside indicator-display
virtual bool drawRect(int x1, int y1, int x2, int y2, uint32 color, int width = 1); // Unused outside indicator-display
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index b16cf60752..e4c19fde8b 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -84,7 +84,6 @@ BaseRenderOSystem::~BaseRenderOSystem() {
delete _renderSurface;
_blankSurface->free();
delete _blankSurface;
- TransparentSurface::destroyLookup();
}
//////////////////////////////////////////////////////////////////////////
@@ -127,7 +126,7 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
_windowed = !ConfMan.getBool("fullscreen");
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
g_system->beginGFXTransaction();
g_system->initSize(_width, _height, &format);
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
@@ -244,22 +243,16 @@ void BaseRenderOSystem::fade(uint16 alpha) {
}
//////////////////////////////////////////////////////////////////////////
-void BaseRenderOSystem::fadeToColor(byte r, byte g, byte b, byte a, Common::Rect *rect) {
+void BaseRenderOSystem::fadeToColor(byte r, byte g, byte b, byte a) {
Common::Rect fillRect;
- if (rect) {
- fillRect.left = rect->left;
- fillRect.top = rect->top;
- fillRect.setWidth(rect->width());
- fillRect.setHeight(rect->height());
- } else {
- Rect32 rc;
- _gameRef->getCurrentViewportRect(&rc);
- fillRect.left = (int16)rc.left;
- fillRect.top = (int16)rc.top;
- fillRect.setWidth((int16)(rc.right - rc.left));
- fillRect.setHeight((int16)(rc.bottom - rc.top));
- }
+ Rect32 rc;
+ _gameRef->getCurrentViewportRect(&rc);
+ fillRect.left = (int16)rc.left;
+ fillRect.top = (int16)rc.top;
+ fillRect.setWidth((int16)(rc.right - rc.left));
+ fillRect.setHeight((int16)(rc.bottom - rc.top));
+
modTargetRect(&fillRect);
//TODO: This is only here until I'm sure about the final pixelformat
@@ -613,8 +606,8 @@ bool BaseRenderOSystem::setViewport(int left, int top, int right, int bottom) {
// TODO: Hopefully this is the same logic that ScummVM uses.
rect.left = (int16)(left + _borderLeft);
rect.top = (int16)(top + _borderTop);
- rect.right = (int16)((right - left) * _ratioX);
- rect.bottom = (int16)((bottom - top) * _ratioY);
+ rect.setWidth((int16)((right - left) * _ratioX));
+ rect.setHeight((int16)((bottom - top) * _ratioY));
_renderRect = rect;
return STATUS_OK;
@@ -631,15 +624,13 @@ Rect32 BaseRenderOSystem::getViewPort() {
//////////////////////////////////////////////////////////////////////////
void BaseRenderOSystem::modTargetRect(Common::Rect *rect) {
- // FIXME: This is wrong in quite a few ways right now, and ends up
- // breaking the notebook in Dirty Split, so we disable the correction
- // for now, this will need fixing when a game with odd aspect-ratios
- // show up.
return;
- rect->left = (int16)MathUtil::round(rect->left * _ratioX + _borderLeft - _renderRect.left);
- rect->top = (int16)MathUtil::round(rect->top * _ratioY + _borderTop - _renderRect.top);
- rect->setWidth((int16)MathUtil::roundUp(rect->width() * _ratioX));
- rect->setHeight((int16)MathUtil::roundUp(rect->height() * _ratioY));
+ int newWidth = (int16)MathUtil::roundUp(rect->width() * _ratioX);
+ int newHeight = (int16)MathUtil::roundUp(rect->height() * _ratioY);
+ rect->left = (int16)MathUtil::round(rect->left * _ratioX + _borderLeft);
+ rect->top = (int16)MathUtil::round(rect->top * _ratioY + _borderTop);
+ rect->setWidth(newWidth);
+ rect->setHeight(newHeight);
}
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index bf2914b430..306563af3b 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -38,6 +38,25 @@
namespace Wintermute {
class BaseSurfaceOSystem;
class RenderTicket;
+/**
+ * A 2D-renderer implementation for WME.
+ * This renderer makes use of a "ticket"-system, where all draw-calls
+ * are stored as tickets until flip() is called, and compared against the tickets
+ * from last frame, to determine which calls were the same as last round
+ * (i.e. in the exact same order, with the exact same arguments), and thus
+ * figure out which parts of the screen need to be redrawn.
+ *
+ * Important concepts to handle here, is the ordered number of any ticket
+ * which is called the "drawNum", every frame this starts from scratch, and
+ * then the incoming tickets created from the draw-calls are checked to see whether
+ * they came before, on, or after the drawNum they had last frame. Everything else
+ * being equal, this information is then used to check whether the draw order changed,
+ * which will then create a need for redrawing, as we draw with an alpha-channel here.
+ *
+ * There is also a draw path that draws without tickets, for debugging purposes,
+ * as well as to accomodate situations with large enough amounts of draw calls,
+ * that there will be too much overhead involved with comparing the generated tickets.
+ */
class BaseRenderOSystem : public BaseRenderer {
public:
BaseRenderOSystem(BaseGame *inGame);
@@ -51,7 +70,7 @@ public:
bool fill(byte r, byte g, byte b, Common::Rect *rect = nullptr) override;
Graphics::PixelFormat getPixelFormat() const override;
void fade(uint16 alpha) override;
- void fadeToColor(byte r, byte g, byte b, byte a, Common::Rect *rect = nullptr) override;
+ void fadeToColor(byte r, byte g, byte b, byte a) override;
bool drawLine(int x1, int y1, int x2, int y2, uint32 color) override;
@@ -59,6 +78,11 @@ public:
void invalidateTicket(RenderTicket *renderTicket);
void invalidateTicketsFromSurface(BaseSurfaceOSystem *surf);
+ /**
+ * Insert a ticket into the queue, adding a dirty rect if it's
+ * new, or out-of-order from last draw from the ticket.
+ * param renderTicket the ticket to be added.
+ */
void drawFromTicket(RenderTicket *renderTicket);
bool setViewport(int left, int top, int right, int bottom) override;
@@ -79,11 +103,18 @@ public:
virtual bool startSpriteBatch() override;
virtual bool endSpriteBatch() override;
void endSaveLoad();
- void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform);
+ void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform);
void repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY);
BaseSurface *createSurface() override;
private:
- void addDirtyRect(const Common::Rect &rect) ;
+ /**
+ * Mark a specified rect of the screen as dirty.
+ * @param rect the region to be marked as dirty
+ */
+ void addDirtyRect(const Common::Rect &rect);
+ /**
+ * Traverse the tickets that are dirty, and draw them
+ */
void drawTickets();
// Non-dirty-rects:
void drawFromSurface(RenderTicket *ticket);
@@ -96,7 +127,7 @@ private:
RenderTicket *_previousTicket;
bool _needsFlip;
- uint32 _drawNum;
+ uint32 _drawNum; ///< The global number of the current draw-operation.
Common::Rect _renderRect;
Graphics::Surface *_renderSurface;
Graphics::Surface *_blankSurface;
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index d4c5905c4b..14767aa067 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -48,7 +48,7 @@ namespace Wintermute {
BaseSurfaceOSystem::BaseSurfaceOSystem(BaseGame *inGame) : BaseSurface(inGame) {
_surface = new Graphics::Surface();
_alphaMask = nullptr;
- _hasAlpha = true;
+ _alphaType = TransparentSurface::ALPHA_FULL;
_lockPixels = nullptr;
_lockPitch = 0;
_loaded = false;
@@ -71,22 +71,37 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
renderer->invalidateTicketsFromSurface(this);
}
-bool hasTransparency(Graphics::Surface *surf) {
+TransparentSurface::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
if (surf->format.bytesPerPixel != 4) {
- warning("hasTransparency:: non 32 bpp surface passed as argument");
- return false;
+ warning("hasTransparencyType:: non 32 bpp surface passed as argument");
+ return TransparentSurface::ALPHA_OPAQUE;
}
uint8 r, g, b, a;
+ bool seenAlpha = false;
+ bool seenFullAlpha = false;
for (int i = 0; i < surf->h; i++) {
+ if (seenFullAlpha) {
+ break;
+ }
for (int j = 0; j < surf->w; j++) {
- uint32 pix = *(uint32 *)surf->getBasePtr(j, i);
+ uint32 pix = *(const uint32 *)surf->getBasePtr(j, i);
surf->format.colorToARGB(pix, a, r, g, b);
if (a != 255) {
- return true;
+ seenAlpha = true;
+ if (a != 0) {
+ seenFullAlpha = true;
+ break;
+ }
}
}
}
- return false;
+ if (seenFullAlpha) {
+ return TransparentSurface::ALPHA_FULL;
+ } else if (seenAlpha) {
+ return TransparentSurface::ALPHA_BINARY;
+ } else {
+ return TransparentSurface::ALPHA_OPAQUE;
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -128,39 +143,36 @@ bool BaseSurfaceOSystem::finishLoad() {
_width = image->getSurface()->w;
_height = image->getSurface()->h;
- bool isSaveGameGrayscale = scumm_strnicmp(_filename.c_str(), "savegame:", 9) == 0 && (_filename.c_str()[_filename.size() - 1] == 'g' || _filename.c_str()[_filename.size() - 1] == 'G');
+ bool isSaveGameGrayscale = _filename.matchString("savegame:*g", true);
if (isSaveGameGrayscale) {
warning("grayscaleConversion not yet implemented");
// FIBITMAP *newImg = FreeImage_ConvertToGreyscale(img); TODO
}
- // no alpha, set color key
- /* if (surface->format.bytesPerPixel != 4)
- SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf->format, ck_red, ck_green, ck_blue));*/
-
- // convert 32-bit BMPs to 24-bit or they appear totally transparent (does any app actually write alpha in BMP properly?)
- // Well, actually, we don't convert via 24-bit as the color-key application overwrites the Alpha-channel anyhow.
_surface->free();
delete _surface;
bool needsColorKey = false;
bool replaceAlpha = true;
- if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) {
- _surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette());
- needsColorKey = true;
- replaceAlpha = false;
- } else if (image->getSurface()->format.bytesPerPixel == 1 && image->getPalette()) {
+ if (image->getSurface()->format.bytesPerPixel == 1) {
+ if (!image->getPalette()) {
+ error("Missing palette while loading 8bit image %s", _filename.c_str());
+ }
_surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette());
needsColorKey = true;
- } else if (image->getSurface()->format.bytesPerPixel >= 3 && image->getSurface()->format != g_system->getScreenFormat()) {
- _surface = image->getSurface()->convertTo(g_system->getScreenFormat());
- if (image->getSurface()->format.bytesPerPixel == 3) {
- needsColorKey = true;
- }
} else {
- _surface = new Graphics::Surface();
- _surface->copyFrom(*image->getSurface());
- if (_surface->format.aBits() == 0) {
+ if (image->getSurface()->format != g_system->getScreenFormat()) {
+ _surface = image->getSurface()->convertTo(g_system->getScreenFormat());
+ } else {
+ _surface = new Graphics::Surface();
+ _surface->copyFrom(*image->getSurface());
+ }
+
+ if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) {
+ // 32 bpp BMPs have nothing useful in their alpha-channel -> color-key
+ needsColorKey = true;
+ replaceAlpha = false;
+ } else if (image->getSurface()->format.aBits() == 0) {
needsColorKey = true;
}
}
@@ -170,7 +182,7 @@ bool BaseSurfaceOSystem::finishLoad() {
trans.applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha);
}
- _hasAlpha = hasTransparency(_surface);
+ _alphaType = hasTransparencyType(_surface);
_valid = true;
_gameRef->addMem(_width * _height * 4);
@@ -409,8 +421,6 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
if (newRect) {
position.top = y;
position.left = x;
- position.right = x + newRect->width();
- position.bottom = y + newRect->height();
position.setWidth(newRect->width());
position.setHeight(newRect->height());
} else {
@@ -422,17 +432,11 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
// TODO: This actually requires us to have the SAME source-offsets every time,
// But no checking is in place for that yet.
- // TODO: Optimize by not doing alpha-blits if we lack or disable alpha
-
- bool hasAlpha = false;
-
- if (_hasAlpha && !transform._alphaDisable) {
- hasAlpha = true;
- }
-
- if (transform._alphaDisable) {
- warning("BaseSurfaceOSystem::drawSprite - AlphaDisable ignored");
+ // Optimize by not doing alpha-blits if we lack alpha
+ if (_alphaType == TransparentSurface::ALPHA_OPAQUE && !transform._alphaDisable) {
+ transform._alphaDisable = true;
}
+
renderer->drawSurface(this, _surface, &srcRect, &position, transform);
return STATUS_OK;
}
@@ -447,7 +451,11 @@ bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAl
_loaded = true;
_surface->free();
_surface->copyFrom(surface);
- _hasAlpha = hasAlpha;
+ if (hasAlpha) {
+ _alphaType = TransparentSurface::ALPHA_FULL;
+ } else {
+ _alphaType = TransparentSurface::ALPHA_OPAQUE;
+ }
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
renderer->invalidateTicketsFromSurface(this);
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index da86833517..6cf19d00fb 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -30,6 +30,7 @@
#define WINTERMUTE_BASE_SURFACESDL_H
#include "graphics/surface.h"
+#include "engines/wintermute/graphics/transparent_surface.h"
#include "engines/wintermute/base/gfx/base_surface.h"
#include "common/list.h"
@@ -81,6 +82,7 @@ public:
return _height;
}
+ TransparentSurface::AlphaType getAlphaType() const { return _alphaType; }
private:
Graphics::Surface *_surface;
bool _loaded;
@@ -90,7 +92,7 @@ private:
uint32 getPixelAt(Graphics::Surface *surface, int x, int y);
uint32 _rotation;
- bool _hasAlpha;
+ TransparentSurface::AlphaType _alphaType;
void *_lockPixels;
int _lockPitch;
byte *_alphaMask;
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index 98739e0778..b1720c1b0b 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -28,6 +28,7 @@
#include "engines/wintermute/base/gfx/osystem/render_ticket.h"
+#include "engines/wintermute/base/gfx/osystem/base_surface_osystem.h"
#include "engines/wintermute/graphics/transform_tools.h"
#include "common/textconsole.h"
@@ -104,7 +105,13 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
clipRect.setWidth(getSurface()->w);
clipRect.setHeight(getSurface()->h);
- src._enableAlphaBlit = !_transform._alphaDisable;
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
}
@@ -118,7 +125,13 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
clipRect->setHeight(getSurface()->h);
}
- src._enableAlphaBlit = !_transform._alphaDisable;
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height());
if (doDelete) {
delete clipRect;
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.h b/engines/wintermute/base/gfx/osystem/render_ticket.h
index b1313e932d..875102d01c 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.h
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.h
@@ -36,6 +36,19 @@
namespace Wintermute {
class BaseSurfaceOSystem;
+/**
+ * A single RenderTicket.
+ * A render ticket is a collection of the data and draw specifications made
+ * for a single draw-call in the OSystem-backend for WME. The ticket additionally
+ * holds the order in which this call was made, so that it can be detected if
+ * the same call is done in the following frame. Thus allowing us to potentially
+ * skip drawing the same region again, unless anything has changed. Since a surface
+ * can have a potentially large amount of draw-calls made to it, at varying rotation,
+ * zoom, and crop-levels we also need to hold a copy of the necessary data.
+ * (Video-surfaces may even change their data). The promise that is made when a ticket
+ * is created is that what the state was of the surface at THAT point, is what will end
+ * up on screen at flip() time.
+ */
class RenderTicket {
public:
RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, TransformStruct transform);
diff --git a/engines/wintermute/base/particles/part_emitter.cpp b/engines/wintermute/base/particles/part_emitter.cpp
index 5c21988141..aaffa0965a 100644
--- a/engines/wintermute/base/particles/part_emitter.cpp
+++ b/engines/wintermute/base/particles/part_emitter.cpp
@@ -1163,12 +1163,12 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_angle1));
persistMgr->transfer(TMEMBER(_angle2));
- persistMgr->transfer(TMEMBER(_velocity1));
- persistMgr->transfer(TMEMBER(_velocity2));
+ persistMgr->transferFloat(TMEMBER(_velocity1));
+ persistMgr->transferFloat(TMEMBER(_velocity2));
persistMgr->transfer(TMEMBER(_velocityZBased));
- persistMgr->transfer(TMEMBER(_scale1));
- persistMgr->transfer(TMEMBER(_scale2));
+ persistMgr->transferFloat(TMEMBER(_scale1));
+ persistMgr->transferFloat(TMEMBER(_scale2));
persistMgr->transfer(TMEMBER(_scaleZBased));
persistMgr->transfer(TMEMBER(_maxParticles));
@@ -1196,14 +1196,14 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alpha2));
persistMgr->transfer(TMEMBER(_alphaTimeBased));
- persistMgr->transfer(TMEMBER(_angVelocity1));
- persistMgr->transfer(TMEMBER(_angVelocity2));
+ persistMgr->transferFloat(TMEMBER(_angVelocity1));
+ persistMgr->transferFloat(TMEMBER(_angVelocity2));
- persistMgr->transfer(TMEMBER(_rotation1));
- persistMgr->transfer(TMEMBER(_rotation2));
+ persistMgr->transferFloat(TMEMBER(_rotation1));
+ persistMgr->transferFloat(TMEMBER(_rotation2));
- persistMgr->transfer(TMEMBER(_growthRate1));
- persistMgr->transfer(TMEMBER(_growthRate2));
+ persistMgr->transferFloat(TMEMBER(_growthRate1));
+ persistMgr->transferFloat(TMEMBER(_growthRate2));
persistMgr->transfer(TMEMBER(_exponentialGrowth));
persistMgr->transfer(TMEMBER(_useRegion));
diff --git a/engines/wintermute/base/particles/part_particle.cpp b/engines/wintermute/base/particles/part_particle.cpp
index 2ae867fd42..86cacacb5c 100644
--- a/engines/wintermute/base/particles/part_particle.cpp
+++ b/engines/wintermute/base/particles/part_particle.cpp
@@ -234,9 +234,9 @@ bool PartParticle::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alpha2));
persistMgr->transfer(TMEMBER(_border));
persistMgr->transfer(TMEMBER(_pos));
- persistMgr->transfer(TMEMBER(_posZ));
+ persistMgr->transferFloat(TMEMBER(_posZ));
persistMgr->transfer(TMEMBER(_velocity));
- persistMgr->transfer(TMEMBER(_scale));
+ persistMgr->transferFloat(TMEMBER(_scale));
persistMgr->transfer(TMEMBER(_creationTime));
persistMgr->transfer(TMEMBER(_lifeTime));
persistMgr->transfer(TMEMBER(_isDead));
@@ -244,9 +244,9 @@ bool PartParticle::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_fadeStart));
persistMgr->transfer(TMEMBER(_fadeTime));
persistMgr->transfer(TMEMBER(_currentAlpha));
- persistMgr->transfer(TMEMBER(_angVelocity));
- persistMgr->transfer(TMEMBER(_rotation));
- persistMgr->transfer(TMEMBER(_growthRate));
+ persistMgr->transferFloat(TMEMBER(_angVelocity));
+ persistMgr->transferFloat(TMEMBER(_rotation));
+ persistMgr->transferFloat(TMEMBER(_growthRate));
persistMgr->transfer(TMEMBER(_exponentialGrowth));
persistMgr->transfer(TMEMBER(_fadeStartAlpha));
diff --git a/engines/wintermute/base/scriptables/script_engine.cpp b/engines/wintermute/base/scriptables/script_engine.cpp
index dd24457d6c..bb819b23e4 100644
--- a/engines/wintermute/base/scriptables/script_engine.cpp
+++ b/engines/wintermute/base/scriptables/script_engine.cpp
@@ -362,6 +362,8 @@ bool ScEngine::tick() {
//////////////////////////////////////////////////////////////////////////
bool ScEngine::tickUnbreakable() {
+ ScScript *oldScript = _currentScript;
+
// execute unbreakable scripts
for (uint32 i = 0; i < _scripts.size(); i++) {
if (!_scripts[i]->_unbreakable) {
@@ -373,9 +375,12 @@ bool ScEngine::tickUnbreakable() {
_scripts[i]->executeInstruction();
}
_scripts[i]->finish();
- _currentScript = nullptr;
+ _currentScript = oldScript;
}
- removeFinishedScripts();
+
+ // NB: Don't remove finished scripts here since we could be recursively
+ // executing scripts. Doing so could invalidate the outer iteration in
+ // ::tick() over _scripts.
return STATUS_OK;
}
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index 3532e127d0..31ec457df1 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -827,6 +827,17 @@ bool ScValue::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_valRef));
persistMgr->transfer(TMEMBER(_valString));
+ if (!persistMgr->getIsSaving() && !persistMgr->checkVersion(1,2,2)) {
+ // Savegames prior to 1.2.2 stored empty strings as NULL.
+ // We disambiguate those by turning NULL strings into empty
+ // strings if _type is VAL_STRING instead of VAL_NULL.
+
+ if (_type == VAL_STRING && !_valString) {
+ _valString = new char[1];
+ _valString[0] = '\0';
+ }
+ }
+
/* // TODO: Convert to Debug-statements.
FILE* f = fopen("c:\\val.log", "a+");
switch(_type)
diff --git a/engines/wintermute/dcgf.h b/engines/wintermute/dcgf.h
index fe92194443..3db443965e 100644
--- a/engines/wintermute/dcgf.h
+++ b/engines/wintermute/dcgf.h
@@ -33,7 +33,7 @@
//////////////////////////////////////////////////////////////////////////
#define DCGF_VER_MAJOR 1
#define DCGF_VER_MINOR 2
-#define DCGF_VER_BUILD 1
+#define DCGF_VER_BUILD 2
#define DCGF_VER_SUFFIX "ScummVM"
#define DCGF_VER_BETA true
diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h
index 702c0b28ba..63f5078c12 100644
--- a/engines/wintermute/detection_tables.h
+++ b/engines/wintermute/detection_tables.h
@@ -40,16 +40,20 @@ static const PlainGameDescriptor wintermuteGames[] = {
{"dreaming", "Des Reves Elastiques Avec Mille Insectes Nommes Georges"},
{"dirtysplit", "Dirty Split"},
{"dreamscape", "Dreamscape"},
+ {"escapemansion", "Escape from the Mansion"},
{"ghostsheet", "Ghost in the Sheet"},
{"hamlet", "Hamlet or the last game without MMORPS features, shaders and product placement"},
{"jamesperis", "James Peris: No License Nor Control"},
+ {"looky", "Looky"},
{"julia", "J.U.L.I.A."},
{"mirage", "Mirage"},
{"pigeons", "Pigeons in the Park"},
{"reversion1", "Reversion: The Escape"},
{"reversion2", "Reversion: The Meeting"},
{"rosemary", "Rosemary"},
+ {"shaban", "Shaban"},
{"shinestar", "The Shine of a Star"},
+ {"spacemadness", "Space Madness"},
{"thebox", "The Box"},
{"tib", "Fairy Tales About Toshechka and Boshechka"},
{"tradestory", "The Trader of Stories"},
@@ -284,6 +288,26 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "Beta 1",
+ AD_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "Beta 2",
+ AD_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Ghosts in the Sheet
{
"ghostsheet",
@@ -379,6 +403,48 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_DEMO,
GUIO0()
},
+ // Looky Demo (English)
+ {
+ "looky",
+ "Demo",
+ {
+ {"english.dcp", 0, "1388e1dd320f4d553dea3b0316812f9d", 1358442},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Looky Demo (German)
+ {
+ "looky",
+ "Demo",
+ {
+ {"german.dcp", 0, "606c048426dfbe94442b59fd34a5c76e", 14339496},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Looky (German)
+ {
+ "looky",
+ "",
+ {
+ {"german.dcp", 0, "bf4c2b8c26342342441a6d64934ab832", 107027865},
+ {"data.dcp", 0, "50de0beaa5ad621aa9f020df901d1e74", 1342214},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Mirage
{
"mirage",
@@ -625,6 +691,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Shaban
+ {
+ "shaban",
+ "",
+ AD_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Shine of a Star
{
"shinestar",
@@ -635,6 +711,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Space Madness
+ {
+ "spacemadness",
+ "1.0.2",
+ AD_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Box
{
"thebox",
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index df6286e37a..cd200354f7 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -140,16 +140,9 @@ void TransparentSurface::copyPixelNearestNeighbor(float projX, float projY, int
}
#endif
-byte *TransparentSurface::_lookup = nullptr;
+TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
-void TransparentSurface::destroyLookup() {
- delete[] _lookup;
- _lookup = nullptr;
-}
-
-TransparentSurface::TransparentSurface() : Surface(), _enableAlphaBlit(true) {}
-
-TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _enableAlphaBlit(true) {
+TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
if (copyData) {
copyFrom(surf);
} else {
@@ -168,9 +161,9 @@ void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pit
byte *in, *out;
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
-#else
const int aIndex = 0;
+#else
+ const int aIndex = 3;
#endif
for (uint32 i = 0; i < height; i++) {
@@ -186,42 +179,60 @@ void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pit
}
}
-void TransparentSurface::generateLookup() {
- _lookup = new byte[256 * 256];
- for (int i = 0; i < 256; i++) {
- for (int j = 0; j < 256; j++) {
- _lookup[(i << 8) + j] = (i * j) >> 8;
+void doBlitBinary(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+ byte *in, *out;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ const int aIndex = 0;
+#else
+ const int aIndex = 3;
+#endif
+ const int aShift = 0;//img->format.aShift;
+
+ for (uint32 i = 0; i < height; i++) {
+ out = outo;
+ in = ino;
+ for (uint32 j = 0; j < width; j++) {
+ uint32 pix = *(uint32 *)in;
+ int a = (pix >> aShift) & 0xff;
+ in += inStep;
+
+ if (a == 0) { // Full transparency
+ out += 4;
+ } else { // Full opacity (Any value not exactly 0 is Opaque here)
+ *(uint32 *)out = pix;
+ out[aIndex] = 0xFF;
+ out += 4;
+ }
}
+ outo += pitch;
+ ino += inoStep;
}
}
-void TransparentSurface::doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
byte *in, *out;
- if (!_lookup) {
- generateLookup();
- }
-
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
- const int bIndex = 0;
- const int gIndex = 1;
- const int rIndex = 2;
-#else
const int aIndex = 0;
- const int bIndex = 3;
+ const int bIndex = 1;
const int gIndex = 2;
- const int rIndex = 1;
+ const int rIndex = 3;
+#else
+ const int aIndex = 3;
+ const int bIndex = 2;
+ const int gIndex = 1;
+ const int rIndex = 0;
#endif
- const int bShift = 0;//img->format.bShift;
- const int gShift = 8;//img->format.gShift;
- const int rShift = 16;//img->format.rShift;
- const int aShift = 24;//img->format.aShift;
+ const int bShift = 8;//img->format.bShift;
+ const int gShift = 16;//img->format.gShift;
+ const int rShift = 24;//img->format.rShift;
+ const int aShift = 0;//img->format.aShift;
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ const int bShiftTarget = 8;//target.format.bShift;
+ const int gShiftTarget = 16;//target.format.gShift;
+ const int rShiftTarget = 24;//target.format.rShift;
for (uint32 i = 0; i < height; i++) {
out = outo;
@@ -255,13 +266,9 @@ void TransparentSurface::doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32
default: // alpha blending
outa = 255;
-
- outb = _lookup[(((oPix >> bShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outg = _lookup[(((oPix >> gShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outr = _lookup[(((oPix >> rShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outb += _lookup[b + (a << 8)];
- outg += _lookup[g + (a << 8)];
- outr += _lookup[r + (a << 8)];
+ outb = ((b * a) + ((oPix >> bShiftTarget) & 0xff) * (255-a)) >> 8;
+ outg = ((g * a) + ((oPix >> gShiftTarget) & 0xff) * (255-a)) >> 8;
+ outr = ((r * a) + ((oPix >> rShiftTarget) & 0xff) * (255-a)) >> 8;
out[aIndex] = outa;
out[bIndex] = outb;
@@ -292,14 +299,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
int cg = (color >> 8) & 0xff;
int cb = (color >> 0) & 0xff;
- // Compensate for transparency. Since we're coming
- // down to 255 alpha, we just compensate for the colors here
- if (ca != 255) {
- cr = cr * ca >> 8;
- cg = cg * ca >> 8;
- cb = cb * ca >> 8;
- }
-
// Create an encapsulating surface for the data
TransparentSurface srcImage(*this, false);
// TODO: Is the data really in the screen format?
@@ -309,7 +308,19 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
}
if (pPartRect) {
- srcImage.pixels = getBasePtr(pPartRect->left, pPartRect->top);
+
+ int xOffset = pPartRect->left;
+ int yOffset = pPartRect->top;
+
+ if (flipping & FLIP_V) {
+ yOffset = srcImage.h - pPartRect->bottom;
+ }
+
+ if (flipping & FLIP_H) {
+ xOffset = srcImage.w - pPartRect->right;
+ }
+
+ srcImage.pixels = getBasePtr(xOffset, yOffset);
srcImage.w = pPartRect->width();
srcImage.h = pPartRect->height();
@@ -379,29 +390,32 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
byte *in, *out;
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
- const int bIndex = 0;
- const int gIndex = 1;
- const int rIndex = 2;
-#else
const int aIndex = 0;
- const int bIndex = 3;
+ const int bIndex = 1;
const int gIndex = 2;
- const int rIndex = 1;
+ const int rIndex = 3;
+#else
+ const int aIndex = 3;
+ const int bIndex = 2;
+ const int gIndex = 1;
+ const int rIndex = 0;
#endif
- const int bShift = 0;//img->format.bShift;
- const int gShift = 8;//img->format.gShift;
- const int rShift = 16;//img->format.rShift;
- const int aShift = 24;//img->format.aShift;
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ const int bShift = 8;//img->format.bShift;
+ const int gShift = 16;//img->format.gShift;
+ const int rShift = 24;//img->format.rShift;
+ const int aShift = 0;//img->format.aShift;
+
+ const int bShiftTarget = 8;//target.format.bShift;
+ const int gShiftTarget = 16;//target.format.gShift;
+ const int rShiftTarget = 24;//target.format.rShift;
if (ca == 255 && cb == 255 && cg == 255 && cr == 255) {
- if (_enableAlphaBlit) {
+ if (_alphaMode == ALPHA_FULL) {
doBlitAlpha(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- } else {
+ } else if (_alphaMode == ALPHA_BINARY) {
+ doBlitBinary(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else if (_alphaMode == ALPHA_OPAQUE) {
doBlitOpaque(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
}
} else {
@@ -421,7 +435,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
if (ca != 255) {
a = a * ca >> 8;
}
-
switch (a) {
case 0: // Full transparency
out += 4;
@@ -451,27 +464,27 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
default: // alpha blending
outa = 255;
- outb = (o_pix >> bShiftTarget) & 0xff;
- outg = (o_pix >> gShiftTarget) & 0xff;
- outr = (o_pix >> rShiftTarget) & 0xff;
+ outb = ((o_pix >> bShiftTarget) & 0xff) * (255 - a);
+ outg = ((o_pix >> gShiftTarget) & 0xff) * (255 - a);
+ outr = ((o_pix >> rShiftTarget) & 0xff) * (255 - a);
if (cb == 0)
- outb = 0;
+ outb = outb >> 8;
else if (cb != 255)
- outb += ((b - outb) * a * cb) >> 16;
+ outb = ((outb<<8) + b * a * cb) >> 16;
else
- outb += ((b - outb) * a) >> 8;
+ outb = (outb + b * a) >> 8;
if (cg == 0)
- outg = 0;
+ outg = outg >> 8;
else if (cg != 255)
- outg += ((g - outg) * a * cg) >> 16;
+ outg = ((outg<<8) + g * a * cg) >> 16;
else
- outg += ((g - outg) * a) >> 8;
+ outg = (outg + g * a) >> 8;
if (cr == 0)
- outr = 0;
+ outr = outr >> 8;
else if (cr != 255)
- outr += ((r - outr) * a * cr) >> 16;
+ outr = ((outr<<8) + r * a * cr) >> 16;
else
- outr += ((r - outr) * a) >> 8;
+ outr = (outr + r * a) >> 8;
out[aIndex] = outa;
out[bIndex] = outb;
out[gIndex] = outg;
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index 9d06f3e006..598aaa55d7 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -75,7 +75,13 @@ struct TransparentSurface : public Graphics::Surface {
FLIP_VH = FLIP_H | FLIP_V
};
- bool _enableAlphaBlit;
+ enum AlphaType {
+ ALPHA_OPAQUE = 0,
+ ALPHA_BINARY = 1,
+ ALPHA_FULL = 2
+ };
+
+ AlphaType _alphaMode;
/**
@brief renders the surface to another surface
@@ -114,11 +120,6 @@ struct TransparentSurface : public Graphics::Surface {
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
TransparentSurface *rotoscale(const TransformStruct &transform) const;
- static byte *_lookup;
- static void destroyLookup();
-private:
- static void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
- static void generateLookup();
};
/**
diff --git a/engines/wintermute/utils/string_util.cpp b/engines/wintermute/utils/string_util.cpp
index 23abb5d579..e8e078aba8 100644
--- a/engines/wintermute/utils/string_util.cpp
+++ b/engines/wintermute/utils/string_util.cpp
@@ -146,26 +146,21 @@ Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
return "";
}
-// Currently this only does Ansi->ISO 8859, and only for carets.
-char simpleAnsiToWide(const AnsiString &str, uint32 &offset) {
- byte c = str[offset];
-
- if (c == 146) {
- offset++;
- return 39; // Replace right-quote with apostrophe
- } else {
- offset++;
- return c;
- }
-}
-
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::ansiToWide(const AnsiString &str) {
// TODO: This function gets called a lot, so warnings like these drown out the usefull information
Common::String converted = "";
uint32 index = 0;
while (index != str.size()) {
- converted += simpleAnsiToWide(str, index);
+ byte c = str[index];
+ if (c == 146) {
+ converted += (char)39; // Replace right-quote with apostrophe
+ } else if (c == 133) {
+ converted += Common::String("..."); // Replace ...-symbol with ...
+ } else {
+ converted += c;
+ }
+ index++;
}
// using default os locale!
diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp
index ef4d6b4dd9..f3317684b5 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -498,7 +498,7 @@ bool VideoTheoraPlayer::persist(BasePersistenceManager *persistMgr) {
persistMgr->transfer(TMEMBER(_alphaFilename));
persistMgr->transfer(TMEMBER(_posX));
persistMgr->transfer(TMEMBER(_posY));
- persistMgr->transfer(TMEMBER(_playZoom));
+ persistMgr->transferFloat(TMEMBER(_playZoom));
persistMgr->transfer(TMEMBER_INT(_playbackType));
persistMgr->transfer(TMEMBER(_looping));
persistMgr->transfer(TMEMBER(_volume));
diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp
index a878944661..0a6be4caf8 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -105,7 +105,7 @@ bool WintermuteEngine::hasFeature(EngineFeature f) const {
Common::Error WintermuteEngine::run() {
// Initialize graphics using following:
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
initGraphics(800, 600, true, &format);
if (g_system->getScreenFormat() != format) {
error("Wintermute currently REQUIRES 32bpp");