aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authoruruk2014-05-30 11:14:47 +0200
committeruruk2014-05-30 11:14:47 +0200
commitbb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d (patch)
tree9a1e28cfb1eb1a322225c05adc0962a2f96ea521 /engines
parent5ad4e157e5398347651a0da0db07f9daf01bf373 (diff)
parent0a46d67baea121bed0511ce45bfdd8438a43d35d (diff)
downloadscummvm-rg350-bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d.tar.gz
scummvm-rg350-bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d.tar.bz2
scummvm-rg350-bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d.zip
Merge branch 'master' of https://github.com/scummvm/scummvm into cge2
Diffstat (limited to 'engines')
-rw-r--r--engines/agi/console.cpp92
-rw-r--r--engines/agi/preagi_mickey.cpp4
-rw-r--r--engines/agi/preagi_winnie.cpp2
-rw-r--r--engines/agos/agos.cpp25
-rw-r--r--engines/agos/agos.h14
-rw-r--r--engines/agos/debugger.cpp117
-rw-r--r--engines/agos/debugger.h1
-rw-r--r--engines/agos/gfx.cpp5
-rw-r--r--engines/agos/script.cpp3
-rw-r--r--engines/agos/subroutine.cpp8
-rw-r--r--engines/agos/vga.cpp8
-rw-r--r--engines/avalanche/console.cpp4
-rw-r--r--engines/avalanche/ghostroom.cpp3
-rw-r--r--engines/cge/console.cpp4
-rw-r--r--engines/cine/console.cpp2
-rw-r--r--engines/cine/gfx.cpp4
-rw-r--r--engines/cine/pal.cpp6
-rw-r--r--engines/cruise/debugger.cpp10
-rw-r--r--engines/draci/game.cpp84
-rw-r--r--engines/draci/walking.cpp2
-rw-r--r--engines/drascula/console.cpp4
-rw-r--r--engines/fullpipe/console.cpp6
-rw-r--r--engines/fullpipe/detection.cpp64
-rw-r--r--engines/fullpipe/fullpipe.cpp52
-rw-r--r--engines/fullpipe/fullpipe.h1
-rw-r--r--engines/fullpipe/gameloader.cpp45
-rw-r--r--engines/fullpipe/gameloader.h16
-rw-r--r--engines/fullpipe/gfx.cpp25
-rw-r--r--engines/fullpipe/gfx.h9
-rw-r--r--engines/fullpipe/messagehandlers.cpp6
-rw-r--r--engines/fullpipe/messages.cpp15
-rw-r--r--engines/fullpipe/modal.cpp185
-rw-r--r--engines/fullpipe/modal.h18
-rw-r--r--engines/fullpipe/motion.cpp866
-rw-r--r--engines/fullpipe/motion.h74
-rw-r--r--engines/fullpipe/scene.cpp106
-rw-r--r--engines/fullpipe/scene.h11
-rw-r--r--engines/fullpipe/scenes.cpp29
-rw-r--r--engines/fullpipe/sound.cpp82
-rw-r--r--engines/fullpipe/stateloader.cpp5
-rw-r--r--engines/fullpipe/statics.cpp126
-rw-r--r--engines/fullpipe/statics.h7
-rw-r--r--engines/fullpipe/utils.h3
-rw-r--r--engines/gob/cheater_geisha.cpp2
-rw-r--r--engines/gob/console.cpp48
-rw-r--r--engines/groovie/debug.cpp34
-rw-r--r--engines/hopkins/computer.cpp48
-rw-r--r--engines/hopkins/computer.h26
-rw-r--r--engines/hopkins/debugger.cpp22
-rw-r--r--engines/hopkins/files.cpp3
-rw-r--r--engines/hugo/console.cpp34
-rw-r--r--engines/kyra/debugger.cpp334
-rw-r--r--engines/kyra/debugger.h60
-rw-r--r--engines/lastexpress/debug.cpp212
-rw-r--r--engines/lure/debugger.cpp206
-rw-r--r--engines/mads/action.cpp708
-rw-r--r--engines/mads/action.h176
-rw-r--r--engines/mads/animation.cpp591
-rw-r--r--engines/mads/animation.h230
-rw-r--r--engines/mads/assets.cpp228
-rw-r--r--engines/mads/assets.h111
-rw-r--r--engines/mads/audio.cpp129
-rw-r--r--engines/mads/audio.h64
-rw-r--r--engines/mads/compression.cpp194
-rw-r--r--engines/mads/compression.h89
-rw-r--r--engines/mads/configure.engine3
-rw-r--r--engines/mads/debugger.cpp326
-rw-r--r--engines/mads/debugger.h61
-rw-r--r--engines/mads/detection.cpp194
-rw-r--r--engines/mads/detection_tables.h122
-rw-r--r--engines/mads/dialogs.cpp398
-rw-r--r--engines/mads/dialogs.h229
-rw-r--r--engines/mads/dragonsphere/dragonsphere_scenes.cpp236
-rw-r--r--engines/mads/dragonsphere/dragonsphere_scenes.h695
-rw-r--r--engines/mads/dragonsphere/game_dragonsphere.cpp173
-rw-r--r--engines/mads/dragonsphere/game_dragonsphere.h151
-rw-r--r--engines/mads/events.cpp256
-rw-r--r--engines/mads/events.h164
-rw-r--r--engines/mads/font.cpp252
-rw-r--r--engines/mads/font.h95
-rw-r--r--engines/mads/game.cpp608
-rw-r--r--engines/mads/game.h241
-rw-r--r--engines/mads/game_data.cpp54
-rw-r--r--engines/mads/game_data.h73
-rw-r--r--engines/mads/globals.cpp33
-rw-r--r--engines/mads/globals.h47
-rw-r--r--engines/mads/hotspots.cpp207
-rw-r--r--engines/mads/hotspots.h114
-rw-r--r--engines/mads/inventory.cpp226
-rw-r--r--engines/mads/inventory.h141
-rw-r--r--engines/mads/mads.cpp157
-rw-r--r--engines/mads/mads.h152
-rw-r--r--engines/mads/messages.cpp570
-rw-r--r--engines/mads/messages.h192
-rw-r--r--engines/mads/module.mk58
-rw-r--r--engines/mads/msurface.cpp572
-rw-r--r--engines/mads/msurface.h255
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp698
-rw-r--r--engines/mads/nebular/dialogs_nebular.h179
-rw-r--r--engines/mads/nebular/game_nebular.cpp819
-rw-r--r--engines/mads/nebular/game_nebular.h153
-rw-r--r--engines/mads/nebular/globals_nebular.cpp55
-rw-r--r--engines/mads/nebular/globals_nebular.h305
-rw-r--r--engines/mads/nebular/nebular_scenes.cpp628
-rw-r--r--engines/mads/nebular/nebular_scenes.h1417
-rw-r--r--engines/mads/nebular/nebular_scenes1.cpp3168
-rw-r--r--engines/mads/nebular/nebular_scenes1.h264
-rw-r--r--engines/mads/nebular/nebular_scenes2.cpp5380
-rw-r--r--engines/mads/nebular/nebular_scenes2.h325
-rw-r--r--engines/mads/nebular/nebular_scenes3.cpp5818
-rw-r--r--engines/mads/nebular/nebular_scenes3.h548
-rw-r--r--engines/mads/nebular/nebular_scenes4.cpp4191
-rw-r--r--engines/mads/nebular/nebular_scenes4.h258
-rw-r--r--engines/mads/nebular/nebular_scenes5.cpp2872
-rw-r--r--engines/mads/nebular/nebular_scenes5.h254
-rw-r--r--engines/mads/nebular/nebular_scenes6.cpp4743
-rw-r--r--engines/mads/nebular/nebular_scenes6.h322
-rw-r--r--engines/mads/nebular/nebular_scenes7.cpp2678
-rw-r--r--engines/mads/nebular/nebular_scenes7.h238
-rw-r--r--engines/mads/nebular/nebular_scenes8.cpp1524
-rw-r--r--engines/mads/nebular/nebular_scenes8.h165
-rw-r--r--engines/mads/nebular/sound_nebular.cpp3119
-rw-r--r--engines/mads/nebular/sound_nebular.h720
-rw-r--r--engines/mads/palette.cpp830
-rw-r--r--engines/mads/palette.h330
-rw-r--r--engines/mads/phantom/game_phantom.cpp161
-rw-r--r--engines/mads/phantom/game_phantom.h124
-rw-r--r--engines/mads/phantom/phantom_scenes.cpp204
-rw-r--r--engines/mads/phantom/phantom_scenes.h521
-rw-r--r--engines/mads/player.cpp794
-rw-r--r--engines/mads/player.h228
-rw-r--r--engines/mads/rails.cpp277
-rw-r--r--engines/mads/rails.h134
-rw-r--r--engines/mads/resources.cpp417
-rw-r--r--engines/mads/resources.h89
-rw-r--r--engines/mads/scene.cpp719
-rw-r--r--engines/mads/scene.h251
-rw-r--r--engines/mads/scene_data.cpp463
-rw-r--r--engines/mads/scene_data.h224
-rw-r--r--engines/mads/screen.cpp642
-rw-r--r--engines/mads/screen.h240
-rw-r--r--engines/mads/sequence.cpp541
-rw-r--r--engines/mads/sequence.h131
-rw-r--r--engines/mads/sound.cpp142
-rw-r--r--engines/mads/sound.h103
-rw-r--r--engines/mads/sprites.cpp417
-rw-r--r--engines/mads/sprites.h239
-rw-r--r--engines/mads/staticres.cpp58
-rw-r--r--engines/mads/staticres.h47
-rw-r--r--engines/mads/user_interface.cpp1096
-rw-r--r--engines/mads/user_interface.h306
-rw-r--r--engines/mohawk/console.cpp266
-rw-r--r--engines/mohawk/riven.cpp82
-rw-r--r--engines/mohawk/riven.h22
-rw-r--r--engines/mohawk/riven_external.cpp6
-rw-r--r--engines/mohawk/riven_graphics.cpp2
-rw-r--r--engines/mohawk/riven_saveload.cpp79
-rw-r--r--engines/mohawk/riven_scripts.cpp4
-rw-r--r--engines/mohawk/riven_vars.cpp418
-rw-r--r--engines/mortevielle/debugger.cpp6
-rw-r--r--engines/neverhood/console.cpp86
-rw-r--r--engines/neverhood/gamevars.cpp2
-rw-r--r--engines/neverhood/graphics.cpp1
-rw-r--r--engines/neverhood/modules/module1000.cpp10
-rw-r--r--engines/neverhood/scene.cpp2
-rw-r--r--engines/neverhood/staticdata.cpp47
-rw-r--r--engines/parallaction/debug.cpp76
-rw-r--r--engines/parallaction/debug.h1
-rw-r--r--engines/pegasus/console.cpp16
-rw-r--r--engines/queen/debug.cpp72
-rw-r--r--engines/saga/actor_walk.cpp2
-rw-r--r--engines/saga/animation.cpp8
-rw-r--r--engines/saga/console.cpp76
-rw-r--r--engines/saga/objectmap.cpp2
-rw-r--r--engines/saga/scene.cpp2
-rw-r--r--engines/saga/sfuncs.cpp2
-rw-r--r--engines/sci/console.cpp1721
-rw-r--r--engines/sci/detection_tables.h2
-rw-r--r--engines/sci/engine/kevent.cpp12
-rw-r--r--engines/sci/engine/script_patches.cpp167
-rw-r--r--engines/sci/engine/scriptdebug.cpp16
-rw-r--r--engines/sci/graphics/animate.cpp2
-rw-r--r--engines/sci/graphics/frameout.cpp10
-rw-r--r--engines/sci/graphics/ports.cpp2
-rw-r--r--engines/sci/parser/grammar.cpp22
-rw-r--r--engines/sci/parser/vocabulary.cpp20
-rw-r--r--engines/sci/sound/music.cpp56
-rw-r--r--engines/sci/sound/music.h2
-rw-r--r--engines/scumm/debugger.cpp258
-rw-r--r--engines/scumm/debugger.h4
-rw-r--r--engines/scumm/scumm.cpp4
-rw-r--r--engines/scumm/scumm.h2
-rw-r--r--engines/scumm/vars.cpp2
-rw-r--r--engines/sky/debug.cpp106
-rw-r--r--engines/sword2/console.cpp264
-rw-r--r--engines/sword2/resman.cpp2
-rw-r--r--engines/sword2/sound.cpp2
-rw-r--r--engines/teenagent/console.cpp46
-rw-r--r--engines/tinsel/debugger.cpp42
-rw-r--r--engines/toltecs/console.cpp14
-rw-r--r--engines/tony/debugger.cpp12
-rw-r--r--engines/tony/detection_tables.h19
-rw-r--r--engines/toon/character.cpp14
-rw-r--r--engines/touche/console.cpp6
-rw-r--r--engines/touche/menu.cpp161
-rw-r--r--engines/touche/resource.cpp20
-rw-r--r--engines/touche/touche.cpp68
-rw-r--r--engines/touche/touche.h108
-rw-r--r--engines/tsage/debugger.cpp388
-rw-r--r--engines/tucker/resource.cpp114
-rw-r--r--engines/tucker/sequences.cpp9
-rw-r--r--engines/tucker/tucker.cpp13
-rw-r--r--engines/tucker/tucker.h1
-rw-r--r--engines/voyeur/animation.cpp24
-rw-r--r--engines/voyeur/animation.h2
-rw-r--r--engines/voyeur/data.cpp6
-rw-r--r--engines/voyeur/data.h12
-rw-r--r--engines/voyeur/debugger.cpp47
-rw-r--r--engines/voyeur/events.cpp18
-rw-r--r--engines/voyeur/events.h2
-rw-r--r--engines/voyeur/files.cpp66
-rw-r--r--engines/voyeur/files.h24
-rw-r--r--engines/voyeur/files_threads.cpp76
-rw-r--r--engines/voyeur/graphics.cpp20
-rw-r--r--engines/voyeur/graphics.h9
-rw-r--r--engines/voyeur/sound.cpp2
-rw-r--r--engines/voyeur/staticres.cpp50
-rw-r--r--engines/voyeur/voyeur.cpp33
-rw-r--r--engines/voyeur/voyeur_game.cpp60
-rw-r--r--engines/wintermute/debugger.cpp10
-rw-r--r--engines/zvision/core/console.cpp48
-rw-r--r--engines/zvision/sound/zork_raw.cpp4
232 files changed, 65247 insertions, 3593 deletions
diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp
index 5f222adf89..6d7f9384cd 100644
--- a/engines/agi/console.cpp
+++ b/engines/agi/console.cpp
@@ -32,27 +32,27 @@ namespace Agi {
Console::Console(AgiEngine *vm) : GUI::Debugger() {
_vm = vm;
- DCmd_Register("debug", WRAP_METHOD(Console, Cmd_Debug));
- DCmd_Register("cont", WRAP_METHOD(Console, Cmd_Cont));
- DCmd_Register("agiver", WRAP_METHOD(Console, Cmd_Agiver));
- DCmd_Register("flags", WRAP_METHOD(Console, Cmd_Flags));
- DCmd_Register("logic0", WRAP_METHOD(Console, Cmd_Logic0));
- DCmd_Register("objs", WRAP_METHOD(Console, Cmd_Objs));
- DCmd_Register("runopcode", WRAP_METHOD(Console, Cmd_RunOpcode));
- DCmd_Register("opcode", WRAP_METHOD(Console, Cmd_Opcode));
- DCmd_Register("step", WRAP_METHOD(Console, Cmd_Step));
- DCmd_Register("trigger", WRAP_METHOD(Console, Cmd_Trigger));
- DCmd_Register("vars", WRAP_METHOD(Console, Cmd_Vars));
- DCmd_Register("setvar", WRAP_METHOD(Console, Cmd_SetVar));
- DCmd_Register("setflag", WRAP_METHOD(Console, Cmd_SetFlag));
- DCmd_Register("setobj", WRAP_METHOD(Console, Cmd_SetObj));
- DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room));
- DCmd_Register("bt", WRAP_METHOD(Console, Cmd_BT));
+ registerCmd("debug", WRAP_METHOD(Console, Cmd_Debug));
+ registerCmd("cont", WRAP_METHOD(Console, Cmd_Cont));
+ registerCmd("agiver", WRAP_METHOD(Console, Cmd_Agiver));
+ registerCmd("flags", WRAP_METHOD(Console, Cmd_Flags));
+ registerCmd("logic0", WRAP_METHOD(Console, Cmd_Logic0));
+ registerCmd("objs", WRAP_METHOD(Console, Cmd_Objs));
+ registerCmd("runopcode", WRAP_METHOD(Console, Cmd_RunOpcode));
+ registerCmd("opcode", WRAP_METHOD(Console, Cmd_Opcode));
+ registerCmd("step", WRAP_METHOD(Console, Cmd_Step));
+ registerCmd("trigger", WRAP_METHOD(Console, Cmd_Trigger));
+ registerCmd("vars", WRAP_METHOD(Console, Cmd_Vars));
+ registerCmd("setvar", WRAP_METHOD(Console, Cmd_SetVar));
+ registerCmd("setflag", WRAP_METHOD(Console, Cmd_SetFlag));
+ registerCmd("setobj", WRAP_METHOD(Console, Cmd_SetObj));
+ registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
+ registerCmd("bt", WRAP_METHOD(Console, Cmd_BT));
}
bool Console::Cmd_SetVar(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Usage: setvar <varnum> <value>\n");
+ debugPrintf("Usage: setvar <varnum> <value>\n");
return true;
}
int p1 = (int)atoi(argv[1]);
@@ -64,7 +64,7 @@ bool Console::Cmd_SetVar(int argc, const char **argv) {
bool Console::Cmd_SetFlag(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Usage: setvar <varnum> <value>\n");
+ debugPrintf("Usage: setvar <varnum> <value>\n");
return true;
}
int p1 = (int)atoi(argv[1]);
@@ -76,7 +76,7 @@ bool Console::Cmd_SetFlag(int argc, const char **argv) {
bool Console::Cmd_SetObj(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Usage: setvar <varnum> <value>\n");
+ debugPrintf("Usage: setvar <varnum> <value>\n");
return true;
}
int p1 = (int)atoi(argv[1]);
@@ -88,7 +88,7 @@ bool Console::Cmd_SetObj(int argc, const char **argv) {
bool Console::Cmd_RunOpcode(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: runopcode <name> <parameter0> ....\n");
+ debugPrintf("Usage: runopcode <name> <parameter0> ....\n");
return true;
}
@@ -96,7 +96,7 @@ bool Console::Cmd_RunOpcode(int argc, const char **argv) {
if (!strcmp(argv[1], logicNamesCmd[i].name)) {
uint8 p[16];
if ((argc - 2) != logicNamesCmd[i].argumentsLength()) {
- DebugPrintf("AGI command wants %d arguments\n", logicNamesCmd[i].argumentsLength());
+ debugPrintf("AGI command wants %d arguments\n", logicNamesCmd[i].argumentsLength());
return 0;
}
p[0] = argv[2] ? (char)strtoul(argv[2], NULL, 0) : 0;
@@ -113,7 +113,7 @@ bool Console::Cmd_RunOpcode(int argc, const char **argv) {
}
}
- DebugPrintf("Unknown opcode\n");
+ debugPrintf("Unknown opcode\n");
return true;
}
@@ -125,7 +125,7 @@ bool Console::Cmd_Agiver(int argc, const char **argv) {
maj = (ver >> 12) & 0xf;
min = ver & 0xfff;
- DebugPrintf(maj <= 2 ? "%x.%03x\n" : "%x.002.%03x\n", maj, min);
+ debugPrintf(maj <= 2 ? "%x.%03x\n" : "%x.002.%03x\n", maj, min);
return true;
}
@@ -133,17 +133,17 @@ bool Console::Cmd_Agiver(int argc, const char **argv) {
bool Console::Cmd_Flags(int argc, const char **argv) {
int i, j;
- DebugPrintf(" ");
+ debugPrintf(" ");
for (j = 0; j < 10; j++)
- DebugPrintf("%d ", j);
- DebugPrintf("\n");
+ debugPrintf("%d ", j);
+ debugPrintf("\n");
for (i = 0; i < 255;) {
- DebugPrintf("%3d ", i);
+ debugPrintf("%3d ", i);
for (j = 0; j < 10; j++, i++) {
- DebugPrintf("%c ", _vm->getflag(i) ? 'T' : 'F');
+ debugPrintf("%c ", _vm->getflag(i) ? 'T' : 'F');
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
return true;
@@ -154,9 +154,9 @@ bool Console::Cmd_Vars(int argc, const char **argv) {
for (i = 0; i < 255;) {
for (j = 0; j < 5; j++, i++) {
- DebugPrintf("%03d:%3d ", i, _vm->getvar(i));
+ debugPrintf("%03d:%3d ", i, _vm->getvar(i));
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
return true;
@@ -166,7 +166,7 @@ bool Console::Cmd_Objs(int argc, const char **argv) {
unsigned int i;
for (i = 0; i < _vm->_game.numObjects; i++) {
- DebugPrintf("%3d]%-24s(%3d)\n", i, _vm->objectName(i), _vm->objectGetLocation(i));
+ debugPrintf("%3d]%-24s(%3d)\n", i, _vm->objectName(i), _vm->objectGetLocation(i));
}
return true;
@@ -174,7 +174,7 @@ bool Console::Cmd_Objs(int argc, const char **argv) {
bool Console::Cmd_Opcode(int argc, const char **argv) {
if (argc != 2 || (strcmp(argv[1], "on") && strcmp(argv[1], "off"))) {
- DebugPrintf("Usage: opcode on|off\n");
+ debugPrintf("Usage: opcode on|off\n");
return true;
}
@@ -185,7 +185,7 @@ bool Console::Cmd_Opcode(int argc, const char **argv) {
bool Console::Cmd_Logic0(int argc, const char **argv) {
if (argc != 2 || (strcmp(argv[1], "on") && strcmp(argv[1], "off"))) {
- DebugPrintf("Usage: logic0 on|off\n");
+ debugPrintf("Usage: logic0 on|off\n");
return true;
}
@@ -196,7 +196,7 @@ bool Console::Cmd_Logic0(int argc, const char **argv) {
bool Console::Cmd_Trigger(int argc, const char **argv) {
if (argc != 2 || (strcmp(argv[1], "on") && strcmp(argv[1], "off"))) {
- DebugPrintf("Usage: trigger on|off\n");
+ debugPrintf("Usage: trigger on|off\n");
return true;
}
_vm->_debug.ignoretriggers = strcmp (argv[1], "on");
@@ -236,13 +236,13 @@ bool Console::Cmd_Room(int argc, const char **argv) {
_vm->newRoom(strtoul(argv[1], NULL, 0));
}
- DebugPrintf("Current room: %d\n", _vm->getvar(0));
+ debugPrintf("Current room: %d\n", _vm->getvar(0));
return true;
}
bool Console::Cmd_BT(int argc, const char **argv) {
- DebugPrintf("Current script: %d\nStack depth: %d\n", _vm->_game.lognum, _vm->_game.execStack.size());
+ debugPrintf("Current script: %d\nStack depth: %d\n", _vm->_game.lognum, _vm->_game.execStack.size());
uint8 *code = NULL;
uint8 op = 0;
@@ -257,12 +257,12 @@ bool Console::Cmd_BT(int argc, const char **argv) {
memmove(p, &code[it->curIP], num);
memset(p + num, 0, CMD_BSIZE - num);
- DebugPrintf("%d(%d): %s(", it->script, it->curIP, logicNamesCmd[op].name);
+ debugPrintf("%d(%d): %s(", it->script, it->curIP, logicNamesCmd[op].name);
for (int i = 0; i < num; i++)
- DebugPrintf("%d, ", p[i]);
+ debugPrintf("%d, ", p[i]);
- DebugPrintf(")\n");
+ debugPrintf(")\n");
}
return true;
@@ -271,9 +271,9 @@ bool Console::Cmd_BT(int argc, const char **argv) {
MickeyConsole::MickeyConsole(MickeyEngine *mickey) : GUI::Debugger() {
_mickey = mickey;
- DCmd_Register("room", WRAP_METHOD(MickeyConsole, Cmd_Room));
- DCmd_Register("drawPic", WRAP_METHOD(MickeyConsole, Cmd_DrawPic));
- DCmd_Register("drawObj", WRAP_METHOD(MickeyConsole, Cmd_DrawObj));
+ registerCmd("room", WRAP_METHOD(MickeyConsole, Cmd_Room));
+ registerCmd("drawPic", WRAP_METHOD(MickeyConsole, Cmd_DrawPic));
+ registerCmd("drawObj", WRAP_METHOD(MickeyConsole, Cmd_DrawObj));
}
bool MickeyConsole::Cmd_Room(int argc, const char **argv) {
@@ -287,7 +287,7 @@ bool MickeyConsole::Cmd_Room(int argc, const char **argv) {
bool MickeyConsole::Cmd_DrawPic(int argc, const char **argv) {
if (argc != 2)
- DebugPrintf("Usage: %s <Picture number>\n", argv[0]);
+ debugPrintf("Usage: %s <Picture number>\n", argv[0]);
else
_mickey->drawPic(atoi(argv[1]));
return true;
@@ -295,7 +295,7 @@ bool MickeyConsole::Cmd_DrawPic(int argc, const char **argv) {
bool MickeyConsole::Cmd_DrawObj(int argc, const char **argv) {
if (argc != 2)
- DebugPrintf("Usage: %s <Object number>\n", argv[0]);
+ debugPrintf("Usage: %s <Object number>\n", argv[0]);
else
_mickey->drawObj((ENUM_MSA_OBJECT)atoi(argv[1]), 0, 0);
return true;
@@ -304,7 +304,7 @@ bool MickeyConsole::Cmd_DrawObj(int argc, const char **argv) {
WinnieConsole::WinnieConsole(WinnieEngine *winnie) : GUI::Debugger() {
_winnie = winnie;
- DCmd_Register("curRoom", WRAP_METHOD(WinnieConsole, Cmd_CurRoom));
+ registerCmd("curRoom", WRAP_METHOD(WinnieConsole, Cmd_CurRoom));
}
bool WinnieConsole::Cmd_CurRoom(int argc, const char **argv) {
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index 561b56d199..4ca8d00824 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -2228,10 +2228,10 @@ void MickeyEngine::waitAnyKey(bool anim) {
// Console-related functions
void MickeyEngine::debugCurRoom() {
- _console->DebugPrintf("Current Room = %d\n", _gameStateMickey.iRoom);
+ _console->debugPrintf("Current Room = %d\n", _gameStateMickey.iRoom);
if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] != IDI_MSA_OBJECT_NONE) {
- _console->DebugPrintf("Object %d is in the room\n", _gameStateMickey.iRmObj[_gameStateMickey.iRoom]);
+ _console->debugPrintf("Object %d is in the room\n", _gameStateMickey.iRmObj[_gameStateMickey.iRoom]);
}
}
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index d5ae0b59a0..a91ad24fc6 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -1308,7 +1308,7 @@ void WinnieEngine::printStrWinnie(char *szMsg) {
// Console-related functions
void WinnieEngine::debugCurRoom() {
- _console->DebugPrintf("Current Room = %d\n", _room);
+ _console->debugPrintf("Current Room = %d\n", _room);
}
WinnieEngine::WinnieEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 7266c75474..6eda2eb9aa 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -21,6 +21,7 @@
*/
#include "common/config-manager.h"
+#include "common/debug-channels.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/textconsole.h"
@@ -144,6 +145,14 @@ AGOSEngine_Elvira1::AGOSEngine_Elvira1(OSystem *system, const AGOSGameDescriptio
AGOSEngine::AGOSEngine(OSystem *system, const AGOSGameDescription *gd)
: Engine(system), _rnd("agos"), _gameDescription(gd) {
+ DebugMan.addDebugChannel(kDebugOpcode, "opcode", "Opcode debug level");
+ DebugMan.addDebugChannel(kDebugVGAOpcode, "vga_opcode", "VGA Opcode debug level");
+ DebugMan.addDebugChannel(kDebugSubroutine, "subroutine", "Subroutine debug level");
+ DebugMan.addDebugChannel(kDebugVGAScript, "vga_script", "VGA Script debug level");
+ //Image dumping command disabled as it doesn't work well
+#if 0
+ DebugMan.addDebugChannel(kDebugImageDump, "image_dump", "Enable dumping of images to files");
+#endif
_vcPtr = 0;
_vcGetOutOfCode = 0;
_gameOffsetsPtr = 0;
@@ -243,13 +252,6 @@ AGOSEngine::AGOSEngine(OSystem *system, const AGOSGameDescription *gd)
_backFlag = false;
- _debugMode = 0;
- _dumpScripts = false;
- _dumpOpcodes = false;
- _dumpVgaScripts = false;
- _dumpVgaOpcodes = false;
- _dumpImages = false;
-
_copyProtection = false;
_pause = false;
_speech = false;
@@ -675,15 +677,6 @@ Common::Error AGOSEngine::init() {
_subtitles = true;
}
- // TODO: Use special debug levels instead of the following hack.
- _debugMode = (gDebugLevel >= 0);
- switch (gDebugLevel) {
- case 2: _dumpOpcodes = true; break;
- case 3: _dumpVgaOpcodes = true; break;
- case 4: _dumpScripts = true; break;
- case 5: _dumpVgaScripts = true; break;
- }
-
return Common::kNoError;
}
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 5e49fce5ff..b6b5e427e1 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -61,6 +61,14 @@ struct Surface;
namespace AGOS {
+enum {
+ kDebugOpcode = 1 << 0,
+ kDebugVGAOpcode = 1 << 1,
+ kDebugSubroutine = 1 << 2,
+ kDebugVGAScript = 1 << 3,
+ kDebugImageDump = 1 << 4
+};
+
uint fileReadItemID(Common::SeekableReadStream *in);
#define CHECK_BOUNDS(x, y) assert((uint)(x) < ARRAYSIZE(y))
@@ -324,15 +332,9 @@ protected:
bool _fastMode;
bool _backFlag;
- uint16 _debugMode;
Common::Language _language;
bool _copyProtection;
bool _pause;
- bool _dumpScripts;
- bool _dumpOpcodes;
- bool _dumpVgaScripts;
- bool _dumpVgaOpcodes;
- bool _dumpImages;
bool _speech;
bool _subtitles;
bool _vgaVar9;
diff --git a/engines/agos/debugger.cpp b/engines/agos/debugger.cpp
index 512137b685..7ad742c928 100644
--- a/engines/agos/debugger.cpp
+++ b/engines/agos/debugger.cpp
@@ -32,44 +32,21 @@ Debugger::Debugger(AGOSEngine *vm)
: GUI::Debugger() {
_vm = vm;
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("level", WRAP_METHOD(Debugger, Cmd_DebugLevel));
- DCmd_Register("music", WRAP_METHOD(Debugger, Cmd_PlayMusic));
- DCmd_Register("sound", WRAP_METHOD(Debugger, Cmd_PlaySound));
- DCmd_Register("voice", WRAP_METHOD(Debugger, Cmd_PlayVoice));
- DCmd_Register("bit", WRAP_METHOD(Debugger, Cmd_SetBit));
- DCmd_Register("bit2", WRAP_METHOD(Debugger, Cmd_SetBit2));
- DCmd_Register("bit3", WRAP_METHOD(Debugger, Cmd_SetBit3));
- DCmd_Register("var", WRAP_METHOD(Debugger, Cmd_SetVar));
- DCmd_Register("obj", WRAP_METHOD(Debugger, Cmd_SetObjectFlag));
- DCmd_Register("sub", WRAP_METHOD(Debugger, Cmd_StartSubroutine));
- DCmd_Register("dumpimage", WRAP_METHOD(Debugger, Cmd_dumpImage));
- DCmd_Register("dumpscript", WRAP_METHOD(Debugger, Cmd_dumpScript));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("music", WRAP_METHOD(Debugger, Cmd_PlayMusic));
+ registerCmd("sound", WRAP_METHOD(Debugger, Cmd_PlaySound));
+ registerCmd("voice", WRAP_METHOD(Debugger, Cmd_PlayVoice));
+ registerCmd("bit", WRAP_METHOD(Debugger, Cmd_SetBit));
+ registerCmd("bit2", WRAP_METHOD(Debugger, Cmd_SetBit2));
+ registerCmd("bit3", WRAP_METHOD(Debugger, Cmd_SetBit3));
+ registerCmd("var", WRAP_METHOD(Debugger, Cmd_SetVar));
+ registerCmd("obj", WRAP_METHOD(Debugger, Cmd_SetObjectFlag));
+ registerCmd("sub", WRAP_METHOD(Debugger, Cmd_StartSubroutine));
+ registerCmd("dumpimage", WRAP_METHOD(Debugger, Cmd_dumpImage));
+ registerCmd("dumpscript", WRAP_METHOD(Debugger, Cmd_dumpScript));
}
-
-bool Debugger::Cmd_DebugLevel(int argc, const char **argv) {
- if (argc == 1) {
- if (_vm->_debugMode == false)
- DebugPrintf("Debugging is not enabled at this time\n");
- else
- DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel);
- } else { // set level
- gDebugLevel = atoi(argv[1]);
- if (0 <= gDebugLevel && gDebugLevel < 11) {
- _vm->_debugMode = true;
- DebugPrintf("Debug level set to level %d\n", gDebugLevel);
- } else if (gDebugLevel < 0) {
- _vm->_debugMode = false;
- DebugPrintf("Debugging is now disabled\n");
- } else
- DebugPrintf("Not a valid debug level (0 - 10)\n");
- }
-
- return true;
-}
-
bool Debugger::Cmd_PlayMusic(int argc, const char **argv) {
if (argc > 1) {
uint music = atoi(argv[1]);
@@ -83,9 +60,9 @@ bool Debugger::Cmd_PlayMusic(int argc, const char **argv) {
_vm->playMusic(music, 0);
}
} else
- DebugPrintf("Music out of range (0 - %d)\n", _vm->_numMusic);
+ debugPrintf("Music out of range (0 - %d)\n", _vm->_numMusic);
} else
- DebugPrintf("Syntax: music <musicnum>\n");
+ debugPrintf("Syntax: music <musicnum>\n");
return true;
}
@@ -96,9 +73,9 @@ bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
if (sound <= _vm->_numSFX)
_vm->_sound->playEffects(sound);
else
- DebugPrintf("Sound out of range (0 - %d)\n", _vm->_numSFX);
+ debugPrintf("Sound out of range (0 - %d)\n", _vm->_numSFX);
} else
- DebugPrintf("Syntax: sound <soundnum>\n");
+ debugPrintf("Syntax: sound <soundnum>\n");
return true;
}
@@ -109,9 +86,9 @@ bool Debugger::Cmd_PlayVoice(int argc, const char **argv) {
if (voice <= _vm->_numSpeech)
_vm->_sound->playVoice(voice);
else
- DebugPrintf("Voice out of range (0 - %d)\n", _vm->_numSpeech);
+ debugPrintf("Voice out of range (0 - %d)\n", _vm->_numSpeech);
} else
- DebugPrintf("Syntax: voice <voicenum>\n");
+ debugPrintf("Syntax: voice <voicenum>\n");
return true;
}
@@ -123,15 +100,15 @@ bool Debugger::Cmd_SetBit(int argc, const char **argv) {
value = atoi(argv[2]);
if (value <= 1) {
_vm->setBitFlag(bit, value != 0);
- DebugPrintf("Set bit %d to %d\n", bit, value);
+ debugPrintf("Set bit %d to %d\n", bit, value);
} else
- DebugPrintf("Bit value out of range (0 - 1)\n");
+ debugPrintf("Bit value out of range (0 - 1)\n");
} else if (argc > 1) {
bit = atoi(argv[1]);
value = _vm->getBitFlag(bit);
- DebugPrintf("Bit %d is %d\n", bit, value);
+ debugPrintf("Bit %d is %d\n", bit, value);
} else
- DebugPrintf("Syntax: bit <bitnum> <value>\n");
+ debugPrintf("Syntax: bit <bitnum> <value>\n");
return true;
}
@@ -143,18 +120,18 @@ bool Debugger::Cmd_SetBit2(int argc, const char **argv) {
value = atoi(argv[2]);
if (value == 0) {
_vm->_bitArrayTwo[bit / 16] &= ~(1 << (bit & 15));
- DebugPrintf("Set bit2 %d to %d\n", bit, value);
+ debugPrintf("Set bit2 %d to %d\n", bit, value);
} else if (value == 1) {
_vm->_bitArrayTwo[bit / 16] |= (1 << (bit & 15));
- DebugPrintf("Set bit2 %d to %d\n", bit, value);
+ debugPrintf("Set bit2 %d to %d\n", bit, value);
} else
- DebugPrintf("Bit2 value out of range (0 - 1)\n");
+ debugPrintf("Bit2 value out of range (0 - 1)\n");
} else if (argc > 1) {
bit = atoi(argv[1]);
value = (_vm->_bitArrayTwo[bit / 16] & (1 << (bit & 15))) != 0;
- DebugPrintf("Bit2 %d is %d\n", bit, value);
+ debugPrintf("Bit2 %d is %d\n", bit, value);
} else
- DebugPrintf("Syntax: bit2 <bitnum> <value>\n");
+ debugPrintf("Syntax: bit2 <bitnum> <value>\n");
return true;
}
@@ -166,18 +143,18 @@ bool Debugger::Cmd_SetBit3(int argc, const char **argv) {
value = atoi(argv[2]);
if (value == 0) {
_vm->_bitArrayThree[bit / 16] &= ~(1 << (bit & 15));
- DebugPrintf("Set bit3 %d to %d\n", bit, value);
+ debugPrintf("Set bit3 %d to %d\n", bit, value);
} else if (value == 1) {
_vm->_bitArrayThree[bit / 16] |= (1 << (bit & 15));
- DebugPrintf("Set bit3 %d to %d\n", bit, value);
+ debugPrintf("Set bit3 %d to %d\n", bit, value);
} else
- DebugPrintf("Bit3 value out of range (0 - 1)\n");
+ debugPrintf("Bit3 value out of range (0 - 1)\n");
} else if (argc > 1) {
bit = atoi(argv[1]);
value = (_vm->_bitArrayThree[bit / 16] & (1 << (bit & 15))) != 0;
- DebugPrintf("Bit3 %d is %d\n", bit, value);
+ debugPrintf("Bit3 %d is %d\n", bit, value);
} else
- DebugPrintf("Syntax: bit3 <bitnum> <value>\n");
+ debugPrintf("Syntax: bit3 <bitnum> <value>\n");
return true;
}
@@ -190,15 +167,15 @@ bool Debugger::Cmd_SetVar(int argc, const char **argv) {
if (argc > 2) {
value = atoi(argv[2]);
_vm->writeVariable(var, value);
- DebugPrintf("Set var %d to %d\n", var, value);
+ debugPrintf("Set var %d to %d\n", var, value);
} else {
value = _vm->readVariable(var);
- DebugPrintf("Var %d is %d\n", var, value);
+ debugPrintf("Var %d is %d\n", var, value);
}
} else
- DebugPrintf("Var out of range (0 - %d)\n", _vm->_numVars - 1);
+ debugPrintf("Var out of range (0 - %d)\n", _vm->_numVars - 1);
} else
- DebugPrintf("Syntax: var <varnum> <value>\n");
+ debugPrintf("Syntax: var <varnum> <value>\n");
return true;
}
@@ -217,22 +194,22 @@ bool Debugger::Cmd_SetObjectFlag(int argc, const char **argv) {
if (argc > 3) {
value = atoi(argv[3]);
o->objectFlagValue[offs] = value;
- DebugPrintf("Object %d Flag %d set to %d\n", obj, prop, value);
+ debugPrintf("Object %d Flag %d set to %d\n", obj, prop, value);
} else {
value = o->objectFlagValue[offs];
- DebugPrintf("Object %d Flag %d is %d\n", obj, prop, value);
+ debugPrintf("Object %d Flag %d is %d\n", obj, prop, value);
}
} else {
- DebugPrintf("Object flag out of range\n");
+ debugPrintf("Object flag out of range\n");
}
} else {
- DebugPrintf("Item isn't an object\n");
+ debugPrintf("Item isn't an object\n");
}
} else {
- DebugPrintf("Item out of range (1 - %d)\n", _vm->_itemArraySize - 1);
+ debugPrintf("Item out of range (1 - %d)\n", _vm->_itemArraySize - 1);
}
} else {
- DebugPrintf("Syntax: obj <itemnum> <flag> <value>\n");
+ debugPrintf("Syntax: obj <itemnum> <flag> <value>\n");
}
return true;
@@ -246,7 +223,7 @@ bool Debugger::Cmd_StartSubroutine(int argc, const char **argv) {
if (sub != NULL)
_vm->startSubroutine(sub);
} else
- DebugPrintf("Subroutine %d\n", _vm->_currentTable->id);
+ debugPrintf("Subroutine %d\n", _vm->_currentTable->id);
return true;
}
@@ -259,11 +236,11 @@ bool Debugger::Cmd_dumpImage(int argc, const char **argv) {
if (vpe->vgaFile2 != NULL) {
_vm->dumpVgaBitmaps(zoneNum);
} else {
- DebugPrintf("Invalid Zone Number %d\n", zoneNum);
+ debugPrintf("Invalid Zone Number %d\n", zoneNum);
}
} else
- DebugPrintf("Syntax: dumpimage <zonenum>\n");
+ debugPrintf("Syntax: dumpimage <zonenum>\n");
return true;
}
@@ -276,11 +253,11 @@ bool Debugger::Cmd_dumpScript(int argc, const char **argv) {
if (vpe->vgaFile1 != NULL) {
_vm->dumpVgaFile(vpe->vgaFile1);
} else {
- DebugPrintf("Invalid Zone Number %d\n", zoneNum);
+ debugPrintf("Invalid Zone Number %d\n", zoneNum);
}
} else
- DebugPrintf("Syntax: dumpscript <zonenum>\n");
+ debugPrintf("Syntax: dumpscript <zonenum>\n");
return true;
}
diff --git a/engines/agos/debugger.h b/engines/agos/debugger.h
index caac6e2caf..026194410f 100644
--- a/engines/agos/debugger.h
+++ b/engines/agos/debugger.h
@@ -37,7 +37,6 @@ public:
private:
AGOSEngine *_vm;
- bool Cmd_DebugLevel(int argc, const char **argv);
bool Cmd_PlayMusic(int argc, const char **argv);
bool Cmd_PlaySound(int argc, const char **argv);
bool Cmd_PlayVoice(int argc, const char **argv);
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 6e97084811..33145b7d0d 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -20,6 +20,7 @@
*
*/
+#include "common/debug-channels.h"
#include "common/endian.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -1129,7 +1130,7 @@ void AGOSEngine::animate(uint16 windowNum, uint16 zoneNum, uint16 vgaSpriteId, i
assert(READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId);
}
- if (_dumpVgaScripts) {
+ if (DebugMan.isDebugChannelEnabled(kDebugVGAScript)) {
if (getGameType() == GType_FF || getGameType() == GType_PP) {
dumpVgaScript(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), zoneNum, vgaSpriteId);
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
@@ -1235,7 +1236,7 @@ void AGOSEngine::setImage(uint16 vgaSpriteId, bool vgaScript) {
}
}
- if (_dumpVgaScripts) {
+ if (DebugMan.isDebugChannelEnabled(kDebugVGAScript)) {
if (getGameType() == GType_FF || getGameType() == GType_PP) {
dumpVgaScript(_curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble*)b)->scriptOffs), zoneNum, vgaSpriteId);
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp
index 6f809d9e2d..1dbb9c255a 100644
--- a/engines/agos/script.cpp
+++ b/engines/agos/script.cpp
@@ -22,6 +22,7 @@
// Item script opcodes for Simon1/Simon2
+#include "common/debug-channels.h"
#include "common/endian.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -987,7 +988,7 @@ int AGOSEngine::runScript() {
return 1;
do {
- if (_dumpOpcodes)
+ if (DebugMan.isDebugChannelEnabled(kDebugOpcode))
dumpOpcode(_codePtr);
if (getGameType() == GType_ELVIRA1) {
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index 39bc468dea..1e6ecaa829 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -20,8 +20,7 @@
*
*/
-
-
+#include "common/debug-channels.h"
#include "common/file.h"
#include "common/textconsole.h"
@@ -531,7 +530,7 @@ int AGOSEngine::startSubroutine(Subroutine *sub) {
_classMode1 = 0;
_classMode2 = 0;
- if (_dumpScripts)
+ if (DebugMan.isDebugChannelEnabled(kDebugSubroutine))
dumpSubroutine(sub);
if (++_recursionDepth > 40)
@@ -564,8 +563,7 @@ restart:
else
_codePtr += 8;
- if (_dumpOpcodes)
- debug("; %d", sub->id);
+ debugC(kDebugOpcode, "; %d", sub->id);
result = runScript();
if (result != 0) {
break;
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index c656c0167a..f761c3fc3f 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -27,6 +27,7 @@
#include "agos/intern.h"
#include "agos/vga.h"
+#include "common/debug-channels.h"
#include "common/endian.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -152,7 +153,7 @@ void AGOSEngine::runVgaScript() {
for (;;) {
uint opcode;
- if (_dumpVgaOpcodes) {
+ if (DebugMan.isDebugChannelEnabled(kDebugVGAOpcode)) {
if (_vcPtr != (const byte *)&_vcGetOutOfCode) {
debugN("%.5d %.5X: %5d %4d ", _vgaTickCounter, (unsigned int)(_vcPtr - _curVgaFile1), _vgaCurSpriteId, _vgaCurZoneNum);
dumpVideoScript(_vcPtr, true);
@@ -381,8 +382,7 @@ void AGOSEngine::vcSkipNextInstruction() {
_vcPtr += opcodeParamLenPN[opcode];
}
- if (_dumpVgaOpcodes)
- debugN("; skipped\n");
+ debugCN(kDebugVGAOpcode, "; skipped\n");
}
// VGA Script commands
@@ -648,7 +648,7 @@ void AGOSEngine::drawImage_init(int16 image, uint16 palette, int16 x, int16 y, u
if (height == 0 || width == 0)
return;
- if (_dumpImages)
+ if (DebugMan.isDebugChannelEnabled(kDebugImageDump))
dumpSingleBitmap(_vgaCurZoneNum, state.image, state.srcPtr, width, height,
state.palette);
state.width = state.draw_width = width; /* cl */
diff --git a/engines/avalanche/console.cpp b/engines/avalanche/console.cpp
index 29ae5cf9c3..d4923affc1 100644
--- a/engines/avalanche/console.cpp
+++ b/engines/avalanche/console.cpp
@@ -31,7 +31,7 @@
namespace Avalanche {
AvalancheConsole::AvalancheConsole(AvalancheEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("magic_lines", WRAP_METHOD(AvalancheConsole, Cmd_MagicLines));
+ registerCmd("magic_lines", WRAP_METHOD(AvalancheConsole, Cmd_MagicLines));
}
AvalancheConsole::~AvalancheConsole() {
@@ -42,7 +42,7 @@ AvalancheConsole::~AvalancheConsole() {
*/
bool AvalancheConsole::Cmd_MagicLines(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
diff --git a/engines/avalanche/ghostroom.cpp b/engines/avalanche/ghostroom.cpp
index 16c79fdee0..047a3670c2 100644
--- a/engines/avalanche/ghostroom.cpp
+++ b/engines/avalanche/ghostroom.cpp
@@ -49,6 +49,9 @@ GhostRoom::GhostRoom(AvalancheEngine *vm) {
_greldetCount = 0;
_redGreldet = false;
_wasLoaded = false;
+
+ _ghost = nullptr;
+ _glerk = nullptr;
}
GhostRoom::~GhostRoom() {
diff --git a/engines/cge/console.cpp b/engines/cge/console.cpp
index 447875c06f..e926e89506 100644
--- a/engines/cge/console.cpp
+++ b/engines/cge/console.cpp
@@ -26,7 +26,7 @@
namespace CGE {
CGEConsole::CGEConsole(CGEEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("Boundaries", WRAP_METHOD(CGEConsole, Cmd_boundaries));
+ registerCmd("Boundaries", WRAP_METHOD(CGEConsole, Cmd_boundaries));
}
CGEConsole::~CGEConsole() {
@@ -37,7 +37,7 @@ CGEConsole::~CGEConsole() {
*/
bool CGEConsole::Cmd_boundaries(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
diff --git a/engines/cine/console.cpp b/engines/cine/console.cpp
index 82197693d4..4646bdf280 100644
--- a/engines/cine/console.cpp
+++ b/engines/cine/console.cpp
@@ -29,7 +29,7 @@ bool labyrinthCheat;
CineConsole::CineConsole(CineEngine *vm) : GUI::Debugger(), _vm(vm) {
assert(_vm);
- DCmd_Register("labyrinthCheat", WRAP_METHOD(CineConsole, Cmd_LabyrinthCheat));
+ registerCmd("labyrinthCheat", WRAP_METHOD(CineConsole, Cmd_LabyrinthCheat));
labyrinthCheat = false;
}
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index f6419ecafc..b9175cac72 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -1902,7 +1902,9 @@ void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 he
destPtr++;
srcPtr++;
- maskPtr++;
+
+ if (maskPtr)
+ maskPtr++;
}
}
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp
index f3985c691e..18f260cab7 100644
--- a/engines/cine/pal.cpp
+++ b/engines/cine/pal.cpp
@@ -332,9 +332,9 @@ byte *Palette::save(byte *buf, const uint size, const Graphics::PixelFormat form
// Save the palette to the output in the specified format
for (uint i = firstIndex; i < firstIndex + numColors; i++) {
- const uint r = (_colors[i].r * rNewMax) / rOrigMax;
- const uint g = (_colors[i].g * gNewMax) / gOrigMax;
- const uint b = (_colors[i].b * bNewMax) / bOrigMax;
+ const uint r = (_colors[i].r * rNewMax) / (rOrigMax == 0 ? 1 : rOrigMax);
+ const uint g = (_colors[i].g * gNewMax) / (gOrigMax == 0 ? 1 : gOrigMax);
+ const uint b = (_colors[i].b * bNewMax) / (bOrigMax == 0 ? 1 : bOrigMax);
buf[i * format.bytesPerPixel + rBytePos] |= r << (format.rShift % 8);
buf[i * format.bytesPerPixel + gBytePos] |= g << (format.gShift % 8);
diff --git a/engines/cruise/debugger.cpp b/engines/cruise/debugger.cpp
index 4ef66ee11e..d4e706a094 100644
--- a/engines/cruise/debugger.cpp
+++ b/engines/cruise/debugger.cpp
@@ -29,9 +29,9 @@
namespace Cruise {
Debugger::Debugger(): GUI::Debugger() {
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("hotspots", WRAP_METHOD(Debugger, cmd_hotspots));
- DCmd_Register("items", WRAP_METHOD(Debugger, cmd_items));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("hotspots", WRAP_METHOD(Debugger, cmd_hotspots));
+ registerCmd("items", WRAP_METHOD(Debugger, cmd_items));
}
/**
@@ -70,7 +70,7 @@ bool Debugger::cmd_hotspots(int argc, const char **argv) {
if (*pObjectName) {
getMultipleObjectParam(currentObject->overlay, currentObject->idx, &params);
- DebugPrintf("%s %s - %d,%d\n", pObjectName, pObjType, params.X, params.Y);
+ debugPrintf("%s %s - %d,%d\n", pObjectName, pObjType, params.X, params.Y);
}
}
@@ -96,7 +96,7 @@ bool Debugger::cmd_items(int argc, const char **argv) {
getSingleObjectParam(i, j, 5, &returnVar);
if (returnVar < -1)
- DebugPrintf("%s\n", getObjectName(j, pOvlData->arrayNameObj));
+ debugPrintf("%s\n", getObjectName(j, pOvlData->arrayNameObj));
}
}
}
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index 4893b0fe34..4fbf2d31ea 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -50,44 +50,46 @@ enum {
};
Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
- uint i;
-
_dialogueLinesNum = 0;
_blockNum = 0;
- for (i = 0; i < kDialogueLines; i++)
- _dialogueAnims[0] = 0;
+ for (uint i = 0; i < kDialogueLines; i++)
+ _dialogueAnims[0] = nullptr;
_loopStatus = kStatusOrdinary;
_loopSubstatus = kOuterLoop;
- _shouldQuit = 0;
- _shouldExitLoop = 0;
- _isReloaded = 0;
_speechTick = 0;
_speechDuration = 0;
- _objUnderCursor = 0;
- _animUnderCursor = 0;
_markedAnimationIndex = 0;
_scheduledPalette = 0;
_fadePhases = 0;
_fadePhase = 0;
_fadeTick = 0;
- _isFadeOut = 1;
_mouseChangeTick = 0;
- _enableQuickHero = 0;
- _wantQuickHero = 0;
- _enableSpeedText = 0;
- _titleAnim = 0;
- _inventoryAnim = 0;
- _walkingMapOverlay = 0;
- _walkingShortestPathOverlay = 0;
- _walkingObliquePathOverlay = 0;
- _currentItem = 0;
- _itemUnderCursor = 0;
_previousItemPosition = 0;
- for (i = 0; i < kInventorySlots; i++)
- _inventory[i] = 0;
+ _shouldQuit = false;
+ _shouldExitLoop = false;
+ _isReloaded = false;
+ _isPositionLoaded = false;
+ _isFadeOut = true;
+ _enableQuickHero = false;
+ _wantQuickHero = false;
+ _enableSpeedText = false;
+ _isPositionLoaded = false;
+
+ _objUnderCursor = nullptr;
+ _animUnderCursor = nullptr;
+ _titleAnim = nullptr;
+ _inventoryAnim = nullptr;
+ _walkingMapOverlay = nullptr;
+ _walkingShortestPathOverlay = nullptr;
+ _walkingObliquePathOverlay = nullptr;
+ _currentItem = nullptr;
+ _itemUnderCursor = nullptr;
+
+ for (int i = 0; i < kInventorySlots; i++)
+ _inventory[i] = nullptr;
_newRoom = 0;
_newGate = 0;
@@ -95,10 +97,10 @@ Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
_pushedNewRoom = 0;
_pushedNewGate = 0;
_currentDialogue = 0;
- _dialogueArchive = 0;
- _dialogueBlocks = 0;
- _dialogueBegin = 0;
- _dialogueExit = 0;
+ _dialogueArchive = nullptr;
+ _dialogueBlocks = nullptr;
+ _dialogueBegin = false;
+ _dialogueExit = false;
_currentBlock = 0;
_lastBlock = 0;
@@ -113,7 +115,7 @@ Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
uint numPersons = file->_length / personSize;
_persons = new Person[numPersons];
- for (i = 0; i < numPersons; ++i) {
+ for (uint i = 0; i < numPersons; ++i) {
_persons[i]._x = personData.readUint16LE();
_persons[i]._y = personData.readUint16LE();
_persons[i]._fontColor = personData.readByte();
@@ -126,9 +128,9 @@ Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
uint numDialogues = file->_length / sizeof(uint16);
_dialogueOffsets = new uint[numDialogues];
- uint curOffset;
- for (i = 0, curOffset = 0; i < numDialogues; ++i) {
- _dialogueOffsets[i] = curOffset;
+ uint curOffset, idx;
+ for (idx = 0, curOffset = 0; idx < numDialogues; ++idx) {
+ _dialogueOffsets[idx] = curOffset;
curOffset += dialogueData.readUint16LE();
}
@@ -163,7 +165,7 @@ Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
_variables = new int[numVariables];
Common::MemoryReadStream variableData(file->_data, file->_length);
- for (i = 0; i < numVariables; ++i) {
+ for (uint i = 0; i < numVariables; ++i) {
_variables[i] = variableData.readUint16LE();
}
@@ -181,7 +183,7 @@ Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
_objects = new GameObject[numObjects];
Common::MemoryReadStream objStatus(file->_data, file->_length);
- for (i = 0; i < numObjects; ++i) {
+ for (uint i = 0; i < numObjects; ++i) {
byte tmp = objStatus.readByte();
// Set object visibility
@@ -251,14 +253,14 @@ void Game::init() {
setLoopStatus(kStatusGate);
setLoopSubstatus(kOuterLoop);
- _animUnderCursor = NULL;
+ _animUnderCursor = nullptr;
- _currentItem = _itemUnderCursor = NULL;
+ _currentItem = _itemUnderCursor = nullptr;
_previousItemPosition = -1;
_vm->_mouse->setCursorType(kHighlightedCursor); // anything different from kNormalCursor
- _objUnderCursor = NULL;
+ _objUnderCursor = nullptr;
// Set the inventory to empty initially
memset(_inventory, 0, kInventorySlots * sizeof(GameItem *));
@@ -402,12 +404,12 @@ void Game::handleInventoryLoop() {
// an overlay, for which we check. Item animations have their IDs
// calculated by offseting their itemID from the ID of the last "special"
// animation ID. In this way, we obtain its itemID.
- if (_animUnderCursor != NULL && _animUnderCursor != _inventoryAnim && _animUnderCursor->getID() != kOverlayImage) {
+ if (_animUnderCursor != nullptr && _animUnderCursor != _inventoryAnim && _animUnderCursor->getID() != kOverlayImage) {
_itemUnderCursor = getItem(kInventoryItemsID - _animUnderCursor->getID());
- assert(_itemUnderCursor != NULL);
+ assert(_itemUnderCursor != nullptr);
assert(_itemUnderCursor->_anim == _animUnderCursor);
} else {
- _itemUnderCursor = NULL;
+ _itemUnderCursor = nullptr;
}
// If the user pressed the left mouse button
@@ -824,7 +826,7 @@ void Game::removeItem(GameItem *item) {
return;
for (uint i = 0; i < kInventorySlots; ++i) {
if (_inventory[i] == item) {
- _inventory[i] = NULL;
+ _inventory[i] = nullptr;
item->_anim->stop();
break;
}
@@ -931,7 +933,7 @@ void Game::inventoryDone() {
_walkingState.callbackLast();
// Reset item under cursor
- _itemUnderCursor = NULL;
+ _itemUnderCursor = nullptr;
// Don't start the inventory mode again if the mouse is on the top.
_mouseChangeTick = kMouseDoNotSwitch;
@@ -1640,7 +1642,7 @@ void Game::DoSync(Common::Serializer &s, uint8 saveVersion) {
_currentItem = getItem(handItemID);
}
} else {
- _currentItem = 0;
+ _currentItem = nullptr;
}
}
diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp
index 6914898ec1..04cd929ac6 100644
--- a/engines/draci/walking.cpp
+++ b/engines/draci/walking.cpp
@@ -453,7 +453,7 @@ void WalkingState::callback() {
_callback = NULL;
_vm->_script->runWrapper(originalCallback, _callbackOffset, true, false);
_callbackLast = NULL;
- _callbackOffset = NULL;
+ _callbackOffset = 0;
}
void WalkingState::callbackLast() {
diff --git a/engines/drascula/console.cpp b/engines/drascula/console.cpp
index 50e96c8757..b545c096d0 100644
--- a/engines/drascula/console.cpp
+++ b/engines/drascula/console.cpp
@@ -27,7 +27,7 @@
namespace Drascula {
Console::Console(DrasculaEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room));
+ registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
}
Console::~Console() {
@@ -35,7 +35,7 @@ Console::~Console() {
bool Console::Cmd_Room(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: room <number>\n");
+ debugPrintf("Usage: room <number>\n");
return true;
}
diff --git a/engines/fullpipe/console.cpp b/engines/fullpipe/console.cpp
index cb76345d66..dd3d1bf693 100644
--- a/engines/fullpipe/console.cpp
+++ b/engines/fullpipe/console.cpp
@@ -28,14 +28,14 @@
namespace Fullpipe {
Console::Console(FullpipeEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("scene", WRAP_METHOD(Console, Cmd_Scene));
+ registerCmd("scene", WRAP_METHOD(Console, Cmd_Scene));
}
bool Console::Cmd_Scene(int argc, const char **argv) {
if (argc != 2) {
int sceneTag = _vm->_currentScene->_sceneId;
- DebugPrintf("Current scene: %d (scene tag: %d)\n", _vm->getSceneFromTag(sceneTag), sceneTag);
- DebugPrintf("Use %s <scene> to change the current scene\n", argv[0]);
+ debugPrintf("Current scene: %d (scene tag: %d)\n", _vm->getSceneFromTag(sceneTag), sceneTag);
+ debugPrintf("Use %s <scene> to change the current scene\n", argv[0]);
return true;
} else {
int scene = _vm->convertScene(atoi(argv[1]));
diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp
index 62c5dd3b80..de0ed04d25 100644
--- a/engines/fullpipe/detection.cpp
+++ b/engines/fullpipe/detection.cpp
@@ -26,6 +26,7 @@
#include "common/file.h"
#include "fullpipe/fullpipe.h"
+#include "fullpipe/gameloader.h"
namespace Fullpipe {
@@ -87,15 +88,72 @@ public:
}
virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual int getMaximumSaveSlot() const { return 8; }
+ virtual SaveStateList listSaves(const char *target) const;
+ virtual void removeSaveState(const char *target, int slot) const;
+ virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
};
bool FullpipeMetaEngine::hasFeature(MetaEngineFeature f) const {
- return false;
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSavesSupportCreationDate) ||
+ (f == kSupportsLoadingDuringStartup);
}
-bool Fullpipe::FullpipeEngine::hasFeature(EngineFeature f) const {
- return false;
+SaveStateList FullpipeMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String pattern("fullpipe.s??");
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(*file);
+ if (in) {
+ Fullpipe::FullpipeSavegameHeader header;
+ Fullpipe::readSavegameHeader(in, header);
+ saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
+ delete header.thumbnail;
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+void FullpipeMetaEngine::removeSaveState(const char *target, int slot) const {
+ g_system->getSavefileManager()->removeSavefile(Fullpipe::getSavegameFile(slot));
+}
+
+SaveStateDescriptor FullpipeMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(
+ Fullpipe::getSavegameFile(slot));
+
+ if (f) {
+ Fullpipe::FullpipeSavegameHeader header;
+ Fullpipe::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header.saveName);
+ desc.setThumbnail(header.thumbnail);
+
+ return desc;
+ }
+
+ return SaveStateDescriptor();
}
bool FullpipeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 5369c05de7..85a5167841 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -37,6 +37,7 @@
#include "fullpipe/scenes.h"
#include "fullpipe/floaters.h"
#include "fullpipe/console.h"
+#include "fullpipe/constants.h"
namespace Fullpipe {
@@ -205,7 +206,39 @@ void FullpipeEngine::initialize() {
}
void FullpipeEngine::restartGame() {
- warning("STUB: FullpipeEngine::restartGame()");
+ _floaters->stopAll();
+
+ clearGlobalMessageQueueList();
+ clearMessages();
+
+ initObjectStates();
+
+ if (_scene2) {
+ _scene2->getAniMan();
+ _scene2 = 0;
+ }
+
+ if (_currentScene) {
+ _gameLoader->unloadScene(_currentScene->_sceneId);
+
+ _currentScene = 0;
+ }
+
+ _gameLoader->restoreDefPicAniInfos();
+
+ getGameLoaderInventory()->clear();
+ getGameLoaderInventory()->addItem(ANI_INV_MAP, 1);
+ getGameLoaderInventory()->rebuildItemRects();
+
+ initMap();
+
+ if (_flgPlayIntro) {
+ _gameLoader->loadScene(SC_INTRO1);
+ _gameLoader->gotoScene(SC_INTRO1, TrubaUp);
+ } else {
+ _gameLoader->loadScene(SC_1);
+ _gameLoader->gotoScene(SC_1, TrubaLeft);
+ }
}
Common::Error FullpipeEngine::run() {
@@ -347,7 +380,7 @@ void FullpipeEngine::updateEvents() {
case Common::EVENT_QUIT:
_gameContinue = false;
break;
- case Common::EVENT_RBUTTONDOWN:
+ 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;
@@ -477,7 +510,20 @@ void FullpipeEngine::setObjectState(const char *name, int state) {
}
void FullpipeEngine::disableSaves(ExCommand *ex) {
- warning("STUB: FullpipeEngine::disableSaves()");
+ if (_isSaveAllowed) {
+ _isSaveAllowed = false;
+
+ if (_globalMessageQueueList->size() && (*_globalMessageQueueList)[0] != 0) {
+ for (int i = 0; i < _globalMessageQueueList->size(); i++) {
+ if ((*_globalMessageQueueList)[i]->_flags & 1)
+ if ((*_globalMessageQueueList)[i]->_id != ex->_parId && !(*_globalMessageQueueList)[i]->_isFinished)
+ return;
+ }
+ }
+
+ if (_currentScene)
+ _gameLoader->writeSavegame(_currentScene, "savetmp.sav");
+ }
}
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 27505252ab..afdc493258 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -99,7 +99,6 @@ public:
const ADGameDescription *_gameDescription;
const char *getGameId() const;
Common::Platform getPlatform() const;
- bool hasFeature(EngineFeature f) const;
Common::RandomSource *_rnd;
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index d9f7327a6b..c8b01939dd 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -21,6 +21,7 @@
*/
#include "fullpipe/fullpipe.h"
+#include "graphics/thumbnail.h"
#include "fullpipe/gameloader.h"
#include "fullpipe/scene.h"
@@ -501,6 +502,14 @@ void GameLoader::updateSystems(int counterdiff) {
}
}
+void GameLoader::readSavegame(const char *fname) {
+ warning("STUB: readSavegame(%s)", fname);
+}
+
+void GameLoader::writeSavegame(Scene *sc, const char *fname) {
+ warning("STUB: writeSavegame(sc, %s)", fname);
+}
+
Sc2::Sc2() {
_sceneId = 0;
_field_2 = 0;
@@ -593,6 +602,42 @@ bool PreloadItems::load(MfcArchive &file) {
return true;
}
+const char *getSavegameFile(int saveGameIdx) {
+ static char buffer[20];
+ sprintf(buffer, "fullpipe.s%02d", saveGameIdx);
+ return buffer;
+}
+
+bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) {
+ char saveIdentBuffer[6];
+ header.thumbnail = NULL;
+
+ // Validate the header Id
+ in->read(saveIdentBuffer, 6);
+ if (strcmp(saveIdentBuffer, "SVMCR"))
+ return false;
+
+ header.version = in->readByte();
+ if (header.version != FULLPIPE_SAVEGAME_VERSION)
+ return false;
+
+ // Read in the string
+ header.saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0') header.saveName += ch;
+
+ // Get the thumbnail
+ header.thumbnail = Graphics::loadThumbnail(*in);
+ if (!header.thumbnail)
+ return false;
+
+ return true;
+}
+
+void GameLoader::restoreDefPicAniInfos() {
+ warning("STUB: restoreDefPicAniInfos()");
+}
+
GameVar *FullpipeEngine::getGameLoaderGameVar() {
if (_gameLoader)
return _gameLoader->_gameVar;
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index a79c0e11b4..772cc51130 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -29,6 +29,8 @@
namespace Fullpipe {
+#define FULLPIPE_SAVEGAME_VERSION 1
+
class SceneTag;
class MctlCompound;
class InputController;
@@ -72,6 +74,12 @@ class PreloadItems : public Common::Array<PreloadItem *>, public CObject {
virtual bool load(MfcArchive &file);
};
+struct FullpipeSavegameHeader {
+ uint8 version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+};
+
class GameLoader : public CObject {
public:
GameLoader();
@@ -89,6 +97,11 @@ class GameLoader : public CObject {
void applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAniInfoCount);
void saveScenePicAniInfos(int sceneId);
+ void readSavegame(const char *fname);
+ void writeSavegame(Scene *sc, const char *fname);
+
+ void restoreDefPicAniInfos();
+
GameProject *_gameProject;
InteractionController *_interactionController;
InputController *_inputController;
@@ -108,6 +121,9 @@ class GameLoader : public CObject {
int _preloadEntranceId;
};
+const char *getSavegameFile(int saveGameIdx);
+bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header);
+
Inventory2 *getGameLoaderInventory();
InteractionController *getGameLoaderInteractionController();
MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId);
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 7c66a9a747..520e81835b 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -145,7 +145,7 @@ void Background::addPictureObject(PictureObject *pct) {
bool inserted = false;
for (uint i = 1; i < _picObjList.size(); i++) {
- if (((PictureObject *)_picObjList[i])->_priority <= pct->_priority) {
+ if (_picObjList[i]->_priority <= pct->_priority) {
_picObjList.insert_at(i, pct);
inserted = true;
break;
@@ -192,7 +192,7 @@ bool PictureObject::load(MfcArchive &file, bool bigPicture) {
_picture->load(file);
- _pictureObject2List = new PtrList();
+ _pictureObject2List = new Common::Array<GameObject *>;
int count = file.readUint16LE();
@@ -351,7 +351,25 @@ void GameObject::setOXY(int x, int y) {
_oy = y;
}
-void GameObject::renumPictures(PtrList *lst) {
+void GameObject::renumPictures(Common::Array<StaticANIObject *> *lst) {
+ int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
+
+ for (uint i = 0; i < lst->size(); i++) {
+ if (_id == ((GameObject *)((*lst)[i]))->_id)
+ buf[((GameObject *)((*lst)[i]))->_okeyCode] = 1;
+ }
+
+ if (buf[_okeyCode]) {
+ uint count;
+ for (count = 1; buf[count] && count < lst->size() + 2; count++)
+ ;
+ _okeyCode = count;
+ }
+
+ free(buf);
+}
+
+void GameObject::renumPictures(Common::Array<PictureObject *> *lst) {
int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
for (uint i = 0; i < lst->size(); i++) {
@@ -380,6 +398,7 @@ bool GameObject::getPicAniInfo(PicAniInfo *info) {
info->ox = _ox;
info->oy = _oy;
info->priority = _priority;
+ warning("Yep %d", _id);
return true;
}
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index b3e22b610b..191df7709a 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -92,7 +92,7 @@ class Picture : public MemoryObject {
virtual bool load(MfcArchive &file);
void setAOIDs();
- void init();
+ virtual void init();
void getDibInfo();
Bitmap *getPixelData();
virtual void draw(int x, int y, int style, int angle);
@@ -141,7 +141,8 @@ class GameObject : public CObject {
virtual bool load(MfcArchive &file);
void setOXY(int x, int y);
- void renumPictures(PtrList *lst);
+ void renumPictures(Common::Array<StaticANIObject *> *lst);
+ void renumPictures(Common::Array<PictureObject *> *lst);
void setFlags(int16 flags) { _flags = flags; }
void clearFlags() { _flags = 0; }
const char *getName() { return _objectName; }
@@ -153,7 +154,7 @@ class GameObject : public CObject {
class PictureObject : public GameObject {
public:
Picture *_picture;
- PtrList *_pictureObject2List;
+ Common::Array<GameObject *> *_pictureObject2List;
int _ox2;
int _oy2;
@@ -178,7 +179,7 @@ class PictureObject : public GameObject {
class Background : public CObject {
public:
- PtrList _picObjList;
+ Common::Array<PictureObject *> _picObjList;
char *_bgname;
int _x;
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
index 15aa78d342..d4f79d1dd8 100644
--- a/engines/fullpipe/messagehandlers.cpp
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -392,12 +392,10 @@ int global_messageHandler3(ExCommand *cmd) {
}
return result;
case 29:
- if (!g_fp->_currentScene)
- return result;
-
- if (g_fp->_gameLoader->_interactionController->_flag24) {
+ if (g_fp->_gameLoader->_interactionController->_flag24 && g_fp->_currentScene) {
ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
ani2 = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1);
+
if (ani) {
if (g_fp->_msgObjectId2 == ani->_id && g_fp->_msgId == ani->_okeyCode) {
cmd->_messageKind = 0;
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 8257d1459f..b643ff9b8f 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -26,6 +26,7 @@
#include "fullpipe/messages.h"
#include "fullpipe/modal.h"
#include "fullpipe/statics.h"
+#include "fullpipe/gameloader.h"
namespace Fullpipe {
@@ -394,8 +395,18 @@ void MessageQueue::update() {
}
void MessageQueue::messageQueueCallback1(int par) {
- // Autosave
- debug(3, "STUB: MessageQueue::messageQueueCallback1()");
+ if (g_fp->_isSaveAllowed && par == 16) {
+ if (g_fp->_globalMessageQueueList->size() && (*g_fp->_globalMessageQueueList)[0] != 0) {
+ for (int i = 0; i < g_fp->_globalMessageQueueList->size(); i++) {
+ if ((*g_fp->_globalMessageQueueList)[i]->_flags & 1)
+ if ((*g_fp->_globalMessageQueueList)[i] != this && !(*g_fp->_globalMessageQueueList)[i]->_isFinished)
+ return;
+ }
+ }
+
+ if (g_fp->_currentScene)
+ g_fp->_gameLoader->writeSavegame(g_fp->_currentScene, "savetmp.sav");
+ }
}
void MessageQueue::addExCommand(ExCommand *ex) {
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index bba5df0cd5..8981cdb8e6 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -34,6 +34,8 @@
#include "graphics/palette.h"
#include "video/avi_decoder.h"
+#include "engines/savestate.h"
+
namespace Fullpipe {
ModalIntro::ModalIntro() {
@@ -1084,17 +1086,17 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
b = 800 - dx;
}
- int32 pp = b * a; //(0x51EB851F * b * a) >> 32) >> 8; // TODO FIXME
+ int32 pp = b * a;
- snd->setPanAndVolume(pan + (pp >> 31) + pp, par);
+ snd->setPanAndVolume(pan + pp / 800, par);
return;
}
int dx = _screct.left - ani->_ox;
if (dx <= 800) {
- int32 s = 0x51EB851F * (800 - dx) * (g_fp->_sfxVolume - (-3500)); // TODO FIXME
- int32 p = -3500 + (s >> 31) + (s >> 8);
+ int32 s = (800 - dx) * (g_fp->_sfxVolume - (-3500));
+ int32 p = -3500 + s / 800;
if (p > g_fp->_sfxVolume)
p = g_fp->_sfxVolume;
@@ -1103,8 +1105,6 @@ void ModalMainMenu::updateSoundVolume(Sound *snd) {
} else {
snd->setPanAndVolume(-3500, 0);
}
-
- warning("STUB: ModalMainMenu::updateSoundVolume()");
}
void ModalMainMenu::updateSliderPos() {
@@ -1460,6 +1460,8 @@ ModalSaveGame::ModalSaveGame() {
_rect = g_fp->_sceneRect;
_queryDlg = 0;
_mode = 1;
+
+ _objtype = kObjTypeModalSaveGame;
}
ModalSaveGame::~ModalSaveGame() {
@@ -1591,9 +1593,9 @@ void ModalSaveGame::setup(Scene *sc, int mode) {
fileinfo = new FileInfo;
memset(fileinfo, 0, sizeof(FileInfo));
- snprintf(fileinfo->filename, 160, "save%02d.sav", i);
+ strncpy(fileinfo->filename, getSavegameFile(i), 160);
- if (!getFileInfo(fileinfo->filename, fileinfo)) {
+ if (!getFileInfo(i, fileinfo)) {
fileinfo->empty = true;
w = _emptyD->getDimensions(&point)->x;
} else {
@@ -1623,12 +1625,175 @@ char *ModalSaveGame::getSaveName() {
return _files[_queryRes]->filename;
}
-bool ModalSaveGame::getFileInfo(char *filename, FileInfo *fileinfo) {
- warning("STUB: ModalSaveGame::getFileInfo()");
+bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(
+ Fullpipe::getSavegameFile(slot));
+
+ if (!f)
+ return false;
+
+ Fullpipe::FullpipeSavegameHeader header;
+ Fullpipe::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header.saveName);
+ char res[17];
+
+ snprintf(res, 17, "%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str());
+
+ for (int i = 0; i < 16; i++) {
+ switch(res[i]) {
+ case '.':
+ fileinfo->date[i] = 11;
+ break;
+ case ' ':
+ fileinfo->date[i] = 12;
+ break;
+ case ':':
+ fileinfo->date[i] = 10;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ fileinfo->date[i] = res[i] - '0';
+ break;
+ default:
+ error("Incorrect date format: %s", res);
+ }
+ }
+
+ return true;
+}
+
+void ModalSaveGame::update() {
+ if (_menuScene)
+ _menuScene->draw();
+
+ _bgr->draw();
+
+ if (_queryDlg) {
+ _queryDlg->update();
+
+ return;
+ }
+
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+
+ g_fp->setCursor(g_fp->_cursorId);
+
+ Common::Point point;
+
+ for (uint i = 0; i < _files.size(); i++) {
+ if (g_fp->_mouseScreenPos.x < _files[i]->fx1 || g_fp->_mouseScreenPos.x > _files[i]->fx2 ||
+ g_fp->_mouseScreenPos.y < _files[i]->fy1 || g_fp->_mouseScreenPos.y > _files[i]->fy2 ) {
+ if (_files[i]->empty) {
+ _emptyD->setOXY(_files[i]->fx1, _files[i]->fy1);
+ _emptyD->draw();
+ } else {
+ int x = _files[i]->fx1;
+
+ for (int j = 0; j < 16; j++) {
+ _arrayL[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1);
+ _arrayL[_files[i]->date[j]]->draw();
+
+ x += _arrayL[_files[i]->date[j]]->getDimensions(&point)->x + 2;
+ }
+ }
+ } else {
+ if (_files[i]->empty) {
+ _emptyL->setOXY(_files[i]->fx1, _files[i]->fy1);
+ _emptyL->draw();
+ } else {
+ int x = _files[i]->fx1;
+
+ for (int j = 0; j < 16; j++) {
+ _arrayD[_files[i]->date[j]]->setOXY(x + 1, _files[i]->fy1);
+ _arrayD[_files[i]->date[j]]->draw();
+
+ x += _arrayD[_files[i]->date[j]]->getDimensions(&point)->x + 2;
+ }
+ }
+ }
+ }
+ if (_cancelL->isPixelHitAtPos(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
+ _cancelL->draw();
+ else if (_okL->isPixelHitAtPos(g_fp->_mouseScreenPos.x, g_fp->_mouseScreenPos.y))
+ _okL->draw();
+}
+
+bool ModalSaveGame::handleMessage(ExCommand *cmd) {
+ if (_queryDlg)
+ return _queryDlg->handleMessage(cmd);
+
+ if (cmd->_messageNum == 29)
+ processMouse(cmd->_x, cmd->_y);
+ else if (cmd->_messageNum == 36)
+ processKey(cmd->_keyCode);
return false;
}
+void ModalSaveGame::processMouse(int x, int y) {
+ for (uint i = 0; i < _files.size(); i++) {
+ if (x >= _files[i]->fx1 && x <= _files[i]->fx2 && y >= _files[i]->fy1 && y <= _files[i]->fy2) {
+ _queryRes = i + 1;
+
+ if (_mode) {
+ if (!_files[i]->empty) {
+ _queryDlg = new ModalQuery;
+
+ _queryDlg->create(_menuScene, 0, PIC_MOV_BGR);
+ }
+ }
+
+ return;
+ }
+ }
+
+ if (_cancelL->isPixelHitAtPos(x, y))
+ _queryRes = 0;
+}
+
+void ModalSaveGame::saveload() {
+ if (_objtype != kObjTypeModalSaveGame)
+ return;
+
+ if (_mode) {
+ if (getSaveName()) {
+ bool allowed = true;
+
+ for (Common::Array<MessageQueue *>::iterator s = g_fp->_globalMessageQueueList->begin(); s != g_fp->_globalMessageQueueList->end(); ++s) {
+ if (!(*s)->_isFinished && ((*s)->getFlags() & 1))
+ allowed = false;
+ }
+
+ if (g_fp->_isSaveAllowed && allowed)
+ g_fp->_gameLoader->writeSavegame(g_fp->_currentScene, getSaveName());
+ }
+ } else {
+ if (getSaveName()) {
+ if (_parentObj) {
+ delete _parentObj;
+
+ _parentObj = 0;
+ }
+
+ g_fp->stopAllSoundStreams();
+ g_fp->stopSoundStream2();
+
+ g_fp->_gameLoader->readSavegame(getSaveName());
+ }
+ }
+}
+
void FullpipeEngine::openHelp() {
if (!_modalObject) {
ModalHelp *help = new ModalHelp;
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index a214b1c639..01d8e6b0ee 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -32,10 +32,7 @@ class Sound;
struct FileInfo {
char filename[260];
bool empty;
- int day;
- int month;
- int year;
- int time;
+ char date[16];
int fx1;
int fx2;
int fy1;
@@ -46,9 +43,10 @@ class BaseModalObject {
public:
BaseModalObject *_parentObj;
+ ObjType _objtype;
public:
- BaseModalObject() : _parentObj(0) {}
+ BaseModalObject() : _parentObj(0) { _objtype = kObjTypeDefault; }
virtual ~BaseModalObject() {}
@@ -256,17 +254,19 @@ public:
virtual ~ModalSaveGame();
virtual bool pollEvent() { return true; }
- virtual bool handleMessage(ExCommand *message) { return false; }
+ virtual bool handleMessage(ExCommand *message);
virtual bool init(int counterdiff);
- virtual void update() {}
- virtual void saveload() {}
+ virtual void update();
+ virtual void saveload();
+
+ void processMouse(int x, int y);
void setScene(Scene *sc);
void setup(Scene *sc, int mode);
void processKey(int key);
char *getSaveName();
- bool getFileInfo(char *filename, FileInfo *fileinfo);
+ bool getFileInfo(int slot, FileInfo *fileinfo);
Common::Rect _rect;
int _oldBgX;
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index 35da154570..5b7419c7f4 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -125,9 +125,10 @@ void MctlCompound::addObject(StaticANIObject *obj) {
}
int MctlCompound::removeObject(StaticANIObject *obj) {
- warning("STUB: MctlCompound::removeObject()");
+ for (uint i = 0; i < _motionControllers.size(); i++)
+ _motionControllers[i]->_motionControllerObj->removeObject(obj);
- return 0;
+ return 1;
}
void MctlCompound::initMovGraph2() {
@@ -193,7 +194,8 @@ MessageQueue *MctlCompound::method34(StaticANIObject *ani, int sourceX, int sour
if (idx == sourceIdx)
return _motionControllers[idx]->_motionControllerObj->method34(ani, sourceX, sourceY, fuzzyMatch, staticsId);
- MctlConnectionPoint *cp = findClosestConnectionPoint(ani->_ox, ani->_oy, idx, sourceX, sourceY, sourceIdx, &sourceIdx);
+ double dist;
+ MctlConnectionPoint *cp = findClosestConnectionPoint(ani->_ox, ani->_oy, idx, sourceX, sourceY, sourceIdx, &dist);
if (!cp)
return 0;
@@ -261,7 +263,8 @@ MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos,
if (match1 == match2)
return _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId);
- MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &match2);
+ double dist;
+ MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &dist);
if (!closestP)
return 0;
@@ -427,14 +430,75 @@ MessageQueue *MctlLadder::controllerWalkTo(StaticANIObject *ani, int off) {
return doWalkTo(ani, _ladderX + off * _width, _ladderY + off * _height, 1, 0);
}
-MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr) {
+MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, double *minDistancePtr) {
+#if 0
+ if (destIndex == sourceIndex) {
+ *minDistancePtr = sqrt((double)((oy - connectionY) * (oy - connectionY) + (ox - connectionX) * (ox - connectionX)));
+
+ return 0;
+ }
+
+ v11 = this->_motionControllers.m_pData;
+ currDistance = 0.0;
+ v12 = 0;
+ v13 = (MctlCompoundArrayItem *)*(&v11->vmt + sourceIndex);
+ minDistance = 1.0e10;
+ minConnectionPoint = 0;
+ if (v13->mctlConnectionPointsArray.CObArray.m_nSize > 0) {
+ do {
+ v14 = 0;
+ for (currMctlIndex = 0; v14 < this->_motionControllers.m_nSize; currMctlIndex = v14) {
+ v15 = this->_motionControllers.m_pData;
+ v16 = *(MovGraphReact **)(*(&v15->vmt + v14) + offsetof(MctlCompoundArrayItem, movGraphReactObj));
+ if (v16) {
+ v17 = *(MctlConnectionPoint **)(*(_DWORD *)(*(&v15->vmt + sourceIndex) + 0x10) + 4 * v12);// MctlCompoundArrayItem.mctlConnectionPointsArray.CObArray.m_pData
+ LOBYTE(v18) = (*(bool (__thiscall **)(MovGraphReact *, int, int))(v16->CObject.vmt + offsetof(MovGraphReactVmt, pointInRegion)))(v16, v17->_connectionX, v17->_connectionY);
+ if (v18) {
+ v14 = currMctlIndex;
+ v19 = *(MctlConnectionPoint **)(*(_DWORD *)(*(&this->_motionControllers.m_pData->vmt + sourceIndex) + 0x10) + 4 * v12);
+ v20 = MctlCompound_findClosestConnectionPoint(this, ox, oy, destIndex, v19->_connectionX, v19->_connectionY, currMctlIndex, (int *)&currDistance);
+ if (currDistance < minDistance) {
+ minDistance = currDistance;
+ if (v20)
+ minConnectionPoint = v20;
+ else
+ minConnectionPoint = *(MctlConnectionPoint **)(*(_DWORD *)(*(&this->_motionControllers.m_pData->vmt + sourceIndex) + 0x10) + 4 * v12);
+ }
+ } else {
+ v14 = currMctlIndex;
+ }
+ }
+ ++v14;
+ }
+ ++v12;
+ } while (v12 < *(_DWORD *)(*(&this->_motionControllers.m_pData->vmt + sourceIndex) + 0x14)); // MctlCompoundArrayItem.mctlConnectionPointsArray.CObArray.m_nSize
+ }
+
+ *minDistancePtr = minDistance;
+
+ return minConnectionPoint;
+}
+#endif
warning("STUB: MctlCompound::findClosestConnectionPoint()");
return 0;
}
void MctlCompound::replaceNodeX(int from, int to) {
- warning("STUB: MctlCompound::replaceNodeX()");
+ for (uint i = 0; i < _motionControllers.size(); i++) {
+ if (_motionControllers[i]->_motionControllerObj->_objtype == kObjTypeMovGraph) {
+ MovGraph *gr = (MovGraph *)_motionControllers[i]->_motionControllerObj;
+
+ for (ObList::iterator n = gr->_nodes.begin(); n != gr->_nodes.end(); ++n) {
+ MovGraphNode *node = (MovGraphNode *)*n;
+
+ if (node->_x == from)
+ node->_x = to;
+ }
+
+ gr->calcNodeDistancesAndAngles();
+ }
+ }
}
MctlConnectionPoint::MctlConnectionPoint() {
@@ -493,15 +557,7 @@ bool MctlCompoundArray::load(MfcArchive &file) {
MovGraphItem::MovGraphItem() {
ani = 0;
field_4 = 0;
- field_8 = 0;
- field_C = 0;
- field_10 = 0;
- field_14 = 0;
- field_18 = 0;
- field_1C = 0;
- field_20 = 0;
- field_24 = 0;
- items = 0;
+ movitems = 0;
count = 0;
field_30 = 0;
field_34 = 0;
@@ -509,16 +565,36 @@ MovGraphItem::MovGraphItem() {
field_3C = 0;
}
+void MovGraphItem::free() {
+ for (uint i = 0; i < movitems->size(); i++) {
+ (*movitems)[i]->movarr->_movSteps.clear();
+ delete (*movitems)[i]->movarr;
+ }
+
+ delete movitems;
+
+ movitems = 0;
+}
+
int MovGraph_messageHandler(ExCommand *cmd);
-int MovGraphCallback(int a1, int a2, int a3) {
- warning("STUB: MovgraphCallback");
+MovArr *movGraphCallback(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter) {
+ int residx = 0;
+ int itemidx = 0;
- return 0;
+ while (counter > 1) {
+ if ((*items)[itemidx]->_mfield_4 > (*items)[itemidx + 1]->_mfield_4)
+ residx = itemidx;
+
+ counter--;
+ itemidx++;
+ }
+
+ return (*items)[residx]->movarr;
}
MovGraph::MovGraph() {
- _callback1 = MovGraphCallback;
+ _callback1 = movGraphCallback;
_field_44 = 0;
insertMessageHandler(MovGraph_messageHandler, getMessageHandlersCount() - 1, 129);
@@ -562,54 +638,482 @@ int MovGraph::removeObject(StaticANIObject *obj) {
}
void MovGraph::freeItems() {
- warning("STUB: MovGraph::freeItems()");
+ for (uint i = 0; i < _items.size(); i++) {
+ _items[i]->free();
+
+ _items[i]->movarr._movSteps.clear();
+ }
+
+ _items.clear();
}
+Common::Array<MovItem *> *MovGraph::method28(StaticANIObject *ani, int x, int y, int flag1, int *rescount) {
+ *rescount = 0;
+
+ if (_items.size() <= 0)
+ return 0;
+
+ int idx = 0;
-int MovGraph::method28() {
- warning("STUB: MovGraph::method28()");
+ while (_items[idx]->ani != ani) {
+ idx++;
+
+ if (idx >= _items.size())
+ return 0;
+ }
+ _items[idx]->free();
+
+ calcNodeDistancesAndAngles();
+
+ _items[idx]->movarr._movSteps.clear();
+
+ Common::Point point;
+
+ point.x = ani->_ox;
+ point.y = ani->_oy;
+
+ if (!calcChunk(idx, ani->_ox, ani->_oy, &_items[idx]->movarr, 0))
+ findClosestLink(idx, &point, &_items[idx]->movarr);
+
+ _items[idx]->count = 0;
+
+ delete _items[idx]->movitems;
+ _items[idx]->movitems = 0;
+
+ int arrSize;
+ Common::Array<MovArr *> *movarr = genMovArr(x, y, &arrSize, flag1, 0);
+
+ if (movarr) {
+ for (int i = 0; i < arrSize; i++) {
+ int sz;
+ Common::Array<MovItem *> *movitems = calcMovItems(&_items[idx]->movarr, (*movarr)[i], &sz);
+
+ if (sz > 0) {
+ for (uint j = 0; j < sz; j++)
+ _items[idx]->movitems->push_back(movitems[j]);
+
+ delete movitems;
+ }
+ }
+
+ delete movarr;
+ }
+
+ if (_items[idx]->count) {
+ *rescount = _items[idx]->count;
+
+ return _items[idx]->movitems;
+ }
return 0;
}
-int MovGraph::method2C(StaticANIObject *obj, int x, int y) {
+bool MovGraph::method2C(StaticANIObject *obj, int x, int y) {
obj->setOXY(x, y);
return method3C(obj, 1);
}
-MessageQueue *MovGraph::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
- warning("STUB: MovGraph::method34()");
+MessageQueue *MovGraph::method34(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ if (!ani) {
+ if (!_items.size())
+ return 0;
- return 0;
-}
+ ani = _items[0]->ani;
+ }
+
+ if (ABS(ani->_ox - xpos) < 50 && ABS(ani->_oy - ypos) < 50)
+ return 0;
-int MovGraph::changeCallback() {
- warning("STUB: MovGraph::changeCallback()");
+ if (!ani->isIdle())
+ return 0;
- return 0;
+ if (ani->_flags & 0x100)
+ return 0;
+
+ int count;
+ Common::Array<MovItem *> *movitems = method28(ani, xpos, ypos, fuzzyMatch, &count);
+
+ if (!movitems)
+ return 0;
+
+ if (ani->_movement) {
+ Common::Point point;
+
+ ani->calcStepLen(&point);
+
+ MessageQueue *mq = sub1(ani, ani->_ox - point.x, ani->_oy - point.y, ani->_movement->_staticsObj1->_staticsId, xpos, ypos, 0, fuzzyMatch);
+
+ if (!mq || !mq->getExCommandByIndex(0))
+ return 0;
+
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if ((ex->_messageKind != 1 && ex->_messageKind != 20) || ex->_messageNum != ani->_movement->_id ||
+ (ex->_field_14 >= 1 && ex->_field_14 <= ani->_movement->_currDynamicPhaseIndex)) {
+ mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ex = new ExCommand(ani->_id, 21, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = ani->_okeyCode;
+ ex->_field_3C = 1;
+ ex->_field_24 = 0;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ani->_id, 51, 0, xpos, ypos, 0, 1, 0, 0, 0);
+ ex->_keyCode = ani->_okeyCode;
+ ex->_field_3C = 1;
+ ex->_field_24 = 0;
+ ex->_field_20 = fuzzyMatch;
+ mq->addExCommandToEnd(ex);
+
+ if (mq->chain(0))
+ return mq;
+
+ delete mq;
+
+ return 0;
+ }
+
+ int count2;
+
+ ani->setSomeDynamicPhaseIndex(ex->_field_14);
+ method28(ani, xpos, ypos, fuzzyMatch, &count2);
+
+ int idx = getItemIndexByStaticAni(ani);
+ count = _items[idx]->count;
+ movitems = _items[idx]->movitems;
+ }
+
+ return method50(ani, _callback1(ani, movitems, count), staticsId);
}
-int MovGraph::method3C(StaticANIObject *ani, int flag) {
- warning("STUB: MovGraph::method3C()");
+void MovGraph::changeCallback(MovArr *(*callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter)) {
+ _callback1 = callback1;
+}
- return 0;
+bool MovGraph::method3C(StaticANIObject *ani, int flag) {
+ int idx = getItemIndexByStaticAni(ani);
+
+ if (idx == -1)
+ return false;
+
+ Common::Point point;
+ MovArr movarr;
+
+ point.x = ani->_ox;
+ point.y = ani->_oy;
+
+ findClosestLink(idx, &point, &movarr);
+ ani->setOXY(point.x, point.y);
+
+ if (flag) {
+ Statics *st;
+
+ if (ani->_statics) {
+ int t = _mgm.refreshOffsets(ani->_id, ani->_statics->_staticsId, movarr._link->_dwordArray2[_field_44]);
+ if (t > _mgm.refreshOffsets(ani->_id, ani->_statics->_staticsId, movarr._link->_dwordArray2[_field_44 + 1]))
+ st = ani->getStaticsById(movarr._link->_dwordArray2[_field_44 + 1]);
+ else
+ st = ani->getStaticsById(movarr._link->_dwordArray2[_field_44]);
+ } else {
+ ani->stopAnim_maybe();
+ st = ani->getStaticsById(movarr._link->_dwordArray2[_field_44]);
+ }
+
+ ani->_statics = st;
+ }
+
+ return true;
}
-int MovGraph::method44() {
- warning("STUB: MovGraph::method44()");
+bool MovGraph::method44(StaticANIObject *ani, int x, int y) {
+ int idx = getItemIndexByStaticAni(ani);
+ MovArr m;
- return 0;
+ if (idx != -1) {
+ if (x != -1 || y != -1) {
+ int counter;
+
+ Common::Array<MovItem *> *movitem = method28(ani, x, y, 0, &counter);
+
+ if (movitem) {
+ MovArr *movarr = _callback1(ani, movitem, counter);
+ int cnt = movarr->_movStepCount;
+
+ if (cnt > 0) {
+ if (movarr->_movSteps[cnt - 1]->link->_flags & 0x4000000)
+ return true;
+ }
+ }
+ } else if (calcChunk(idx, ani->_ox, ani->_oy, &m, 0) && m._link && (m._link->_flags & 0x4000000)) {
+ return true;
+ }
+ }
+
+ return false;
}
MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
- warning("STUB: MovGraph::doWalkTo()");
+ PicAniInfo picAniInfo;
+ int ss;
+
+ Common::Array<MovItem *> *movitem = method28(subj, xpos, ypos, fuzzyMatch, &ss);
+
+ subj->getPicAniInfo(&picAniInfo);
+
+ if (movitem) {
+ MovArr *goal = _callback1(subj, movitem, ss);
+ int idx = getItemIndexByStaticAni(subj);
+
+ for (int i = 0; i < _items[idx]->count; i++) {
+ if ((*_items[idx]->movitems)[i]->movarr == goal) {
+ if (subj->_movement) {
+ Common::Point point;
+
+ subj->calcStepLen(&point);
+
+ MessageQueue *mq = sub1(subj, subj->_ox - point.x, subj->_oy - point.y, subj->_movement->_staticsObj1->_staticsId, xpos, ypos, 0, fuzzyMatch);
+
+ if (!mq || !mq->getExCommandByIndex(0))
+ return 0;
+
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if ((ex->_messageKind != 1 && ex->_messageKind != 20) ||
+ ex->_messageNum != subj->_movement->_id ||
+ (ex->_field_14 >= 1 && ex->_field_14 <= subj->_movement->_currDynamicPhaseIndex))
+ subj->playIdle();
+ }
+ }
+ }
+ }
+
+ movitem = method28(subj, xpos, ypos, fuzzyMatch, &ss);
+ if (movitem) {
+ MovArr *goal = _callback1(subj, movitem, ss);
+ int idx = getItemIndexByStaticAni(subj);
+
+ if (_items[idx]->count > 0) {
+ int arridx = 0;
+
+ while ((*_items[idx]->movitems)[arridx]->movarr != goal) {
+ arridx++;
+
+ if (arridx >= _items[idx]->count) {
+ subj->setPicAniInfo(&picAniInfo);
+ return 0;
+ }
+ }
+
+ _items[idx]->movarr._movSteps.clear();
+ _items[idx]->movarr = *(*_items[idx]->movitems)[arridx]->movarr;
+ _items[idx]->movarr._movSteps = (*_items[idx]->movitems)[arridx]->movarr->_movSteps;
+ _items[idx]->movarr._afield_8 = -1;
+ _items[idx]->movarr._link = 0;
+
+ MessageQueue *mq = fillMGMinfo(_items[idx]->ani, &_items[idx]->movarr, staticsId);
+ if (mq) {
+ ExCommand *ex = new ExCommand();
+ ex->_messageKind = 17;
+ ex->_messageNum = 54;
+ ex->_parentId = subj->_id;
+ ex->_field_3C = 1;
+ mq->addExCommandToEnd(ex);
+ }
+ subj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+ }
+ }
+
+ subj->setPicAniInfo(&picAniInfo);
return 0;
}
-int MovGraph::method50() {
- warning("STUB: MovGraph::method50()");
+MessageQueue *MovGraph::sub1(StaticANIObject *ani, int x, int y, int stid, int x1, int y1, int stid2, int flag1) {
+ PicAniInfo picinfo;
- return 0;
+ ani->getPicAniInfo(&picinfo);
+
+ ani->_statics = ani->getStaticsById(stid);
+ ani->_movement = 0;
+ ani->setOXY(x, y);
+
+ int rescount;
+
+ Common::Array<MovItem *> *movitems = method28(ani, x1, y1, flag1, &rescount);
+
+ if (!movitems) {
+ ani->setPicAniInfo(&picinfo);
+
+ return 0;
+ }
+
+ MessageQueue *res = 0;
+
+ MovArr *goal = _callback1(ani, movitems, rescount);
+ int idx = getItemIndexByStaticAni(ani);
+
+ MovGraphItem *movgitem = _items[idx];
+ int cnt = movgitem->count;
+
+ for (int nidx = 0; nidx < cnt; nidx++) {
+ if ((*movgitem->movitems)[nidx]->movarr == goal) {
+ movgitem->movarr._movSteps.clear();
+ _items[idx]->movarr = *(*movgitem->movitems)[nidx]->movarr;
+ _items[idx]->movarr._movSteps = (*movgitem->movitems)[nidx]->movarr->_movSteps;
+ _items[idx]->movarr._afield_8 = -1;
+ _items[idx]->movarr._link = 0;
+
+ res = fillMGMinfo(_items[idx]->ani, &_items[idx]->movarr, stid2);
+ }
+ }
+
+ ani->setPicAniInfo(&picinfo);
+
+ return res;
+}
+
+MessageQueue *MovGraph::fillMGMinfo(StaticANIObject *ani, MovArr *movarr, int staticsId) {
+ if (!movarr->_movStepCount)
+ return 0;
+
+ MessageQueue *mq = 0;
+ int ox = ani->_ox;
+ int oy = ani->_oy;
+ int id1 = 0;
+ int id2;
+
+ for (int i = 0; i < movarr->_movStepCount; i++) {
+ while (i < movarr->_movStepCount - 1) {
+ if (movarr->_movSteps[i ]->link->_dwordArray1[movarr->_movSteps[i - 1]->sfield_0 + _field_44] !=
+ movarr->_movSteps[i + 1]->link->_dwordArray1[movarr->_movSteps[i ]->sfield_0 + _field_44])
+ break;
+ i++;
+ }
+
+ MovStep *st = movarr->_movSteps[i];
+
+ ani->getMovementById(st->link->_dwordArray1[_field_44 + st->sfield_0]);
+
+ if (i == movarr->_movStepCount - 1 && staticsId) {
+ id2 = staticsId;
+ } else {
+ if (i < movarr->_movStepCount - 1)
+ id2 = ani->getMovementById(movarr->_movSteps[i + 1]->link->_dwordArray1[_field_44 + st->sfield_0])->_staticsObj1->_staticsId;
+ else
+ id2 = st->link->_dwordArray2[_field_44 + st->sfield_0];
+ }
+
+ int nx, ny, nd;
+
+ if (i == movarr->_movStepCount - 1) {
+ nx = movarr->_point.x;
+ ny = movarr->_point.y;
+ nd = st->link->_movGraphNode1->_distance;
+ } else {
+ if (st->sfield_0) {
+ nx = st->link->_movGraphNode1->_x;
+ ny = st->link->_movGraphNode1->_y;
+ nd = st->link->_movGraphNode1->_distance;
+ } else {
+ nx = st->link->_movGraphNode2->_x;
+ ny = st->link->_movGraphNode2->_y;
+ nd = st->link->_movGraphNode2->_distance;
+ }
+ }
+
+ MGMInfo mgminfo;
+
+ memset(&mgminfo, 0, sizeof(mgminfo));
+ mgminfo.ani = ani;
+ mgminfo.staticsId2 = id2;
+ mgminfo.staticsId1 = id1;
+ mgminfo.x1 = nx;
+ mgminfo.x2 = ox;
+ mgminfo.y2 = oy;
+ mgminfo.y1 = ny;
+ mgminfo.field_1C = nd;
+ mgminfo.movementId = st->link->_dwordArray1[_field_44 + st->sfield_0];
+
+ mgminfo.flags = 0xe;
+ if (mq)
+ mgminfo.flags |= 0x31;
+
+ MessageQueue *newmq = _mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ if (newmq) {
+ mq->transferExCommands(newmq);
+
+ delete newmq;
+ }
+ } else {
+ mq = newmq;
+ }
+
+ ox = nx;
+ oy = ny;
+ id1 = id2;
+ }
+
+ return mq;
+}
+
+MessageQueue *MovGraph::method50(StaticANIObject *ani, MovArr *movarr, int staticsId) {
+ if (_items.size() == 0)
+ return 0;
+
+ uint idx;
+ int movidx;
+ bool done = false;
+
+ for (idx = 0; idx <= _items.size() && !done; idx++) {
+ if (idx == _items.size())
+ return 0;
+
+ if (_items[idx]->ani == ani) {
+ if (!_items[idx]->movitems)
+ return 0;
+
+ if (_items[idx]->count < 1)
+ return 0;
+
+ for (movidx = 0; movidx < _items[idx]->count; movidx++) {
+ if ((*_items[idx]->movitems)[movidx]->movarr == movarr) {
+ done = true;
+
+ break;
+ }
+ }
+ }
+ }
+
+ _items[idx]->movarr._movSteps.clear();
+ _items[idx]->movarr = *(*_items[idx]->movitems)[movidx]->movarr;
+ _items[idx]->movarr._movSteps = (*_items[idx]->movitems)[movidx]->movarr->_movSteps;
+ _items[idx]->movarr._afield_8 = -1;
+ _items[idx]->movarr._link = 0;
+
+ MessageQueue *mq = fillMGMinfo(_items[idx]->ani, &_items[idx]->movarr, 0);
+
+ if (!mq)
+ return 0;
+
+ ExCommand *ex = new ExCommand();
+
+ ex->_messageKind = 17;
+ ex->_messageNum = 54;
+ ex->_parentId = ani->_id;
+ ex->_field_3C = 1;
+ mq->addExCommandToEnd(ex);
+
+ if (!mq->chain(ani)) {
+ delete mq;
+
+ return 0;
+ }
+
+ return mq;
}
double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch) {
@@ -660,6 +1164,61 @@ void MovGraph::calcNodeDistancesAndAngles() {
}
}
+bool MovGraph::findClosestLink(int unusedArg, Common::Point *p, MovArr *movarr) {
+ MovGraphLink *link = 0;
+ double mindist = 1.0e20;
+ int resx = 0, resy = 0;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if ((lnk->_flags & 0x10000000) && !(lnk->_flags & 0x20000000) ) {
+ double dx1 = lnk->_movGraphNode1->_x - p->x;
+ double dy1 = lnk->_movGraphNode1->_y - p->y;
+ double dx2 = lnk->_movGraphNode2->_x - p->x;
+ double dy2 = lnk->_movGraphNode2->_y - p->y;
+ double dx3 = lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x;
+ double dy3 = lnk->_movGraphNode2->_y - lnk->_movGraphNode1->_y;
+ double sq1 = sqrt(dy1 * dy1 + dx1 * dx1);
+ double sdist = (dy3 * dy1 + dx3 * dx1) / lnk->_distance / sq1;
+ double ldist = sdist * sq1;
+ double dist = sqrt(1.0 - sdist * sdist) * sq1;
+
+ if (ldist < 0.0) {
+ ldist = 0.0;
+ dist = sqrt(dx1 * dx1 + dy1 * dy1);
+ }
+
+ if (ldist > lnk->_distance) {
+ ldist = lnk->_distance;
+ dist = sqrt(dx2 * dx2 + dy2 * dy2);
+ }
+
+ if (ldist >= 0.0 && ldist <= lnk->_distance && dist < mindist) {
+ resx = lnk->_movGraphNode1->_x + (int)(dx3 * ldist / lnk->_distance);
+ resy = lnk->_movGraphNode1->_y + (int)(dy3 * ldist / lnk->_distance);
+
+ mindist = dist;
+ link = lnk;
+ }
+ }
+ }
+
+ if (mindist < 1.0e20) {
+ if (movarr)
+ movarr->_link = link;
+
+ if (p) {
+ p->x = resx;
+ p->y = resy;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
int MovGraph::getItemIndexByStaticAni(StaticANIObject *ani) {
for (uint i = 0; i < _items.size(); i++)
if (_items[i]->ani == ani)
@@ -668,6 +1227,209 @@ int MovGraph::getItemIndexByStaticAni(StaticANIObject *ani) {
return -1;
}
+Common::Array<MovArr *> *MovGraph::genMovArr(int x, int y, int *arrSize, int flag1, int flag2) {
+ if (!_links.size()) {
+ *arrSize = 0;
+
+ return 0;
+ }
+
+ Common::Array<MovArr *> *arr = new Common::Array<MovArr *>;
+ MovArr *movarr;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (flag1) {
+ Common::Point point(x, y);
+ double dist = calcDistance(&point, lnk, 0);
+
+ if (dist >= 0.0 && dist < 2.0) {
+ movarr = new MovArr;
+
+ movarr->_link = lnk;
+ movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - point.y) +
+ (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(point.x - lnk->_movGraphNode1->_x)) /
+ lnk->_distance / lnk->_distance;
+ movarr->_point = point;
+
+ arr->push_back(movarr);
+ }
+ } else {
+ if (lnk->_movGraphReact) {
+ if (lnk->_movGraphReact->pointInRegion(x, y)) {
+ if (!(lnk->_flags & 0x10000000) || lnk->_flags & 0x20000000) {
+ if (!flag2) {
+ movarr = new MovArr;
+ movarr->_link = lnk;
+ movarr->_dist = 0.0;
+ movarr->_point.x = lnk->_movGraphNode1->_x;
+ movarr->_point.y = lnk->_movGraphNode1->_y;
+ arr->push_back(movarr);
+
+ movarr = new MovArr;
+ movarr->_link = lnk;
+ movarr->_dist = 1.0;
+ movarr->_point.x = lnk->_movGraphNode1->_x;
+ movarr->_point.y = lnk->_movGraphNode1->_y;
+ arr->push_back(movarr);
+ }
+ } else {
+ movarr = new MovArr;
+ movarr->_link = lnk;
+ movarr->_dist = ((double)(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y) * (double)(lnk->_movGraphNode1->_y - y) +
+ (double)(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) * (double)(x - lnk->_movGraphNode1->_x)) /
+ lnk->_distance / lnk->_distance;
+ movarr->_point.x = x;
+ movarr->_point.y = y;
+
+ calcDistance(&movarr->_point, lnk, 0);
+
+ arr->push_back(movarr);
+ }
+ }
+ }
+ }
+ }
+
+ *arrSize = arr->size();
+
+ return arr;
+}
+
+void MovGraph::shuffleTree(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &tempObList2) {
+ if (lnk == lnk2) {
+ for (uint i = 0; i < tempObList1.size(); i++)
+ tempObList2.push_back(tempObList1[i]);
+
+ tempObList2.push_back(lnk);
+ } else {
+ lnk->_flags |= 0x80000000;
+
+ tempObList1.push_back(lnk);
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ MovGraphLink *l = (MovGraphLink *)*i;
+
+ if (l->_movGraphNode1 != lnk->_movGraphNode1) {
+ if (l->_movGraphNode2 != lnk->_movGraphNode1) {
+ if (l->_movGraphNode1 != lnk->_movGraphNode2 && l->_movGraphNode2 != lnk->_movGraphNode2)
+ continue;
+ }
+ }
+
+ if (!(l->_flags & 0xA0000000))
+ shuffleTree(l, lnk2, tempObList1, tempObList2);
+ }
+
+ lnk->_flags &= 0x7FFFFFFF;
+ }
+}
+
+Common::Array<MovItem *> *MovGraph::calcMovItems(MovArr *movarr1, MovArr *movarr2, int *listCount) {
+ Common::Array<MovGraphLink *> tempObList1;
+ Common::Array<MovGraphLink *> tempObList2;
+
+ shuffleTree(movarr1->_link, movarr2->_link, tempObList1, tempObList2);
+
+ *listCount = 0;
+
+ if (!tempObList2.size())
+ return 0;
+
+ *listCount = tempObList2.size();
+
+ Common::Array<MovItem *> *res = new Common::Array<MovItem *>;
+
+ for (int i = 0; i < *listCount; i++) {
+ MovItem *r = new MovItem;
+
+ genMovItem(r, tempObList2[i], movarr1, movarr2);
+
+ delete tempObList2[i];
+ }
+
+ movarr2->_link = movarr1->_link;
+
+ return res;
+}
+
+void MovGraph::genMovItem(MovItem *movitem, MovGraphLink *grlink, MovArr *movarr1, MovArr *movarr2) {
+ warning("STUB: MovGraph::genMovItem()");
+}
+
+bool MovGraph::calcChunk(int idx, int x, int y, MovArr *arr, int a6) {
+ int staticsId;
+
+ if (_items[idx]->ani->_statics) {
+ staticsId = _items[idx]->ani->_statics->_staticsId;
+ } else {
+ if (!_items[idx]->ani->_movement->_staticsObj2)
+ return 0;
+
+ staticsId = _items[idx]->ani->_movement->_staticsObj2->_staticsId;
+ }
+
+ int arrSize;
+
+ Common::Array<MovArr *> *movarr = genMovArr(x, y, &arrSize, 0, 1);
+
+ if (!movarr)
+ return findClosestLink(idx, 0, arr);
+
+ bool res = false;
+
+ int idxmin = -1;
+ int offmin = 100;
+
+ for (int i = 0; i < arrSize; i++) {
+ int off = _mgm.refreshOffsets(_items[idx]->ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44]);
+
+ if (off < offmin) {
+ offmin = off;
+ idxmin = i;
+ }
+
+ off = _mgm.refreshOffsets(_items[idx]->ani->_id, staticsId, (*movarr)[i]->_link->_dwordArray2[_field_44 + 1]);
+ if (off < offmin) {
+ offmin = off;
+ idxmin = i;
+ }
+ }
+
+ if (idxmin != -1) {
+ *arr = *(*movarr)[idxmin];
+
+ res = true;
+ }
+
+ delete movarr;
+
+ return res;
+}
+
+void MovGraph::setEnds(MovStep *step1, MovStep *step2) {
+ if (step1->link->_movGraphNode1 == step2->link->_movGraphNode2) {
+ step1->sfield_0 = 1;
+ step2->sfield_0 = 1;
+
+ return;
+ }
+
+ if (step1->link->_movGraphNode1 == step2->link->_movGraphNode1) {
+ step1->sfield_0 = 1;
+ step2->sfield_0 = 0;
+ } else {
+ step1->sfield_0 = 0;
+
+ if (step1->link->_movGraphNode2 != step2->link->_movGraphNode1) {
+ step2->sfield_0 = 1;
+ } else {
+ step2->sfield_0 = 0;
+ }
+ }
+}
+
int MovGraph2::getItemIndexByGameObjectId(int objectId) {
for (uint i = 0; i < _items2.size(); i++)
if (_items2[i]->_objectId == objectId)
@@ -1089,7 +1851,10 @@ int MovGraph2::removeObject(StaticANIObject *obj) {
}
void MovGraph2::freeItems() {
- warning("STUB: MovGraph2::freeItems()");
+ for (uint i = 0; i < _items2.size(); i++)
+ delete _items2[i];
+
+ _items2.clear();
}
MessageQueue *MovGraph2::method34(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) {
@@ -1140,6 +1905,8 @@ MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int
PicAniInfo picAniInfo;
Common::Point point;
+ debug(0, "MovGraph2::doWalkTo(%d, %d, %d, %d, %d)", obj->_id, xpos, ypos, fuzzyMatch, staticsId);
+
int idx = getItemIndexByGameObjectId(obj->_id);
if (idx < 0)
@@ -2528,7 +3295,10 @@ MovGraphLink::MovGraphLink() {
}
MovGraphLink::~MovGraphLink() {
- warning("STUB: MovGraphLink::~MovGraphLink()");
+ delete _movGraphReact;
+
+ _dwordArray1.clear();
+ _dwordArray2.clear();
}
@@ -2764,26 +3534,26 @@ bool MovGraphReact::pointInRegion(int x, int y) {
}
}
-int startWalkTo(int objId, int objKey, int x, int y, int a5) {
- MctlCompound *mc = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
+int startWalkTo(int objId, int objKey, int x, int y, int fuzzyMatch) {
+ MctlCompound *mc = getCurrSceneSc2MotionController();
if (mc)
- return (mc->method34(g_fp->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, a5, 0) != 0);
+ return (mc->method34(g_fp->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, fuzzyMatch, 0) != 0);
return 0;
}
-int doSomeAnimation(int objId, int objKey, int a3) {
+bool doSomeAnimation(int objId, int objKey, int a3) {
StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(objId, objKey);
MctlCompound *cmp = getCurrSceneSc2MotionController();
if (ani && cmp)
return cmp->method3C(ani, a3);
- return 0;
+ return false;
}
-int doSomeAnimation2(int objId, int objKey) {
+bool doSomeAnimation2(int objId, int objKey) {
return doSomeAnimation(objId, objKey, 0);
}
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index 4d92fd7fed..2b40791340 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -31,10 +31,12 @@ class MctlConnectionPoint;
class MovGraphLink;
class MessageQueue;
class ExCommand2;
+struct MovArr;
+struct MovItem;
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);
+bool doSomeAnimation(int objId, int objKey, int a3);
+bool doSomeAnimation2(int objId, int objKey);
class MotionController : public CObject {
public:
@@ -52,14 +54,14 @@ public:
virtual void addObject(StaticANIObject *obj) {}
virtual int removeObject(StaticANIObject *obj) { return 0; }
virtual void freeItems() {}
- virtual int method28() { return 0; }
- virtual int method2C(StaticANIObject *obj, int x, int y) { return 0; }
+ virtual Common::Array<MovItem *> *method28(StaticANIObject *ani, int x, int y, int flag1, int *rescount) { return 0; }
+ virtual bool method2C(StaticANIObject *obj, int x, int y) { return false; }
virtual int method30() { return 0; }
virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; }
- virtual int changeCallback() { return 0; }
- virtual int method3C(StaticANIObject *ani, int flag) { return 0; }
+ virtual void changeCallback(MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter)) {}
+ virtual bool method3C(StaticANIObject *ani, int flag) { return 0; }
virtual int method40() { return 0; }
- virtual int method44() { return 0; }
+ virtual bool method44(StaticANIObject *ani, int x, int y) { return false; }
virtual int method48() { return -1; }
virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; }
@@ -115,7 +117,7 @@ public:
virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
void initMovGraph2();
- MctlConnectionPoint *findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr);
+ MctlConnectionPoint *findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, double *minDistancePtr);
void replaceNodeX(int from, int to);
uint getMotionControllerCount() { return _motionControllers.size(); }
@@ -299,18 +301,32 @@ class MovGraphLink : public CObject {
void calcNodeDistanceAndAngle();
};
+struct MovStep {
+ int sfield_0;
+ MovGraphLink *link;
+};
+
+struct MovArr {
+ Common::Array<MovStep *> _movSteps;
+ int _movStepCount;
+ int _afield_8;
+ MovGraphLink *_link;
+ double _dist;
+ Common::Point _point;
+};
+
+struct MovItem {
+ MovArr *movarr;
+ int _mfield_4;
+ int _mfield_8;
+ int _mfield_C;
+};
+
struct MovGraphItem {
StaticANIObject *ani;
int field_4;
- int field_8;
- int field_C;
- int field_10;
- int field_14;
- int field_18;
- int field_1C;
- int field_20;
- int field_24;
- int items;
+ MovArr movarr;
+ Common::Array<MovItem *> *movitems;
int count;
int field_30;
int field_34;
@@ -318,6 +334,7 @@ struct MovGraphItem {
int field_3C;
MovGraphItem();
+ void free();
};
class MovGraph : public MotionController {
@@ -326,7 +343,7 @@ public:
ObList _links;
int _field_44;
Common::Array<MovGraphItem *> _items;
- int (*_callback1)(int, int, int);
+ MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter);
MGM _mgm;
public:
@@ -338,19 +355,28 @@ public:
virtual void addObject(StaticANIObject *obj);
virtual int removeObject(StaticANIObject *obj);
virtual void freeItems();
- virtual int method28();
- virtual int method2C(StaticANIObject *obj, int x, int y);
+ virtual Common::Array<MovItem *> *method28(StaticANIObject *ani, int x, int y, int flag1, int *rescount);
+ virtual bool method2C(StaticANIObject *obj, int x, int y);
virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
- virtual int changeCallback();
- virtual int method3C(StaticANIObject *ani, int flag);
- virtual int method44();
+ virtual void changeCallback(MovArr *(*_callback1)(StaticANIObject *ani, Common::Array<MovItem *> *items, signed int counter));
+ virtual bool method3C(StaticANIObject *ani, int flag);
+ virtual bool method44(StaticANIObject *ani, int x, int y);
virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
- virtual int method50();
+ virtual MessageQueue *method50(StaticANIObject *ani, MovArr *movarr, int staticsId);
double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch);
void calcNodeDistancesAndAngles();
+ bool findClosestLink(int unusedArg, Common::Point *p, MovArr *movarr);
MovGraphNode *calcOffset(int ox, int oy);
int getItemIndexByStaticAni(StaticANIObject *ani);
+ Common::Array<MovArr *> *genMovArr(int x, int y, int *arrSize, int flag1, int flag2);
+ void shuffleTree(MovGraphLink *lnk, MovGraphLink *lnk2, Common::Array<MovGraphLink *> &tempObList1, Common::Array<MovGraphLink *> &tempObList2);
+ Common::Array<MovItem *> *calcMovItems(MovArr *movarr1, MovArr *movarr2, int *listCount);
+ void genMovItem(MovItem *movitem, MovGraphLink *grlink, MovArr *movarr1, MovArr *movarr2);
+ bool calcChunk(int idx, int x, int y, MovArr *arr, int a6);
+ MessageQueue *sub1(StaticANIObject *ani, int x, int y, int a5, int x1, int y1, int a8, int a9);
+ MessageQueue *fillMGMinfo(StaticANIObject *ani, MovArr *movarr, int staticsId);
+ void setEnds(MovStep *step1, MovStep *step2);
};
class Movement;
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index 462401b3b2..1247d9380e 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -133,7 +133,27 @@ Scene::Scene() {
}
Scene::~Scene() {
- warning("STUB: Scene::~Scene()");
+ delete _soundList;
+ delete _shadows;
+ delete _palette;
+
+ // _faObjlist is not used
+
+ for (uint i = 0; i < _messageQueueList.size(); i++)
+ delete _messageQueueList[i];
+
+ _messageQueueList.clear();
+
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ delete _staticANIObjectList1[i];
+
+ _staticANIObjectList1.clear();
+
+ delete _libHandle;
+
+ // delete _field_BC;
+
+ free(_sceneName);
}
bool Scene::load(MfcArchive &file) {
@@ -249,7 +269,7 @@ bool Scene::load(MfcArchive &file) {
void Scene::initStaticANIObjects() {
for (uint i = 0; i < _staticANIObjectList1.size(); i++)
- ((StaticANIObject *)_staticANIObjectList1[i])->initMovements();
+ _staticANIObjectList1[i]->initMovements();
}
void Scene::init() {
@@ -262,13 +282,13 @@ void Scene::init() {
((PictureObject *)_picObjList[i])->clearFlags();
for (uint i = 0; i < _staticANIObjectList1.size(); i++)
- ((StaticANIObject *)_staticANIObjectList1[i])->clearFlags();
+ _staticANIObjectList1[i]->clearFlags();
if (_staticANIObjectList2.size() != _staticANIObjectList1.size()) {
_staticANIObjectList2.clear();
- for (PtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s)
- _staticANIObjectList2.push_back(*s);
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ _staticANIObjectList2.push_back(_staticANIObjectList1[i]);
}
}
@@ -281,35 +301,33 @@ StaticANIObject *Scene::getAniMan() {
}
StaticANIObject *Scene::getStaticANIObject1ById(int obj, int a3) {
- for (PtrList::iterator s = _staticANIObjectList1.begin(); s != _staticANIObjectList1.end(); ++s) {
- StaticANIObject *o = (StaticANIObject *)*s;
- if (o->_id == obj && (a3 == -1 || o->_okeyCode == a3))
- return o;
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++) {
+ if (_staticANIObjectList1[i]->_id == obj && (a3 == -1 || _staticANIObjectList1[i]->_okeyCode == a3))
+ return _staticANIObjectList1[i];
}
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;
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++) {
+ if (!strcmp(_staticANIObjectList1[i]->_objectName, name) && (a3 == -1 || _staticANIObjectList1[i]->_okeyCode == a3))
+ return _staticANIObjectList1[i];
}
return 0;
}
void Scene::deleteStaticANIObject(StaticANIObject *obj) {
- for (uint n = 0; n < _staticANIObjectList1.size(); n++)
- if ((StaticANIObject *)_staticANIObjectList1[n] == obj) {
- _staticANIObjectList1.remove_at(n);
+ for (uint i = 0; i < _staticANIObjectList1.size(); i++)
+ if (_staticANIObjectList1[i] == obj) {
+ _staticANIObjectList1.remove_at(i);
break;
}
- for (uint n = 0; n < _staticANIObjectList2.size(); n++)
- if ((StaticANIObject *)_staticANIObjectList2[n] == obj) {
- _staticANIObjectList2.remove_at(n);
+ for (uint i = 0; i < _staticANIObjectList2.size(); i++)
+ if (_staticANIObjectList2[i] == obj) {
+ _staticANIObjectList2.remove_at(i);
break;
}
}
@@ -335,11 +353,12 @@ void Scene::setPictureObjectsFlag4() {
}
void Scene::stopAllSounds() {
- warning("STUB: Scene:stopAllSounds()");
+ for (int i = 0; i < _soundList->getCount(); i++)
+ _soundList->getSoundByIndex(i)->stop();
}
PictureObject *Scene::getPictureObjectById(int objId, int flags) {
- for (uint i = 0; i < _picObjList.size(); i++) {
+ for (uint i = 1; i < _picObjList.size(); i++) {
if (((PictureObject *)_picObjList[i])->_id == objId && ((PictureObject *)_picObjList[i])->_okeyCode == flags)
return (PictureObject *)_picObjList[i];
}
@@ -369,16 +388,16 @@ void Scene::deletePictureObject(PictureObject *obj) {
MessageQueue *Scene::getMessageQueueById(int messageId) {
for (uint i = 0; i < _messageQueueList.size(); i++)
- if (((MessageQueue *)_messageQueueList[i])->_dataId == messageId)
- return (MessageQueue *)_messageQueueList[i];
+ if (_messageQueueList[i]->_dataId == messageId)
+ return _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];
+ if (!strcmp(_messageQueueList[i]->_queueName, name))
+ return _messageQueueList[i];
return 0;
}
@@ -447,15 +466,27 @@ void Scene::initObjectCursors(const char *varname) {
}
bool Scene::compareObjPriority(const void *p1, const void *p2) {
- if (((const StaticANIObject *)p1)->_priority > ((const StaticANIObject *)p2)->_priority)
+ if (((const GameObject *)p1)->_priority > ((const GameObject *)p2)->_priority)
return true;
return false;
}
-void Scene::objectList_sortByPriority(PtrList &list, bool skipFirst) {
+void Scene::objectList_sortByPriority(Common::Array<StaticANIObject *> &list, bool skipFirst) {
if (skipFirst) {
- PtrList::iterator s = list.begin();
+ Common::Array<StaticANIObject *>::iterator s = list.begin();
+
+ ++s;
+
+ Common::sort(s, list.end(), Scene::compareObjPriority);
+ } else {
+ Common::sort(list.begin(), list.end(), Scene::compareObjPriority);
+ }
+}
+
+void Scene::objectList_sortByPriority(Common::Array<PictureObject *> &list, bool skipFirst) {
+ if (skipFirst) {
+ Common::Array<PictureObject *>::iterator s = list.begin();
++s;
@@ -476,16 +507,15 @@ void Scene::draw() {
objectList_sortByPriority(_staticANIObjectList2);
- for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) {
- ((StaticANIObject *)*s)->draw2();
- }
+ for (uint i = 0; i < _staticANIObjectList2.size(); i++)
+ _staticANIObjectList2[i]->draw2();
int priority = -1;
- for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) {
- drawContent(((StaticANIObject *)*s)->_priority, priority, false);
- ((StaticANIObject *)*s)->draw();
+ for (uint i = 0; i < _staticANIObjectList2.size(); i++) {
+ drawContent(_staticANIObjectList2[i]->_priority, priority, false);
+ _staticANIObjectList2[i]->draw();
- priority = ((StaticANIObject *)*s)->_priority;
+ priority = _staticANIObjectList2[i]->_priority;
}
drawContent(-1, priority, false);
@@ -566,7 +596,7 @@ StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) {
StaticANIObject *res = 0;
for (uint i = 0; i < _staticANIObjectList1.size(); i++) {
- StaticANIObject *p = (StaticANIObject *)_staticANIObjectList1[i];
+ StaticANIObject *p = _staticANIObjectList1[i];
int pixel;
if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
@@ -612,8 +642,8 @@ int Scene::getPictureObjectIdAtPos(int x, int y) {
void Scene::update(int counterdiff) {
debug(6, "Scene::update(%d)", counterdiff);
- for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s)
- ((StaticANIObject *)*s)->update(counterdiff);
+ for (uint i = 0; i < _staticANIObjectList2.size(); i++)
+ _staticANIObjectList2[i]->update(counterdiff);
}
void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
index 8306974f7b..1e2dae81fe 100644
--- a/engines/fullpipe/scene.h
+++ b/engines/fullpipe/scene.h
@@ -31,10 +31,10 @@ class MessageQueue;
class Scene : public Background {
public:
- PtrList _staticANIObjectList1;
- PtrList _staticANIObjectList2;
- PtrList _messageQueueList;
- PtrList _faObjectList;
+ Common::Array<StaticANIObject *> _staticANIObjectList1;
+ Common::Array<StaticANIObject *> _staticANIObjectList2;
+ Common::Array<MessageQueue *> _messageQueueList;
+ // PtrList _faObjectList; // not used
Shadows *_shadows;
SoundList *_soundList;
int16 _sceneId;
@@ -82,7 +82,8 @@ class Scene : public Background {
private:
static bool compareObjPriority(const void *p1, const void *p2);
- void objectList_sortByPriority(PtrList &list, bool skipFirst = false);
+ void objectList_sortByPriority(Common::Array<StaticANIObject *> &list, bool skipFirst = false);
+ void objectList_sortByPriority(Common::Array<PictureObject *> &list, bool skipFirst = false);
};
class SceneTag : public CObject {
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index 7420c1b1cf..b346bf3a17 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -590,10 +590,8 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->setPictureObjectsFlag4();
- for (PtrList::iterator s = scene->_staticANIObjectList1.begin(); s != scene->_staticANIObjectList1.end(); ++s) {
- StaticANIObject *o = (StaticANIObject *)*s;
- o->setFlags(o->_flags & 0xFE7F);
- }
+ for (uint i = 0; i < scene->_staticANIObjectList1.size(); i++)
+ scene->_staticANIObjectList1[i]->_flags &= 0xFE7F;
PictureObject *p = accessScene(SC_INV)->getPictureObjectById(PIC_INV_MENU, 0);
p->setFlags(p->_flags & 0xFFFB);
@@ -1456,9 +1454,28 @@ void BallChain::init(Ball **ball) {
}
Ball *BallChain::sub04(Ball *ballP, Ball *ballN) {
- warning("STUB: BallChain::sub04");
+ if (!pTail) {
+ cPlex = (byte *)calloc(cPlexLen, sizeof(Ball));
+
+ Ball *runPtr = (Ball *)&cPlex[(cPlexLen - 1) * sizeof(Ball)];
+
+ for (int i = 0; i < cPlexLen; i++) {
+ runPtr->p0 = pTail;
+ pTail = runPtr;
+
+ runPtr -= sizeof(Ball);
+ }
+ }
+
+ Ball *res = pTail;
+
+ pTail = res->p0;
+ res->p1 = ballP;
+ res->p0 = ballN;
+ numBalls++;
+ res->ani = 0;
- return pTail;
+ return res;
}
void BallChain::removeBall(Ball *ball) {
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index 3c13bad854..65c9bf84ca 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -27,6 +27,8 @@
#include "fullpipe/sound.h"
#include "fullpipe/ngiarchive.h"
#include "fullpipe/messages.h"
+#include "fullpipe/statics.h"
+
#include "common/memstream.h"
#include "audio/audiostream.h"
#include "audio/decoders/vorbis.h"
@@ -132,7 +134,75 @@ void Sound::updateVolume() {
}
void Sound::setPanAndVolumeByStaticAni() {
- debug(3, "STUB Sound::setPanAndVolumeByStaticAni()");
+ if (!_objectId)
+ return;
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(_objectId, -1);
+ if (!ani)
+ return;
+
+ int a, b;
+
+ if (ani->_ox >= g_fp->_sceneRect.left) {
+ int par, pan;
+
+ if (ani->_ox <= g_fp->_sceneRect.right) {
+ int dx;
+
+ if (ani->_oy <= g_fp->_sceneRect.bottom) {
+ if (ani->_oy >= g_fp->_sceneRect.top) {
+ setPanAndVolume(g_fp->_sfxVolume, 0);
+
+ return;
+ }
+ dx = g_fp->_sceneRect.top - ani->_oy;
+ } else {
+ dx = ani->_oy - g_fp->_sceneRect.bottom;
+ }
+
+ par = 0;
+
+ if (dx > 800) {
+ setPanAndVolume(-3500, 0);
+ return;
+ }
+
+ pan = -3500;
+ a = g_fp->_sfxVolume - (-3500);
+ b = 800 - dx;
+ } else {
+ int dx = ani->_ox - g_fp->_sceneRect.right;
+
+ if (dx > 800) {
+ setPanAndVolume(-3500, 0);
+ return;
+ }
+
+ pan = -3500;
+ par = dx * (-3500) / -800;
+ a = g_fp->_sfxVolume - (-3500);
+ b = 800 - dx;
+ }
+
+ int32 pp = b * a;
+
+ setPanAndVolume(pan + pp / 800, par);
+
+ return;
+ }
+
+ int dx = g_fp->_sceneRect.left - ani->_ox;
+ if (dx <= 800) {
+ int32 s = (800 - dx) * (g_fp->_sfxVolume - (-3500));
+ int32 p = -3500 + s / 800;
+
+ if (p > g_fp->_sfxVolume)
+ p = g_fp->_sfxVolume;
+
+ setPanAndVolume(p, dx * (-3500) / 800);
+ } else {
+ setPanAndVolume(-3500, 0);
+ }
}
void Sound::setPanAndVolume(int vol, int pan) {
@@ -298,8 +368,12 @@ void FullpipeEngine::startSoundStream1(char *trackName) {
}
void FullpipeEngine::stopAllSounds() {
- // TODO: Differences from stopAllSoundStreams()
- _mixer->stopAll();
+ // _mixer->stopAll();
+
+ for (int i = 0; i < _currSoundListCount; i++)
+ for (int j = 0; j < _currSoundList1[i]->getCount(); j++) {
+ _currSoundList1[i]->getSoundByIndex(j)->stop();
+ }
}
void FullpipeEngine::toggleMute() {
@@ -447,7 +521,7 @@ void FullpipeEngine::updateSoundVolume() {
void FullpipeEngine::setMusicVolume(int vol) {
_musicVolume = vol;
- debug(3, "STUB FullpipeEngine::setMusicVolume()");
+ g_fp->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol);
}
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index e36b196517..41641457d3 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -55,9 +55,8 @@ bool FullpipeEngine::loadGam(const char *fname, int scene) {
_inventory->rebuildItemRects();
- for (PtrList::iterator p = _inventory->getScene()->_picObjList.begin(); p != _inventory->getScene()->_picObjList.end(); ++p) {
- ((MemoryObject *)((PictureObject *)*p)->_picture)->load();
- }
+ for (uint i = 0; i < _inventory->getScene()->_picObjList.size(); i++)
+ ((MemoryObject *)_inventory->getScene()->_picObjList[i]->_picture)->load();
// _sceneSwitcher = sceneSwitcher; // substituted with direct call
_gameLoader->_preloadCallback = preloadCallback;
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index f1abac5778..b6b312ab85 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -141,7 +141,17 @@ StaticANIObject::StaticANIObject() {
}
StaticANIObject::~StaticANIObject() {
- warning("STUB: StaticANIObject::~StaticANIObject()");
+ for (uint i = 0; i < _staticsList.size(); i++)
+ delete _staticsList[i];
+
+ _staticsList.clear();
+
+ for (uint i = 0; i < _movements.size(); i++)
+ delete _movements[i];
+
+ _movements.clear();
+
+ g_fp->_mgm->clear();
}
StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
@@ -164,22 +174,21 @@ StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
_objtype = kObjTypeStaticANIObject;
for (uint i = 0; i < src->_staticsList.size(); i++)
- _staticsList.push_back(new Statics((Statics *)src->_staticsList[i], 0));
+ _staticsList.push_back(new Statics(src->_staticsList[i], 0));
_movement = 0;
_statics = 0;
for (uint i = 0; i < src->_movements.size(); i++) {
Movement *newmov;
- Movement *mov = (Movement *)src->_movements[i];
- if (mov->_currMovement) {
+ if (src->_movements[i]->_currMovement) {
// WORKAROUND: Original uses weird construction here:
// new Movement(getMovementById(src->getMovementIdById(mov->_id)), this);
- newmov = new Movement(src->getMovementById(src->getMovementIdById(mov->_id)), this);
- newmov->_id = mov->_id;
+ newmov = new Movement(src->getMovementById(src->getMovementIdById(src->_movements[i]->_id)), this);
+ newmov->_id = src->_movements[i]->_id;
} else {
- newmov = new Movement(mov, 0, -1, this);
+ newmov = new Movement(src->_movements[i], 0, -1, this);
}
_movements.push_back(newmov);
@@ -224,7 +233,7 @@ bool StaticANIObject::load(MfcArchive &file) {
Common::Point pt;
if (count) { // We have movements
- ((Movement *)_movements[0])->getCurrDynamicPhaseXY(pt);
+ _movements[0]->getCurrDynamicPhaseXY(pt);
} else {
pt.x = pt.y = 100;
}
@@ -392,34 +401,36 @@ bool StaticANIObject::isIdle() {
Statics *StaticANIObject::getStaticsById(int itemId) {
for (uint i = 0; i < _staticsList.size(); i++)
- if (((Statics *)_staticsList[i])->_staticsId == itemId)
- return (Statics *)_staticsList[i];
+ if (_staticsList[i]->_staticsId == itemId)
+ return _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];
+ if (!strcmp(_staticsList[i]->_staticsName, name))
+ return _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];
+ if (_movements[i]->_id == itemId)
+ return _movements[i];
return 0;
}
int StaticANIObject::getMovementIdById(int itemId) {
for (uint i = 0; i < _movements.size(); i++) {
- Movement *mov = (Movement *)_movements[i];
+ Movement *mov = _movements[i];
+
if (mov->_currMovement) {
if (mov->_id == itemId)
return mov->_id;
+
if (mov->_currMovement->_id == itemId)
return mov->_id;
}
@@ -430,8 +441,8 @@ int StaticANIObject::getMovementIdById(int itemId) {
Movement *StaticANIObject::getMovementByName(char *name) {
for (uint i = 0; i < _movements.size(); i++)
- if (!strcmp(((Movement *)_movements[i])->_objectName, name))
- return (Movement *)_movements[i];
+ if (!strcmp(_movements[i]->_objectName, name))
+ return _movements[i];
return 0;
}
@@ -551,12 +562,12 @@ void Movement::draw(bool flipFlag, int angle) {
void StaticANIObject::loadMovementsPixelData() {
for (uint i = 0; i < _movements.size(); i++)
- ((Movement *)_movements[i])->loadPixelData();
+ _movements[i]->loadPixelData();
}
void StaticANIObject::freeMovementsPixelData() {
for (uint i = 0; i < _movements.size(); i++)
- ((Movement *)_movements[i])->freePixelData();
+ _movements[i]->freePixelData();
}
Statics *StaticANIObject::addReverseStatics(Statics *st) {
@@ -665,11 +676,10 @@ MovTable *StaticANIObject::countMovements() {
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 (GameVar *sub = preloadSubVar->_subVars; sub; sub = sub->_nextVarObj) {
- if (scumm_stricmp(obj->getName(), sub->_varName) == 0) {
+ if (scumm_stricmp(_movements[i]->getName(), sub->_varName) == 0) {
movTable->movs[i] = 1;
break;
}
@@ -702,21 +712,21 @@ void StaticANIObject::setSpeed(int speed) {
void StaticANIObject::setAlpha(int alpha) {
for (uint i = 0; i < _movements.size(); i++)
- ((Movement *)_movements[i])->setAlpha(alpha);
+ _movements[i]->setAlpha(alpha);
for (uint i = 0; i < _staticsList.size(); i++)
- ((Statics *)_staticsList[i])->setAlpha(alpha);
+ _staticsList[i]->setAlpha(alpha);
}
void StaticANIObject::initMovements() {
for (uint i = 0; i < _movements.size(); i++)
- ((Movement *)_movements[i])->removeFirstPhase();
+ _movements[i]->removeFirstPhase();
}
void StaticANIObject::preloadMovements(MovTable *mt) {
- if ( mt ) {
+ if (mt) {
for (uint i = 0; i < _movements.size(); i++) {
- Movement *mov = (Movement *)_movements[i];
+ Movement *mov = _movements[i];
if (mt->movs[i] == 1)
mov->loadPixelData();
@@ -1177,8 +1187,8 @@ void StaticANIObject::startAnimSteps(int movementId, int messageQueueId, int x,
if (!(_flags & 0x80)) {
if (!_messageQueueId)
for (uint i = 0; i < _movements.size(); i++) {
- if (((Movement *)_movements[i])->_id == movementId) {
- mov = (Movement *)_movements[i];
+ if (_movements[i]->_id == movementId) {
+ mov = _movements[i];
break;
}
}
@@ -1266,7 +1276,7 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
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);
+ debug(4, "StaticANIObject::startAnim(%d, %d, %d) (%s [%d]) [%d, %d]", movementId, messageQueueId, dynPhaseIdx, transCyrillic((byte *)_objectName), _id, _ox, _oy);
if (_messageQueueId) {
updateGlobalMessageQueue(messageQueueId, _id);
@@ -1276,9 +1286,8 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
Movement *mov = 0;
for (uint i = 0; i < _movements.size(); i++) {
-
- if (((Movement *)_movements[i])->_id == movementId) {
- mov = (Movement *)_movements[i];
+ if (_movements[i]->_id == movementId) {
+ mov = _movements[i];
break;
}
}
@@ -1441,6 +1450,19 @@ bool Statics::load(MfcArchive &file) {
return true;
}
+void Statics::init() {
+ Picture::init();
+
+ if (_staticsId & 0x4000) {
+ Bitmap *bmp = _bitmap->reverseImage();
+
+ freePixelData();
+
+ _bitmap = bmp;
+ _data = bmp->_pixels;
+ }
+}
+
Common::Point *Statics::getSomeXY(Common::Point &p) {
p.x = _someX;
p.y = _someY;
@@ -1493,7 +1515,17 @@ Movement::Movement() {
}
Movement::~Movement() {
- warning("STUB: Movement::~Movement()");
+ for (uint i = 0; i < _dynamicPhases.size(); i++)
+ delete _framePosOffsets[i];
+
+ if (!_currMovement ) {
+ if (_updateFlag1)
+ _dynamicPhases.remove_at(0);
+
+ _dynamicPhases.clear();
+ }
+
+ free(_framePosOffsets);
}
Movement::Movement(Movement *src, StaticANIObject *ani) {
@@ -1748,11 +1780,11 @@ Common::Point *Movement::calcSomeXY(Common::Point &p, int idx) {
void Movement::setAlpha(int alpha) {
if (_currMovement)
for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
- ((DynamicPhase *)_currMovement->_dynamicPhases[i])->setAlpha(alpha);
+ _currMovement->_dynamicPhases[i]->setAlpha(alpha);
}
else
for (uint i = 0; i < _dynamicPhases.size(); i++) {
- ((DynamicPhase *)_dynamicPhases[i])->setAlpha(alpha);
+ _dynamicPhases[i]->setAlpha(alpha);
}
}
@@ -1765,9 +1797,9 @@ Common::Point *Movement::getDimensionsOfPhase(Common::Point *p, int phaseIndex)
DynamicPhase *dyn;
if (_currMovement)
- dyn = (DynamicPhase *)_currMovement->_dynamicPhases[idx];
+ dyn = _currMovement->_dynamicPhases[idx];
else
- dyn = (DynamicPhase *)_dynamicPhases[idx];
+ dyn = _dynamicPhases[idx];
Common::Point point;
@@ -1816,13 +1848,13 @@ void Movement::updateCurrDynamicPhase() {
return;
if (_currMovement->_dynamicPhases[_currDynamicPhaseIndex])
- _currDynamicPhase = (DynamicPhase *)_currMovement->_dynamicPhases[_currDynamicPhaseIndex];
+ _currDynamicPhase = _currMovement->_dynamicPhases[_currDynamicPhaseIndex];
} else {
if (_dynamicPhases.size() == 0 || (uint)_currDynamicPhaseIndex >= _dynamicPhases.size())
return;
if (_dynamicPhases[_currDynamicPhaseIndex])
- _currDynamicPhase = (DynamicPhase *)_dynamicPhases[_currDynamicPhaseIndex];
+ _currDynamicPhase = _dynamicPhases[_currDynamicPhaseIndex];
}
}
@@ -1831,11 +1863,11 @@ int Movement::calcDuration() {
if (_currMovement)
for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
- res += ((DynamicPhase *)_currMovement->_dynamicPhases[i])->_initialCountdown;
+ res += _currMovement->_dynamicPhases[i]->_initialCountdown;
}
else
for (uint i = 0; i < _dynamicPhases.size(); i++) {
- res += ((DynamicPhase *)_dynamicPhases[i])->_initialCountdown;
+ res += _dynamicPhases[i]->_initialCountdown;
}
return res;
@@ -1876,12 +1908,12 @@ DynamicPhase *Movement::getDynamicPhaseByIndex(int idx) {
if (_currMovement->_dynamicPhases.size() == 0 || (uint)idx >= _currMovement->_dynamicPhases.size())
return 0;
- return (DynamicPhase *)_currMovement->_dynamicPhases[idx];
+ return _currMovement->_dynamicPhases[idx];
} else {
if (_dynamicPhases.size() == 0 || (uint)idx >= _dynamicPhases.size())
return 0;
- return (DynamicPhase *)_dynamicPhases[idx];
+ return _dynamicPhases[idx];
}
}
@@ -1892,7 +1924,7 @@ void Movement::loadPixelData() {
for (uint i = 0; i < _dynamicPhases.size(); i++) {
if ((Statics *)_dynamicPhases[i] != mov->_staticsObj2 || !(mov->_staticsObj2->_staticsId & 0x4000))
- ((Statics *)_dynamicPhases[i])->getPixelData();
+ _dynamicPhases[i]->getPixelData();
}
if (!(mov->_staticsObj1->_staticsId & 0x4000))
@@ -1902,7 +1934,7 @@ void Movement::loadPixelData() {
void Movement::freePixelData() {
if (!_currMovement)
for (uint i = 0; i < _dynamicPhases.size(); i++)
- ((DynamicPhase *)_dynamicPhases[i])->freePixelData();
+ _dynamicPhases[i]->freePixelData();
if (_staticsObj1)
_staticsObj1->freePixelData();
@@ -1934,11 +1966,11 @@ bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, i
if (!callback2) {
if (_currMovement) {
if ((uint)_currDynamicPhaseIndex == _currMovement->_dynamicPhases.size() - 1
- && !(((DynamicPhase *)(_currMovement->_dynamicPhases.back()))->_countdown)) {
+ && !(_currMovement->_dynamicPhases.back()->_countdown)) {
return false;
}
} else if ((uint)_currDynamicPhaseIndex == _dynamicPhases.size() - 1
- && !(((DynamicPhase *)(_dynamicPhases.back()))->_countdown)) {
+ && !(_dynamicPhases.back()->_countdown)) {
return false;
}
}
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index d678957163..63661157b2 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -98,6 +98,7 @@ class Statics : public DynamicPhase {
virtual ~Statics();
virtual bool load(MfcArchive &file);
+ virtual void init();
Statics *getStaticsById(int itemId);
Common::Point *getSomeXY(Common::Point &p);
@@ -121,7 +122,7 @@ class Movement : public GameObject {
int _field_50;
int _counterMax;
int _counter;
- PtrList _dynamicPhases;
+ Common::Array<DynamicPhase *> _dynamicPhases;
int _field_78;
Common::Point **_framePosOffsets;
Movement *_currMovement;
@@ -181,8 +182,8 @@ class StaticANIObject : public GameObject {
int _initialCounter;
void (*_callback1)(int, Common::Point *point, int, int);
void (*_callback2)(int *);
- PtrList _movements;
- PtrList _staticsList;
+ Common::Array<Movement *> _movements;
+ Common::Array<Statics *> _staticsList;
StepArray _stepArray;
int16 _field_96;
int _messageQueueId;
diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
index 72e746cd03..da3ab7ee4f 100644
--- a/engines/fullpipe/utils.h
+++ b/engines/fullpipe/utils.h
@@ -68,6 +68,7 @@ enum ObjType {
kObjTypeDefault,
kObjTypeExCommand,
kObjTypeExCommand2,
+ kObjTypeModalSaveGame,
kObjTypeMovGraph,
kObjTypeMovGraphLink,
kObjTypeMovGraphNode,
@@ -148,8 +149,6 @@ class DWordArray : public Common::Array<int32>, public CObject {
virtual bool load(MfcArchive &file);
};
-typedef Common::Array<void *> PtrList;
-
char *genFileName(int superId, int sceneId, const char *ext);
byte *transCyrillic(byte *s);
diff --git a/engines/gob/cheater_geisha.cpp b/engines/gob/cheater_geisha.cpp
index 8c4deec370..ec6fe09d59 100644
--- a/engines/gob/cheater_geisha.cpp
+++ b/engines/gob/cheater_geisha.cpp
@@ -61,7 +61,7 @@ bool Cheater_Geisha::cheat(GUI::Debugger &console) {
uint32 digit5 = READ_VARO_UINT32(0x778);
if (digit1 && digit2 && digit3 && digit4 && digit5)
- console.DebugPrintf("Mastermind solution: %d %d %d %d %d\n",
+ console.debugPrintf("Mastermind solution: %d %d %d %d %d\n",
digit1, digit2, digit3, digit4, digit5);
return true;
diff --git a/engines/gob/console.cpp b/engines/gob/console.cpp
index b0f6006284..2252606243 100644
--- a/engines/gob/console.cpp
+++ b/engines/gob/console.cpp
@@ -29,14 +29,14 @@
namespace Gob {
GobConsole::GobConsole(GobEngine *vm) : GUI::Debugger(), _vm(vm), _cheater(0) {
- DCmd_Register("varSize", WRAP_METHOD(GobConsole, cmd_varSize));
- DCmd_Register("dumpVars", WRAP_METHOD(GobConsole, cmd_dumpVars));
- DCmd_Register("var8", WRAP_METHOD(GobConsole, cmd_var8));
- DCmd_Register("var16", WRAP_METHOD(GobConsole, cmd_var16));
- DCmd_Register("var32", WRAP_METHOD(GobConsole, cmd_var32));
- DCmd_Register("varString", WRAP_METHOD(GobConsole, cmd_varString));
- DCmd_Register("cheat", WRAP_METHOD(GobConsole, cmd_cheat));
- DCmd_Register("listArchives", WRAP_METHOD(GobConsole, cmd_listArchives));
+ registerCmd("varSize", WRAP_METHOD(GobConsole, cmd_varSize));
+ registerCmd("dumpVars", WRAP_METHOD(GobConsole, cmd_dumpVars));
+ registerCmd("var8", WRAP_METHOD(GobConsole, cmd_var8));
+ registerCmd("var16", WRAP_METHOD(GobConsole, cmd_var16));
+ registerCmd("var32", WRAP_METHOD(GobConsole, cmd_var32));
+ registerCmd("varString", WRAP_METHOD(GobConsole, cmd_varString));
+ registerCmd("cheat", WRAP_METHOD(GobConsole, cmd_cheat));
+ registerCmd("listArchives", WRAP_METHOD(GobConsole, cmd_listArchives));
}
GobConsole::~GobConsole() {
@@ -51,7 +51,7 @@ void GobConsole::unregisterCheater() {
}
bool GobConsole::cmd_varSize(int argc, const char **argv) {
- DebugPrintf("Size of the variable space: %d bytes\n", _vm->_inter->_variables->getSize());
+ debugPrintf("Size of the variable space: %d bytes\n", _vm->_inter->_variables->getSize());
return true;
}
@@ -74,14 +74,14 @@ bool GobConsole::cmd_dumpVars(int argc, const char **argv) {
bool GobConsole::cmd_var8(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: var8 <var offset> (<value>)\n");
+ debugPrintf("Usage: var8 <var offset> (<value>)\n");
return true;
}
uint32 varNum = atoi(argv[1]);
if (varNum >= _vm->_inter->_variables->getSize()) {
- DebugPrintf("Variable offset out of range\n");
+ debugPrintf("Variable offset out of range\n");
return true;
}
@@ -90,21 +90,21 @@ bool GobConsole::cmd_var8(int argc, const char **argv) {
_vm->_inter->_variables->writeOff8(varNum, varVal);
}
- DebugPrintf("var8_%d = %d\n", varNum, _vm->_inter->_variables->readOff8(varNum));
+ debugPrintf("var8_%d = %d\n", varNum, _vm->_inter->_variables->readOff8(varNum));
return true;
}
bool GobConsole::cmd_var16(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: var16 <var offset> (<value>)\n");
+ debugPrintf("Usage: var16 <var offset> (<value>)\n");
return true;
}
uint32 varNum = atoi(argv[1]);
if ((varNum + 1) >= _vm->_inter->_variables->getSize()) {
- DebugPrintf("Variable offset out of range\n");
+ debugPrintf("Variable offset out of range\n");
return true;
}
@@ -113,21 +113,21 @@ bool GobConsole::cmd_var16(int argc, const char **argv) {
_vm->_inter->_variables->writeOff16(varNum, varVal);
}
- DebugPrintf("var16_%d = %d\n", varNum, _vm->_inter->_variables->readOff16(varNum));
+ debugPrintf("var16_%d = %d\n", varNum, _vm->_inter->_variables->readOff16(varNum));
return true;
}
bool GobConsole::cmd_var32(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: var32 <var offset> (<value>)\n");
+ debugPrintf("Usage: var32 <var offset> (<value>)\n");
return true;
}
uint32 varNum = atoi(argv[1]);
if ((varNum + 3) >= _vm->_inter->_variables->getSize()) {
- DebugPrintf("Variable offset out of range\n");
+ debugPrintf("Variable offset out of range\n");
return true;
}
@@ -136,21 +136,21 @@ bool GobConsole::cmd_var32(int argc, const char **argv) {
_vm->_inter->_variables->writeOff32(varNum, varVal);
}
- DebugPrintf("var8_%d = %d\n", varNum, _vm->_inter->_variables->readOff32(varNum));
+ debugPrintf("var8_%d = %d\n", varNum, _vm->_inter->_variables->readOff32(varNum));
return true;
}
bool GobConsole::cmd_varString(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: varString <var offset> (<value>)\n");
+ debugPrintf("Usage: varString <var offset> (<value>)\n");
return true;
}
uint32 varNum = atoi(argv[1]);
if (varNum >= _vm->_inter->_variables->getSize()) {
- DebugPrintf("Variable offset out of range\n");
+ debugPrintf("Variable offset out of range\n");
return true;
}
@@ -160,7 +160,7 @@ bool GobConsole::cmd_varString(int argc, const char **argv) {
Common::strlcpy(_vm->_inter->_variables->getAddressOffString(varNum), argv[2], maxLength);
}
- DebugPrintf("varString_%d = \"%s\"\n", varNum, _vm->_inter->_variables->getAddressOffString(varNum));
+ debugPrintf("varString_%d = \"%s\"\n", varNum, _vm->_inter->_variables->getAddressOffString(varNum));
return true;
}
@@ -177,11 +177,11 @@ bool GobConsole::cmd_listArchives(int argc, const char **argv) {
_vm->_dataIO->getArchiveInfo(info);
- DebugPrintf(" Archive | Base | FileCount\n");
- DebugPrintf("--------------------------------\n");
+ debugPrintf(" Archive | Base | FileCount\n");
+ debugPrintf("--------------------------------\n");
for (Common::Array<ArchiveInfo>::const_iterator it = info.begin(); it != info.end(); ++it)
if (!it->name.empty())
- DebugPrintf("%13s | %d | %d\n", it->name.c_str(), it->base, it->fileCount);
+ debugPrintf("%13s | %d | %d\n", it->name.c_str(), it->base, it->fileCount);
return true;
}
diff --git a/engines/groovie/debug.cpp b/engines/groovie/debug.cpp
index 8103e4f4c6..16db20413f 100644
--- a/engines/groovie/debug.cpp
+++ b/engines/groovie/debug.cpp
@@ -36,16 +36,16 @@ Debugger::Debugger(GroovieEngine *vm) :
_vm(vm), _script(_vm->_script) {
// Register the debugger comands
- DCmd_Register("step", WRAP_METHOD(Debugger, cmd_step));
- DCmd_Register("go", WRAP_METHOD(Debugger, cmd_go));
- DCmd_Register("pc", WRAP_METHOD(Debugger, cmd_pc));
- DCmd_Register("fg", WRAP_METHOD(Debugger, cmd_fg));
- DCmd_Register("bg", WRAP_METHOD(Debugger, cmd_bg));
- DCmd_Register("mem", WRAP_METHOD(Debugger, cmd_mem));
- DCmd_Register("load", WRAP_METHOD(Debugger, cmd_loadgame));
- DCmd_Register("save", WRAP_METHOD(Debugger, cmd_savegame));
- DCmd_Register("playref", WRAP_METHOD(Debugger, cmd_playref));
- DCmd_Register("dumppal", WRAP_METHOD(Debugger, cmd_dumppal));
+ registerCmd("step", WRAP_METHOD(Debugger, cmd_step));
+ registerCmd("go", WRAP_METHOD(Debugger, cmd_go));
+ registerCmd("pc", WRAP_METHOD(Debugger, cmd_pc));
+ registerCmd("fg", WRAP_METHOD(Debugger, cmd_fg));
+ registerCmd("bg", WRAP_METHOD(Debugger, cmd_bg));
+ registerCmd("mem", WRAP_METHOD(Debugger, cmd_mem));
+ registerCmd("load", WRAP_METHOD(Debugger, cmd_loadgame));
+ registerCmd("save", WRAP_METHOD(Debugger, cmd_savegame));
+ registerCmd("playref", WRAP_METHOD(Debugger, cmd_playref));
+ registerCmd("dumppal", WRAP_METHOD(Debugger, cmd_dumppal));
}
Debugger::~Debugger() {
@@ -81,7 +81,7 @@ bool Debugger::cmd_pc(int argc, const char **argv) {
int val = getNumber(argv[1]);
_script->_currentInstruction = val;
}
- DebugPrintf("pc = 0x%04X (%d)\n", _script->_currentInstruction, _script->_currentInstruction);
+ debugPrintf("pc = 0x%04X (%d)\n", _script->_currentInstruction, _script->_currentInstruction);
return true;
}
@@ -97,9 +97,9 @@ bool Debugger::cmd_mem(int argc, const char **argv) {
// Get
val = _script->_variables[pos];
}
- DebugPrintf("mem[0x%04X] = 0x%02X\n", pos, val);
+ debugPrintf("mem[0x%04X] = 0x%02X\n", pos, val);
} else {
- DebugPrintf("Syntax: mem <addr> [<val>]\n");
+ debugPrintf("Syntax: mem <addr> [<val>]\n");
}
return true;
}
@@ -109,7 +109,7 @@ bool Debugger::cmd_loadgame(int argc, const char **argv) {
int slot = getNumber(argv[1]);
_script->loadgame(slot);
} else {
- DebugPrintf("Syntax: load <slot>\n");
+ debugPrintf("Syntax: load <slot>\n");
}
return true;
}
@@ -119,7 +119,7 @@ bool Debugger::cmd_savegame(int argc, const char **argv) {
int slot = getNumber(argv[1]);
_script->savegame(slot);
} else {
- DebugPrintf("Syntax: save <slot>\n");
+ debugPrintf("Syntax: save <slot>\n");
}
return true;
}
@@ -129,7 +129,7 @@ bool Debugger::cmd_playref(int argc, const char **argv) {
int ref = getNumber(argv[1]);
_script->playvideofromref(ref);
} else {
- DebugPrintf("Syntax: playref <videorefnum>\n");
+ debugPrintf("Syntax: playref <videorefnum>\n");
}
return true;
}
@@ -140,7 +140,7 @@ bool Debugger::cmd_dumppal(int argc, const char **argv) {
_vm->_system->getPaletteManager()->grabPalette(palettedump, 0, 256);
for (i = 0; i < 256; i++) {
- DebugPrintf("%3d: %3d,%3d,%3d\n", i, palettedump[(i * 3)], palettedump[(i * 3) + 1], palettedump[(i * 3) + 2]);
+ debugPrintf("%3d: %3d,%3d,%3d\n", i, palettedump[(i * 3)], palettedump[(i * 3) + 1], palettedump[(i * 3) + 2]);
}
return true;
}
diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp
index 1307cd5796..84d5c631c7 100644
--- a/engines/hopkins/computer.cpp
+++ b/engines/hopkins/computer.cpp
@@ -38,10 +38,9 @@ namespace Hopkins {
ComputerManager::ComputerManager(HopkinsEngine *vm) {
_vm = vm;
- for (int i = 0; i < 50; i++) {
- _menuText[i]._actvFl = false;
+ for (int i = 0; i < ARRAYSIZE(_menuText); i++) {
_menuText[i]._lineSize = 0;
- memset(_menuText[i]._line, 0, 90);
+ memset(_menuText[i]._line, 0, ARRAYSIZE(_menuText[0]._line));
}
Common::fill(&_inputBuf[0], &_inputBuf[200], '\0');
_breakoutSpr = NULL;
@@ -346,6 +345,7 @@ static const char _spanishText[] =
* Load Menu data
*/
void ComputerManager::loadMenu() {
+ debug(9, "ComputerManager::loadMenu()");
char *ptr;
if (_vm->_fileIO->fileExists("COMPUTAN.TXT")) {
ptr = (char *)_vm->_fileIO->loadFile("COMPUTAN.TXT");
@@ -353,46 +353,52 @@ void ComputerManager::loadMenu() {
switch (_vm->_globals->_language) {
case LANG_FR:
ptr = (char *)_vm->_globals->allocMemory(sizeof(_frenchText));
- strcpy(ptr, _frenchText);
+ Common::strlcpy(ptr, _frenchText, sizeof(_frenchText));
break;
case LANG_SP:
ptr = (char *)_vm->_globals->allocMemory(sizeof(_spanishText));
- strcpy(ptr, _spanishText);
+ Common::strlcpy(ptr, _spanishText, sizeof(_spanishText));
break;
default:
ptr = (char *)_vm->_globals->allocMemory(sizeof(_englishText));
- strcpy(ptr, _englishText);
+ Common::strlcpy(ptr, _englishText, sizeof(_englishText));
break;
}
}
char *tmpPtr = ptr;
int lineNum = 0;
- int strPos;
- bool loopCond = false;
- do {
- if (tmpPtr[0] == '%') {
- if (tmpPtr[1] == '%') {
- loopCond = true;
- break;
- }
- _menuText[lineNum]._actvFl = 1;
- strPos = 0;
- while (strPos <= 89) {
+ const char lineSep = tmpPtr[0];
+
+ while (tmpPtr[0] != '\0' && lineNum < ARRAYSIZE(_menuText)) {
+ if (tmpPtr[0] == '%' && tmpPtr[1] == '%') {
+ // End of file marker found - Break out of parse loop
+ break;
+ }
+
+ if (tmpPtr[0] == lineSep) {
+ int strPos = 0;
+ while (strPos < ARRAYSIZE(_menuText[0]._line)) {
char curChar = tmpPtr[strPos + 2];
- if (curChar == '%' || curChar == 10)
+ if (curChar == '\0' || curChar == lineSep || curChar == 0x0a) // Line Feed
break;
_menuText[lineNum]._line[strPos++] = curChar;
}
- if (strPos <= 89) {
+
+ if (strPos < ARRAYSIZE(_menuText[0]._line)) {
_menuText[lineNum]._line[strPos] = 0;
_menuText[lineNum]._lineSize = strPos - 1;
}
- ++lineNum;
+
+ if (strPos != 0) {
+ debug(9, "_menuText[%d]._line (size: %d): \"%s\"", lineNum, _menuText[lineNum]._lineSize, _menuText[lineNum]._line);
+ ++lineNum;
+ }
}
++tmpPtr;
- } while (!loopCond);
+ }
+
_vm->_globals->freeMemory((byte *)ptr);
}
diff --git a/engines/hopkins/computer.h b/engines/hopkins/computer.h
index e8857a234b..ba50dca4cf 100644
--- a/engines/hopkins/computer.h
+++ b/engines/hopkins/computer.h
@@ -31,22 +31,22 @@ namespace Hopkins {
class HopkinsEngine;
-struct MenuItem {
- bool _actvFl;
- int _lineSize;
- char _line[90];
-};
-
-struct ScoreItem {
- Common::String _name;
- Common::String _score;
-};
-
enum ComputerEnum { COMPUTER_HOPKINS = 1, COMPUTER_SAMANTHA = 2, COMPUTER_PUBLIC = 3 };
class ComputerManager {
private:
HopkinsEngine *_vm;
+
+ struct MenuItem {
+ int _lineSize;
+ char _line[90];
+ };
+
+ struct ScoreItem {
+ Common::String _name;
+ Common::String _score;
+ };
+
MenuItem _menuText[50];
char _inputBuf[200];
ScoreItem _score[6];
@@ -84,14 +84,14 @@ private:
void displayLives();
void displayBricks();
void displayGamesSubMenu();
- int displayHiscores();
+ int displayHiscores();
void displayHiscoreLine(const byte *objectData, int x, int y, int curChar);
void displayMessage(int xp, int yp, int textIdx);
void displayScore();
void displayScoreChar(int charPos, int charDisp);
void getScoreName();
void playBreakout();
- int moveBall();
+ int moveBall();
void saveScore();
void checkBallCollisions();
diff --git a/engines/hopkins/debugger.cpp b/engines/hopkins/debugger.cpp
index 14b1c183a8..3dcfdfea7b 100644
--- a/engines/hopkins/debugger.cpp
+++ b/engines/hopkins/debugger.cpp
@@ -30,18 +30,18 @@ namespace Hopkins {
Debugger::Debugger(HopkinsEngine *vm) : GUI::Debugger() {
_vm = vm;
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("rects", WRAP_METHOD(Debugger, cmd_DirtyRects));
- DCmd_Register("teleport", WRAP_METHOD(Debugger, cmd_Teleport));
- DCmd_Register("show_room", WRAP_METHOD(Debugger, cmd_ShowCurrentRoom));
- DCmd_Register("zones", WRAP_METHOD(Debugger, cmd_Zones));
- DCmd_Register("lines", WRAP_METHOD(Debugger, cmd_Lines));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("rects", WRAP_METHOD(Debugger, cmd_DirtyRects));
+ registerCmd("teleport", WRAP_METHOD(Debugger, cmd_Teleport));
+ registerCmd("show_room", WRAP_METHOD(Debugger, cmd_ShowCurrentRoom));
+ registerCmd("zones", WRAP_METHOD(Debugger, cmd_Zones));
+ registerCmd("lines", WRAP_METHOD(Debugger, cmd_Lines));
}
// Turns dirty rects on or off
bool Debugger::cmd_DirtyRects(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("%s: [on | off]\n", argv[0]);
+ debugPrintf("%s: [on | off]\n", argv[0]);
return true;
} else {
_vm->_graphicsMan->_showDirtyRects = !strcmp(argv[1], "on");
@@ -52,7 +52,7 @@ bool Debugger::cmd_DirtyRects(int argc, const char **argv) {
// Change room number
bool Debugger::cmd_Teleport(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("%s: [Room number]\n", argv[0]);
+ debugPrintf("%s: [Room number]\n", argv[0]);
return true;
} else {
_vm->_globals->_exitId = atoi(argv[1]);
@@ -62,13 +62,13 @@ bool Debugger::cmd_Teleport(int argc, const char **argv) {
// Display room number
bool Debugger::cmd_ShowCurrentRoom(int argc, const char **argv) {
- DebugPrintf("Current room: %d\n", _vm->_globals->_curRoomNum);
+ debugPrintf("Current room: %d\n", _vm->_globals->_curRoomNum);
return true;
}
bool Debugger::cmd_Zones(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("%s: [on | off]\n", argv[0]);
+ debugPrintf("%s: [on | off]\n", argv[0]);
return true;
} else {
_vm->_graphicsMan->_showZones = !strcmp(argv[1], "on");
@@ -78,7 +78,7 @@ if (argc != 2) {
bool Debugger::cmd_Lines(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("%s: [on | off]\n", argv[0]);
+ debugPrintf("%s: [on | off]\n", argv[0]);
return true;
} else {
_vm->_graphicsMan->_showLines = !strcmp(argv[1], "on");
diff --git a/engines/hopkins/files.cpp b/engines/hopkins/files.cpp
index 75f429f860..6620f2878c 100644
--- a/engines/hopkins/files.cpp
+++ b/engines/hopkins/files.cpp
@@ -51,12 +51,13 @@ byte *FileManager::loadFile(const Common::String &file) {
// Allocate space for the file contents
size_t filesize = f.size();
- byte *data = _vm->_globals->allocMemory(filesize);
+ byte *data = _vm->_globals->allocMemory(filesize+1);
if (!data)
error("Error allocating space for file being loaded - %s", file.c_str());
readStream(f, data, filesize);
f.close();
+ data[filesize] = '\0';
return data;
}
diff --git a/engines/hugo/console.cpp b/engines/hugo/console.cpp
index 56025bfbfd..d02c42658f 100644
--- a/engines/hugo/console.cpp
+++ b/engines/hugo/console.cpp
@@ -30,12 +30,12 @@
namespace Hugo {
HugoConsole::HugoConsole(HugoEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("listscreens", WRAP_METHOD(HugoConsole, Cmd_listScreens));
- DCmd_Register("listobjects", WRAP_METHOD(HugoConsole, Cmd_listObjects));
- DCmd_Register("getobject", WRAP_METHOD(HugoConsole, Cmd_getObject));
- DCmd_Register("getallobjects", WRAP_METHOD(HugoConsole, Cmd_getAllObjects));
- DCmd_Register("gotoscreen", WRAP_METHOD(HugoConsole, Cmd_gotoScreen));
- DCmd_Register("Boundaries", WRAP_METHOD(HugoConsole, Cmd_boundaries));
+ registerCmd("listscreens", WRAP_METHOD(HugoConsole, Cmd_listScreens));
+ registerCmd("listobjects", WRAP_METHOD(HugoConsole, Cmd_listObjects));
+ registerCmd("getobject", WRAP_METHOD(HugoConsole, Cmd_getObject));
+ registerCmd("getallobjects", WRAP_METHOD(HugoConsole, Cmd_getAllObjects));
+ registerCmd("gotoscreen", WRAP_METHOD(HugoConsole, Cmd_gotoScreen));
+ registerCmd("Boundaries", WRAP_METHOD(HugoConsole, Cmd_boundaries));
}
HugoConsole::~HugoConsole() {
@@ -62,7 +62,7 @@ static int strToInt(const char *s) {
*/
bool HugoConsole::Cmd_gotoScreen(int argc, const char **argv) {
if ((argc != 2) || (strToInt(argv[1]) > _vm->_numScreens)){
- DebugPrintf("Usage: %s <screen number>\n", argv[0]);
+ debugPrintf("Usage: %s <screen number>\n", argv[0]);
return true;
}
@@ -75,13 +75,13 @@ bool HugoConsole::Cmd_gotoScreen(int argc, const char **argv) {
*/
bool HugoConsole::Cmd_listScreens(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
- DebugPrintf("Available screens for this game are:\n");
+ debugPrintf("Available screens for this game are:\n");
for (int i = 0; i < _vm->_numScreens; i++)
- DebugPrintf("%2d - %s\n", i, _vm->_text->getScreenNames(i));
+ debugPrintf("%2d - %s\n", i, _vm->_text->getScreenNames(i));
return true;
}
@@ -90,14 +90,14 @@ bool HugoConsole::Cmd_listScreens(int argc, const char **argv) {
*/
bool HugoConsole::Cmd_listObjects(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
- DebugPrintf("Available objects for this game are:\n");
+ debugPrintf("Available objects for this game are:\n");
for (int i = 0; i < _vm->_object->_numObj; i++) {
if (_vm->_object->_objects[i]._genericCmd & TAKE)
- DebugPrintf("%2d - %s\n", i, _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2));
+ debugPrintf("%2d - %s\n", i, _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2));
}
return true;
}
@@ -107,14 +107,14 @@ bool HugoConsole::Cmd_listObjects(int argc, const char **argv) {
*/
bool HugoConsole::Cmd_getObject(int argc, const char **argv) {
if ((argc != 2) || (strToInt(argv[1]) > _vm->_object->_numObj)) {
- DebugPrintf("Usage: %s <object number>\n", argv[0]);
+ debugPrintf("Usage: %s <object number>\n", argv[0]);
return true;
}
if (_vm->_object->_objects[strToInt(argv[1])]._genericCmd & TAKE)
_vm->_parser->takeObject(&_vm->_object->_objects[strToInt(argv[1])]);
else
- DebugPrintf("Object not available\n");
+ debugPrintf("Object not available\n");
return true;
}
@@ -124,7 +124,7 @@ bool HugoConsole::Cmd_getObject(int argc, const char **argv) {
*/
bool HugoConsole::Cmd_getAllObjects(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
@@ -141,7 +141,7 @@ bool HugoConsole::Cmd_getAllObjects(int argc, const char **argv) {
*/
bool HugoConsole::Cmd_boundaries(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index e4806afb70..4a90722a35 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -40,45 +40,45 @@ Debugger::Debugger(KyraEngine_v1 *vm)
}
void Debugger::initialize() {
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("screen_debug_mode", WRAP_METHOD(Debugger, cmd_setScreenDebug));
- DCmd_Register("load_palette", WRAP_METHOD(Debugger, cmd_loadPalette));
- DCmd_Register("facings", WRAP_METHOD(Debugger, cmd_showFacings));
- DCmd_Register("gamespeed", WRAP_METHOD(Debugger, cmd_gameSpeed));
- DCmd_Register("flags", WRAP_METHOD(Debugger, cmd_listFlags));
- DCmd_Register("toggleflag", WRAP_METHOD(Debugger, cmd_toggleFlag));
- DCmd_Register("queryflag", WRAP_METHOD(Debugger, cmd_queryFlag));
- DCmd_Register("timers", WRAP_METHOD(Debugger, cmd_listTimers));
- DCmd_Register("settimercountdown", WRAP_METHOD(Debugger, cmd_setTimerCountdown));
-}
-
-bool Debugger::cmd_setScreenDebug(int argc, const char **argv) {
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("screen_debug_mode", WRAP_METHOD(Debugger, cmdSetScreenDebug));
+ registerCmd("load_palette", WRAP_METHOD(Debugger, cmdLoadPalette));
+ registerCmd("facings", WRAP_METHOD(Debugger, cmdShowFacings));
+ registerCmd("gamespeed", WRAP_METHOD(Debugger, cmdGameSpeed));
+ registerCmd("flags", WRAP_METHOD(Debugger, cmdListFlags));
+ registerCmd("toggleflag", WRAP_METHOD(Debugger, cmdToggleFlag));
+ registerCmd("queryflag", WRAP_METHOD(Debugger, cmdQueryFlag));
+ registerCmd("timers", WRAP_METHOD(Debugger, cmdListTimers));
+ registerCmd("settimercountdown", WRAP_METHOD(Debugger, cmdSetTimerCountdown));
+}
+
+bool Debugger::cmdSetScreenDebug(int argc, const char **argv) {
if (argc > 1) {
if (scumm_stricmp(argv[1], "enable") == 0)
_vm->screen()->enableScreenDebug(true);
else if (scumm_stricmp(argv[1], "disable") == 0)
_vm->screen()->enableScreenDebug(false);
else
- DebugPrintf("Use screen_debug_mode <enable/disable> to enable or disable it.\n");
+ debugPrintf("Use screen_debug_mode <enable/disable> to enable or disable it.\n");
} else {
- DebugPrintf("Screen debug mode is %s.\n", (_vm->screen()->queryScreenDebug() ? "enabled" : "disabled"));
- DebugPrintf("Use screen_debug_mode <enable/disable> to enable or disable it.\n");
+ debugPrintf("Screen debug mode is %s.\n", (_vm->screen()->queryScreenDebug() ? "enabled" : "disabled"));
+ debugPrintf("Use screen_debug_mode <enable/disable> to enable or disable it.\n");
}
return true;
}
-bool Debugger::cmd_loadPalette(int argc, const char **argv) {
+bool Debugger::cmdLoadPalette(int argc, const char **argv) {
Palette palette(_vm->screen()->getPalette(0).getNumColors());
if (argc <= 1) {
- DebugPrintf("Use load_palette <file> [start_col] [end_col]\n");
+ debugPrintf("Use load_palette <file> [start_col] [end_col]\n");
return true;
}
if (_vm->game() != GI_KYRA1 && _vm->resource()->getFileSize(argv[1]) != 768) {
uint8 *buffer = new uint8[320 * 200 * sizeof(uint8)];
if (!buffer) {
- DebugPrintf("ERROR: Cannot allocate buffer for screen region!\n");
+ debugPrintf("ERROR: Cannot allocate buffer for screen region!\n");
return true;
}
@@ -89,7 +89,7 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
delete[] buffer;
} else if (!_vm->screen()->loadPalette(argv[1], palette)) {
- DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]);
+ debugPrintf("ERROR: Palette '%s' not found!\n", argv[1]);
return true;
}
@@ -111,87 +111,87 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
return true;
}
-bool Debugger::cmd_showFacings(int argc, const char **argv) {
- DebugPrintf("Facing directions:\n");
- DebugPrintf("7 0 1\n");
- DebugPrintf(" \\ | / \n");
- DebugPrintf("6--*--2\n");
- DebugPrintf(" / | \\\n");
- DebugPrintf("5 4 3\n");
+bool Debugger::cmdShowFacings(int argc, const char **argv) {
+ debugPrintf("Facing directions:\n");
+ debugPrintf("7 0 1\n");
+ debugPrintf(" \\ | / \n");
+ debugPrintf("6--*--2\n");
+ debugPrintf(" / | \\\n");
+ debugPrintf("5 4 3\n");
return true;
}
-bool Debugger::cmd_gameSpeed(int argc, const char **argv) {
+bool Debugger::cmdGameSpeed(int argc, const char **argv) {
if (argc == 2) {
int val = atoi(argv[1]);
if (val < 1 || val > 1000) {
- DebugPrintf("speed must lie between 1 and 1000 (default: 60)\n");
+ debugPrintf("speed must lie between 1 and 1000 (default: 60)\n");
return true;
}
_vm->_tickLength = (uint8)(1000.0 / val);
} else {
- DebugPrintf("Syntax: gamespeed <value>\n");
+ debugPrintf("Syntax: gamespeed <value>\n");
}
return true;
}
-bool Debugger::cmd_listFlags(int argc, const char **argv) {
+bool Debugger::cmdListFlags(int argc, const char **argv) {
for (int i = 0, p = 0; i < (int)sizeof(_vm->_flagsTable) * 8; i++, ++p) {
- DebugPrintf("(%-3i): %-2i", i, _vm->queryGameFlag(i));
+ debugPrintf("(%-3i): %-2i", i, _vm->queryGameFlag(i));
if (p == 5) {
- DebugPrintf("\n");
+ debugPrintf("\n");
p -= 6;
}
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
-bool Debugger::cmd_toggleFlag(int argc, const char **argv) {
+bool Debugger::cmdToggleFlag(int argc, const char **argv) {
if (argc > 1) {
uint flag = atoi(argv[1]);
if (_vm->queryGameFlag(flag))
_vm->resetGameFlag(flag);
else
_vm->setGameFlag(flag);
- DebugPrintf("Flag %i is now %i\n", flag, _vm->queryGameFlag(flag));
+ debugPrintf("Flag %i is now %i\n", flag, _vm->queryGameFlag(flag));
} else {
- DebugPrintf("Syntax: toggleflag <flag>\n");
+ debugPrintf("Syntax: toggleflag <flag>\n");
}
return true;
}
-bool Debugger::cmd_queryFlag(int argc, const char **argv) {
+bool Debugger::cmdQueryFlag(int argc, const char **argv) {
if (argc > 1) {
uint flag = atoi(argv[1]);
- DebugPrintf("Flag %i is %i\n", flag, _vm->queryGameFlag(flag));
+ debugPrintf("Flag %i is %i\n", flag, _vm->queryGameFlag(flag));
} else {
- DebugPrintf("Syntax: queryflag <flag>\n");
+ debugPrintf("Syntax: queryflag <flag>\n");
}
return true;
}
-bool Debugger::cmd_listTimers(int argc, const char **argv) {
- DebugPrintf("Current time: %-8u\n", g_system->getMillis());
+bool Debugger::cmdListTimers(int argc, const char **argv) {
+ debugPrintf("Current time: %-8u\n", g_system->getMillis());
for (int i = 0; i < _vm->timer()->count(); i++)
- DebugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i %-8u\n", i, _vm->timer()->isEnabled(i) ? "Yes" : "No", _vm->timer()->getDelay(i), _vm->timer()->getNextRun(i));
+ debugPrintf("Timer %-2i: Active: %-3s Countdown: %-6i %-8u\n", i, _vm->timer()->isEnabled(i) ? "Yes" : "No", _vm->timer()->getDelay(i), _vm->timer()->getNextRun(i));
return true;
}
-bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) {
+bool Debugger::cmdSetTimerCountdown(int argc, const char **argv) {
if (argc > 2) {
uint timer = atoi(argv[1]);
uint countdown = atoi(argv[2]);
_vm->timer()->setCountdown(timer, countdown);
- DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->timer()->getDelay(timer));
+ debugPrintf("Timer %i now has countdown %i\n", timer, _vm->timer()->getDelay(timer));
} else {
- DebugPrintf("Syntax: settimercountdown <timer> <countdown>\n");
+ debugPrintf("Syntax: settimercountdown <timer> <countdown>\n");
}
return true;
@@ -204,21 +204,21 @@ Debugger_LoK::Debugger_LoK(KyraEngine_LoK *vm)
}
void Debugger_LoK::initialize() {
- DCmd_Register("enter", WRAP_METHOD(Debugger_LoK, cmd_enterRoom));
- DCmd_Register("scenes", WRAP_METHOD(Debugger_LoK, cmd_listScenes));
- DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem));
- DCmd_Register("birthstones", WRAP_METHOD(Debugger_LoK, cmd_listBirthstones));
+ registerCmd("enter", WRAP_METHOD(Debugger_LoK, cmdEnterRoom));
+ registerCmd("scenes", WRAP_METHOD(Debugger_LoK, cmdListScenes));
+ registerCmd("give", WRAP_METHOD(Debugger_LoK, cmdGiveItem));
+ registerCmd("birthstones", WRAP_METHOD(Debugger_LoK, cmdListBirthstones));
Debugger::initialize();
}
-bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) {
+bool Debugger_LoK::cmdEnterRoom(int argc, const char **argv) {
uint direction = 0;
if (argc > 1) {
int room = atoi(argv[1]);
// game will crash if entering a non-existent room
if (room >= _vm->_roomTableSize) {
- DebugPrintf("room number must be any value between (including) 0 and %d\n", _vm->_roomTableSize - 1);
+ debugPrintf("room number must be any value between (including) 0 and %d\n", _vm->_roomTableSize - 1);
return true;
}
@@ -246,44 +246,44 @@ bool Debugger_LoK::cmd_enterRoom(int argc, const char **argv) {
return false;
}
- DebugPrintf("Syntax: room <roomnum> <direction>\n");
+ debugPrintf("Syntax: room <roomnum> <direction>\n");
return true;
}
-bool Debugger_LoK::cmd_listScenes(int argc, const char **argv) {
+bool Debugger_LoK::cmdListScenes(int argc, const char **argv) {
for (int i = 0; i < _vm->_roomTableSize; i++) {
- DebugPrintf("%-3i: %-10s", i, _vm->_roomFilenameTable[_vm->_roomTable[i].nameIndex]);
+ debugPrintf("%-3i: %-10s", i, _vm->_roomFilenameTable[_vm->_roomTable[i].nameIndex]);
if (!(i % 8))
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("\n");
- DebugPrintf("Current room: %i\n", _vm->_currentRoom);
+ debugPrintf("\n");
+ debugPrintf("Current room: %i\n", _vm->_currentRoom);
return true;
}
-bool Debugger_LoK::cmd_giveItem(int argc, const char **argv) {
+bool Debugger_LoK::cmdGiveItem(int argc, const char **argv) {
if (argc == 2) {
int item = atoi(argv[1]);
// Kyrandia 1 has only 108 items (-1 to 106), otherwise it will crash
if (item < -1 || item > 106) {
- DebugPrintf("'itemid' must be any value between (including) -1 and 106\n");
+ debugPrintf("'itemid' must be any value between (including) -1 and 106\n");
return true;
}
_vm->setMouseItem(item);
_vm->_itemInHand = item;
} else {
- DebugPrintf("Syntax: give <itemid>\n");
+ debugPrintf("Syntax: give <itemid>\n");
}
return true;
}
-bool Debugger_LoK::cmd_listBirthstones(int argc, const char **argv) {
- DebugPrintf("Needed birthstone gems:\n");
+bool Debugger_LoK::cmdListBirthstones(int argc, const char **argv) {
+ debugPrintf("Needed birthstone gems:\n");
for (int i = 0; i < ARRAYSIZE(_vm->_birthstoneGemTable); ++i)
- DebugPrintf("%-3d '%s'\n", _vm->_birthstoneGemTable[i], _vm->_itemList[_vm->_birthstoneGemTable[i]]);
+ debugPrintf("%-3d '%s'\n", _vm->_birthstoneGemTable[i], _vm->_itemList[_vm->_birthstoneGemTable[i]]);
return true;
}
@@ -293,23 +293,23 @@ Debugger_v2::Debugger_v2(KyraEngine_v2 *vm) : Debugger(vm), _vm(vm) {
}
void Debugger_v2::initialize() {
- DCmd_Register("character_info", WRAP_METHOD(Debugger_v2, cmd_characterInfo));
- DCmd_Register("enter", WRAP_METHOD(Debugger_v2, cmd_enterScene));
- DCmd_Register("scenes", WRAP_METHOD(Debugger_v2, cmd_listScenes));
- DCmd_Register("scene_info", WRAP_METHOD(Debugger_v2, cmd_sceneInfo));
- DCmd_Register("scene_to_facing", WRAP_METHOD(Debugger_v2, cmd_sceneToFacing));
- DCmd_Register("give", WRAP_METHOD(Debugger_v2, cmd_giveItem));
+ registerCmd("character_info", WRAP_METHOD(Debugger_v2, cmdCharacterInfo));
+ registerCmd("enter", WRAP_METHOD(Debugger_v2, cmdEnterScene));
+ registerCmd("scenes", WRAP_METHOD(Debugger_v2, cmdListScenes));
+ registerCmd("scene_info", WRAP_METHOD(Debugger_v2, cmdSceneInfo));
+ registerCmd("scene_to_facing", WRAP_METHOD(Debugger_v2, cmdSceneToFacing));
+ registerCmd("give", WRAP_METHOD(Debugger_v2, cmdGiveItem));
Debugger::initialize();
}
-bool Debugger_v2::cmd_enterScene(int argc, const char **argv) {
+bool Debugger_v2::cmdEnterScene(int argc, const char **argv) {
uint direction = 0;
if (argc > 1) {
int scene = atoi(argv[1]);
// game will crash if entering a non-existent scene
if (scene >= _vm->_sceneListSize) {
- DebugPrintf("scene number must be any value between (including) 0 and %d\n", _vm->_sceneListSize - 1);
+ debugPrintf("scene number must be any value between (including) 0 and %d\n", _vm->_sceneListSize - 1);
return true;
}
@@ -337,40 +337,40 @@ bool Debugger_v2::cmd_enterScene(int argc, const char **argv) {
return false;
}
- DebugPrintf("Syntax: %s <scenenum> <direction>\n", argv[0]);
+ debugPrintf("Syntax: %s <scenenum> <direction>\n", argv[0]);
return true;
}
-bool Debugger_v2::cmd_listScenes(int argc, const char **argv) {
+bool Debugger_v2::cmdListScenes(int argc, const char **argv) {
int shown = 1;
for (int i = 0; i < _vm->_sceneListSize; ++i) {
if (_vm->_sceneList[i].filename1[0]) {
- DebugPrintf("%-2i: %-10s", i, _vm->_sceneList[i].filename1);
+ debugPrintf("%-2i: %-10s", i, _vm->_sceneList[i].filename1);
if (!(shown % 5))
- DebugPrintf("\n");
+ debugPrintf("\n");
++shown;
}
}
- DebugPrintf("\n");
- DebugPrintf("Current scene: %i\n", _vm->_currentScene);
+ debugPrintf("\n");
+ debugPrintf("Current scene: %i\n", _vm->_currentScene);
return true;
}
-bool Debugger_v2::cmd_sceneInfo(int argc, const char **argv) {
- DebugPrintf("Current scene: %d '%s'\n", _vm->_currentScene, _vm->_sceneList[_vm->_currentScene].filename1);
- DebugPrintf("\n");
- DebugPrintf("Exit information:\n");
- DebugPrintf("Exit1: leads to %d, position %dx%d\n", int16(_vm->_sceneExit1), _vm->_sceneEnterX1, _vm->_sceneEnterY1);
- DebugPrintf("Exit2: leads to %d, position %dx%d\n", int16(_vm->_sceneExit2), _vm->_sceneEnterX2, _vm->_sceneEnterY2);
- DebugPrintf("Exit3: leads to %d, position %dx%d\n", int16(_vm->_sceneExit3), _vm->_sceneEnterX3, _vm->_sceneEnterY3);
- DebugPrintf("Exit4: leads to %d, position %dx%d\n", int16(_vm->_sceneExit4), _vm->_sceneEnterX4, _vm->_sceneEnterY4);
- DebugPrintf("Special exit information:\n");
+bool Debugger_v2::cmdSceneInfo(int argc, const char **argv) {
+ debugPrintf("Current scene: %d '%s'\n", _vm->_currentScene, _vm->_sceneList[_vm->_currentScene].filename1);
+ debugPrintf("\n");
+ debugPrintf("Exit information:\n");
+ debugPrintf("Exit1: leads to %d, position %dx%d\n", int16(_vm->_sceneExit1), _vm->_sceneEnterX1, _vm->_sceneEnterY1);
+ debugPrintf("Exit2: leads to %d, position %dx%d\n", int16(_vm->_sceneExit2), _vm->_sceneEnterX2, _vm->_sceneEnterY2);
+ debugPrintf("Exit3: leads to %d, position %dx%d\n", int16(_vm->_sceneExit3), _vm->_sceneEnterX3, _vm->_sceneEnterY3);
+ debugPrintf("Exit4: leads to %d, position %dx%d\n", int16(_vm->_sceneExit4), _vm->_sceneEnterX4, _vm->_sceneEnterY4);
+ debugPrintf("Special exit information:\n");
if (!_vm->_specialExitCount) {
- DebugPrintf("No special exits.\n");
+ debugPrintf("No special exits.\n");
} else {
- DebugPrintf("This scene has %d special exits.\n", _vm->_specialExitCount);
+ debugPrintf("This scene has %d special exits.\n", _vm->_specialExitCount);
for (int i = 0; i < _vm->_specialExitCount; ++i) {
- DebugPrintf("SpecialExit%d: facing %d, position (x1/y1/x2/y2): %d/%d/%d/%d\n", i,
+ debugPrintf("SpecialExit%d: facing %d, position (x1/y1/x2/y2): %d/%d/%d/%d\n", i,
_vm->_specialExitTable[20 + i], _vm->_specialExitTable[0 + i], _vm->_specialExitTable[5 + i],
_vm->_specialExitTable[10 + i], _vm->_specialExitTable[15 + i]);
}
@@ -379,20 +379,20 @@ bool Debugger_v2::cmd_sceneInfo(int argc, const char **argv) {
return true;
}
-bool Debugger_v2::cmd_characterInfo(int argc, const char **argv) {
- DebugPrintf("Main character is in scene: %d '%s'\n", _vm->_mainCharacter.sceneId, _vm->_sceneList[_vm->_mainCharacter.sceneId].filename1);
- DebugPrintf("Position: %dx%d\n", _vm->_mainCharacter.x1, _vm->_mainCharacter.y1);
- DebugPrintf("Facing: %d\n", _vm->_mainCharacter.facing);
- DebugPrintf("Inventory:\n");
+bool Debugger_v2::cmdCharacterInfo(int argc, const char **argv) {
+ debugPrintf("Main character is in scene: %d '%s'\n", _vm->_mainCharacter.sceneId, _vm->_sceneList[_vm->_mainCharacter.sceneId].filename1);
+ debugPrintf("Position: %dx%d\n", _vm->_mainCharacter.x1, _vm->_mainCharacter.y1);
+ debugPrintf("Facing: %d\n", _vm->_mainCharacter.facing);
+ debugPrintf("Inventory:\n");
for (int i = 0; i < 20; ++i) {
- DebugPrintf("%-2d ", int8(_vm->_mainCharacter.inventory[i]));
+ debugPrintf("%-2d ", int8(_vm->_mainCharacter.inventory[i]));
if (i == 9 || i == 19)
- DebugPrintf("\n");
+ debugPrintf("\n");
}
return true;
}
-bool Debugger_v2::cmd_sceneToFacing(int argc, const char **argv) {
+bool Debugger_v2::cmdSceneToFacing(int argc, const char **argv) {
if (argc == 2) {
int facing = atoi(argv[1]);
int16 exit = -1;
@@ -418,26 +418,26 @@ bool Debugger_v2::cmd_sceneToFacing(int argc, const char **argv) {
break;
}
- DebugPrintf("Exit to facing %d leads to room %d.\n", facing, exit);
+ debugPrintf("Exit to facing %d leads to room %d.\n", facing, exit);
} else {
- DebugPrintf("Usage: %s <facing>\n", argv[0]);
+ debugPrintf("Usage: %s <facing>\n", argv[0]);
}
return true;
}
-bool Debugger_v2::cmd_giveItem(int argc, const char **argv) {
+bool Debugger_v2::cmdGiveItem(int argc, const char **argv) {
if (argc == 2) {
int item = atoi(argv[1]);
if (item < -1 || item > _vm->engineDesc().maxItemId) {
- DebugPrintf("itemid must be any value between (including) -1 and %d\n", _vm->engineDesc().maxItemId);
+ debugPrintf("itemid must be any value between (including) -1 and %d\n", _vm->engineDesc().maxItemId);
return true;
}
_vm->setHandItem(item);
} else {
- DebugPrintf("Syntax: give <itemid>\n");
+ debugPrintf("Syntax: give <itemid>\n");
}
return true;
@@ -449,22 +449,22 @@ Debugger_HoF::Debugger_HoF(KyraEngine_HoF *vm) : Debugger_v2(vm), _vm(vm) {
}
void Debugger_HoF::initialize() {
- DCmd_Register("pass_codes", WRAP_METHOD(Debugger_HoF, cmd_passcodes));
+ registerCmd("pass_codes", WRAP_METHOD(Debugger_HoF, cmdPasscodes));
Debugger_v2::initialize();
}
-bool Debugger_HoF::cmd_passcodes(int argc, const char **argv) {
+bool Debugger_HoF::cmdPasscodes(int argc, const char **argv) {
if (argc == 2) {
int val = atoi(argv[1]);
if (val < 0 || val > 1) {
- DebugPrintf("value must be either 1 (on) or 0 (off)\n");
+ debugPrintf("value must be either 1 (on) or 0 (off)\n");
return true;
}
_vm->_dbgPass = val;
} else {
- DebugPrintf("Syntax: pass_codes <0/1>\n");
+ debugPrintf("Syntax: pass_codes <0/1>\n");
}
return true;
@@ -482,43 +482,43 @@ Debugger_EoB::Debugger_EoB(EoBCoreEngine *vm) : Debugger(vm), _vm(vm) {
}
void Debugger_EoB::initialize() {
- DCmd_Register("import_savefile", WRAP_METHOD(Debugger_EoB, cmd_importSaveFile));
- DCmd_Register("save_original", WRAP_METHOD(Debugger_EoB, cmd_saveOriginal));
- DCmd_Register("list_monsters", WRAP_METHOD(Debugger_EoB, cmd_listMonsters));
- DCmd_Register("show_position", WRAP_METHOD(Debugger_EoB, cmd_showPosition));
- DCmd_Register("set_position", WRAP_METHOD(Debugger_EoB, cmd_setPosition));
- DCmd_Register("open_door", WRAP_METHOD(Debugger_EoB, cmd_openDoor));
- DCmd_Register("close_door", WRAP_METHOD(Debugger_EoB, cmd_closeDoor));
- DCmd_Register("list_flags", WRAP_METHOD(Debugger_EoB, cmd_listFlags));
- DCmd_Register("set_flag", WRAP_METHOD(Debugger_EoB, cmd_setFlag));
- DCmd_Register("clear_flag", WRAP_METHOD(Debugger_EoB, cmd_clearFlag));
-}
-
-bool Debugger_EoB::cmd_importSaveFile(int argc, const char **argv) {
+ registerCmd("import_savefile", WRAP_METHOD(Debugger_EoB, cmdImportSaveFile));
+ registerCmd("save_original", WRAP_METHOD(Debugger_EoB, cmdSaveOriginal));
+ registerCmd("list_monsters", WRAP_METHOD(Debugger_EoB, cmdListMonsters));
+ registerCmd("show_position", WRAP_METHOD(Debugger_EoB, cmdShowPosition));
+ registerCmd("set_position", WRAP_METHOD(Debugger_EoB, cmdSetPosition));
+ registerCmd("open_door", WRAP_METHOD(Debugger_EoB, cmdOpenDoor));
+ registerCmd("close_door", WRAP_METHOD(Debugger_EoB, cmdCloseDoor));
+ registerCmd("list_flags", WRAP_METHOD(Debugger_EoB, cmdListFlags));
+ registerCmd("set_flag", WRAP_METHOD(Debugger_EoB, cmdSetFlag));
+ registerCmd("clear_flag", WRAP_METHOD(Debugger_EoB, cmdClearFlag));
+}
+
+bool Debugger_EoB::cmdImportSaveFile(int argc, const char **argv) {
if (!_vm->_allowImport) {
- DebugPrintf("This command only works from the main menu.\n");
+ debugPrintf("This command only works from the main menu.\n");
return true;
}
if (argc == 3) {
int slot = atoi(argv[1]);
if (slot < -1 || slot > 989) {
- DebugPrintf("slot must be between (including) -1 and 989 \n");
+ debugPrintf("slot must be between (including) -1 and 989 \n");
return true;
}
- DebugPrintf(_vm->importOriginalSaveFile(slot, argv[2]) ? "Success.\n" : "Failure.\n");
+ debugPrintf(_vm->importOriginalSaveFile(slot, argv[2]) ? "Success.\n" : "Failure.\n");
_vm->loadItemDefs();
} else {
- DebugPrintf("Syntax: import_savefile <dest slot> <source file>\n (Imports source save game file to dest slot.)\n import_savefile -1\n (Imports all original save game files found and puts them into the first available slots.)\n\n");
+ debugPrintf("Syntax: import_savefile <dest slot> <source file>\n (Imports source save game file to dest slot.)\n import_savefile -1\n (Imports all original save game files found and puts them into the first available slots.)\n\n");
}
return true;
}
-bool Debugger_EoB::cmd_saveOriginal(int argc, const char **argv) {
+bool Debugger_EoB::cmdSaveOriginal(int argc, const char **argv) {
if (!_vm->_runFlag) {
- DebugPrintf("This command doesn't work during intro or outro sequences,\nfrom the main menu or from the character generation.\n");
+ debugPrintf("This command doesn't work during intro or outro sequences,\nfrom the main menu or from the character generation.\n");
return true;
}
@@ -535,57 +535,57 @@ bool Debugger_EoB::cmd_saveOriginal(int argc, const char **argv) {
if (_vm->saveAsOriginalSaveFile()) {
Common::FSNode nf = nd.getChild(Common::String::format("EOBDATA.SAV"));
if (nf.isReadable())
- DebugPrintf("Saved to file: %s\n\n", nf.getPath().c_str());
+ debugPrintf("Saved to file: %s\n\n", nf.getPath().c_str());
else
- DebugPrintf("Failure.\n");
+ debugPrintf("Failure.\n");
} else {
- DebugPrintf("Failure.\n");
+ debugPrintf("Failure.\n");
}
} else {
- DebugPrintf("Syntax: save_original\n (Saves game in original file format to a file which can be used with the orginal game executable.)\n\n");
+ debugPrintf("Syntax: save_original\n (Saves game in original file format to a file which can be used with the orginal game executable.)\n\n");
}
return true;
} else if (argc == 2) {
int slot = atoi(argv[1]);
if (slot < 0 || slot > 5) {
- DebugPrintf("Slot must be between (including) 0 and 5.\n");
+ debugPrintf("Slot must be between (including) 0 and 5.\n");
} else if (_vm->saveAsOriginalSaveFile(slot)) {
Common::FSNode nf = nd.getChild(Common::String::format("EOBDATA%d.SAV", slot));
if (nf.isReadable())
- DebugPrintf("Saved to file: %s\n\n", nf.getPath().c_str());
+ debugPrintf("Saved to file: %s\n\n", nf.getPath().c_str());
else
- DebugPrintf("Failure.\n");
+ debugPrintf("Failure.\n");
} else {
- DebugPrintf("Failure.\n");
+ debugPrintf("Failure.\n");
}
return true;
}
- DebugPrintf("Syntax: save_original <slot>\n (Saves game in original file format to a file which can be used with the orginal game executable.\n A save slot between 0 and 5 must be specified.)\n\n");
+ debugPrintf("Syntax: save_original <slot>\n (Saves game in original file format to a file which can be used with the orginal game executable.\n A save slot between 0 and 5 must be specified.)\n\n");
return true;
}
-bool Debugger_EoB::cmd_listMonsters(int, const char **) {
- DebugPrintf("\nCurrent level: %d\n----------------------\n\n", _vm->_currentLevel);
- DebugPrintf("Id Type Unit Block Position Direction Sub Level Mode Dst.block HP Flags\n--------------------------------------------------------------------------------------------------------------\n");
+bool Debugger_EoB::cmdListMonsters(int, const char **) {
+ debugPrintf("\nCurrent level: %d\n----------------------\n\n", _vm->_currentLevel);
+ debugPrintf("Id Type Unit Block Position Direction Sub Level Mode Dst.block HP Flags\n--------------------------------------------------------------------------------------------------------------\n");
for (int i = 0; i < 30; i++) {
EoBMonsterInPlay *m = &_vm->_monsters[i];
- DebugPrintf("%.02d %.02d %.02d 0x%.04x %d %d %d %.02d 0x%.04x %.03d/%.03d 0x%.02x\n", i, m->type, m->unit, m->block, m->pos, m->dir, m->sub, m->mode, m->dest, m->hitPointsCur, m->hitPointsMax, m->flags);
+ debugPrintf("%.02d %.02d %.02d 0x%.04x %d %d %d %.02d 0x%.04x %.03d/%.03d 0x%.02x\n", i, m->type, m->unit, m->block, m->pos, m->dir, m->sub, m->mode, m->dest, m->hitPointsCur, m->hitPointsMax, m->flags);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
-bool Debugger_EoB::cmd_showPosition(int, const char **) {
- DebugPrintf("\nCurrent level: %d\nCurrent Sub Level: %d\nCurrent block: %d (0x%.04x)\nNext block: %d (0x%.04x)\nCurrent direction: %d\n\n", _vm->_currentLevel, _vm->_currentSub, _vm->_currentBlock, _vm->_currentBlock, _vm->calcNewBlockPosition(_vm->_currentBlock, _vm->_currentDirection), _vm->calcNewBlockPosition(_vm->_currentBlock, _vm->_currentDirection), _vm->_currentDirection);
+bool Debugger_EoB::cmdShowPosition(int, const char **) {
+ debugPrintf("\nCurrent level: %d\nCurrent Sub Level: %d\nCurrent block: %d (0x%.04x)\nNext block: %d (0x%.04x)\nCurrent direction: %d\n\n", _vm->_currentLevel, _vm->_currentSub, _vm->_currentBlock, _vm->_currentBlock, _vm->calcNewBlockPosition(_vm->_currentBlock, _vm->_currentDirection), _vm->calcNewBlockPosition(_vm->_currentBlock, _vm->_currentDirection), _vm->_currentDirection);
return true;
}
-bool Debugger_EoB::cmd_setPosition(int argc, const char **argv) {
+bool Debugger_EoB::cmdSetPosition(int argc, const char **argv) {
if (argc == 4) {
_vm->_currentBlock = atoi(argv[3]);
int sub = atoi(argv[2]);
@@ -593,7 +593,7 @@ bool Debugger_EoB::cmd_setPosition(int argc, const char **argv) {
int maxLevel = (_vm->game() == GI_EOB1) ? 12 : 16;
if (level < 1 || level > maxLevel) {
- DebugPrintf("<level> must be a value from 1 to %d.\n\n", maxLevel);
+ debugPrintf("<level> must be a value from 1 to %d.\n\n", maxLevel);
return true;
}
@@ -613,83 +613,83 @@ bool Debugger_EoB::cmd_setPosition(int argc, const char **argv) {
_vm->_sceneUpdateRequired = true;
_vm->gui_drawAllCharPortraitsWithStats();
- DebugPrintf("Success.\n\n");
+ debugPrintf("Success.\n\n");
} else {
- DebugPrintf("Syntax: set_position <level>, <sub level>, <block>\n");
- DebugPrintf(" (Warning: The sub level and block position parameters will not be checked. Invalid parameters may cause problems.)\n\n");
+ debugPrintf("Syntax: set_position <level>, <sub level>, <block>\n");
+ debugPrintf(" (Warning: The sub level and block position parameters will not be checked. Invalid parameters may cause problems.)\n\n");
}
return true;
}
-bool Debugger_EoB::cmd_openDoor(int, const char **) {
- DebugPrintf("Warning: Using this command may cause glitches.\n");
+bool Debugger_EoB::cmdOpenDoor(int, const char **) {
+ debugPrintf("Warning: Using this command may cause glitches.\n");
uint16 block = _vm->calcNewBlockPosition(_vm->_currentBlock, _vm->_currentDirection);
int c = (_vm->_wllWallFlags[_vm->_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
int v = _vm->_levelBlockProperties[block].walls[c];
int flg = (_vm->_flags.gameID == GI_EOB1) ? 1 : 0x10;
if (_vm->_wllWallFlags[v] & flg) {
- DebugPrintf("Couldn't open any door. Make sure you're facing the door you wish to open and standing right in front of it.\n\n");
+ debugPrintf("Couldn't open any door. Make sure you're facing the door you wish to open and standing right in front of it.\n\n");
} else {
_vm->openDoor(block);
- DebugPrintf("Trying to open door at block %d.\n\n", block);
+ debugPrintf("Trying to open door at block %d.\n\n", block);
}
return true;
}
-bool Debugger_EoB::cmd_closeDoor(int, const char **) {
- DebugPrintf("Warning: Using this command may cause glitches.\n");
+bool Debugger_EoB::cmdCloseDoor(int, const char **) {
+ debugPrintf("Warning: Using this command may cause glitches.\n");
uint16 block = _vm->calcNewBlockPosition(_vm->_currentBlock, _vm->_currentDirection);
int c = (_vm->_wllWallFlags[_vm->_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
int v = _vm->_levelBlockProperties[block].walls[c];
if ((_vm->_flags.gameID == GI_EOB1 && !(_vm->_wllWallFlags[v] & 1)) || (_vm->_flags.gameID == GI_EOB2 && (_vm->_wllWallFlags[v] & 0x20))) {
- DebugPrintf("Couldn't close any door. Make sure you're facing the door you wish to close and standing right in front of it.\n\n");
+ debugPrintf("Couldn't close any door. Make sure you're facing the door you wish to close and standing right in front of it.\n\n");
} else {
_vm->closeDoor(block);
- DebugPrintf("Trying to close door at block %d.\n\n", block);
+ debugPrintf("Trying to close door at block %d.\n\n", block);
}
return true;
}
-bool Debugger_EoB::cmd_listFlags(int, const char **) {
- DebugPrintf("Flag Status\n----------------------\n\n");
+bool Debugger_EoB::cmdListFlags(int, const char **) {
+ debugPrintf("Flag Status\n----------------------\n\n");
for (int i = 0; i < 32; i++) {
uint32 flag = 1 << i;
- DebugPrintf("%.2d %s\n", i, _vm->checkScriptFlags(flag) ? "TRUE" : "FALSE");
+ debugPrintf("%.2d %s\n", i, _vm->checkScriptFlags(flag) ? "TRUE" : "FALSE");
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
-bool Debugger_EoB::cmd_setFlag(int argc, const char **argv) {
+bool Debugger_EoB::cmdSetFlag(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Syntax: set_flag <flag>\n\n");
+ debugPrintf("Syntax: set_flag <flag>\n\n");
return true;
}
int flag = atoi(argv[1]);
if (flag < 0 || flag > 31) {
- DebugPrintf("<flag> must be a value from 0 to 31.\n\n");
+ debugPrintf("<flag> must be a value from 0 to 31.\n\n");
} else {
_vm->setScriptFlags(1 << flag);
- DebugPrintf("Flag '%.2d' has been set.\n\n", flag);
+ debugPrintf("Flag '%.2d' has been set.\n\n", flag);
}
return true;
}
-bool Debugger_EoB::cmd_clearFlag(int argc, const char **argv) {
+bool Debugger_EoB::cmdClearFlag(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Syntax: clear_flag <flag>\n\n");
+ debugPrintf("Syntax: clear_flag <flag>\n\n");
return true;
}
int flag = atoi(argv[1]);
if (flag < 0 || flag > 31) {
- DebugPrintf("<flag> must be a value from 0 to 31.\n\n");
+ debugPrintf("<flag> must be a value from 0 to 31.\n\n");
} else {
_vm->clearScriptFlags(1 << flag);
- DebugPrintf("Flag '%.2d' has been cleared.\n\n", flag);
+ debugPrintf("Flag '%.2d' has been cleared.\n\n", flag);
}
return true;
diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h
index aaf7c51c18..15cee2d592 100644
--- a/engines/kyra/debugger.h
+++ b/engines/kyra/debugger.h
@@ -42,15 +42,15 @@ public:
protected:
KyraEngine_v1 *_vm;
- bool cmd_setScreenDebug(int argc, const char **argv);
- bool cmd_loadPalette(int argc, const char **argv);
- bool cmd_showFacings(int argc, const char **argv);
- bool cmd_gameSpeed(int argc, const char **argv);
- bool cmd_listFlags(int argc, const char **argv);
- bool cmd_toggleFlag(int argc, const char **argv);
- bool cmd_queryFlag(int argc, const char **argv);
- bool cmd_listTimers(int argc, const char **argv);
- bool cmd_setTimerCountdown(int argc, const char **argv);
+ bool cmdSetScreenDebug(int argc, const char **argv);
+ bool cmdLoadPalette(int argc, const char **argv);
+ bool cmdShowFacings(int argc, const char **argv);
+ bool cmdGameSpeed(int argc, const char **argv);
+ bool cmdListFlags(int argc, const char **argv);
+ bool cmdToggleFlag(int argc, const char **argv);
+ bool cmdQueryFlag(int argc, const char **argv);
+ bool cmdListTimers(int argc, const char **argv);
+ bool cmdSetTimerCountdown(int argc, const char **argv);
};
class Debugger_LoK : public Debugger {
@@ -62,10 +62,10 @@ public:
protected:
KyraEngine_LoK *_vm;
- bool cmd_enterRoom(int argc, const char **argv);
- bool cmd_listScenes(int argc, const char **argv);
- bool cmd_giveItem(int argc, const char **argv);
- bool cmd_listBirthstones(int argc, const char **argv);
+ bool cmdEnterRoom(int argc, const char **argv);
+ bool cmdListScenes(int argc, const char **argv);
+ bool cmdGiveItem(int argc, const char **argv);
+ bool cmdListBirthstones(int argc, const char **argv);
};
class Debugger_v2 : public Debugger {
@@ -77,12 +77,12 @@ public:
protected:
KyraEngine_v2 *_vm;
- bool cmd_enterScene(int argc, const char **argv);
- bool cmd_listScenes(int argc, const char **argv);
- bool cmd_sceneInfo(int argc, const char **argv);
- bool cmd_characterInfo(int argc, const char **argv);
- bool cmd_sceneToFacing(int argc, const char **argv);
- bool cmd_giveItem(int argc, const char **argv);
+ bool cmdEnterScene(int argc, const char **argv);
+ bool cmdListScenes(int argc, const char **argv);
+ bool cmdSceneInfo(int argc, const char **argv);
+ bool cmdCharacterInfo(int argc, const char **argv);
+ bool cmdSceneToFacing(int argc, const char **argv);
+ bool cmdGiveItem(int argc, const char **argv);
};
class Debugger_HoF : public Debugger_v2 {
@@ -93,7 +93,7 @@ public:
protected:
KyraEngine_HoF *_vm;
- bool cmd_passcodes(int argc, const char **argv);
+ bool cmdPasscodes(int argc, const char **argv);
};
#ifdef ENABLE_LOL
@@ -119,16 +119,16 @@ public:
protected:
EoBCoreEngine *_vm;
- bool cmd_importSaveFile(int argc, const char **argv);
- bool cmd_saveOriginal(int argc, const char **argv);
- bool cmd_listMonsters(int argc, const char **argv);
- bool cmd_showPosition(int argc, const char **argv);
- bool cmd_setPosition(int argc, const char **argv);
- bool cmd_openDoor(int argc, const char **argv);
- bool cmd_closeDoor(int argc, const char **argv);
- bool cmd_listFlags(int argc, const char **argv);
- bool cmd_setFlag(int argc, const char **argv);
- bool cmd_clearFlag(int argc, const char **argv);
+ bool cmdImportSaveFile(int argc, const char **argv);
+ bool cmdSaveOriginal(int argc, const char **argv);
+ bool cmdListMonsters(int argc, const char **argv);
+ bool cmdShowPosition(int argc, const char **argv);
+ bool cmdSetPosition(int argc, const char **argv);
+ bool cmdOpenDoor(int argc, const char **argv);
+ bool cmdCloseDoor(int argc, const char **argv);
+ bool cmdListFlags(int argc, const char **argv);
+ bool cmdSetFlag(int argc, const char **argv);
+ bool cmdClearFlag(int argc, const char **argv);
};
#endif // ENABLE_EOB
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index 6c2d833271..57943f9a8d 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -60,33 +60,33 @@ Debugger::Debugger(LastExpressEngine *engine) : _engine(engine), _command(NULL),
// Register the debugger commands
// General
- DCmd_Register("help", WRAP_METHOD(Debugger, cmdHelp));
+ registerCmd("help", WRAP_METHOD(Debugger, cmdHelp));
// Data
- DCmd_Register("ls", WRAP_METHOD(Debugger, cmdListFiles));
- DCmd_Register("dump", WRAP_METHOD(Debugger, cmdDumpFiles));
+ registerCmd("ls", WRAP_METHOD(Debugger, cmdListFiles));
+ registerCmd("dump", WRAP_METHOD(Debugger, cmdDumpFiles));
- DCmd_Register("showframe", WRAP_METHOD(Debugger, cmdShowFrame));
- DCmd_Register("showbg", WRAP_METHOD(Debugger, cmdShowBg));
- DCmd_Register("playseq", WRAP_METHOD(Debugger, cmdPlaySeq));
- DCmd_Register("playsnd", WRAP_METHOD(Debugger, cmdPlaySnd));
- DCmd_Register("playsbe", WRAP_METHOD(Debugger, cmdPlaySbe));
- DCmd_Register("playnis", WRAP_METHOD(Debugger, cmdPlayNis));
+ registerCmd("showframe", WRAP_METHOD(Debugger, cmdShowFrame));
+ registerCmd("showbg", WRAP_METHOD(Debugger, cmdShowBg));
+ registerCmd("playseq", WRAP_METHOD(Debugger, cmdPlaySeq));
+ registerCmd("playsnd", WRAP_METHOD(Debugger, cmdPlaySnd));
+ registerCmd("playsbe", WRAP_METHOD(Debugger, cmdPlaySbe));
+ registerCmd("playnis", WRAP_METHOD(Debugger, cmdPlayNis));
// Scene & interaction
- DCmd_Register("loadscene", WRAP_METHOD(Debugger, cmdLoadScene));
- DCmd_Register("fight", WRAP_METHOD(Debugger, cmdFight));
- DCmd_Register("beetle", WRAP_METHOD(Debugger, cmdBeetle));
+ registerCmd("loadscene", WRAP_METHOD(Debugger, cmdLoadScene));
+ registerCmd("fight", WRAP_METHOD(Debugger, cmdFight));
+ registerCmd("beetle", WRAP_METHOD(Debugger, cmdBeetle));
// Game
- DCmd_Register("delta", WRAP_METHOD(Debugger, cmdTimeDelta));
- DCmd_Register("time", WRAP_METHOD(Debugger, cmdTime));
- DCmd_Register("show", WRAP_METHOD(Debugger, cmdShow));
- DCmd_Register("entity", WRAP_METHOD(Debugger, cmdEntity));
+ registerCmd("delta", WRAP_METHOD(Debugger, cmdTimeDelta));
+ registerCmd("time", WRAP_METHOD(Debugger, cmdTime));
+ registerCmd("show", WRAP_METHOD(Debugger, cmdShow));
+ registerCmd("entity", WRAP_METHOD(Debugger, cmdEntity));
// Misc
- DCmd_Register("chapter", WRAP_METHOD(Debugger, cmdSwitchChapter));
- DCmd_Register("clear", WRAP_METHOD(Debugger, cmdClear));
+ registerCmd("chapter", WRAP_METHOD(Debugger, cmdSwitchChapter));
+ registerCmd("clear", WRAP_METHOD(Debugger, cmdClear));
resetCommand();
@@ -146,7 +146,7 @@ void Debugger::copyCommand(int argc, const char **argv) {
}
// Exit the debugger!
- Cmd_Exit(0, 0);
+ cmdExit(0, 0);
}
void Debugger::callCommand() {
@@ -156,7 +156,7 @@ void Debugger::callCommand() {
bool Debugger::loadArchive(int index) {
if (index < 1 || index > 3) {
- DebugPrintf("Invalid cd number (was: %d, valid: [1-3])\n", index);
+ debugPrintf("Invalid cd number (was: %d, valid: [1-3])\n", index);
return false;
}
@@ -198,36 +198,36 @@ void Debugger::restoreArchive() const {
// Debugger commands
//////////////////////////////////////////////////////////////////////////
bool Debugger::cmdHelp(int, const char **) {
- DebugPrintf("Debug flags\n");
- DebugPrintf("-----------\n");
- DebugPrintf(" debugflag_list - Lists the available debug flags and their status\n");
- DebugPrintf(" debugflag_enable - Enables a debug flag\n");
- DebugPrintf(" debugflag_disable - Disables a debug flag\n");
- DebugPrintf("\n");
- DebugPrintf("Commands\n");
- DebugPrintf("--------\n");
- DebugPrintf(" ls - list files in the archive\n");
- DebugPrintf(" dump - dump a list of files in all archives\n");
- DebugPrintf("\n");
- DebugPrintf(" showframe - show a frame from a sequence\n");
- DebugPrintf(" showbg - show a background\n");
- DebugPrintf(" playseq - play a sequence\n");
- DebugPrintf(" playsnd - play a sound\n");
- DebugPrintf(" playsbe - play a subtitle\n");
- DebugPrintf(" playnis - play an animation\n");
- DebugPrintf("\n");
- DebugPrintf(" loadscene - load a scene\n");
- DebugPrintf(" fight - start a fight\n");
- DebugPrintf(" beetle - start the beetle game\n");
- DebugPrintf("\n");
- DebugPrintf(" delta - Adjust the time delta\n");
- DebugPrintf(" show - show game data\n");
- DebugPrintf(" entity - show entity data\n");
- DebugPrintf("\n");
- DebugPrintf(" loadgame - load a saved game\n");
- DebugPrintf(" chapter - switch to a specific chapter\n");
- DebugPrintf(" clear - clear the screen\n");
- DebugPrintf("\n");
+ debugPrintf("Debug flags\n");
+ debugPrintf("-----------\n");
+ debugPrintf(" debugflag_list - Lists the available debug flags and their status\n");
+ debugPrintf(" debugflag_enable - Enables a debug flag\n");
+ debugPrintf(" debugflag_disable - Disables a debug flag\n");
+ debugPrintf("\n");
+ debugPrintf("Commands\n");
+ debugPrintf("--------\n");
+ debugPrintf(" ls - list files in the archive\n");
+ debugPrintf(" dump - dump a list of files in all archives\n");
+ debugPrintf("\n");
+ debugPrintf(" showframe - show a frame from a sequence\n");
+ debugPrintf(" showbg - show a background\n");
+ debugPrintf(" playseq - play a sequence\n");
+ debugPrintf(" playsnd - play a sound\n");
+ debugPrintf(" playsbe - play a subtitle\n");
+ debugPrintf(" playnis - play an animation\n");
+ debugPrintf("\n");
+ debugPrintf(" loadscene - load a scene\n");
+ debugPrintf(" fight - start a fight\n");
+ debugPrintf(" beetle - start the beetle game\n");
+ debugPrintf("\n");
+ debugPrintf(" delta - Adjust the time delta\n");
+ debugPrintf(" show - show game data\n");
+ debugPrintf(" entity - show entity data\n");
+ debugPrintf("\n");
+ debugPrintf(" loadgame - load a saved game\n");
+ debugPrintf(" chapter - switch to a specific chapter\n");
+ debugPrintf(" clear - clear the screen\n");
+ debugPrintf("\n");
return true;
}
@@ -252,15 +252,15 @@ bool Debugger::cmdListFiles(int argc, const char **argv) {
Common::ArchiveMemberList list;
int count = _engine->getResourceManager()->listMatchingMembers(list, filter);
- DebugPrintf("Number of matches: %d\n", count);
+ debugPrintf("Number of matches: %d\n", count);
for (Common::ArchiveMemberList::iterator it = list.begin(); it != list.end(); ++it)
- DebugPrintf(" %s\n", (*it)->getName().c_str());
+ debugPrintf(" %s\n", (*it)->getName().c_str());
// Restore archive
if (argc == 3)
restoreArchive();
} else {
- DebugPrintf("Syntax: ls <filter> (use * for all) (<cd number>)\n");
+ debugPrintf("Syntax: ls <filter> (use * for all) (<cd number>)\n");
}
return true;
@@ -287,7 +287,7 @@ bool Debugger::cmdDumpFiles(int argc, const char **) {
for (Common::ArchiveMemberList::iterator it = list.begin(); it != list.end(); ++it) { \
Common::SeekableReadStream *stream = getArchive((*it)->getName()); \
if (!stream) { \
- DebugPrintf("ERROR: Cannot create stream for file: %s\n", (*it)->getName().c_str()); \
+ debugPrintf("ERROR: Cannot create stream for file: %s\n", (*it)->getName().c_str()); \
restoreArchive(); \
return true; \
} \
@@ -311,7 +311,7 @@ bool Debugger::cmdDumpFiles(int argc, const char **) {
// Restore current loaded archive
restoreArchive();
} else {
- DebugPrintf("Syntax: dump");
+ debugPrintf("Syntax: dump");
}
return true;
@@ -336,7 +336,7 @@ bool Debugger::cmdShowFrame(int argc, const char **argv) {
}
if (!_engine->getResourceManager()->hasFile(filename)) {
- DebugPrintf("Cannot find file: %s\n", filename.c_str());
+ debugPrintf("Cannot find file: %s\n", filename.c_str());
return true;
}
@@ -345,7 +345,7 @@ bool Debugger::cmdShowFrame(int argc, const char **argv) {
_command = WRAP_METHOD(Debugger, cmdShowFrame);
copyCommand(argc, argv);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
Sequence sequence(filename);
if (sequence.load(getArchive(filename))) {
@@ -354,7 +354,7 @@ bool Debugger::cmdShowFrame(int argc, const char **argv) {
AnimFrame *frame = sequence.getFrame((uint16)getNumber(argv[2]));
if (!frame) {
- DebugPrintf("Invalid frame index '%s'\n", argv[2]);
+ debugPrintf("Invalid frame index '%s'\n", argv[2]);
resetCommand();
return true;
}
@@ -375,7 +375,7 @@ bool Debugger::cmdShowFrame(int argc, const char **argv) {
restoreArchive();
}
} else {
- DebugPrintf("Syntax: cmd_showframe <seqname> <index> (<cd number>)\n");
+ debugPrintf("Syntax: cmd_showframe <seqname> <index> (<cd number>)\n");
}
return true;
}
@@ -398,7 +398,7 @@ bool Debugger::cmdShowBg(int argc, const char **argv) {
}
if (!_engine->getResourceManager()->hasFile(filename + ".BG")) {
- DebugPrintf("Cannot find file: %s\n", (filename + ".BG").c_str());
+ debugPrintf("Cannot find file: %s\n", (filename + ".BG").c_str());
return true;
}
@@ -407,7 +407,7 @@ bool Debugger::cmdShowBg(int argc, const char **argv) {
_command = WRAP_METHOD(Debugger, cmdShowBg);
copyCommand(argc, argv);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
clearBg(GraphicsManager::kBackgroundC);
@@ -429,7 +429,7 @@ bool Debugger::cmdShowBg(int argc, const char **argv) {
resetCommand();
}
} else {
- DebugPrintf("Syntax: showbg <bgname> (<cd number>)\n");
+ debugPrintf("Syntax: showbg <bgname> (<cd number>)\n");
}
return true;
}
@@ -453,7 +453,7 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
}
if (!_engine->getResourceManager()->hasFile(filename)) {
- DebugPrintf("Cannot find file: %s\n", filename.c_str());
+ debugPrintf("Cannot find file: %s\n", filename.c_str());
return true;
}
@@ -462,7 +462,7 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
_command = WRAP_METHOD(Debugger, cmdPlaySeq);
copyCommand(argc, argv);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
Sequence *sequence = new Sequence(filename);
if (sequence->load(getArchive(filename))) {
@@ -510,7 +510,7 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
restoreArchive();
}
} else {
- DebugPrintf("Syntax: playseq <seqname> (<cd number>)\n");
+ debugPrintf("Syntax: playseq <seqname> (<cd number>)\n");
}
return true;
}
@@ -537,7 +537,7 @@ bool Debugger::cmdPlaySnd(int argc, const char **argv) {
name += ".SND";
if (!_engine->getResourceManager()->hasFile(name)) {
- DebugPrintf("Cannot find file: %s\n", name.c_str());
+ debugPrintf("Cannot find file: %s\n", name.c_str());
return true;
}
@@ -548,7 +548,7 @@ bool Debugger::cmdPlaySnd(int argc, const char **argv) {
if (argc == 3)
restoreArchive();
} else {
- DebugPrintf("Syntax: playsnd <sndname> (<cd number>)\n");
+ debugPrintf("Syntax: playsnd <sndname> (<cd number>)\n");
}
return true;
}
@@ -573,7 +573,7 @@ bool Debugger::cmdPlaySbe(int argc, const char **argv) {
filename += ".sbe";
if (!_engine->getResourceManager()->hasFile(filename)) {
- DebugPrintf("Cannot find file: %s\n", filename.c_str());
+ debugPrintf("Cannot find file: %s\n", filename.c_str());
return true;
}
@@ -582,7 +582,7 @@ bool Debugger::cmdPlaySbe(int argc, const char **argv) {
_command = WRAP_METHOD(Debugger, cmdPlaySbe);
copyCommand(argc, argv);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
SubtitleManager subtitle(_engine->getFont());
if (subtitle.load(getArchive(filename))) {
@@ -615,7 +615,7 @@ bool Debugger::cmdPlaySbe(int argc, const char **argv) {
resetCommand();
}
} else {
- DebugPrintf("Syntax: playsbe <sbename> (<cd number>)\n");
+ debugPrintf("Syntax: playsbe <sbename> (<cd number>)\n");
}
return true;
}
@@ -639,7 +639,7 @@ bool Debugger::cmdPlayNis(int argc, const char **argv) {
// If we got a nis filename, check that the file exists
if (name.contains('.') && !_engine->getResourceManager()->hasFile(name)) {
- DebugPrintf("Cannot find file: %s\n", name.c_str());
+ debugPrintf("Cannot find file: %s\n", name.c_str());
return true;
}
@@ -648,7 +648,7 @@ bool Debugger::cmdPlayNis(int argc, const char **argv) {
_command = WRAP_METHOD(Debugger, cmdPlayNis);
copyCommand(argc, argv);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
// Make sure we are not called in a loop
_numParams = 0;
@@ -672,7 +672,7 @@ bool Debugger::cmdPlayNis(int argc, const char **argv) {
resetCommand();
}
} else {
- DebugPrintf("Syntax: playnis <nisname.nis or animation index> (<cd number>)\n");
+ debugPrintf("Syntax: playnis <nisname.nis or animation index> (<cd number>)\n");
}
return true;
}
@@ -697,7 +697,7 @@ bool Debugger::cmdLoadScene(int argc, const char **argv) {
}
if (index > 2500) {
- DebugPrintf("Error: invalid index value (0-2500)");
+ debugPrintf("Error: invalid index value (0-2500)");
return true;
}
@@ -706,7 +706,7 @@ bool Debugger::cmdLoadScene(int argc, const char **argv) {
_command = WRAP_METHOD(Debugger, cmdLoadScene);
copyCommand(argc, argv);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
clearBg(GraphicsManager::kBackgroundAll);
@@ -718,7 +718,7 @@ bool Debugger::cmdLoadScene(int argc, const char **argv) {
// loadSceneObject(scene, i);
// if (scene.getHeader() && scene.getHeader()->car == 5 && scene.getHeader()->position == 81) {
- // DebugPrintf("Found scene: %d", i);
+ // debugPrintf("Found scene: %d", i);
// // Draw scene found
// _engine->getGraphicsManager()->draw(&scene, GraphicsManager::kBackgroundC);
@@ -738,7 +738,7 @@ bool Debugger::cmdLoadScene(int argc, const char **argv) {
/*********************************************/
Scene *scene = getScenes()->get(index);
if (!scene) {
- DebugPrintf("Cannot load scene %i from CD %i", index, cd);
+ debugPrintf("Cannot load scene %i from CD %i", index, cd);
resetCommand();
return true;
@@ -758,7 +758,7 @@ bool Debugger::cmdLoadScene(int argc, const char **argv) {
resetCommand();
}
} else {
- DebugPrintf("Syntax: loadscene <scene index> (<cd number>)\n");
+ debugPrintf("Syntax: loadscene <scene index> (<cd number>)\n");
}
return true;
}
@@ -814,7 +814,7 @@ bool Debugger::cmdFight(int argc, const char **argv) {
SceneIndex lastScene = getState()->scene;
- getFight()->setup(type) ? DebugPrintf("Lost fight!\n") : DebugPrintf("Won fight!\n");
+ getFight()->setup(type) ? debugPrintf("Lost fight!\n") : debugPrintf("Won fight!\n");
// Pause for a second to be able to see the final scene
_engine->_system->delayMillis(1000);
@@ -837,7 +837,7 @@ bool Debugger::cmdFight(int argc, const char **argv) {
}
} else {
error:
- DebugPrintf("Syntax: fight <id> (id=2001-2005)\n");
+ debugPrintf("Syntax: fight <id> (id=2001-2005)\n");
}
return true;
@@ -968,7 +968,7 @@ bool Debugger::cmdBeetle(int argc, const char **argv) {
resetCommand();
}
} else {
- DebugPrintf("Syntax: beetle\n");
+ debugPrintf("Syntax: beetle\n");
}
return true;
@@ -992,7 +992,7 @@ bool Debugger::cmdTimeDelta(int argc, const char **argv) {
getState()->timeDelta = (uint)delta;
} else {
label_error:
- DebugPrintf("Syntax: delta <time delta> (delta=1-500)\n");
+ debugPrintf("Syntax: delta <time delta> (delta=1-500)\n");
}
return true;
@@ -1018,10 +1018,10 @@ bool Debugger::cmdTime(int argc, const char **argv) {
uint8 minutes = 0;
State::getHourMinutes((uint32)time, &hours, &minutes);
- DebugPrintf("%02d:%02d\n", hours, minutes);
+ debugPrintf("%02d:%02d\n", hours, minutes);
} else {
label_error:
- DebugPrintf("Syntax: time <time to convert> (time=0-INT_MAX)\n");
+ debugPrintf("Syntax: time <time to convert> (time=0-INT_MAX)\n");
}
return true;
@@ -1037,10 +1037,10 @@ label_error:
*/
bool Debugger::cmdShow(int argc, const char **argv) {
#define OUTPUT_DUMP(name, text) \
- DebugPrintf(#name "\n"); \
- DebugPrintf("--------------------------------------------------------------------\n\n"); \
- DebugPrintf("%s", text); \
- DebugPrintf("\n");
+ debugPrintf(#name "\n"); \
+ debugPrintf("--------------------------------------------------------------------\n\n"); \
+ debugPrintf("%s", text); \
+ debugPrintf("\n");
if (argc == 2) {
@@ -1066,14 +1066,14 @@ bool Debugger::cmdShow(int argc, const char **argv) {
} else {
label_error:
- DebugPrintf("Syntax: state <option>\n");
- DebugPrintf(" state / st\n");
- DebugPrintf(" progress / pr\n");
- DebugPrintf(" flags / fl\n");
- DebugPrintf(" inventory / inv\n");
- DebugPrintf(" objects / obj\n");
- DebugPrintf(" savepoints / pt\n");
- DebugPrintf(" scene / sc\n");
+ debugPrintf("Syntax: state <option>\n");
+ debugPrintf(" state / st\n");
+ debugPrintf(" progress / pr\n");
+ debugPrintf(" flags / fl\n");
+ debugPrintf(" inventory / inv\n");
+ debugPrintf(" objects / obj\n");
+ debugPrintf(" savepoints / pt\n");
+ debugPrintf(" scene / sc\n");
}
return true;
@@ -1096,26 +1096,26 @@ bool Debugger::cmdEntity(int argc, const char **argv) {
if (index > 39)
goto label_error;
- DebugPrintf("Entity %s\n", ENTITY_NAME(index));
- DebugPrintf("--------------------------------------------------------------------\n\n");
- DebugPrintf("%s", getEntities()->getData(index)->toString().c_str());
+ debugPrintf("Entity %s\n", ENTITY_NAME(index));
+ debugPrintf("--------------------------------------------------------------------\n\n");
+ debugPrintf("%s", getEntities()->getData(index)->toString().c_str());
// The Player entity does not have any callback data
if (index != kEntityPlayer) {
EntityData *data = getEntities()->get(index)->getParamData();
for (uint callback = 0; callback < 9; callback++) {
- DebugPrintf("Call parameters %d:\n", callback);
+ debugPrintf("Call parameters %d:\n", callback);
for (byte ix = 0; ix < 4; ix++)
- DebugPrintf(" %s", data->getParameters(callback, ix)->toString().c_str());
+ debugPrintf(" %s", data->getParameters(callback, ix)->toString().c_str());
}
}
- DebugPrintf("\n");
+ debugPrintf("\n");
} else {
label_error:
- DebugPrintf("Syntax: entity <index>\n");
+ debugPrintf("Syntax: entity <index>\n");
for (int i = 0; i < 40; i += 4)
- DebugPrintf(" %s - %d %s - %d %s - %d %s - %d\n", ENTITY_NAME(i), i, ENTITY_NAME(i+1), i+1, ENTITY_NAME(i+2), i+2, ENTITY_NAME(i+3), i+3);
+ debugPrintf(" %s - %d %s - %d %s - %d %s - %d\n", ENTITY_NAME(i), i, ENTITY_NAME(i+1), i+1, ENTITY_NAME(i+2), i+2, ENTITY_NAME(i+3), i+3);
}
return true;
@@ -1152,7 +1152,7 @@ bool Debugger::cmdSwitchChapter(int argc, const char **argv) {
}
} else {
error:
- DebugPrintf("Syntax: chapter <id> (id=2-6)\n");
+ debugPrintf("Syntax: chapter <id> (id=2-6)\n");
}
return true;
@@ -1172,7 +1172,7 @@ bool Debugger::cmdClear(int argc, const char **) {
askForRedraw();
redrawScreen();
} else {
- DebugPrintf("Syntax: clear - clear the screen\n");
+ debugPrintf("Syntax: clear - clear the screen\n");
}
return true;
diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp
index bbaa68befa..032186717d 100644
--- a/engines/lure/debugger.cpp
+++ b/engines/lure/debugger.cpp
@@ -35,20 +35,20 @@
namespace Lure {
Debugger::Debugger(): GUI::Debugger() {
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("enter", WRAP_METHOD(Debugger, cmd_enterRoom));
- DCmd_Register("rooms", WRAP_METHOD(Debugger, cmd_listRooms));
- DCmd_Register("fields", WRAP_METHOD(Debugger, cmd_listFields));
- DCmd_Register("setfield", WRAP_METHOD(Debugger, cmd_setField));
- DCmd_Register("queryfield", WRAP_METHOD(Debugger, cmd_queryField));
- DCmd_Register("give", WRAP_METHOD(Debugger, cmd_giveItem));
- DCmd_Register("hotspots", WRAP_METHOD(Debugger, cmd_hotspots));
- DCmd_Register("hotspot", WRAP_METHOD(Debugger, cmd_hotspot));
- DCmd_Register("room", WRAP_METHOD(Debugger, cmd_room));
- DCmd_Register("showanim", WRAP_METHOD(Debugger, cmd_showAnim));
- DCmd_Register("strings", WRAP_METHOD(Debugger, cmd_saveStrings));
- DCmd_Register("debug", WRAP_METHOD(Debugger, cmd_debug));
- DCmd_Register("script", WRAP_METHOD(Debugger, cmd_script));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("enter", WRAP_METHOD(Debugger, cmd_enterRoom));
+ registerCmd("rooms", WRAP_METHOD(Debugger, cmd_listRooms));
+ registerCmd("fields", WRAP_METHOD(Debugger, cmd_listFields));
+ registerCmd("setfield", WRAP_METHOD(Debugger, cmd_setField));
+ registerCmd("queryfield", WRAP_METHOD(Debugger, cmd_queryField));
+ registerCmd("give", WRAP_METHOD(Debugger, cmd_giveItem));
+ registerCmd("hotspots", WRAP_METHOD(Debugger, cmd_hotspots));
+ registerCmd("hotspot", WRAP_METHOD(Debugger, cmd_hotspot));
+ registerCmd("room", WRAP_METHOD(Debugger, cmd_room));
+ registerCmd("showanim", WRAP_METHOD(Debugger, cmd_showAnim));
+ registerCmd("strings", WRAP_METHOD(Debugger, cmd_saveStrings));
+ registerCmd("debug", WRAP_METHOD(Debugger, cmd_debug));
+ registerCmd("script", WRAP_METHOD(Debugger, cmd_script));
}
static int strToInt(const char *s) {
@@ -88,7 +88,7 @@ bool Debugger::cmd_enterRoom(int argc, const char **argv) {
// Validate that it's an existing room
if (res.getRoom(roomNumber) == NULL) {
- DebugPrintf("specified number was not a valid room\n");
+ debugPrintf("specified number was not a valid room\n");
return true;
}
@@ -105,9 +105,9 @@ bool Debugger::cmd_enterRoom(int argc, const char **argv) {
return false;
}
- DebugPrintf("Syntax: room <roomnum> [<remoteview>]\n");
- DebugPrintf("A non-zero value for reomteview will change the room without ");
- DebugPrintf("moving the player.\n");
+ debugPrintf("Syntax: room <roomnum> [<remoteview>]\n");
+ debugPrintf("A non-zero value for reomteview will change the room without ");
+ debugPrintf("moving the player.\n");
return true;
}
@@ -117,7 +117,7 @@ bool Debugger::cmd_listRooms(int argc, const char **argv) {
char buffer[MAX_DESC_SIZE];
int ctr = 0;
- DebugPrintf("Available rooms are:\n");
+ debugPrintf("Available rooms are:\n");
for (RoomDataList::iterator i = rooms.begin(); i != rooms.end(); ++i) {
RoomData const &room = **i;
// Explictly note the second drawbridge room as "Alt"
@@ -128,20 +128,20 @@ bool Debugger::cmd_listRooms(int argc, const char **argv) {
strings.getString(room.roomNumber, buffer);
}
- DebugPrintf("#%d - %s", room.roomNumber, buffer);
+ debugPrintf("#%d - %s", room.roomNumber, buffer);
- if (++ctr % 3 == 0) DebugPrintf("\n");
+ if (++ctr % 3 == 0) debugPrintf("\n");
else {
// Write out spaces between columns
int numSpaces = 25 - strlen(buffer) - (room.roomNumber >= 10 ? 2 : 1);
char *s = buffer;
while (numSpaces-- > 0) *s++ = ' ';
*s = '\0';
- DebugPrintf("%s", buffer);
+ debugPrintf("%s", buffer);
}
}
- DebugPrintf("\n");
- DebugPrintf("Current room: %d\n", Room::getReference().roomNumber());
+ debugPrintf("\n");
+ debugPrintf("Current room: %d\n", Room::getReference().roomNumber());
return true;
}
@@ -150,11 +150,11 @@ bool Debugger::cmd_listFields(int argc, const char **argv) {
ValueTableData &fields = Resources::getReference().fieldList();
for (int ctr = 0; ctr < fields.size(); ++ctr) {
- DebugPrintf("(%-2d): %-5d", ctr, fields.getField(ctr));
+ debugPrintf("(%-2d): %-5d", ctr, fields.getField(ctr));
if (!((ctr + 1) % 7))
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
@@ -167,13 +167,13 @@ bool Debugger::cmd_setField(int argc, const char **argv) {
if ((fieldNum < 0) || (fieldNum >= fields.size())) {
// Invalid field number
- DebugPrintf("Invalid field number specified\n");
+ debugPrintf("Invalid field number specified\n");
} else {
// Set the field value
fields.setField(fieldNum, value);
}
} else {
- DebugPrintf("Syntax: setfield <field_number> <value>\n");
+ debugPrintf("Syntax: setfield <field_number> <value>\n");
}
return true;
@@ -186,14 +186,14 @@ bool Debugger::cmd_queryField(int argc, const char **argv) {
int fieldNum = strToInt(argv[1]);
if ((fieldNum < 0) || (fieldNum >= fields.size())) {
// Invalid field number
- DebugPrintf("Invalid field number specified\n");
+ debugPrintf("Invalid field number specified\n");
} else {
// Get the field value
- DebugPrintf("Field %d is %d (%xh)\n", fieldNum,
+ debugPrintf("Field %d is %d (%xh)\n", fieldNum,
fields.getField(fieldNum), fields.getField(fieldNum));
}
} else {
- DebugPrintf("Syntax: queryfield <field_num>\n");
+ debugPrintf("Syntax: queryfield <field_num>\n");
}
return true;
@@ -215,18 +215,18 @@ bool Debugger::cmd_giveItem(int argc, const char **argv) {
charHotspot = res.getHotspot(charNum);
if (itemHotspot == NULL) {
- DebugPrintf("The specified item does not exist\n");
+ debugPrintf("The specified item does not exist\n");
} else if (itemNum < 0x408) {
- DebugPrintf("The specified item number is not an object\n");
+ debugPrintf("The specified item number is not an object\n");
} else if ((charNum < PLAYER_ID) || (charNum >= 0x408) ||
(charHotspot == NULL)) {
- DebugPrintf("The specified character does not exist");
+ debugPrintf("The specified character does not exist");
} else {
// Set the item's room number to be the destination character
itemHotspot->roomNumber = charNum;
}
} else {
- DebugPrintf("Syntax: give <item_id> [<character_id>]\n");
+ debugPrintf("Syntax: give <item_id> [<character_id>]\n");
}
return true;
@@ -248,7 +248,7 @@ bool Debugger::cmd_hotspots(int argc, const char **argv) {
if (hotspot.nameId() == 0) strcpy(buffer, "none");
else strings.getString(hotspot.nameId(), buffer);
- DebugPrintf("%4xh - %s pos=(%d,%d,%d)\n", hotspot.hotspotId(), buffer,
+ debugPrintf("%4xh - %s pos=(%d,%d,%d)\n", hotspot.hotspotId(), buffer,
hotspot.x(), hotspot.y(), hotspot.roomNumber());
}
} else {
@@ -263,16 +263,16 @@ bool Debugger::cmd_hotspots(int argc, const char **argv) {
if (hotspot.nameId == 0) strcpy(buffer, "none");
else strings.getString(hotspot.nameId, buffer);
- DebugPrintf("%4xh - %s pos=(%d,%d,%d)\n", hotspot.hotspotId, buffer,
+ debugPrintf("%4xh - %s pos=(%d,%d,%d)\n", hotspot.hotspotId, buffer,
hotspot.startX, hotspot.startY, hotspot.roomNumber);
}
}
}
} else {
- DebugPrintf("Syntax: hotspots ['active' | ['room' | 'room' '<room_number>']]\n");
- DebugPrintf("Gives a list of all the currently active hotspots, or the hotspots\n");
- DebugPrintf("present in either the current room or a designated one\n");
+ debugPrintf("Syntax: hotspots ['active' | ['room' | 'room' '<room_number>']]\n");
+ debugPrintf("Gives a list of all the currently active hotspots, or the hotspots\n");
+ debugPrintf("present in either the current room or a designated one\n");
}
return true;
@@ -287,12 +287,12 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) {
Hotspot *h;
if (argc < 2) {
- DebugPrintf("hotspot <hotspot_id> ['paths' | 'schedule' | 'actions' | 'activate' | 'deactivate' | 'setpos']\n");
+ debugPrintf("hotspot <hotspot_id> ['paths' | 'schedule' | 'actions' | 'activate' | 'deactivate' | 'setpos']\n");
return true;
}
hs = res.getHotspot(strToInt(argv[1]));
if (!hs) {
- DebugPrintf("Unknown hotspot specified\n");
+ debugPrintf("Unknown hotspot specified\n");
return true;
}
@@ -300,26 +300,26 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) {
if (argc == 2) {
// Show the hotspot properties
strings.getString(hs->nameId, buffer);
- DebugPrintf("name = %d - %s, descs = (%d,%d)\n", hs->nameId, buffer,
+ debugPrintf("name = %d - %s, descs = (%d,%d)\n", hs->nameId, buffer,
hs->descId, hs->descId2);
- DebugPrintf("actions = %xh, offset = %xh\n", hs->actions, hs->actionsOffset);
- DebugPrintf("flags = %xh, layer = %d\n", hs->flags, hs->layer);
- DebugPrintf("position = %d,%d,%d\n", hs->startX, hs->startY, hs->roomNumber);
- DebugPrintf("size = %d,%d, alt = %d,%d, yCorrection = %d\n",
+ debugPrintf("actions = %xh, offset = %xh\n", hs->actions, hs->actionsOffset);
+ debugPrintf("flags = %xh, layer = %d\n", hs->flags, hs->layer);
+ debugPrintf("position = %d,%d,%d\n", hs->startX, hs->startY, hs->roomNumber);
+ debugPrintf("size = %d,%d, alt = %d,%d, yCorrection = %d\n",
hs->width, hs->height, hs->widthCopy, hs->heightCopy, hs->yCorrection);
- DebugPrintf("Talk bubble offset = %d,%d\n", hs->talkX, hs->talkY);
- DebugPrintf("load offset = %xh, script load = %d\n", hs->loadOffset, hs->scriptLoadFlag);
- DebugPrintf("Animation Id = %xh, Color offset = %d\n", hs->animRecordId, hs->colorOffset);
- DebugPrintf("Talk Script offset = %xh, Tick Script offset = %xh\n",
+ debugPrintf("Talk bubble offset = %d,%d\n", hs->talkX, hs->talkY);
+ debugPrintf("load offset = %xh, script load = %d\n", hs->loadOffset, hs->scriptLoadFlag);
+ debugPrintf("Animation Id = %xh, Color offset = %d\n", hs->animRecordId, hs->colorOffset);
+ debugPrintf("Talk Script offset = %xh, Tick Script offset = %xh\n",
hs->talkScriptOffset, hs->tickScriptOffset);
- DebugPrintf("Tick Proc offset = %xh\n", hs->tickProcId);
- DebugPrintf("Tick timeout = %d\n", hs->tickTimeout);
- DebugPrintf("Character mode = %d, delay ctr = %d, pause ctr = %d\n",
+ debugPrintf("Tick Proc offset = %xh\n", hs->tickProcId);
+ debugPrintf("Tick timeout = %d\n", hs->tickTimeout);
+ debugPrintf("Character mode = %d, delay ctr = %d, pause ctr = %d\n",
hs->characterMode, hs->delayCtr, hs->pauseCtr);
if (h != NULL) {
- DebugPrintf("Frame Number = %d of %d\n", h->frameNumber(), h->numFrames());
- DebugPrintf("Persistent = %s\n", h->persistant() ? "true" : "false");
+ debugPrintf("Frame Number = %d of %d\n", h->frameNumber(), h->numFrames());
+ debugPrintf("Persistent = %s\n", h->persistant() ? "true" : "false");
}
} else if (strcmp(argv[2], "actions") == 0) {
@@ -329,42 +329,42 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) {
const char *actionStr = stringList.getString(action);
if (offset >= 0x8000) {
- DebugPrintf("%s - Message %xh\n", actionStr, offset & 0x7ff);
+ debugPrintf("%s - Message %xh\n", actionStr, offset & 0x7ff);
} else if (offset != 0) {
- DebugPrintf("%s - Script %xh\n", actionStr, offset);
+ debugPrintf("%s - Script %xh\n", actionStr, offset);
}
}
} else if (strcmp(argv[2], "activate") == 0) {
// Activate the hotspot
res.activateHotspot(hs->hotspotId);
hs->flags &= ~HOTSPOTFLAG_MENU_EXCLUSION;
- DebugPrintf("Activated\n");
+ debugPrintf("Activated\n");
} else if (strcmp(argv[2], "deactivate") == 0) {
// Deactivate the hotspot
res.deactivateHotspot(hs->hotspotId);
hs->flags |= HOTSPOTFLAG_MENU_EXCLUSION;
- DebugPrintf("Deactivated\n");
+ debugPrintf("Deactivated\n");
} else {
if (strcmp(argv[2], "schedule") == 0) {
// List any current schedule for the character
- DebugPrintf("%s", hs->npcSchedule.getDebugInfo().c_str());
+ debugPrintf("%s", hs->npcSchedule.getDebugInfo().c_str());
}
if (!h)
- DebugPrintf("The specified hotspot is not currently active\n");
+ debugPrintf("The specified hotspot is not currently active\n");
else if (strcmp(argv[2], "paths") == 0) {
// List any paths for a charcter
- DebugPrintf("%s", h->pathFinder().getDebugInfo().c_str());
+ debugPrintf("%s", h->pathFinder().getDebugInfo().c_str());
}
else if (strcmp(argv[2], "pixels") == 0) {
// List the pixel data for the hotspot
HotspotAnimData &pData = h->anim();
- DebugPrintf("Record Id = %xh\n", pData.animRecordId);
- DebugPrintf("Flags = %d\n", pData.flags);
- DebugPrintf("Frames: up=%d down=%d left=%d right=%d\n",
+ debugPrintf("Record Id = %xh\n", pData.animRecordId);
+ debugPrintf("Flags = %d\n", pData.flags);
+ debugPrintf("Frames: up=%d down=%d left=%d right=%d\n",
pData.upFrame, pData.downFrame, pData.leftFrame, pData.rightFrame);
- DebugPrintf("Current frame = %d of %d\n", h->frameNumber(), h->numFrames());
+ debugPrintf("Current frame = %d of %d\n", h->frameNumber(), h->numFrames());
}
else if (strcmp(argv[2], "setpos") == 0) {
// Set the hotspot position
@@ -372,11 +372,11 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) {
h->setPosition(strToInt(argv[3]), strToInt(argv[4]));
if (argc >= 6)
h->setRoomNumber(strToInt(argv[5]));
- DebugPrintf("Done.\n");
+ debugPrintf("Done.\n");
}
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
@@ -388,56 +388,56 @@ bool Debugger::cmd_room(int argc, const char **argv) {
char buffer[MAX_DESC_SIZE];
if (argc < 2) {
- DebugPrintf("room <room_number>\n");
+ debugPrintf("room <room_number>\n");
return true;
}
int roomNumber = strToInt(argv[1]);
RoomData *room = res.getRoom(roomNumber);
if (!room) {
- DebugPrintf("Unknown room specified\n");
+ debugPrintf("Unknown room specified\n");
return true;
}
// Show the room details
strings.getString(roomNumber, buffer);
- DebugPrintf("room #%d - %s\n", roomNumber, buffer);
+ debugPrintf("room #%d - %s\n", roomNumber, buffer);
strings.getString(room->descId, buffer);
- DebugPrintf("%s\n", buffer);
- DebugPrintf("Horizontal clipping = %d->%d walk area=(%d,%d)-(%d,%d)\n",
+ debugPrintf("%s\n", buffer);
+ debugPrintf("Horizontal clipping = %d->%d walk area=(%d,%d)-(%d,%d)\n",
room->clippingXStart, room->clippingXEnd,
room->walkBounds.left, room->walkBounds.top,
room->walkBounds.right, room->walkBounds.bottom);
- DebugPrintf("Exit hotspots:");
+ debugPrintf("Exit hotspots:");
RoomExitHotspotList &exits = room->exitHotspots;
if (exits.empty())
- DebugPrintf(" none\n");
+ debugPrintf(" none\n");
else {
RoomExitHotspotList::iterator i;
for (i = exits.begin(); i != exits.end(); ++i) {
RoomExitHotspotData const &rec = **i;
- DebugPrintf("\nArea - (%d,%d)-(%d,%d) Room=%d Cursor=%d Hotspot=%xh",
+ debugPrintf("\nArea - (%d,%d)-(%d,%d) Room=%d Cursor=%d Hotspot=%xh",
rec.xs, rec.ys, rec.xe, rec.ye, rec.destRoomNumber, rec.cursorNum, rec.hotspotId);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("Room exits:");
+ debugPrintf("Room exits:");
if (room->exits.empty())
- DebugPrintf(" none\n");
+ debugPrintf(" none\n");
else {
RoomExitList::iterator i2;
for (i2 = room->exits.begin(); i2 != room->exits.end(); ++i2) {
RoomExitData const &rec2 = **i2;
- DebugPrintf("\nExit - (%d,%d)-(%d,%d) Dest=%d,(%d,%d) Dir=%s Sequence=%xh",
+ debugPrintf("\nExit - (%d,%d)-(%d,%d) Dest=%d,(%d,%d) Dir=%s Sequence=%xh",
rec2.xs, rec2.ys, rec2.xe, rec2.ye, rec2.roomNumber,
rec2.x, rec2.y, directionList[rec2.direction], rec2.sequenceOffset);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
return true;
@@ -446,7 +446,7 @@ bool Debugger::cmd_room(int argc, const char **argv) {
bool Debugger::cmd_showAnim(int argc, const char **argv) {
Resources &res = Resources::getReference();
if (argc < 2) {
- DebugPrintf("showAnim animId [[frame_width frame_height] | list]\n");
+ debugPrintf("showAnim animId [[frame_width frame_height] | list]\n");
return true;
}
@@ -454,7 +454,7 @@ bool Debugger::cmd_showAnim(int argc, const char **argv) {
int animId = strToInt(argv[1]);
HotspotAnimData *data = res.getAnimation(animId);
if (data == NULL) {
- DebugPrintf("No such animation Id exists\n");
+ debugPrintf("No such animation Id exists\n");
return true;
}
@@ -500,7 +500,7 @@ bool Debugger::cmd_showAnim(int argc, const char **argv) {
height = strToInt(argv[3]);
if ((width * height) != (frameSize * 2)) {
- DebugPrintf("Warning: Total size = %d, Frame size (%d,%d) * %d frames = %d bytes\n",
+ debugPrintf("Warning: Total size = %d, Frame size (%d,%d) * %d frames = %d bytes\n",
destSize, width, height, numFrames, width * height * numFrames / 2);
}
} else {
@@ -511,25 +511,25 @@ bool Debugger::cmd_showAnim(int argc, const char **argv) {
width = frameSize * 3 / 4;
bool descFlag = (argc == 3);
- if (descFlag) DebugPrintf("Target size = %d\n", frameSize * 2);
+ if (descFlag) debugPrintf("Target size = %d\n", frameSize * 2);
while ((width > 0) && (descFlag || (((frameSize * 2) % width) != 0))) {
if (((frameSize * 2) % width) == 0)
- DebugPrintf("Frame size (%d,%d) found\n", width, frameSize * 2 / width);
+ debugPrintf("Frame size (%d,%d) found\n", width, frameSize * 2 / width);
--width;
}
if (argc == 3) {
- DebugPrintf("Done\n");
+ debugPrintf("Done\n");
return true;
} else if (width == 0) {
- DebugPrintf("Total size = %d, # frames = %d, frame Size = %d - No valid frame dimensions\n",
+ debugPrintf("Total size = %d, # frames = %d, frame Size = %d - No valid frame dimensions\n",
destSize, numFrames, frameSize);
return true;
}
height = (frameSize * 2) / width;
- DebugPrintf("# frames = %d, guestimated frame size = (%d,%d)\n",
+ debugPrintf("# frames = %d, guestimated frame size = (%d,%d)\n",
numFrames, width, height);
}
@@ -544,13 +544,13 @@ bool Debugger::cmd_showAnim(int argc, const char **argv) {
hotspot->setAnimation(animId);
- DebugPrintf("Done\n");
+ debugPrintf("Done\n");
return true;
}
bool Debugger::cmd_saveStrings(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("strings <stringId>\n");
+ debugPrintf("strings <stringId>\n");
return true;
}
@@ -558,13 +558,13 @@ bool Debugger::cmd_saveStrings(int argc, const char **argv) {
char *buffer = (char *)malloc(32768);
if (!buffer) {
- DebugPrintf("Cannot allocate strings buffer\n");
+ debugPrintf("Cannot allocate strings buffer\n");
return true;
}
uint16 id = strToInt(argv[1]);
- strings.getString(id, buffer, NULL, NULL);
- DebugPrintf("%s\n", buffer);
+ strings.getString(id, buffer);
+ debugPrintf("%s\n", buffer);
/* Commented out code for saving all text strings - note that 0x1000 is chosen
* arbitrarily, so there'll be a bunch of garbage at the end, or the game will crash
@@ -580,7 +580,7 @@ bool Debugger::cmd_saveStrings(int argc, const char **argv) {
fclose(f);
- DebugPrintf("Done\n");
+ debugPrintf("Done\n");
*/
free(buffer);
@@ -593,16 +593,16 @@ bool Debugger::cmd_debug(int argc, const char **argv) {
Room &room = Room::getReference();
if ((argc == 2) && (strcmp(argv[1], "on") == 0)) {
- DebugPrintf("debug keys are on\n");
+ debugPrintf("debug keys are on\n");
game.debugFlag() = true;
} else if ((argc == 2) && (strcmp(argv[1], "off") == 0)) {
- DebugPrintf("debug keys are off\n");
+ debugPrintf("debug keys are off\n");
game.debugFlag() = false;
room.setShowInfo(false);
} else {
- DebugPrintf("debug [on | off]]\n");
+ debugPrintf("debug [on | off]]\n");
}
return true;
@@ -610,13 +610,13 @@ bool Debugger::cmd_debug(int argc, const char **argv) {
bool Debugger::cmd_script(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("script <script number> [param 1] [param 2] [param 3] [exit flag]\n");
+ debugPrintf("script <script number> [param 1] [param 2] [param 3] [exit flag]\n");
return true;
}
int scriptNumber = strToInt(argv[1]);
if ((scriptNumber < 0) || (scriptNumber > 66)) {
- DebugPrintf("An invalid script number was specified\n");
+ debugPrintf("An invalid script number was specified\n");
return true;
}
@@ -629,7 +629,7 @@ bool Debugger::cmd_script(int argc, const char **argv) {
param3 = strToInt(argv[4]);
Script::executeMethod(scriptNumber, param1, param2, param3);
- DebugPrintf("Script executed\n");
+ debugPrintf("Script executed\n");
return true;
}
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp
new file mode 100644
index 0000000000..80480cbdfd
--- /dev/null
+++ b/engines/mads/action.cpp
@@ -0,0 +1,708 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/action.h"
+#include "mads/inventory.h"
+#include "mads/resources.h"
+#include "mads/scene.h"
+#include "mads/staticres.h"
+
+namespace MADS {
+
+void ActionDetails::synchronize(Common::Serializer &s) {
+ s.syncAsUint16LE(_verbId);
+ s.syncAsUint16LE(_objectNameId);
+ s.syncAsUint16LE(_indirectObjectId);
+}
+
+void ActionSavedFields::synchronize(Common::Serializer &s) {
+ s.syncAsByte(_commandError);
+ s.syncAsSint16LE(_commandSource);
+ s.syncAsSint16LE(_command);
+ s.syncAsSint16LE(_mainObject);
+ s.syncAsSint16LE(_secondObject);
+ s.syncAsSint16LE(_mainObjectSource);
+ s.syncAsSint16LE(_secondObjectSource);
+ s.syncAsSint16LE(_articleNumber);
+ s.syncAsSint16LE(_lookFlag);
+}
+
+/*------------------------------------------------------------------------*/
+
+MADSAction::MADSAction(MADSEngine *vm) : _vm(vm) {
+ clear();
+ _statusTextIndex = -1;
+ _selectedAction = 0;
+ _inProgress = false;
+ _pickedWord = -1;
+
+ _savedFields._commandSource = 0;
+ _savedFields._mainObjectSource = 0;
+ _savedFields._command = -1;
+ _savedFields._mainObject = 0;
+ _savedFields._secondObject = 0;
+ _savedFields._secondObjectSource = 0;
+ _savedFields._articleNumber = PREP_NONE;
+ _savedFields._lookFlag = false;
+
+ _activeAction._verbId = VERB_NONE;
+ _activeAction._objectNameId = -1;
+ _activeAction._indirectObjectId = -1;
+ _savedFields._commandError = false;
+ _verbType = VERB_INIT;
+ _prepType = PREP_NONE;
+}
+
+void MADSAction::clear() {
+ _interAwaiting = AWAITING_COMMAND;
+ _commandSource = CAT_NONE;
+ _mainObjectSource = CAT_NONE;
+ _secondObjectSource = CAT_NONE;
+ _recentCommandSource = CAT_NONE;
+ _articleNumber = 0;
+ _lookFlag = false;
+ _pointEstablished = 0;
+ _statusText.clear();
+ _selectedRow = -1;
+ _hotspotId = -1;
+ _secondObject = -1;
+ _recentCommand = -1;
+ _action._verbId = VERB_NONE;
+ _action._objectNameId = -1;
+ _action._indirectObjectId = -1;
+ _textChanged = true;
+}
+
+void MADSAction::appendVocab(int vocabId, bool capitalize) {
+ Common::String vocabStr = _vm->_game->_scene.getVocab(vocabId);
+ if (capitalize)
+ vocabStr.setChar(toupper(vocabStr[0]), 0);
+
+ _statusText += vocabStr;
+ _statusText += " ";
+}
+
+void MADSAction::startWalkingDirectly(int walkType) {
+ Scene &scene = _vm->_game->_scene;
+ Player &player = _vm->_game->_player;
+
+ if (_pointEstablished && (walkType == -3 || _savedFields._command < 0)) {
+ player._needToWalk = true;
+ player._prepareWalkPos = scene._customDest;
+ }
+}
+
+void MADSAction::set() {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+ _statusText = "";
+
+ _action._verbId = VERB_NONE;
+ _action._objectNameId = -1;
+ _action._indirectObjectId = -1;
+
+ if (_commandSource == CAT_TALK_ENTRY) {
+ // Handle showing the conversation selection. Rex at least doesn't actually seem to use this
+ if (_selectedRow >= 0) {
+ _action._verbId = userInterface._talkIds[_selectedRow];
+ Common::String desc = userInterface._talkStrings[_selectedRow];
+ if (!desc.empty())
+ _statusText = desc;
+ }
+ } else if (_lookFlag && (_selectedRow == 0)) {
+ // Two 'look' actions in succession, so the action becomes 'Look around'
+ _statusText = kLookAroundStr;
+ } else {
+ bool flag = false;
+ if ((_commandSource == CAT_INV_VOCAB) && (_selectedRow >= 0)
+ && (_verbType == VERB_THAT) && (_prepType == PREP_NONE)) {
+ // Use/to action
+ int invIndex = userInterface._selectedInvIndex;
+ InventoryObject &objEntry = _vm->_game->_objects.getItem(invIndex);
+
+ _action._objectNameId = objEntry._descId;
+ _action._verbId = objEntry._vocabList[_selectedRow]._vocabId;
+
+ // Set up the status text string
+ _statusText = kUseStr;
+ appendVocab(_action._objectNameId);
+ _statusText += kToStr;
+ appendVocab(_action._verbId);
+ } else {
+ // Handling for if an action has been selected
+ if (_selectedRow >= 0) {
+ if (_commandSource == CAT_COMMAND) {
+ // Standard verb action
+ _action._verbId = scene._verbList[_selectedRow]._id;
+ } else {
+ // Selected action on an inventory object
+ int invIndex = userInterface._selectedInvIndex;
+ InventoryObject &objEntry = _vm->_game->_objects.getItem(invIndex);
+
+ _action._verbId = objEntry._vocabList[_selectedRow]._vocabId;
+ }
+
+ appendVocab(_action._verbId, true);
+
+ if (_action._verbId == VERB_LOOK) {
+ // Add in the word 'add'
+ _statusText += kArticleList[PREP_AT];
+ _statusText += " ";
+ }
+ }
+
+ // Add in any necessary article if necessary
+ if ((_hotspotId >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_verbType == VERB_THAT)) {
+ flag = true;
+
+ _statusText += kArticleList[_articleNumber];
+ _statusText += " ";
+ }
+
+ // Handling for hotspot
+ if (_hotspotId >= 0) {
+ if (_selectedRow < 0) {
+ int verbId;
+
+ if (_hotspotId < (int)scene._hotspots.size()) {
+ // Get the verb Id from the hotspot
+ verbId = scene._hotspots[_hotspotId]._verbId;
+ } else {
+ // Get the verb Id from the scene object
+ verbId = scene._dynamicHotspots[_hotspotId - scene._hotspots.size()]._verbId;
+ }
+
+ if (verbId > 0) {
+ // Set the specified action
+ _action._verbId = verbId;
+ appendVocab(_action._verbId, true);
+ } else {
+ // Default to a standard 'walk to'
+ _action._verbId = VERB_WALKTO;
+ _statusText += kWalkToStr;
+ }
+ }
+
+ if ((_mainObjectSource == CAT_INV_LIST) || (_mainObjectSource == CAT_INV_ANIM)) {
+ // Get name from given inventory object
+ InventoryObject &invObject = _vm->_game->_objects.getItem(_hotspotId);
+ _action._objectNameId = invObject._descId;
+ } else if (_hotspotId < (int)scene._hotspots.size()) {
+ // Get name from scene hotspot
+ _action._objectNameId = scene._hotspots[_hotspotId]._vocabId;
+ } else {
+ // Get name from temporary scene hotspot
+ _action._objectNameId = scene._dynamicHotspots[_hotspotId - scene._hotspots.size()]._descId;
+ }
+ appendVocab(_action._objectNameId);
+ }
+ }
+
+ if (_secondObject >= 0) {
+ if (_secondObjectSource == CAT_INV_LIST || _secondObjectSource == CAT_INV_ANIM) {
+ InventoryObject &invObject = _vm->_game->_objects.getItem(_secondObject);
+ _action._indirectObjectId = invObject._descId;
+ } else if (_secondObject < (int)scene._hotspots.size()) {
+ _action._indirectObjectId = scene._hotspots[_secondObject]._vocabId;
+ } else {
+ _action._indirectObjectId = scene._dynamicHotspots[_secondObject - scene._hotspots.size()]._descId;
+ }
+ }
+
+ if ((_hotspotId >= 0) && (_articleNumber > 0) && !flag) {
+ if (_articleNumber == PREP_RELATIONAL) {
+ if (_secondObject >= 0) {
+ int articleNum = 0;
+
+ if ((_secondObjectSource == 2) || (_secondObjectSource == 5)) {
+ InventoryObject &invObject = _vm->_game->_objects.getItem(_hotspotId);
+ articleNum = invObject._article;
+ } else if (_hotspotId < (int)scene._hotspots.size()) {
+ articleNum = scene._hotspots[_hotspotId]._articleNumber;
+ } else {
+ articleNum = scene._dynamicHotspots[_hotspotId - scene._hotspots.size()]._articleNumber;
+ }
+
+ _statusText += kArticleList[articleNum];
+ }
+ } else if ((_articleNumber == VERB_LOOK) || (_vm->getGameID() != GType_RexNebular) ||
+ (_action._indirectObjectId >= 0 && scene._vocabStrings[_action._indirectObjectId] != kFenceStr)) {
+ // Write out the article
+ _statusText += kArticleList[_articleNumber];
+ } else {
+ // Special case for a 'fence' entry in Rex Nebular
+ _statusText += kOverStr;
+ }
+
+ _statusText += " ";
+ }
+
+ // Append object description if necessary
+ if (_secondObject >= 0)
+ appendVocab(_action._indirectObjectId);
+
+ // Remove any trailing space character
+ if (_statusText.hasSuffix(" "))
+ _statusText.deleteLastChar();
+ }
+
+ _textChanged = true;
+}
+
+void MADSAction::refresh() {
+ Scene &scene = _vm->_game->_scene;
+
+ // Exit immediately if nothing has changed
+ if (!_textChanged)
+ return;
+
+ // Remove any old copy of the status text
+ if (_statusTextIndex >= 0) {
+ scene._textDisplay.expire(_statusTextIndex);
+ _statusTextIndex = -1;
+ }
+
+ if (!_statusText.empty()) {
+ if ((_vm->_game->_screenObjects._inputMode == kInputBuildingSentences) ||
+ (_vm->_game->_screenObjects._inputMode == kInputLimitedSentences)) {
+ Font *font = _vm->_font->getFont(FONT_MAIN);
+ int textSpacing = -1;
+
+ int strWidth = font->getWidth(_statusText);
+ if (strWidth > MADS_SCREEN_WIDTH) {
+ // Too large to fit, so fall back on interface font
+ font = _vm->_font->getFont(FONT_INTERFACE);
+ strWidth = font->getWidth(_statusText, 0);
+ textSpacing = 0;
+ }
+
+ // Add a new text display entry to display the status text at the bottom of the screen area
+ _statusTextIndex = scene._textDisplay.add(160 - (strWidth / 2),
+ MADS_SCENE_HEIGHT + scene._posAdjust.y - 13, 3, textSpacing, _statusText, font);
+ }
+ }
+
+ _textChanged = false;
+}
+
+void MADSAction::startAction() {
+ Game &game = *_vm->_game;
+ Player &player = game._player;
+ Scene &scene = _vm->_game->_scene;
+ DynamicHotspots &dynHotspots = scene._dynamicHotspots;
+ Hotspots &hotspots = scene._hotspots;
+
+ player.cancelCommand();
+
+ _inProgress = true;
+ _savedFields._commandError = false;
+ _savedFields._command = _selectedRow;
+ _savedFields._mainObject = _hotspotId;
+ _savedFields._secondObject = _secondObject;
+ _savedFields._articleNumber = _articleNumber;
+ _savedFields._commandSource = _commandSource;
+ _savedFields._mainObjectSource = _mainObjectSource;
+ _savedFields._secondObjectSource = _secondObjectSource;
+ _savedFields._lookFlag = _lookFlag;
+ _activeAction = _action;
+
+ // Copy the action to be active
+ _activeAction = _action;
+ _sentence = _statusText;
+
+ if ((_mainObjectSource == CAT_HOTSPOT) && (_secondObjectSource == 4))
+ _savedFields._commandError = true;
+
+ player._needToWalk = false;
+ int hotspotId = -1;
+
+ if (!_savedFields._lookFlag && (_vm->_game->_screenObjects._inputMode != kInputConversation)) {
+ if (_savedFields._mainObjectSource == CAT_HOTSPOT)
+ hotspotId = _savedFields._mainObject;
+ else if (_secondObjectSource == 4)
+ hotspotId = _savedFields._secondObject;
+
+ if (hotspotId >= (int)hotspots.size()) {
+ DynamicHotspot &hs = dynHotspots[hotspotId - hotspots.size()];
+ if ((hs._feetPos.x == -1) || (hs._feetPos.x == -3)) {
+ startWalkingDirectly(hs._feetPos.x);
+ } else if (hs._feetPos.x == 0) {
+ player._prepareWalkFacing = hs._facing;
+ } else if (_savedFields._commandSource == CAT_NONE || hs._cursor < CURSOR_WAIT) {
+ player._needToWalk = true;
+ player._prepareWalkPos = hs._feetPos;
+ }
+
+ player._prepareWalkFacing = hs._facing;
+ hotspotId = -1;
+ }
+ }
+
+ if (hotspotId >= 0) {
+ Hotspot &hs = hotspots[hotspotId];
+
+ if (hs._feetPos.x == -1 || hs._feetPos.x == -3) {
+ startWalkingDirectly(hs._feetPos.x);
+ } else if (hs._feetPos.x >= 0) {
+ if (_savedFields._commandSource == CAT_NONE || hs._cursor < CURSOR_WAIT) {
+ player._needToWalk = true;
+ player._prepareWalkPos = hs._feetPos;
+ }
+ }
+
+ player._prepareWalkFacing = hs._facing;
+ }
+
+ player._readyToWalk = player._needToWalk;
+}
+
+void MADSAction::checkAction() {
+ if (isAction(VERB_LOOK) || isAction(VERB_THROW))
+ _vm->_game->_player._needToWalk = false;
+}
+
+bool MADSAction::isAction(int verbId, int objectNameId, int indirectObjectId) {
+ if (_activeAction._verbId != verbId)
+ return false;
+ if ((objectNameId != 0) && (_activeAction._objectNameId != objectNameId))
+ return false;
+ if ((indirectObjectId != 0) && (_activeAction._indirectObjectId != indirectObjectId))
+ return false;
+
+ return true;
+}
+
+bool MADSAction::isObject(int objectNameId) {
+ return _activeAction._objectNameId == objectNameId;
+}
+
+bool MADSAction::isTarget(int objectNameId) {
+ return _activeAction._indirectObjectId == objectNameId;
+}
+
+void MADSAction::checkActionAtMousePos() {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+
+ if ((userInterface._category == CAT_COMMAND || userInterface._category == CAT_INV_VOCAB) &&
+ _interAwaiting != AWAITING_COMMAND && _pickedWord >= 0) {
+ if (_recentCommandSource == userInterface._category || _recentCommand != _pickedWord ||
+ (_interAwaiting != AWAITING_THIS && _interAwaiting != 3))
+ clear();
+ else if (_selectedRow != 0 || userInterface._category != CAT_COMMAND)
+ scene._lookFlag = false;
+ else
+ scene._lookFlag = true;
+ }
+
+ if (_vm->_events->_rightMousePressed && _vm->_events->_mouseButtons) {
+ switch (userInterface._category) {
+ case CAT_COMMAND:
+ case CAT_INV_VOCAB:
+ return;
+
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ if (_interAwaiting != AWAITING_THAT) {
+ if (userInterface._selectedActionIndex >= 0) {
+ _commandSource = CAT_COMMAND;
+ _selectedRow = userInterface._selectedActionIndex;
+ _verbType = scene._verbList[_selectedRow]._verbType;
+ _prepType = scene._verbList[_selectedRow]._prepType;
+ _interAwaiting = AWAITING_THIS;
+ } else if (userInterface._selectedItemVocabIdx >= 0) {
+ _commandSource = CAT_INV_VOCAB;
+ _selectedRow = userInterface._selectedItemVocabIdx;
+ int objectId = _vm->_game->_objects._inventoryList[_selectedRow];
+ InventoryObject &invObject = _vm->_game->_objects[objectId];
+
+ _verbType = invObject._vocabList[_selectedRow - 1]._verbType;
+ _prepType = invObject._vocabList[_selectedRow - 1]._prepType;
+ _mainObjectSource = CAT_INV_LIST;
+ _hotspotId = userInterface._selectedInvIndex;
+ _articleNumber = _prepType;
+
+ if ((_verbType == VERB_THIS && _prepType == PREP_NONE) ||
+ (_verbType == VERB_THAT && _prepType != PREP_NONE))
+ _interAwaiting = AWAITING_RIGHT_MOUSE;
+ else
+ _interAwaiting = AWAITING_THAT;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (_interAwaiting) {
+ case AWAITING_COMMAND:
+ _articleNumber = 0;
+ switch (userInterface._category) {
+ case CAT_COMMAND:
+ _commandSource = CAT_COMMAND;
+ _selectedRow = _pickedWord;
+ if (_selectedRow >= 0) {
+ _verbType = scene._verbList[_selectedRow]._verbType;
+ _prepType = scene._verbList[_selectedRow]._prepType;
+ }
+ break;
+
+ case CAT_INV_VOCAB:
+ _commandSource = CAT_INV_VOCAB;
+ _selectedRow = _pickedWord;
+ if (_selectedRow < 0) {
+ _hotspotId = -1;
+ _mainObjectSource = CAT_NONE;
+ } else {
+ InventoryObject &invObject = _vm->_game->_objects.getItem(userInterface._selectedInvIndex);
+ _verbType = invObject._vocabList[_selectedRow]._verbType;
+ _prepType = invObject._vocabList[_selectedRow]._prepType;
+ _hotspotId = userInterface._selectedInvIndex;
+ _mainObjectSource = CAT_INV_LIST;
+
+ if (_verbType == VERB_THAT)
+ _articleNumber = _prepType;
+ }
+ break;
+
+ case CAT_HOTSPOT:
+ _selectedRow = -1;
+ _commandSource = CAT_NONE;
+ _mainObjectSource = CAT_HOTSPOT;
+ _hotspotId = _pickedWord;
+ break;
+
+ case CAT_TALK_ENTRY:
+ _commandSource = CAT_TALK_ENTRY;
+ _selectedRow = _pickedWord;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case AWAITING_THIS:
+ _articleNumber = 0;
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ _mainObjectSource = userInterface._category;
+ _hotspotId = _pickedWord;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AWAITING_THAT:
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ _secondObjectSource = userInterface._category;
+ _secondObject = _pickedWord;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void MADSAction::leftClick() {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+ bool abortFlag = false;
+
+ if ((userInterface._category == CAT_COMMAND || userInterface._category == CAT_INV_VOCAB) &&
+ _interAwaiting != 1 && _pickedWord >= 0 &&
+ _recentCommandSource == userInterface._category && _recentCommand == _pickedWord &&
+ (_interAwaiting == 2 || userInterface._category == CAT_INV_VOCAB)) {
+ abortFlag = true;
+ if (_selectedRow == 0 && userInterface._category == CAT_COMMAND) {
+ _selectedAction = CAT_COMMAND;
+ scene._lookFlag = true;
+ } else {
+ _selectedAction = CAT_NONE;
+ scene._lookFlag = false;
+ clear();
+ }
+ }
+
+ if (abortFlag || (_vm->_events->_rightMousePressed && (userInterface._category == CAT_COMMAND ||
+ userInterface._category == CAT_INV_VOCAB)))
+ return;
+
+ switch (_interAwaiting) {
+ case AWAITING_COMMAND:
+ switch (userInterface._category) {
+ case CAT_COMMAND:
+ if (_selectedRow >= 0) {
+ if (_verbType == VERB_ONLY) {
+ _selectedAction = -1;
+ }
+ else {
+ _recentCommand = _selectedRow;
+ _recentCommandSource = _commandSource;
+ _interAwaiting = AWAITING_THIS;
+ }
+ }
+ break;
+
+ case CAT_INV_LIST:
+ if (_pickedWord >= 0) {
+ userInterface.selectObject(_pickedWord);
+ }
+ break;
+
+ case CAT_INV_VOCAB:
+ if (_selectedRow >= 0) {
+ if (_verbType != VERB_THIS || _prepType != PREP_NONE) {
+ if (_verbType != VERB_THAT || _prepType == PREP_NONE) {
+ _interAwaiting = AWAITING_THAT;
+ _articleNumber = _prepType;
+ } else {
+ _articleNumber = _prepType;
+ _selectedAction = -1;
+ }
+ } else {
+ _selectedAction = -1;
+ }
+
+ _recentCommand = _selectedRow;
+ _recentCommandSource = _commandSource;
+ }
+ break;
+
+ case CAT_HOTSPOT:
+ _recentCommand = -1;
+ _recentCommandSource = CAT_NONE;
+
+ if (_vm->_events->currentPos().y < MADS_SCENE_HEIGHT) {
+ scene._customDest = _vm->_events->currentPos() + scene._posAdjust;
+ _selectedAction = -1;
+ _pointEstablished = true;
+ }
+ break;
+
+ case CAT_TALK_ENTRY:
+ if (_selectedRow >= 0)
+ _selectedAction = -1;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case AWAITING_THIS:
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ if (_hotspotId >= 0) {
+ if (_prepType) {
+ _articleNumber = _prepType;
+ _interAwaiting = AWAITING_THAT;
+ } else {
+ _selectedAction = -1;
+ }
+
+ if (userInterface._category == CAT_HOTSPOT) {
+ scene._customDest = _vm->_events->mousePos() + scene._posAdjust;
+ _pointEstablished = true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AWAITING_THAT:
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ if (_secondObject >= 0) {
+ _selectedAction = -1;
+
+ if (userInterface._category == CAT_HOTSPOT) {
+ if (!_pointEstablished) {
+ scene._customDest = _vm->_events->mousePos() + scene._posAdjust;
+ _pointEstablished = true;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void MADSAction::synchronize(Common::Serializer &s) {
+ _action.synchronize(s);
+ _activeAction.synchronize(s);
+ s.syncAsSint16LE(_articleNumber);
+ s.syncAsByte(_lookFlag);
+ s.syncAsByte(_textChanged);
+ s.syncAsSint16LE(_selectedRow);
+ s.syncAsSint16LE(_selectedAction);
+ s.syncAsSint16LE(_statusTextIndex);
+ s.syncAsSint16LE(_hotspotId);
+ _savedFields.synchronize(s);
+
+ // TODO: When saving in Rex Village Hut, _senetence size() doesn't match
+ // string length. Find out why not
+ _sentence = Common::String(_sentence.c_str());
+ s.syncString(_sentence);
+
+ s.syncAsSint16LE(_verbType);
+ s.syncAsSint16LE(_prepType);
+ s.syncAsSint16LE(_commandSource);
+ s.syncAsSint16LE(_mainObjectSource);
+ s.syncAsSint16LE(_secondObject);
+ s.syncAsSint16LE(_secondObjectSource);
+ s.syncAsSint16LE(_recentCommandSource);
+ s.syncAsSint16LE(_recentCommand);
+ s.syncAsSint16LE(_interAwaiting);
+ s.syncAsSint16LE(_pickedWord);
+ s.syncAsByte(_pointEstablished);
+ s.syncAsByte(_inProgress);
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/action.h b/engines/mads/action.h
new file mode 100644
index 0000000000..cfd5a3be3f
--- /dev/null
+++ b/engines/mads/action.h
@@ -0,0 +1,176 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_ACTION_H
+#define MADS_ACTION_H
+
+#include "common/scummsys.h"
+#include "common/serializer.h"
+#include "common/str.h"
+
+namespace MADS {
+
+enum TriggerMode {
+ SEQUENCE_TRIGGER_PARSER = 0, // Triggers parser
+ SEQUENCE_TRIGGER_DAEMON = 1, // Triggers step/daemon code
+ SEQUENCE_TRIGGER_PREPARE = 2 // Triggers preparser
+};
+
+enum InterAwaiting {
+ AWAITING_NONE = 0,
+ AWAITING_COMMAND = 1, // Initial state: waiting for a command verb
+ AWAITING_THIS = 2, // Waiting for object
+ AWAITING_THAT = 3, // Waiting for a second object
+ AWAITING_RIGHT_MOUSE = 4 // Waiting for mouse button release
+};
+
+enum {
+ VERB_NONE = 0,
+ VERB_LOOK = 3,
+ VERB_TAKE = 4,
+ VERB_PUSH = 5,
+ VERB_OPEN = 6,
+ VERB_PUT = 7,
+ VERB_TALKTO = 8,
+ VERB_GIVE = 9,
+ VERB_PULL = 10,
+ VERB_CLOSE = 11,
+ VERB_THROW = 12,
+ VERB_WALKTO = 13
+};
+
+enum VerbType { VERB_ONLY, VERB_THIS, VERB_THAT, VERB_INIT };
+
+enum PrepType {
+ PREP_NONE, PREP_WITH, PREP_TO, PREP_AT, PREP_FROM, PREP_ON, PREP_IN,
+ PREP_UNDER, PREP_BEHIND, PREP_RELATIONAL = 0xff
+};
+
+enum ScrCategory {
+ CAT_NONE = 0, CAT_COMMAND = 1, CAT_INV_LIST = 2, CAT_INV_VOCAB = 3,
+ CAT_HOTSPOT = 4, CAT_INV_ANIM = 5, CAT_TALK_ENTRY = 6, CAT_INV_SCROLLER = 7,
+ CAT_12 = 12
+};
+
+class MADSEngine;
+
+struct ActionDetails {
+ int _verbId;
+ int _objectNameId;
+ int _indirectObjectId;
+
+ /**
+ * Synchronize the action details
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+struct ActionSavedFields {
+ bool _commandError;
+ int _commandSource;
+ int _command;
+ int _mainObject;
+ int _secondObject;
+ int _mainObjectSource;
+ int _secondObjectSource;
+ int _articleNumber;
+ int _lookFlag;
+
+ /**
+ * Synchronize the saved action details
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+class MADSAction {
+private:
+ MADSEngine *_vm;
+ Common::String _statusText;
+
+ void appendVocab(int vocabId, bool capitalize = false);
+
+ void startWalkingDirectly(int walkType);
+public:
+ ActionDetails _action, _activeAction;
+ int _articleNumber;
+ bool _lookFlag;
+ int _selectedRow;
+ bool _textChanged;
+ int _selectedAction;
+ int _statusTextIndex;
+ int _hotspotId;
+ ActionSavedFields _savedFields;
+ Common::String _sentence;
+
+ VerbType _verbType;
+ PrepType _prepType;
+ ScrCategory _commandSource;
+ ScrCategory _mainObjectSource;
+ int _secondObject;
+ ScrCategory _secondObjectSource;
+ ScrCategory _recentCommandSource;
+ bool _pointEstablished;
+ int _recentCommand;
+ InterAwaiting _interAwaiting;
+ bool _inProgress;
+ int _pickedWord;
+
+public:
+ MADSAction(MADSEngine *vm);
+
+ void clear();
+ void set();
+ const Common::String &statusText() const { return _statusText; }
+ void refresh();
+
+ /**
+ * Accepts the currently defined sentence from the ScreenObjects parser.
+ * Copies the data, and checks to see if the action requires the player
+ * to walk to the given hotspot.
+ */
+ void startAction();
+
+ void checkAction();
+ bool isAction(int verbId, int objectNameId = 0, int indirectObjectId = 0);
+ bool isObject(int objectNameId);
+ bool isTarget(int objectNameId);
+
+ /**
+ * Check the result of the current action on the sentence
+ * with the provision that the action is not yet complete.
+ */
+ void checkActionAtMousePos();
+
+ /**
+ * Execute a click within the scene
+ */
+ void leftClick();
+
+ /**
+ * Synchronize the saved action details
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_ACTION_H */
diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp
new file mode 100644
index 0000000000..6af8a9ae5f
--- /dev/null
+++ b/engines/mads/animation.cpp
@@ -0,0 +1,591 @@
+/* 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 "mads/animation.h"
+#include "mads/compression.h"
+
+#define FILENAME_SIZE 13
+
+namespace MADS {
+
+void AAHeader::load(Common::SeekableReadStream *f) {
+ _spriteSetsCount = f->readUint16LE();
+ _miscEntriesCount = f->readUint16LE();
+ _frameEntriesCount = f->readUint16LE();
+ _messagesCount = f->readUint16LE();
+ f->skip(1);
+ _flags = f->readByte();
+
+ f->skip(2);
+ _bgType = (AnimBgType)f->readUint16LE();
+ _roomNumber = f->readUint16LE();
+ f->skip(2);
+ _manualFlag = f->readUint16LE() != 0;
+ _spritesIndex = f->readUint16LE();
+ _scrollPosition.x = f->readSint16LE();
+ _scrollPosition.y = f->readSint16LE();
+ _scrollTicks = f->readUint32LE();
+ f->skip(6);
+
+ char buffer[FILENAME_SIZE];
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE - 1] = '\0';
+ _interfaceFile = Common::String(buffer);
+
+ for (int i = 0; i < 50; ++i) {
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE - 1] = '\0';
+ if (i < _spriteSetsCount)
+ _spriteSetNames.push_back(Common::String(buffer));
+ }
+
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE - 1] = '\0';
+ _soundName = Common::String(buffer);
+
+ f->skip(13);
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE - 1] = '\0';
+ _dsrName = Common::String(buffer);
+
+ f->read(buffer, FILENAME_SIZE);
+ buffer[FILENAME_SIZE - 1] = '\0';
+ _fontResource = Common::String(buffer);
+}
+
+/*------------------------------------------------------------------------*/
+
+void AnimMessage::load(Common::SeekableReadStream *f) {
+ _soundId = f->readSint16LE();
+
+ char buffer[64];
+ f->read(&buffer[0], 64);
+ _msg = Common::String(buffer);
+ f->skip(4);
+ _pos.x = f->readSint16LE();
+ _pos.y = f->readSint16LE();
+ _flags = f->readUint16LE();
+ _rgb1[0] = f->readByte() << 2;
+ _rgb1[1] = f->readByte() << 2;
+ _rgb1[2] = f->readByte() << 2;
+ _rgb2[0] = f->readByte() << 2;
+ _rgb2[1] = f->readByte() << 2;
+ _rgb2[2] = f->readByte() << 2;
+ f->skip(2); // Space for kernelMsgIndex
+ _kernelMsgIndex = -1;
+ f->skip(6);
+ _startFrame = f->readUint16LE();
+ _endFrame = f->readUint16LE();
+ f->skip(2);
+}
+
+void AnimFrameEntry::load(Common::SeekableReadStream *f, bool uiFlag) {
+ if (uiFlag) {
+ f->skip(2);
+ _frameNumber = -1; // Unused
+ _seqIndex = f->readByte();
+ _spriteSlot._spritesIndex = f->readByte();
+ _spriteSlot._frameNumber = (int8)f->readByte();
+ f->skip(1);
+ _spriteSlot._position.x = f->readSint16LE();
+ _spriteSlot._position.y = f->readSint16LE();
+ } else {
+ _frameNumber = f->readUint16LE();
+ if (_frameNumber & 0x8000)
+ _frameNumber = -(_frameNumber & 0x7fff);
+
+ _seqIndex = f->readByte();
+ _spriteSlot._spritesIndex = f->readByte();
+ _spriteSlot._frameNumber = f->readUint16LE();
+ if (_spriteSlot._frameNumber & 0x8000)
+ _spriteSlot._frameNumber = -(_spriteSlot._frameNumber & 0x7fff);
+
+ _spriteSlot._position.x = f->readSint16LE();
+ _spriteSlot._position.y = f->readSint16LE();
+ _spriteSlot._depth = f->readSByte();
+ _spriteSlot._scale = (int8)f->readByte();
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+void AnimMiscEntry::load(Common::SeekableReadStream *f) {
+ _soundId = f->readByte();
+ _msgIndex = f->readSByte();
+ _numTicks = f->readUint16LE();
+ _posAdjust.x = f->readSint16LE();
+ _posAdjust.y = f->readSint16LE();
+ _field8 = f->readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+void AnimUIEntry::load(Common::SeekableReadStream *f) {
+ _probability = f->readUint16LE();
+ _imageCount = f->readUint16LE();
+ _firstImage = f->readUint16LE();
+ _lastImage = f->readUint16LE();
+ _counter = f->readSint16LE();
+ for (int i = 0; i < ANIM_SPAWN_COUNT; ++i)
+ _spawn[i] = f->readByte();
+ for (int i = 0; i < ANIM_SPAWN_COUNT; ++i)
+ _spawnFrame[i] = f->readUint16LE();
+ _sound = f->readUint16LE() & 0xFF;
+ _soundFrame = f->readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+Animation *Animation::init(MADSEngine *vm, Scene *scene) {
+ return new Animation(vm, scene);
+}
+
+Animation::Animation(MADSEngine *vm, Scene *scene) : _vm(vm), _scene(scene) {
+ _font = nullptr;
+ _resetFlag = false;
+ _messageCtr = 0;
+ _skipLoad = false;
+ _freeFlag = false;
+ _unkIndex = -1;
+ _nextFrameTimer = 0;
+ _nextScrollTimer = 0;
+ _trigger = 0;
+ _triggerMode = SEQUENCE_TRIGGER_PREPARE;
+ _actionDetails._verbId = VERB_NONE;
+ _actionDetails._objectNameId = -1;
+ _actionDetails._indirectObjectId = -1;
+ _currentFrame = 0;
+ _oldFrameEntry = 0;
+}
+
+Animation::~Animation() {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_header._manualFlag)
+ scene._sprites.remove(_spriteListIndexes[_header._spritesIndex]);
+
+ for (int idx = 0; idx < _header._spriteSetsCount; ++idx) {
+ if (!_header._manualFlag || _header._spritesIndex != idx)
+ scene._sprites.remove(_spriteListIndexes[idx]);
+ }
+}
+
+void Animation::load(UserInterface &interfaceSurface, DepthSurface &depthSurface,
+ const Common::String &resName, int flags, Common::Array<PaletteCycle> *palCycles,
+ SceneInfo *sceneInfo) {
+ Common::String resourceName = resName;
+ if (!resourceName.contains("."))
+ resourceName += ".AA";
+
+ File f(resourceName);
+ MadsPack madsPack(&f);
+
+ Common::SeekableReadStream *stream = madsPack.getItemStream(0);
+ _header.load(stream);
+ delete stream;
+
+ if (_header._bgType == ANIMBG_INTERFACE)
+ flags |= PALFLAG_RESERVED;
+
+ if (flags & ANIMFLAG_LOAD_BACKGROUND) {
+ loadInterface(interfaceSurface, depthSurface, _header, flags, palCycles, sceneInfo);
+ }
+ if (flags & ANIMFLAG_LOAD_BACKGROUND_ONLY) {
+ // No data
+ _header._messagesCount = 0;
+ _header._frameEntriesCount = 0;
+ _header._miscEntriesCount = 0;
+ }
+
+ // Initialize the reference list
+ _spriteListIndexes.clear();
+ for (int i = 0; i < _header._spriteSetsCount; ++i)
+ _spriteListIndexes.push_back(-1);
+
+ int streamIndex = 1;
+ _messages.clear();
+ if (_header._messagesCount > 0) {
+ // Chunk 2: Following is a list of any messages for the animation
+ Common::SeekableReadStream *msgStream = madsPack.getItemStream(streamIndex++);
+
+ for (int i = 0; i < _header._messagesCount; ++i) {
+ AnimMessage rec;
+ rec.load(msgStream);
+ _messages.push_back(rec);
+ }
+
+ delete msgStream;
+ }
+
+ _frameEntries.clear();
+ if (_header._frameEntriesCount > 0) {
+ // Chunk 3: animation frame info
+ Common::SeekableReadStream *frameStream = madsPack.getItemStream(streamIndex++);
+
+ for (int i = 0; i < _header._frameEntriesCount; i++) {
+ AnimFrameEntry rec;
+ rec.load(frameStream, flags & ANIMFLAG_LOAD_BACKGROUND);
+ _frameEntries.push_back(rec);
+ }
+
+ delete frameStream;
+ }
+
+ _miscEntries.clear();
+ _uiEntries.clear();
+ if (_header._miscEntriesCount > 0) {
+ // Chunk 4: Misc Data
+ Common::SeekableReadStream *miscStream = madsPack.getItemStream(streamIndex++);
+
+ if (flags & ANIMFLAG_LOAD_BACKGROUND) {
+ for (int i = 0; i < _header._miscEntriesCount; ++i) {
+ AnimUIEntry rec;
+ rec.load(miscStream);
+ _uiEntries.push_back(rec);
+ }
+ } else {
+ for (int i = 0; i < _header._miscEntriesCount; ++i) {
+ AnimMiscEntry rec;
+ rec.load(miscStream);
+ _miscEntries.push_back(rec);
+ }
+ }
+
+ delete miscStream;
+ }
+
+ // If the animation specifies a font, then load it for access
+ delete _font;
+ if (_header._flags & ANIMFLAG_CUSTOM_FONT) {
+ Common::String fontName = "*" + _header._fontResource;
+ _font = _vm->_font->getFont(fontName.c_str());
+ } else {
+ _font = nullptr;
+ }
+
+ // Load all the sprite sets for the animation
+ for (uint i = 0; i < _spriteSets.size(); ++i)
+ delete _spriteSets[i];
+ _spriteSets.clear();
+ _spriteSets.resize(_header._spriteSetsCount);
+
+ for (int i = 0; i < _header._spriteSetsCount; ++i) {
+ if (_header._manualFlag && (i == _header._spritesIndex)) {
+ // Skip over field, since it's manually loaded
+ _spriteSets[i] = nullptr;
+ } else {
+ _spriteSets[i] = new SpriteAsset(_vm, _header._spriteSetNames[i], flags);
+ _spriteListIndexes[i] = _vm->_game->_scene._sprites.add(_spriteSets[i]);
+ }
+ }
+
+ if (_header._manualFlag) {
+ Common::String assetResName = "*" + _header._spriteSetNames[_header._spritesIndex];
+ SpriteAsset *sprites = new SpriteAsset(_vm, assetResName, flags);
+ _spriteSets[_header._spritesIndex] = sprites;
+
+ _spriteListIndexes[_header._spritesIndex] = _scene->_sprites.add(sprites);
+ }
+
+ Common::Array<int> usageList;
+ for (int idx = 0; idx < _header._spriteSetsCount; ++idx)
+ usageList.push_back(_spriteSets[idx]->_usageIndex);
+
+ if (usageList.size() > 0)
+ _vm->_palette->_paletteUsage.updateUsage(usageList, _header._messagesCount);
+
+ // Remaps the sprite list indexes for frames to the loaded sprite list indexes
+ for (uint i = 0; i < _frameEntries.size(); ++i) {
+ int spriteListIndex = _frameEntries[i]._spriteSlot._spritesIndex;
+ _frameEntries[i]._spriteSlot._spritesIndex = _spriteListIndexes[spriteListIndex];
+ }
+
+ f.close();
+}
+
+void Animation::preLoad(const Common::String &resName, int level) {
+ // No implementation in ScummVM, since access is fast enough that data
+ // doesn't need to be preloaded
+}
+
+void Animation::startAnimation(int endTrigger) {
+ _messageCtr = 0;
+ _skipLoad = true;
+
+ if (_header._manualFlag) {
+ _unkIndex = -1;
+ //SpriteAsset *asset = _scene->_sprites[_spriteListIndexes[_header._spritesIndex]];
+
+ // TODO: Weird stuff with _unkList. Seems like it's treated as pointers
+ // here, but in processText, it's used as POINTs?
+
+ loadFrame(1);
+ }
+
+ if (_vm->_game->_kernelMode == KERNEL_ACTIVE_CODE)
+ _vm->_palette->refreshSceneColors();
+
+ _currentFrame = 0;
+ _oldFrameEntry = 0;
+ _nextFrameTimer = _vm->_game->_scene._frameStartTime;
+ _trigger = endTrigger;
+ _triggerMode = _vm->_game->_triggerSetupMode;
+ _actionDetails = _vm->_game->_scene._action._activeAction;
+
+ for (int idx = 0; idx < _header._messagesCount; ++idx) {
+ _messages[idx]._kernelMsgIndex = -1;
+ }
+}
+
+void Animation::loadFrame(int frameNumber) {
+ Scene &scene = _vm->_game->_scene;
+ if (_skipLoad)
+ return;
+
+ Common::Point pt;
+ int spriteListIndex = _spriteListIndexes[_header._spritesIndex];
+ SpriteAsset &spriteSet = *scene._sprites[spriteListIndex];
+
+ if (_unkIndex < 0) {
+ MSurface *frame = spriteSet.getFrame(0);
+ pt.x = frame->getBounds().left;
+ pt.y = frame->getBounds().top;
+ } else {
+ pt.x = _unkList[_unkIndex].x;
+ pt.y = _unkList[_unkIndex].y;
+ _unkIndex = 1 - _unkIndex;
+ }
+
+ if (drawFrame(spriteSet, pt, frameNumber))
+ error("drawFrame failure");
+}
+
+bool Animation::drawFrame(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber) {
+ return 0;
+}
+
+void Animation::loadInterface(UserInterface &interfaceSurface, DepthSurface &depthSurface,
+ AAHeader &header, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo) {
+ _scene->_depthStyle = 0;
+ if (header._bgType <= ANIMBG_FULL_SIZE) {
+ _vm->_palette->_paletteUsage.setEmpty();
+ sceneInfo->load(header._roomNumber, flags, header._interfaceFile, 0, depthSurface, interfaceSurface);
+ _scene->_depthStyle = sceneInfo->_depthStyle == 2 ? 1 : 0;
+ if (palCycles) {
+ palCycles->clear();
+ for (uint i = 0; i < sceneInfo->_paletteCycles.size(); ++i)
+ palCycles->push_back(sceneInfo->_paletteCycles[i]);
+ }
+ } else if (header._bgType == ANIMBG_INTERFACE) {
+ // Load a scene interface
+ Common::String resourceName = "*" + header._interfaceFile;
+ interfaceSurface.load(resourceName);
+
+ if (palCycles)
+ palCycles->clear();
+ } else {
+ // Original has useless code here
+ }
+}
+
+bool Animation::hasScroll() const {
+ return (_header._scrollPosition.x != 0) || (_header._scrollPosition.y != 0);
+}
+
+void Animation::update() {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_header._manualFlag) {
+ int spriteListIndex = _spriteListIndexes[_header._spritesIndex];
+ int newIndex = -1;
+
+ for (uint idx = _oldFrameEntry; idx < _frameEntries.size(); ++idx) {
+ if (_frameEntries[idx]._frameNumber > _currentFrame)
+ break;
+ if (_frameEntries[idx]._spriteSlot._spritesIndex == spriteListIndex)
+ newIndex = _frameEntries[idx]._spriteSlot._frameNumber;
+ }
+
+ if (newIndex >= 0)
+ loadFrame(newIndex);
+ }
+
+ // If it's not time for the next frame, then exit
+ if (_vm->_game->_scene._frameStartTime < _nextFrameTimer)
+ return;
+
+ for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) {
+ if (scene._spriteSlots[idx]._seqIndex >= 0x80)
+ scene._spriteSlots[idx]._flags = IMG_ERASE;
+ }
+
+ // Validate the current frame
+ if (_currentFrame >= (int)_miscEntries.size()) {
+ // Is the animation allowed to be repeated?
+ if (_resetFlag) {
+ _currentFrame = 0;
+ _oldFrameEntry = 0;
+ } else {
+ _freeFlag = true;
+ return;
+ }
+ }
+
+ // Handle executing any sound command for this frame
+ AnimMiscEntry &misc = _miscEntries[_currentFrame];
+ if (misc._soundId)
+ _vm->_sound->command(misc._soundId);
+
+ // Handle any screen scrolling
+ if (hasScroll()) {
+ scene._backgroundSurface.scrollX(_header._scrollPosition.x);
+ scene._backgroundSurface.scrollY(_header._scrollPosition.y);
+ scene._spriteSlots.fullRefresh();
+ }
+
+ // Handle any offset adjustment for sprites as of this frame
+ bool paChanged = false;
+ if (scene._posAdjust.x != misc._posAdjust.x) {
+ scene._posAdjust.x = misc._posAdjust.x;
+ paChanged = true;
+ }
+ if (scene._posAdjust.y != misc._posAdjust.y) {
+ scene._posAdjust.y = misc._posAdjust.y;
+ paChanged = true;
+ }
+
+ if (paChanged) {
+ int newIndex = scene._spriteSlots.add();
+ scene._spriteSlots[newIndex]._seqIndex = -1;
+ scene._spriteSlots[newIndex]._flags = IMG_REFRESH;
+ }
+
+ // Main frame animation loop - frames get animated by being placed, as necessary, into the
+ // main sprite slot array
+ while ((uint)_oldFrameEntry < _frameEntries.size()) {
+ if (_frameEntries[_oldFrameEntry]._frameNumber > _currentFrame)
+ break;
+ else if (_frameEntries[_oldFrameEntry]._frameNumber == _currentFrame) {
+ // Found the correct frame
+ int spriteSlotIndex = 0;
+ int index = 0;
+
+ for (;;) {
+ if ((spriteSlotIndex == 0) && (index < (int)scene._spriteSlots.size())) {
+ int seqIndex = _frameEntries[_oldFrameEntry]._seqIndex - scene._spriteSlots[index]._seqIndex;
+ if (seqIndex == 0x80) {
+ if (scene._spriteSlots[index] == _frameEntries[_oldFrameEntry]._spriteSlot) {
+ scene._spriteSlots[index]._flags = IMG_STATIC;
+ spriteSlotIndex = -1;
+ }
+ }
+ ++index;
+ continue;
+ }
+
+ if (spriteSlotIndex == 0) {
+ int slotIndex = scene._spriteSlots.add();
+ SpriteSlot &slot = scene._spriteSlots[slotIndex];
+ slot.copy(_frameEntries[_oldFrameEntry]._spriteSlot);
+ slot._seqIndex = _frameEntries[_oldFrameEntry]._seqIndex + 0x80;
+
+ SpriteAsset &spriteSet = *scene._sprites[
+ scene._spriteSlots[slotIndex]._spritesIndex];
+ slot._flags = spriteSet.isBackground() ? IMG_DELTA : IMG_UPDATE;
+ }
+ break;
+ }
+ }
+
+ ++_oldFrameEntry;
+ }
+
+ // Handle the display of any messages
+ for (uint idx = 0; idx < _messages.size(); ++idx) {
+ if (_messages[idx]._kernelMsgIndex >= 0) {
+ // Handle currently active message
+ if ((_currentFrame < _messages[idx]._startFrame) || (_currentFrame > _messages[idx]._endFrame)) {
+ scene._kernelMessages.remove(_messages[idx]._kernelMsgIndex);
+ _messages[idx]._kernelMsgIndex = -1;
+ --_messageCtr;
+ }
+ } else if ((_currentFrame >= _messages[idx]._startFrame) && (_currentFrame <= _messages[idx]._endFrame)) {
+ // Start displaying the message
+ AnimMessage &me = _messages[idx];
+
+ // The color index to use is dependant on how many messages are currently on-screen
+ uint8 colIndex;
+ switch (_messageCtr) {
+ case 1:
+ colIndex = 252;
+ break;
+ case 2:
+ colIndex = 16;
+ break;
+ default:
+ colIndex = 250;
+ break;
+ }
+
+ _vm->_palette->setEntry(colIndex, me._rgb1[0], me._rgb1[1], me._rgb1[2]);
+ _vm->_palette->setEntry(colIndex + 1, me._rgb2[0], me._rgb2[1], me._rgb2[2]);
+
+ // Add a kernel message to display the given text
+ me._kernelMsgIndex = scene._kernelMessages.add(me._pos, colIndex * 0x101 + 0x100,
+ 0, 0, INDEFINITE_TIMEOUT, me._msg);
+ assert(me._kernelMsgIndex >= 0);
+ ++_messageCtr;
+ }
+ }
+
+ // Move to the next frame
+ _currentFrame++;
+ if (_currentFrame >= (int)_miscEntries.size()) {
+ // Animation is complete
+ if (_trigger != 0) {
+ _vm->_game->_trigger = _trigger;
+ _vm->_game->_triggerMode = _triggerMode;
+
+ if (_triggerMode != SEQUENCE_TRIGGER_DAEMON) {
+ // Copy the noun list
+ scene._action._activeAction = _actionDetails;
+ }
+ }
+ }
+
+ int frameNum = MIN(_currentFrame, (int)_miscEntries.size() - 1);
+ _nextFrameTimer = _vm->_game->_scene._frameStartTime + _miscEntries[frameNum]._numTicks;
+}
+
+void Animation::setCurrentFrame(int frameNumber) {
+ _currentFrame = frameNumber;
+ _oldFrameEntry = 0;
+ _freeFlag = false;
+
+ _nextScrollTimer = _nextFrameTimer = _vm->_game->_scene._frameStartTime;
+}
+
+void Animation::setNextFrameTimer(int frameNumber) {
+ _nextFrameTimer = frameNumber;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/animation.h b/engines/mads/animation.h
new file mode 100644
index 0000000000..15086d3e41
--- /dev/null
+++ b/engines/mads/animation.h
@@ -0,0 +1,230 @@
+/* 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 MADS_ANIMATION_H
+#define MADS_ANIMATION_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "mads/msurface.h"
+#include "mads/scene_data.h"
+#include "mads/font.h"
+#include "mads/user_interface.h"
+
+namespace MADS {
+
+enum AnimFlag {
+ ANIMFLAG_DITHER = 0x0001, // Dither to 16 colors
+ ANIMFLAG_CUSTOM_FONT = 0x0020, // Load ccustom font
+ ANIMFLAG_LOAD_BACKGROUND = 0x0100, // Load background
+ ANIMFLAG_LOAD_BACKGROUND_ONLY = 0x0200 // Load background only
+};
+
+enum AnimBgType {
+ ANIMBG_ROOM = 1, ANIMBG_FULL_SIZE = 2, ANIMBG_BLACK_SCREEN = 3,
+ ANIMBG_INTERFACE = 4
+};
+
+class MADSEngine;
+class Scene;
+
+class AnimMessage {
+public:
+ int16 _soundId;
+ Common::String _msg;
+ Common::Point _pos;
+ byte _rgb1[3], _rgb2[3];
+ int _flags;
+ int _startFrame, _endFrame;
+ int _kernelMsgIndex;
+
+ /**
+ * Loads data for the message from a stream
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class AnimFrameEntry {
+public:
+ int _frameNumber;
+ int _seqIndex;
+ SpriteSlotSubset _spriteSlot;
+
+ /**
+ * Loads data for the record
+ */
+ void load(Common::SeekableReadStream *f, bool uiFlag);
+};
+
+class AnimMiscEntry {
+public:
+ int _soundId;
+ int _msgIndex;
+ int _numTicks;
+ Common::Point _posAdjust;
+ int _field8;
+
+ /**
+ * Loads data for the record
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+#define ANIM_SPAWN_COUNT 2
+
+class AnimUIEntry {
+public:
+ int _probability;
+ int _imageCount;
+ int _firstImage;
+ int _lastImage;
+ int _counter;
+ int _spawn[ANIM_SPAWN_COUNT];
+ int _spawnFrame[ANIM_SPAWN_COUNT];
+ int _sound;
+ int _soundFrame;
+
+ /**
+ * Loads the data for the record
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class AAHeader {
+public:
+ int _spriteSetsCount;
+ int _miscEntriesCount;
+ int _frameEntriesCount;
+ int _messagesCount;
+ byte _flags;
+ AnimBgType _bgType;
+ int _roomNumber;
+ bool _manualFlag;
+ int _spritesIndex;
+ Common::Point _scrollPosition;
+ uint32 _scrollTicks;
+ Common::String _interfaceFile;
+ Common::StringArray _spriteSetNames;
+ Common::String _lbmFilename;
+ Common::String _spritesFilename;
+ Common::String _soundName;
+ Common::String _dsrName;
+ Common::String _fontResource;
+
+ /**
+ * Loads the data for a animation file header
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class Animation {
+private:
+ MADSEngine *_vm;
+ Scene *_scene;
+
+ Common::Array<AnimMiscEntry> _miscEntries;
+ Common::Array<SpriteAsset *> _spriteSets;
+ Font *_font;
+
+ bool _freeFlag;
+ bool _skipLoad;
+ int _unkIndex;
+ Common::Point _unkList[2];
+ uint32 _nextFrameTimer;
+ uint32 _nextScrollTimer;
+ int _messageCtr;
+ int _trigger;
+ TriggerMode _triggerMode;
+ ActionDetails _actionDetails;
+
+ /**
+ * Load data for a given frame
+ * @param frameNumber Frame number
+ */
+ void loadFrame(int frameNumber);
+
+ bool drawFrame(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber);
+
+ /**
+ * Load the user interface display for an animation
+ */
+ void loadInterface(UserInterface &interfaceSurface, DepthSurface &depthSurface,
+ AAHeader &header, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo);
+
+ /**
+ * Returns true if there is a scroll required
+ */
+ bool hasScroll() const;
+protected:
+ Animation(MADSEngine *vm, Scene *scene);
+public:
+ AAHeader _header;
+ Common::Array<int> _spriteListIndexes;
+ Common::Array<AnimFrameEntry> _frameEntries;
+ Common::Array<AnimUIEntry> _uiEntries;
+ Common::Array<AnimMessage> _messages;
+ bool _resetFlag;
+ int _currentFrame;
+ int _oldFrameEntry;
+
+ static Animation *init(MADSEngine *vm, Scene *scene);
+ /*
+ * Destructor
+ */
+ ~Animation();
+
+ /**
+ * Loads animation data
+ */
+ void load(UserInterface &interfaceSurface, DepthSurface &depthSurface, const Common::String &resName,
+ int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo);
+
+ /**
+ * Preload animation data for the scene
+ */
+ void preLoad(const Common::String &resName, int level);
+
+ /**
+ * Setups up a loaded animation for playback
+ */
+ void startAnimation(int endTrigger);
+
+ /**
+ * Update the animation
+ */
+ void update();
+
+ void setNextFrameTimer(int frameNumber);
+ int getNextFrameTimer() const { return _nextFrameTimer; }
+ void setCurrentFrame(int frameNumber);
+ int getCurrentFrame() const { return _currentFrame; }
+
+ bool freeFlag() const { return _freeFlag; }
+ int roomNumber() const { return _header._roomNumber; }
+
+ void resetSpriteSetsCount() { _header._spriteSetsCount = 0; } // CHECKME: See if it doesn't leak the memory when the destructor is called
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_ANIMATION_H */
diff --git a/engines/mads/assets.cpp b/engines/mads/assets.cpp
new file mode 100644
index 0000000000..0bbf6177eb
--- /dev/null
+++ b/engines/mads/assets.cpp
@@ -0,0 +1,228 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/assets.h"
+#include "mads/compression.h"
+#include "mads/events.h"
+#include "mads/palette.h"
+
+namespace MADS {
+
+SpriteAsset::SpriteAsset(MADSEngine *vm, const Common::String &resourceName, int flags) : _vm(vm) {
+ Common::String resName = resourceName;
+ if (!resName.hasSuffix(".SS") && !resName.hasSuffix(".ss"))
+ resName += ".SS";
+ _srcSize = 0;
+
+ File file(resName);
+ load(&file, flags);
+
+ file.close();
+}
+
+SpriteAsset::SpriteAsset(MADSEngine *vm, Common::SeekableReadStream *stream, int flags) : _vm(vm) {
+ _srcSize = 0;
+
+ load(stream, flags);
+}
+
+SpriteAsset::~SpriteAsset() {
+ if (_usageIndex)
+ _vm->_palette->_paletteUsage.resetPalFlags(_usageIndex);
+
+ for (uint i = 0; i < _frames.size(); ++i)
+ delete _frames[i]._frame;
+
+ delete _charInfo;
+}
+
+void SpriteAsset::load(Common::SeekableReadStream *stream, int flags) {
+ int curFrame = 0;
+ uint32 frameOffset = 0;
+ MadsPack sprite(stream);
+ _frameRate = 0;
+ _pixelSpeed = 0;
+ _maxWidth = 0;
+ _maxHeight = 0;
+ _usageIndex = -1;
+
+ Common::SeekableReadStream *spriteStream = sprite.getItemStream(0);
+ _mode = spriteStream->readByte();
+ spriteStream->skip(1);
+ int type1 = spriteStream->readUint16LE();
+ int type2 = spriteStream->readUint16LE();
+ _isBackground = (type1 != 0) && (type2 < 4);
+ spriteStream->skip(32);
+ _frameCount = spriteStream->readUint16LE();
+
+ if ((flags & SPRITE_SET_CHAR_INFO) == 0)
+ _charInfo = nullptr;
+ else
+ _charInfo = new SpriteSetCharInfo(spriteStream);
+
+ delete spriteStream;
+
+ // Get the palette data
+ Common::SeekableReadStream *palStream = sprite.getItemStream(2);
+ Common::Array<RGB6> palette;
+
+ int numColors = palStream->readUint16LE();
+ assert(numColors <= 252);
+ _colorCount = numColors;
+
+ // Load in the palette
+ palette.resize(numColors);
+ for (int i = 0; i < numColors; ++i)
+ palette[i].load(palStream);
+ delete palStream;
+
+ // Process the palette data
+ if (flags & 9) {
+ _usageIndex = 0;
+
+ if (flags & 8) {
+ int newPalCtr = 0;
+
+ for (uint i = 0; i < palette.size(); ++i) {
+ RGB6 &rgb = palette[i];
+
+ // Scan for existing rgb at beginning of the main palette
+ bool found = false;
+ for (int pIndex = 0; pIndex < 4 && !found; ++pIndex) {
+ byte *palP = &_vm->_palette->_mainPalette[pIndex * 3];
+ if (palP[0] == rgb.r && palP[1] == rgb.g && palP[2] == rgb.b) {
+ rgb._palIndex = pIndex;
+ found = true;
+ }
+ }
+
+ if (!found) {
+ // Existing palette entry not found, so need to add it in
+ int palIndex = (0xF7F607 >> (8 * newPalCtr)) & 0xff;
+ byte *palP = &_vm->_palette->_mainPalette[palIndex * 3];
+ palP[0] = rgb.r;
+ palP[1] = rgb.g;
+ palP[2] = rgb.b;
+ rgb._palIndex = palIndex;
+
+ newPalCtr = MIN(newPalCtr + 1, 2);
+ }
+ }
+ }
+ } else {
+ _usageIndex = _vm->_palette->_paletteUsage.process(palette, flags);
+ assert(_usageIndex >= 0);
+ }
+
+ spriteStream = sprite.getItemStream(1);
+ Common::SeekableReadStream *spriteDataStream = sprite.getItemStream(3);
+ SpriteAssetFrame frame;
+ Common::Array<int> frameSizes;
+ for (curFrame = 0; curFrame < _frameCount; curFrame++) {
+ frame._stream = 0;
+ frame._comp = 0;
+ frameOffset = spriteStream->readUint32LE();
+ _frameOffsets.push_back(frameOffset);
+ uint32 frameSize = spriteStream->readUint32LE();
+ frameSizes.push_back(frameSize);
+
+ frame._bounds.left = spriteStream->readSint16LE();
+ frame._bounds.top = spriteStream->readSint16LE();
+ frame._bounds.setWidth(spriteStream->readUint16LE());
+ frame._bounds.setHeight(spriteStream->readUint16LE());
+
+ if (curFrame == 0)
+ debugC(1, kDebugGraphics, "%i frames, x = %i, y = %i, w = %i, h = %i\n",
+ _frameCount, frame._bounds.left, frame._bounds.top,
+ frame._bounds.width(), frame._bounds.height());
+
+ if (_mode == 0) {
+ // Create a frame and decompress the raw pixel data
+ uint32 currPos = (uint32)spriteDataStream->pos();
+ frame._frame = new MSprite(spriteDataStream, palette, frame._bounds);
+ assert((uint32)spriteDataStream->pos() == (currPos + frameSize));
+ }
+
+ _frames.push_back(frame);
+ }
+
+ if (_mode != 0) {
+ // Handle decompressing Fab encoded data
+ for (curFrame = 0; curFrame < _frameCount; curFrame++) {
+ FabDecompressor fab;
+
+ int srcSize = (curFrame == (_frameCount - 1)) ? spriteDataStream->size() - _frameOffsets[curFrame] :
+ _frameOffsets[curFrame + 1] - _frameOffsets[curFrame];
+ byte *srcData = new byte[srcSize];
+ assert(srcData);
+ spriteDataStream->read(srcData, srcSize);
+
+ byte *destData = new byte[frameSizes[curFrame]];
+ assert(destData);
+
+ fab.decompress(srcData, srcSize, destData, frameSizes[curFrame]);
+
+ // Load the frames
+ Common::MemoryReadStream *rs = new Common::MemoryReadStream(destData, frameSizes[curFrame]);
+ _frames[curFrame]._frame = new MSprite(rs, palette, _frames[curFrame]._bounds);
+ delete rs;
+
+ delete[] srcData;
+ delete[] destData;
+ }
+ }
+
+ delete spriteStream;
+ delete spriteDataStream;
+}
+
+MSprite *SpriteAsset::getFrame(int frameIndex) {
+ if ((uint)frameIndex < _frames.size()) {
+ return _frames[frameIndex]._frame;
+ } else {
+ debugC(kDebugGraphics, "SpriteAsset::getFrame: Invalid frame %d, out of %d", frameIndex, _frames.size());
+ return _frames[_frames.size() - 1]._frame;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+SpriteSetCharInfo::SpriteSetCharInfo(Common::SeekableReadStream *s) {
+ _totalFrames = s->readByte();
+ s->skip(1);
+ _numEntries = s->readUint16LE();
+
+ for (int i = 0; i < 16; ++i)
+ _startFrames[i] = s->readUint16LE();
+ for (int i = 0; i < 16; ++i)
+ _stopFrames[i] = s->readUint16LE();
+ for (int i = 0; i < 16; ++i)
+ _ticksList[i] = s->readUint16LE();
+
+ _velocity = s->readUint16LE();
+ _ticksAmount = s->readByte();
+ _centerOfGravity = s->readByte();
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/assets.h b/engines/mads/assets.h
new file mode 100644
index 0000000000..9242802187
--- /dev/null
+++ b/engines/mads/assets.h
@@ -0,0 +1,111 @@
+/* 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 MADS_ASSETS_H
+#define MADS_ASSETS_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/palette.h"
+
+namespace MADS {
+
+#define SPRITE_SET_CHAR_INFO 4
+
+class MADSEngine;
+class MSprite;
+class MSurface;
+
+struct SpriteAssetFrame {
+ uint32 _stream;
+ Common::Rect _bounds;
+ uint32 _comp;
+ MSprite *_frame;
+};
+
+class SpriteSetCharInfo {
+public:
+ SpriteSetCharInfo(Common::SeekableReadStream *s);
+
+ int _totalFrames;
+ int _numEntries;
+ int _startFrames[16];
+ int _stopFrames[16];
+ int _ticksList[16];
+ int _velocity;
+ int _ticksAmount;
+ int _centerOfGravity;
+};
+
+class SpriteAsset {
+private:
+ MADSEngine *_vm;
+ byte _palette[PALETTE_SIZE];
+ int _colorCount;
+ uint32 _srcSize;
+ int _frameRate, _pixelSpeed;
+ int _maxWidth, _maxHeight;
+ int _frameCount;
+ Common::Array<uint32> _frameOffsets;
+ Common::Array<SpriteAssetFrame> _frames;
+ uint8 _mode;
+ bool _isBackground;
+
+ /**
+ * Load the data for the asset
+ */
+ void load(Common::SeekableReadStream *stream, int flags);
+public:
+ SpriteSetCharInfo *_charInfo;
+ int _usageIndex;
+public:
+ /**
+ * Constructor
+ */
+ SpriteAsset(MADSEngine *vm, const Common::String &resourceName, int flags);
+
+ /**
+ * Constructor
+ */
+ SpriteAsset(MADSEngine *vm, Common::SeekableReadStream *stream, int flags);
+
+ /**
+ * Destructor
+ */
+ ~SpriteAsset();
+
+ int getCount() { return _frameCount; }
+ int getFrameRate() const { return _frameRate; }
+ int getPixelSpeed() const { return _pixelSpeed; }
+ int getFrameWidth(int index);
+ int getFrameHeight(int index);
+ int getMaxFrameWidth() const { return _maxWidth; }
+ int getMaxFrameHeight() const { return _maxHeight; }
+ MSprite *getFrame(int frameIndex);
+ byte *getPalette() { return _palette; }
+ int getColorCount() { return _colorCount; }
+ bool isBackground() const { return _isBackground; }
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_ASSETS_H */
diff --git a/engines/mads/audio.cpp b/engines/mads/audio.cpp
new file mode 100644
index 0000000000..1c61e13957
--- /dev/null
+++ b/engines/mads/audio.cpp
@@ -0,0 +1,129 @@
+/* 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 "mads/audio.h"
+#include "mads/compression.h"
+
+#include "common/stream.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+
+namespace MADS {
+
+AudioPlayer::AudioPlayer(Audio::Mixer *mixer, uint32 gameID) : _mixer(mixer), _gameID(gameID) {
+ setVolume(Audio::Mixer::kMaxChannelVolume);
+ setDefaultSoundGroup();
+}
+
+AudioPlayer::~AudioPlayer() {
+ _dsrEntries.clear();
+}
+
+bool AudioPlayer::isPlaying() const {
+ return _mixer->isSoundHandleActive(_handle);
+}
+
+void AudioPlayer::setVolume(int volume) {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
+}
+
+void AudioPlayer::setDefaultSoundGroup() {
+ switch (_gameID) {
+ case GType_RexNebular:
+ setSoundGroup("rex009.dsr");
+ break;
+ case GType_Dragonsphere:
+ setSoundGroup("drag009.dsr");
+ break;
+ case GType_Phantom:
+ setSoundGroup("phan009.dsr");
+ break;
+ default:
+ error("setDefaultSoundGroup: Unknown game");
+ }
+}
+
+void AudioPlayer::setSoundGroup(const Common::String &filename) {
+ _dsrEntries.clear();
+
+ _filename = filename;
+ _dsrFile.open(filename);
+
+ // Read header
+ uint16 entryCount = _dsrFile.readUint16LE();
+
+ for (uint16 i = 0; i < entryCount; i++) {
+ DSREntry newEntry;
+ newEntry.frequency = _dsrFile.readUint16LE();
+ newEntry.channels = _dsrFile.readUint32LE();
+ newEntry.compSize = _dsrFile.readUint32LE();
+ newEntry.uncompSize = _dsrFile.readUint32LE();
+ newEntry.offset = _dsrFile.readUint32LE();
+ _dsrEntries.push_back(newEntry);
+ }
+
+ _dsrFile.close();
+}
+
+void AudioPlayer::playSound(int soundIndex, bool loop) {
+ if (_dsrEntries.empty()) {
+ warning("DSR file not loaded, not playing sound");
+ return;
+ }
+
+ if (soundIndex < 0 || soundIndex > (int)_dsrEntries.size() - 1) {
+ warning("Invalid sound index: %i (max %i), not playing sound", soundIndex, _dsrEntries.size() - 1);
+ return;
+ }
+
+ // Get sound data
+ FabDecompressor fab;
+ int32 compSize = _dsrEntries[soundIndex].compSize;
+ int32 uncompSize = _dsrEntries[soundIndex].uncompSize;
+ int32 offset = _dsrEntries[soundIndex].offset;
+ int16 frequency = _dsrEntries[soundIndex].frequency;
+ byte *compData = new byte[compSize];
+ byte *buffer = new byte[uncompSize];
+ _dsrFile.open(_filename);
+ _dsrFile.seek(offset, SEEK_SET);
+ _dsrFile.read(compData, compSize);
+ _dsrFile.close();
+
+ fab.decompress(compData, compSize, buffer, uncompSize);
+
+ // Play sound
+ Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
+ Audio::makeRawStream(buffer, uncompSize, frequency, Audio::FLAG_UNSIGNED),
+ loop ? 0 : 1);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, stream, -1, Audio::Mixer::kMaxChannelVolume);
+
+ /*
+ // Dump the sound file
+ FILE *destFile = fopen("sound.raw", "wb");
+ fwrite(_dsrFile.dsrEntries[soundIndex]->data, _dsrFile.dsrEntries[soundIndex].uncompSize, 1, destFile);
+ fclose(destFile);
+ */
+}
+
+} // End of namespace M4
diff --git a/engines/mads/audio.h b/engines/mads/audio.h
new file mode 100644
index 0000000000..21f4bed59a
--- /dev/null
+++ b/engines/mads/audio.h
@@ -0,0 +1,64 @@
+/* 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 MADS_AUDIO_H
+#define MADS_AUDIO_H
+
+#include "mads/resources.h"
+
+#include "common/array.h"
+#include "audio/mixer.h"
+
+namespace MADS {
+
+struct DSREntry {
+ int16 frequency;
+ int channels;
+ int32 compSize;
+ int32 uncompSize;
+ int32 offset;
+};
+
+class AudioPlayer {
+public:
+ AudioPlayer(Audio::Mixer *mixer, uint32 gameID);
+ ~AudioPlayer();
+
+ void setSoundGroup(const Common::String &filename);
+ void setDefaultSoundGroup();
+ void playSound(int soundIndex, bool loop = false);
+ void setVolume(int volume);
+ bool isPlaying() const;
+
+ private:
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _handle;
+ uint32 _gameID;
+
+ File _dsrFile;
+ Common::String _filename;
+ Common::Array<DSREntry> _dsrEntries;
+};
+
+} // End of namespace MADS
+
+#endif
diff --git a/engines/mads/compression.cpp b/engines/mads/compression.cpp
new file mode 100644
index 0000000000..79cd1786de
--- /dev/null
+++ b/engines/mads/compression.cpp
@@ -0,0 +1,194 @@
+/* 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 "mads/compression.h"
+
+namespace MADS {
+
+const char *const madsPackString = "MADSPACK";
+const char *const FabInputExceededError = "FabDecompressor - Passed end of input buffer during decompression";
+const char *const FabOutputExceededError = "FabDecompressor - Decompressed data exceeded specified size";
+
+bool MadsPack::isCompressed(Common::SeekableReadStream *stream) {
+ // Check whether the passed stream is packed
+
+ char tempBuffer[8];
+ stream->seek(0);
+ if (stream->read(tempBuffer, 8) == 8) {
+ if (!strncmp(tempBuffer, madsPackString, 8))
+ return true;
+ }
+
+ return false;
+}
+
+MadsPack::MadsPack(Common::SeekableReadStream *stream) {
+ initialize(stream);
+}
+
+MadsPack::MadsPack(const Common::String &resourceName, MADSEngine *vm) {
+ File file(resourceName);
+ initialize(&file);
+ file.close();
+}
+
+void MadsPack::initialize(Common::SeekableReadStream *stream) {
+ if (!MadsPack::isCompressed(stream))
+ error("Attempted to decompress a resource that was not MadsPacked");
+
+ stream->seek(14);
+ _count = stream->readUint16LE();
+ _items = new MadsPackEntry[_count];
+
+ byte *headerData = new byte[0xA0];
+ byte *header = headerData;
+ stream->read(headerData, 0xA0);
+
+ for (int i = 0; i < _count; ++i, header += 10) {
+ // Get header data
+ _items[i]._type = (CompressionType)*header;
+ _items[i]._priority = *(header + 1);
+ _items[i]._size = READ_LE_UINT32(header + 2);
+ _items[i]._compressedSize = READ_LE_UINT32(header + 6);
+
+ byte *sourceData = new byte[_items[i]._compressedSize];
+ stream->read(sourceData, _items[i]._compressedSize);
+
+ switch (_items[i]._type) {
+ case COMPRESS_NONE:
+ // Entry isn't compressed
+ _items[i]._data = sourceData;
+ break;
+
+ case COMPRESS_FAB: {
+ // Decompress the entry
+ _items[i]._data = new byte[_items[i]._size];
+
+ FabDecompressor fab;
+ fab.decompress(sourceData, _items[i]._compressedSize, _items[i]._data, _items[i]._size);
+ delete[] sourceData;
+ break;
+ }
+
+ default:
+ error("Unknown compression type encountered");
+ }
+ }
+
+ delete[] headerData;
+ _dataOffset = stream->pos();
+}
+
+MadsPack::~MadsPack() {
+ for (int i = 0; i < _count; ++i)
+ delete[] _items[i]._data;
+ delete[] _items;
+}
+
+//--------------------------------------------------------------------------
+
+void FabDecompressor::decompress(const byte *srcData, int srcSize, byte *destData, int destSize) {
+ byte copyLen, copyOfsShift, copyOfsMask, copyLenMask;
+ unsigned long copyOfs;
+ byte *destP;
+
+ // Validate that the data starts with the FAB header
+ if (strncmp((const char *)srcData, "FAB", 3) != 0)
+ error("FabDecompressor - Invalid compressed data");
+
+ int shiftVal = srcData[3];
+ if ((shiftVal < 10) || (shiftVal > 13))
+ error("FabDecompressor - Invalid shift start");
+
+ copyOfsShift = 16 - shiftVal;
+ copyOfsMask = 0xFF << (shiftVal - 8);
+ copyLenMask = (1 << copyOfsShift) - 1;
+ copyOfs = 0xFFFF0000;
+ destP = destData;
+
+ // Initialize data fields
+ _srcData = srcData;
+ _srcP = _srcData + 6;
+ _srcSize = srcSize;
+ _bitsLeft = 16;
+ _bitBuffer = READ_LE_UINT16(srcData + 4);
+
+ for (;;) {
+ if (getBit() == 0) {
+ if (getBit() == 0) {
+ copyLen = ((getBit() << 1) | getBit()) + 2;
+ copyOfs = *_srcP++ | 0xFFFFFF00;
+ } else {
+ copyOfs = (((_srcP[1] >> copyOfsShift) | copyOfsMask) << 8) | _srcP[0];
+ copyLen = _srcP[1] & copyLenMask;
+ _srcP += 2;
+ if (copyLen == 0) {
+ copyLen = *_srcP++;
+ if (copyLen == 0)
+ break;
+ else if (copyLen == 1)
+ continue;
+ else
+ copyLen++;
+ } else {
+ copyLen += 2;
+ }
+ copyOfs |= 0xFFFF0000;
+ }
+ while (copyLen-- > 0) {
+ if (destP - destData == destSize)
+ error(FabOutputExceededError);
+
+ *destP = destP[(signed int)copyOfs];
+ destP++;
+ }
+ } else {
+ if (_srcP - srcData == srcSize)
+ error(FabInputExceededError);
+ if (destP - destData == destSize)
+ error(FabOutputExceededError);
+
+ *destP++ = *_srcP++;
+ }
+ }
+
+ if (destP - destData != destSize)
+ error("FabDecompressor - Decompressed data does not match header decompressed size");
+}
+
+int FabDecompressor::getBit() {
+ _bitsLeft--;
+ if (_bitsLeft == 0) {
+ if (_srcP - _srcData == _srcSize)
+ error(FabInputExceededError);
+
+ _bitBuffer = (READ_LE_UINT16(_srcP) << 1) | (_bitBuffer & 1);
+ _srcP += 2;
+ _bitsLeft = 16;
+ }
+
+ int bit = _bitBuffer & 1;
+ _bitBuffer >>= 1;
+ return bit;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/compression.h b/engines/mads/compression.h
new file mode 100644
index 0000000000..f7381e4af3
--- /dev/null
+++ b/engines/mads/compression.h
@@ -0,0 +1,89 @@
+/* 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 MADS_COMPRESSION_H
+#define MADS_COMPRESSION_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/memstream.h"
+#include "common/stream.h"
+
+#include "mads/mads.h"
+
+namespace MADS {
+
+enum CompressionType { COMPRESS_NONE = 0, COMPRESS_FAB = 1 };
+
+struct MadsPackEntry {
+public:
+ CompressionType _type;
+ byte _priority;
+ uint32 _size;
+ uint32 _compressedSize;
+ byte *_data;
+};
+
+class MadsPack {
+private:
+ MadsPackEntry *_items;
+ int _count;
+ int _dataOffset;
+
+ void initialize(Common::SeekableReadStream *stream);
+public:
+ static bool isCompressed(Common::SeekableReadStream *stream);
+ MadsPack(Common::SeekableReadStream *stream);
+ MadsPack(const Common::String &resourceName, MADSEngine *_vm);
+ ~MadsPack();
+
+ int getCount() const { return _count; }
+ MadsPackEntry &getItem(int index) const {
+ assert(index < _count);
+ return _items[index]; }
+ MadsPackEntry &operator[](int index) const {
+ assert(index < _count);
+ return _items[index];
+ }
+ Common::MemoryReadStream *getItemStream(int index) {
+ assert(index < _count);
+ return new Common::MemoryReadStream(_items[index]._data, _items[index]._size,
+ DisposeAfterUse::NO);
+ }
+ int getDataOffset() const { return _dataOffset; }
+};
+
+class FabDecompressor {
+private:
+ int _bitsLeft;
+ uint32 _bitBuffer;
+ const byte *_srcData, *_srcP;
+ int _srcSize;
+
+ int getBit();
+public:
+ void decompress(const byte *srcData, int srcSize, byte *destData, int destSize);
+};
+
+} // End of namespace MADS
+
+#endif
diff --git a/engines/mads/configure.engine b/engines/mads/configure.engine
new file mode 100644
index 0000000000..60d833e9e8
--- /dev/null
+++ b/engines/mads/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine mads "Rex Nebular and the Cosmic Gender Bender" no
diff --git a/engines/mads/debugger.cpp b/engines/mads/debugger.cpp
new file mode 100644
index 0000000000..1ff42c5e2b
--- /dev/null
+++ b/engines/mads/debugger.cpp
@@ -0,0 +1,326 @@
+/* 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 "common/file.h"
+#include "mads/mads.h"
+#include "mads/debugger.h"
+
+namespace MADS {
+
+Debugger::Debugger(MADSEngine *vm) : GUI::Debugger(), _vm(vm) {
+ _showMousePos = false;
+
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("mouse", WRAP_METHOD(Debugger, Cmd_Mouse));
+ registerCmd("scene", WRAP_METHOD(Debugger, Cmd_LoadScene));
+ registerCmd("show_hotspots", WRAP_METHOD(Debugger, Cmd_ShowHotSpots));
+ registerCmd("list_hotspots", WRAP_METHOD(Debugger, Cmd_ListHotSpots));
+ registerCmd("play_sound", WRAP_METHOD(Debugger, Cmd_PlaySound));
+ registerCmd("play_audio", WRAP_METHOD(Debugger, Cmd_PlayAudio));
+ registerCmd("show_codes", WRAP_METHOD(Debugger, Cmd_ShowCodes));
+ registerCmd("dump_file", WRAP_METHOD(Debugger, Cmd_DumpFile));
+ registerCmd("show_quote", WRAP_METHOD(Debugger, Cmd_ShowQuote));
+ registerCmd("show_vocab", WRAP_METHOD(Debugger, Cmd_ShowVocab));
+ registerCmd("dump_vocab", WRAP_METHOD(Debugger, Cmd_DumpVocab));
+ registerCmd("show_message", WRAP_METHOD(Debugger, Cmd_ShowMessage));
+ registerCmd("show_item", WRAP_METHOD(Debugger, Cmd_ShowItem));
+ registerCmd("dump_items", WRAP_METHOD(Debugger, Cmd_DumpItems));
+ registerCmd("item", WRAP_METHOD(Debugger, Cmd_Item));
+}
+
+static int strToInt(const char *s) {
+ if (!*s)
+ // No string at all
+ return 0;
+ else if (toupper(s[strlen(s) - 1]) != 'H')
+ // Standard decimal string
+ return atoi(s);
+
+ // Hexadecimal string
+ uint tmp = 0;
+ int read = sscanf(s, "%xh", &tmp);
+ if (read < 1)
+ error("strToInt failed on string \"%s\"", s);
+ return (int)tmp;
+}
+
+bool Debugger::Cmd_Mouse(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("Usage: %s [ on | off ]\n", argv[0]);
+ } else {
+ _showMousePos = strcmp(argv[1], "on") == 0;
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_LoadScene(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Current scene is: %d\n", _vm->_game->_scene._currentSceneId);
+ debugPrintf("Usage: %s <scene number>\n", argv[0]);
+ return true;
+ } else {
+ _vm->_game->_scene._nextSceneId = strToInt(argv[1]);
+ return false;
+ }
+}
+
+bool Debugger::Cmd_ShowHotSpots(int argc, const char **argv) {
+ Scene &scene = _vm->_game->_scene;
+
+ // hotspots
+ byte hotspotCol = _vm->getRandomNumber(255);
+ for (uint i = 0; i < scene._hotspots.size(); i++) {
+ scene._backgroundSurface.frameRect(scene._hotspots[i]._bounds, hotspotCol);
+ }
+
+ // Dynamic hotspots (red)
+ hotspotCol = _vm->getRandomNumber(255);
+ for (uint i = 0; i < scene._dynamicHotspots.size(); i++) {
+ scene._backgroundSurface.frameRect(scene._dynamicHotspots[i]._bounds, hotspotCol);
+ }
+
+ scene._spriteSlots.fullRefresh();
+ return false;
+}
+
+bool Debugger::Cmd_ListHotSpots(int argc, const char **argv) {
+ Hotspots &hotspots = _vm->_game->_scene._hotspots;
+
+ debugPrintf("%d hotspots present\n", hotspots.size());
+
+ for (uint index = 0; index < hotspots.size(); ++index) {
+ debugPrintf("(%d): %p x1 = %d; y1 = %d; x2 = %d; y2 = %d\n",
+ index, (void *)&hotspots[index],
+ hotspots[index]._bounds.left, hotspots[index]._bounds.top,
+ hotspots[index]._bounds.right, hotspots[index]._bounds.bottom);
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("Usage: %s <sound file>\n", argv[0]);
+ } else {
+ int commandId = strToInt(argv[1]);
+ int param = (argc >= 3) ? strToInt(argv[2]) : 0;
+
+ _vm->_sound->command(commandId, param);
+ }
+
+ return false;
+}
+
+bool Debugger::Cmd_PlayAudio(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("Usage: %s <sound index> <sound group>\n", argv[0]);
+ debugPrintf("If the sound group isn't defined, the default one will be used\n");
+ } else {
+ int index = strToInt(argv[1]);
+ Common::String soundGroup = (argc >= 3) ? argv[2] : "";
+ if (argc >= 3)
+ _vm->_audio->setSoundGroup(argv[2]);
+ else
+ _vm->_audio->setDefaultSoundGroup();
+
+ _vm->_audio->playSound(index);
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_ShowCodes(int argc, const char **argv) {
+ Scene &scene = _vm->_game->_scene;
+
+ // Copy the depth/walk surface to the background and flag for screen refresh
+ scene._depthSurface.copyTo(&scene._backgroundSurface);
+ scene._spriteSlots.fullRefresh();
+
+ // Draw the locations of scene nodes onto the background
+ int color = _vm->getRandomNumber(255);
+ for (int i = 0; i < (int)scene._sceneInfo->_nodes.size(); ++i) {
+ Common::Point &pt = scene._sceneInfo->_nodes[i]._walkPos;
+
+ scene._backgroundSurface.hLine(pt.x - 2, pt.y, pt.x + 2, color);
+ scene._backgroundSurface.vLine(pt.x, pt.y - 2, pt.y + 2, color);
+ }
+
+ return false;
+}
+
+bool Debugger::Cmd_DumpFile(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Usage: %s <resource>\n", argv[0]);
+ } else {
+ Common::DumpFile outFile;
+ Common::File inFile;
+
+ if (!inFile.open(argv[1])) {
+ debugPrintf("Specified resource does not exist\n");
+ } else {
+ outFile.open(argv[1]);
+ byte *data = new byte[inFile.size()];
+
+ inFile.read(data, inFile.size());
+ outFile.write(data, inFile.size());
+ outFile.flush();
+
+ delete[] data;
+ inFile.close();
+ outFile.close();
+
+ debugPrintf("File written successfully.\n");
+ }
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_ShowQuote(int argc, const char **argv) {
+ if (argc != 2)
+ debugPrintf("Usage: %s <quote number>\n", argv[0]);
+ else
+ debugPrintf("%s", _vm->_game->getQuote(strToInt(argv[1])).c_str());
+
+ return true;
+}
+
+bool Debugger::Cmd_ShowVocab(int argc, const char **argv) {
+ if (argc != 2) {
+ for (uint32 i = 0; i < _vm->_game->_scene.getVocabStringsCount(); i++) {
+ debugPrintf("%03d: '%s'\n", i, _vm->_game->_scene.getVocab(i + 1).c_str());
+ }
+ } else {
+ int vocabId = strToInt(argv[1]);
+ debugPrintf("%03d: '%s'\n", vocabId, _vm->_game->_scene.getVocab(vocabId + 1).c_str());
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_DumpVocab(int argc, const char **argv) {
+ Common::DumpFile outFile;
+ outFile.open("vocab.txt");
+
+ for (uint32 i = 0; i < _vm->_game->_scene.getVocabStringsCount(); i++) {
+ Common::String curId = Common::String::format("%x", i + 1);
+ Common::String curVocab = _vm->_game->_scene.getVocab(i + 1);
+ curVocab.toUppercase();
+
+ for (uint j = 0; j < curVocab.size(); j++) {
+ if (curVocab[j] == ' ' || curVocab[j] == '-')
+ curVocab.setChar('_', j);
+ }
+
+ Common::String cur = "\tNOUN_" + curVocab + " = 0x" + curId + ",\n";
+
+ outFile.writeString(cur.c_str());
+ }
+
+ outFile.flush();
+ outFile.close();
+
+ debugPrintf("Game vocab dumped\n");
+
+ return true;
+}
+
+bool Debugger::Cmd_ShowMessage(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Usage: %s <message number>\n", argv[0]);
+ } else {
+ int messageId = strToInt(argv[1]);
+ Common::StringArray msg = _vm->_game->getMessage(messageId);
+ for (uint idx = 0; idx < msg.size(); ++idx) {
+ Common::String srcLine = msg[idx];
+ debugPrintf("%s\n", srcLine.c_str());
+ }
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_ShowItem(int argc, const char **argv) {
+ InventoryObjects &objects = _vm->_game->_objects;
+
+ if (argc != 2) {
+ for (uint32 i = 0; i < objects.size(); i++) {
+ Common::String desc = _vm->_game->_scene.getVocab(objects[i]._descId);
+ debugPrintf("%03d: '%s'\n", i, desc.c_str());
+ }
+ } else {
+ int vocabId = strToInt(argv[1]);
+ Common::String desc = _vm->_game->_scene.getVocab(objects[vocabId]._descId);
+ debugPrintf("%03d: '%s'\n", vocabId, desc.c_str());
+ }
+
+ return true;
+}
+
+bool Debugger::Cmd_DumpItems(int argc, const char **argv) {
+ InventoryObjects &objects = _vm->_game->_objects;
+
+ Common::DumpFile outFile;
+ outFile.open("items.txt");
+
+ for (uint32 i = 0; i < objects.size(); i++) {
+ Common::String curId = Common::String::format("%d", i);
+ Common::String desc = _vm->_game->_scene.getVocab(objects[i]._descId);
+ desc.toUppercase();
+
+ for (uint j = 0; j < desc.size(); j++) {
+ if (desc[j] == ' ' || desc[j] == '-')
+ desc.setChar('_', j);
+ }
+
+ Common::String cur = "\tOBJ_" + desc + " = " + curId + ",\n";
+
+ outFile.writeString(cur.c_str());
+ }
+
+ outFile.flush();
+ outFile.close();
+
+ debugPrintf("Game items dumped\n");
+
+ return true;
+}
+
+bool Debugger::Cmd_Item(int argc, const char **argv) {
+ InventoryObjects &objects = _vm->_game->_objects;
+
+ if (argc != 2) {
+ debugPrintf("Usage: %s <item number>\n", argv[0]);
+ return true;
+ } else {
+ int objectId = strToInt(argv[1]);
+
+ if (!objects.isInInventory(objectId))
+ objects.addToInventory(objectId);
+
+ debugPrintf("Item added.\n");
+ return false;
+ }
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/debugger.h b/engines/mads/debugger.h
new file mode 100644
index 0000000000..351eb13615
--- /dev/null
+++ b/engines/mads/debugger.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 MADS_DEBUGGER_H
+#define MADS_DEBUGGER_H
+
+#include "common/scummsys.h"
+#include "gui/debugger.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+class Debugger : public GUI::Debugger {
+private:
+ MADSEngine *_vm;
+protected:
+ bool Cmd_Mouse(int argc, const char **argv);
+ bool Cmd_LoadScene(int argc, const char **argv);
+ bool Cmd_ShowHotSpots(int argc, const char **argv);
+ bool Cmd_ListHotSpots(int argc, const char **argv);
+ bool Cmd_PlaySound(int argc, const char **argv);
+ bool Cmd_PlayAudio(int argc, const char **argv);
+ bool Cmd_ShowCodes(int argc, const char **argv);
+ bool Cmd_DumpFile(int argc, const char **argv);
+ bool Cmd_ShowQuote(int argc, const char **argv);
+ bool Cmd_ShowVocab(int argc, const char **argv);
+ bool Cmd_DumpVocab(int argc, const char **argv);
+ bool Cmd_ShowMessage(int argc, const char **argv);
+ bool Cmd_ShowItem(int argc, const char **argv);
+ bool Cmd_DumpItems(int argc, const char **argv);
+ bool Cmd_Item(int argc, const char **argv);
+public:
+ bool _showMousePos;
+public:
+ Debugger(MADSEngine *vm);
+ virtual ~Debugger() {}
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_DEBUGGER_H */
diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp
new file mode 100644
index 0000000000..971acde024
--- /dev/null
+++ b/engines/mads/detection.cpp
@@ -0,0 +1,194 @@
+/* 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 "mads/mads.h"
+
+#include "base/plugins.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/memstream.h"
+#include "engines/advancedDetector.h"
+#include "common/system.h"
+#include "graphics/colormasks.h"
+#include "graphics/surface.h"
+#include "mads/events.h"
+#include "mads/game.h"
+
+#define MAX_SAVES 99
+
+namespace MADS {
+
+struct MADSGameDescription {
+ ADGameDescription desc;
+
+ int gameID;
+ uint32 features;
+};
+
+uint32 MADSEngine::getGameID() const {
+ return _gameDescription->gameID;
+}
+
+uint32 MADSEngine::getGameFeatures() const {
+ return _gameDescription->features;
+}
+
+uint32 MADSEngine::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+Common::Language MADSEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+Common::Platform MADSEngine::getPlatform() const {
+ return _gameDescription->desc.platform;
+}
+
+} // End of namespace MADS
+
+static const PlainGameDescriptor MADSGames[] = {
+ {"MADS", "MADS"},
+ {"dragonsphere", "Dragonsphere"},
+ {"nebular", "Rex Nebular and the Cosmic Gender Bender"},
+ {"phantom", "Return of the Phantom"},
+ {0, 0}
+};
+
+#include "mads/detection_tables.h"
+
+class MADSMetaEngine : public AdvancedMetaEngine {
+public:
+ MADSMetaEngine() : AdvancedMetaEngine(MADS::gameDescriptions, sizeof(MADS::MADSGameDescription), MADSGames) {
+ _maxScanDepth = 3;
+ }
+
+ virtual const char *getName() const {
+ return "MADS Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "MADS (c)";
+ }
+
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ virtual SaveStateList listSaves(const char *target) const;
+ virtual int getMaximumSaveSlot() const;
+ virtual void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool MADSMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+bool MADS::MADSEngine::hasFeature(EngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
+bool MADSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const MADS::MADSGameDescription *gd = (const MADS::MADSGameDescription *)desc;
+ if (gd) {
+ *engine = new MADS::MADSEngine(syst, gd);
+ }
+ return gd != 0;
+}
+
+SaveStateList MADSMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String saveDesc;
+ Common::String pattern = Common::String::format("%s.0??", target);
+ MADS::MADSSavegameHeader header;
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ const char *ext = strrchr(file->c_str(), '.');
+ int slot = ext ? atoi(ext + 1) : -1;
+
+ if (slot >= 0 && slot < MAX_SAVES) {
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
+
+ if (in) {
+ MADS::Game::readSavegameHeader(in, header);
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+
+ header._thumbnail->free();
+ delete header._thumbnail;
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+int MADSMetaEngine::getMaximumSaveSlot() const {
+ return MAX_SAVES;
+}
+
+void MADSMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String filename = Common::String::format("%s.%03d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(filename);
+}
+
+SaveStateDescriptor MADSMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Common::String::format("%s.%03d", target, slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
+
+ if (f) {
+ MADS::MADSSavegameHeader header;
+ MADS::Game::readSavegameHeader(f, header);
+ delete f;
+
+ // Create the return descriptor
+ SaveStateDescriptor desc(slot, header._saveName);
+ desc.setThumbnail(header._thumbnail);
+ desc.setSaveDate(header._year, header._month, header._day);
+ desc.setSaveTime(header._hour, header._minute);
+ desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME);
+
+ return desc;
+ }
+
+ return SaveStateDescriptor();
+}
+
+
+#if PLUGIN_ENABLED_DYNAMIC(MADS)
+ REGISTER_PLUGIN_DYNAMIC(MADS, PLUGIN_TYPE_ENGINE, MADSMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(MADS, PLUGIN_TYPE_ENGINE, MADSMetaEngine);
+#endif
diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h
new file mode 100644
index 0000000000..e68ae380d0
--- /dev/null
+++ b/engines/mads/detection_tables.h
@@ -0,0 +1,122 @@
+/* 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.
+ *
+ */
+
+namespace MADS {
+
+static const MADSGameDescription gameDescriptions[] = {
+#if 0
+ {
+ // Rex Nebular and the Cosmic Gender Bender DOS English (compressed)
+ // Removed for now, until the original floppy compression is supported
+ {
+ "nebular",
+ 0,
+ {
+ {"mpslabs.001", 0, "4df5c557b52abb5b661cf4befe5ae301", 1315354},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_RexNebular,
+ 0
+ },
+#endif
+
+ {
+ // Rex Nebular and the Cosmic Gender Bender DOS English
+ {
+ "nebular",
+ 0,
+ {
+ {"section1.hag", 0, "6f725eb38660de8af31ec7cdd628d615", 927222},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_RexNebular,
+ 0
+ },
+
+ {
+ // Rex Nebular and the Cosmic Gender Bender DOS English 8.49 Alternate
+ {
+ "nebular",
+ 0,
+ {
+ { "section1.hag", 0, "d583576923e3437937fb7f46f4b6274f", 927222 },
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_RexNebular,
+ 0
+ },
+
+ {
+ // Return of the Phantom DOS English
+ {
+ "phantom",
+ 0,
+ {
+ {"section1.hag", 0, "76e2d47a7aebafe48edc9884b3d91782", 1130939},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_Phantom,
+ 0
+ },
+
+ {
+ // Dragonsphere DOS English
+ {
+ "dragonsphere",
+ 0,
+ {
+ {"section1.hag", 0, "2770e441d296be5e806194693eebd95a", 2061199},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GType_Dragonsphere,
+ 0
+ },
+
+ { AD_TABLE_END_MARKER, 0, 0 }
+};
+
+} // End of namespace MADS
diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp
new file mode 100644
index 0000000000..dc8c846beb
--- /dev/null
+++ b/engines/mads/dialogs.cpp
@@ -0,0 +1,398 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/nebular/dialogs_nebular.h"
+
+namespace MADS {
+
+Dialog::Dialog(MADSEngine *vm)
+ : _vm(vm), _savedSurface(nullptr), _position(Common::Point(-1, -1)),
+ _width(0), _height(0) {
+ TEXTDIALOG_CONTENT1 = 0XF8;
+ TEXTDIALOG_CONTENT2 = 0XF9;
+ TEXTDIALOG_EDGE = 0XFA;
+ TEXTDIALOG_BACKGROUND = 0XFB;
+ TEXTDIALOG_FC = 0XFC;
+ TEXTDIALOG_FD = 0XFD;
+ TEXTDIALOG_FE = 0XFE;
+ TEXTDIALOG_BLACK = 0;
+}
+
+Dialog::~Dialog() {
+}
+
+void Dialog::save() {
+ _savedSurface = new MSurface(_width, _height);
+ _vm->_screen.copyTo(_savedSurface,
+ Common::Rect(_position.x, _position.y, _position.x + _width, _position.y + _height),
+ Common::Point());
+
+ _vm->_screen.copyRectToScreen(getBounds());
+}
+
+void Dialog::restore() {
+ if (_savedSurface) {
+ _savedSurface->copyTo(&_vm->_screen, _position);
+ delete _savedSurface;
+ _savedSurface = nullptr;
+
+ _vm->_screen.copyRectToScreen(getBounds());
+
+ Common::copy(&_dialogPalette[0], &_dialogPalette[8 * 3],
+ &_vm->_palette->_mainPalette[248 * 3]);
+ _vm->_palette->setPalette(_vm->_palette->_mainPalette, 248, 8);
+ }
+}
+
+void Dialog::draw() {
+ // Calculate the dialog positioning
+ calculateBounds();
+
+ // Save the screen portion the dialog will overlap
+ save();
+
+ setDialogPalette();
+
+ // Draw the dialog
+ // Fill entire content of dialog
+ Common::Rect bounds = getBounds();
+ _vm->_screen.fillRect(bounds, TEXTDIALOG_BACKGROUND);
+
+ // Draw the outer edge lines
+ _vm->_screen.hLine(_position.x + 1, _position.y + _height - 2,
+ _position.x + _width - 2, TEXTDIALOG_EDGE);
+ _vm->_screen.hLine(_position.x, _position.y + _height - 1,
+ _position.x + _width - 1, TEXTDIALOG_EDGE);
+ _vm->_screen.vLine(_position.x + _width - 2, _position.y + 2,
+ _position.y + _height - 2, TEXTDIALOG_EDGE);
+ _vm->_screen.vLine(_position.x + _width - 1, _position.y + 1,
+ _position.y + _height - 1, TEXTDIALOG_EDGE);
+
+ // Draw the gravelly dialog content
+ drawContent(Common::Rect(_position.x + 2, _position.y + 2,
+ _position.x + _width - 2, _position.y + _height - 2), 0,
+ TEXTDIALOG_CONTENT1, TEXTDIALOG_CONTENT2);
+}
+
+void Dialog::setDialogPalette() {
+ // Save the high end of the palette, and set up the entries for dialog display
+ Common::copy(&_vm->_palette->_mainPalette[TEXTDIALOG_CONTENT1 * 3],
+ &_vm->_palette->_mainPalette[TEXTDIALOG_CONTENT1 * 3 + 8 * 3],
+ &_dialogPalette[0]);
+ Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_CONTENT1, 2, 0x90, 0x80);
+ Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_EDGE, 2, 0x9C, 0x70);
+ Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_FC, 2, 0x90, 0x80);
+ Palette::setGradient(_vm->_palette->_mainPalette, TEXTDIALOG_FE, 1, 0xDC, 0xDC);
+
+ _vm->_palette->setPalette(_vm->_palette->_mainPalette + (TEXTDIALOG_CONTENT1 * 3),
+ TEXTDIALOG_CONTENT1, 8);
+}
+
+void Dialog::calculateBounds() {
+}
+
+void Dialog::drawContent(const Common::Rect &r, int seed, byte color1, byte color2) {
+ uint16 currSeed = seed ? seed : 0xB78E;
+
+ for (int yp = 0; yp < r.height(); ++yp) {
+ byte *destP = _vm->_screen.getBasePtr(r.left, r.top + yp);
+
+ for (int xp = 0; xp < r.width(); ++xp) {
+ uint16 seedAdjust = currSeed;
+ currSeed += 0x181D;
+ seedAdjust = (seedAdjust >> 9) | ((seedAdjust & 0x1ff) << 7);
+ currSeed ^= seedAdjust;
+ seedAdjust = (seedAdjust >> 3) | ((seedAdjust & 7) << 13);
+ currSeed += seedAdjust;
+
+ *destP++ = (currSeed & 0x10) ? color2 : color1;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+TextDialog::TextDialog(MADSEngine *vm, const Common::String &fontName,
+ const Common::Point &pos, int maxChars)
+ : Dialog(vm) {
+ _vm = vm;
+ _font = _vm->_font->getFont(fontName);
+ _position = pos;
+
+ _vm->_font->setColors(TEXTDIALOG_BLACK, TEXTDIALOG_BLACK, TEXTDIALOG_BLACK, TEXTDIALOG_BLACK);
+
+ _innerWidth = (_font->maxWidth() + 1) * maxChars;
+ _width = _innerWidth + 10;
+ _lineSize = maxChars * 2;
+ _lineWidth = 0;
+ _currentX = 0;
+ _numLines = 0;
+ Common::fill(&_lineXp[0], &_lineXp[TEXT_DIALOG_MAX_LINES], 0);
+ _askLineNum = -1;
+ _askXp = 0;
+}
+
+TextDialog::~TextDialog() {
+}
+
+void TextDialog::addLine(const Common::String &line, bool underline) {
+ if (_lineWidth > 0 || _currentX > 0)
+ incNumLines();
+
+ int stringWidth = _font->getWidth(line, 1);
+ if (stringWidth >= _innerWidth || (int)line.size() >= _lineSize) {
+ wordWrap(line);
+ } else {
+ _lineXp[_numLines] = (_innerWidth / 2) - (stringWidth / 2);
+ _lines[_numLines] = line;
+
+ if (underline)
+ underlineLine();
+ }
+
+ incNumLines();
+}
+
+void TextDialog::underlineLine() {
+ _lineXp[_numLines] |= 0x80;
+}
+
+void TextDialog::downPixelLine() {
+ _lineXp[_numLines] |= 0x40;
+}
+
+void TextDialog::incNumLines() {
+ _lineWidth = 0;
+ _currentX = 0;
+ if (++_numLines == TEXT_DIALOG_MAX_LINES)
+ error("Exceeded text dialog line max");
+}
+
+void TextDialog::wordWrap(const Common::String &line) {
+ Common::String tempLine;
+
+ if (!line.empty()) {
+ const char *srcP = line.c_str();
+
+ do {
+ tempLine = "";
+ bool endWord = false;
+ bool newLine = false;
+ bool continueFlag = true;
+
+ do {
+ if (!*srcP) {
+ continueFlag = false;
+ } else {
+ tempLine += *srcP;
+
+ if (*srcP == 10) {
+ continueFlag = false;
+ newLine = true;
+ ++srcP;
+ tempLine.deleteLastChar();
+ } else if (*srcP == ' ') {
+ ++srcP;
+ endWord = true;
+ } else if (!endWord) {
+ ++srcP;
+ } else {
+ tempLine.deleteLastChar();
+ continueFlag = false;
+ }
+ }
+ } while (continueFlag);
+
+ if (tempLine.hasSuffix(" "))
+ tempLine.deleteLastChar();
+
+ Common::String tempLine2;
+ if (_currentX > 0)
+ tempLine2 += ' ';
+ tempLine2 += tempLine;
+
+ int lineWidth = _font->getWidth(tempLine2, 1);
+ if (((_currentX + (int)tempLine2.size()) > _lineSize) ||
+ ((_lineWidth + lineWidth) > _innerWidth)) {
+ incNumLines();
+ appendLine(tempLine);
+ } else {
+ appendLine(tempLine2);
+ }
+
+ if (newLine)
+ incNumLines();
+ } while (*srcP);
+ }
+}
+
+void TextDialog::appendLine(const Common::String &line) {
+ _currentX += line.size();
+ _lineWidth += _font->getWidth(line, 1) + 1;
+ _lines[_numLines] += line;
+}
+
+void TextDialog::addInput() {
+ _askXp = _currentX + 1;
+ _askLineNum = _numLines;
+ incNumLines();
+}
+
+void TextDialog::addBarLine() {
+ if (_lineWidth > 0 || _currentX > 0)
+ incNumLines();
+
+ _lineXp[_numLines] = 0xFF;
+ incNumLines();
+}
+
+void TextDialog::setLineXp(int xp) {
+ _lineXp[_numLines] = xp;
+}
+
+void TextDialog::draw() {
+ if (!_lineWidth)
+ --_numLines;
+
+ // Figure out the size and position for the dialog
+ calculateBounds();
+
+ // Draw the underlying dialog
+ Dialog::draw();
+
+ // Draw the text lines
+ int lineYp = _position.y + 5;
+ for (int lineNum = 0; lineNum <= _numLines; ++lineNum) {
+ if (_lineXp[lineNum] == -1) {
+ // Draw a line across the entire dialog
+ _vm->_screen.hLine(_position.x + 2,
+ lineYp + (_font->getHeight() + 1) / 2,
+ _position.x + _width - 4, TEXTDIALOG_BLACK);
+ } else {
+ // Draw a text line
+ int xp = (_lineXp[lineNum] & 0x7F) + _position.x + 5;
+ int yp = lineYp;
+ if (_lineXp[lineNum] & 0x40)
+ ++yp;
+
+ _font->writeString(&_vm->_screen, _lines[lineNum],
+ Common::Point(xp, yp), 1);
+
+ if (_lineXp[lineNum] & 0x80) {
+ // Draw an underline under the text
+ int lineWidth = _font->getWidth(_lines[lineNum], 1);
+ _vm->_screen.hLine(xp, yp + _font->getHeight(), xp + lineWidth,
+ TEXTDIALOG_BLACK);
+ }
+ }
+
+ lineYp += _font->getHeight() + 1;
+ }
+
+ _vm->_screen.copyRectToScreen(getBounds());
+}
+
+void TextDialog::calculateBounds() {
+ _height = (_font->getHeight() + 1) * (_numLines + 1) + 10;
+ if (_position.x == -1)
+ _position.x = 160 - (_width / 2);
+ if (_position.y == -1)
+ _position.y = 100 - (_height / 2);
+
+ if ((_position.x + _width) > _vm->_screen.getWidth())
+ _position.x = _vm->_screen.getWidth() - (_position.x + _width);
+ if ((_position.y + _height) > _vm->_screen.getHeight())
+ _position.y = _vm->_screen.getHeight() - (_position.y + _height);
+}
+
+void TextDialog::drawWithInput() {
+ //int innerWidth = _innerWidth;
+ //int lineHeight = _font->getHeight() + 1;
+ //int xp = _position.x + 5;
+
+ // Draw the content of the dialog
+ drawContent(Common::Rect(_position.x + 2, _position.y + 2,
+ _position.x + _width - 2, _position.y + _height - 2), 0,
+ TEXTDIALOG_CONTENT1, TEXTDIALOG_CONTENT2);
+
+ error("TODO: drawWithInput");
+}
+
+void TextDialog::show() {
+ // Draw the dialog
+ draw();
+ _vm->_events->showCursor();
+
+ // Wait for mouse click
+ do {
+ _vm->_events->waitForNextFrame();
+ } while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed() && !_vm->_events->_mouseReleased);
+
+ // Allow the mouse release or keypress to be gobbled up
+ if (!_vm->shouldQuit()) {
+ _vm->_events->waitForNextFrame();
+ _vm->_events->_pendingKeys.clear();
+ }
+
+ // Restore the background
+ restore();
+}
+
+/*------------------------------------------------------------------------*/
+
+MessageDialog::MessageDialog(MADSEngine *vm, int maxChars, ...)
+ : TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), maxChars) {
+ // Add in passed line list
+ va_list va;
+ va_start(va, maxChars);
+
+ const char *line = va_arg(va, const char *);
+ while (line) {
+ addLine(line);
+ line = va_arg(va, const char *);
+ }
+ va_end(va);
+}
+
+/*------------------------------------------------------------------------*/
+
+Dialogs *Dialogs::init(MADSEngine *vm) {
+ if (vm->getGameID() == GType_RexNebular)
+ return new Nebular::DialogsNebular(vm);
+
+ // Throw a warning for now, since the associated Dialogs class isn't implemented yet
+ warning("Dialogs: Unknown game");
+ // HACK: Reuse the implemented Nebular dialogs for now, to avoid crashing later on
+ return new Nebular::DialogsNebular(vm);
+}
+
+Dialogs::Dialogs(MADSEngine *vm)
+ : _vm(vm) {
+ _pendingDialog = DIALOG_NONE;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h
new file mode 100644
index 0000000000..aad29f6551
--- /dev/null
+++ b/engines/mads/dialogs.h
@@ -0,0 +1,229 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_DIALOGS_H
+#define MADS_DIALOGS_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/font.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+class Dialog {
+private:
+ void setDialogPalette();
+protected:
+ MADSEngine *_vm;
+ MSurface *_savedSurface;
+ Common::Point _position;
+ int _width;
+ int _height;
+ byte _dialogPalette[8 * 3];
+
+ int TEXTDIALOG_CONTENT1;
+ int TEXTDIALOG_CONTENT2;
+ int TEXTDIALOG_EDGE;
+ int TEXTDIALOG_BACKGROUND;
+ int TEXTDIALOG_FC;
+ int TEXTDIALOG_FD;
+ int TEXTDIALOG_FE;
+ int TEXTDIALOG_BLACK;
+protected:
+ /**
+ * Draw the dialog
+ */
+ virtual void draw();
+
+ /**
+ * Calculate bounds for the dialog
+ */
+ virtual void calculateBounds();
+
+ /**
+ * Save the section of the passed surface the dialog will cover.
+ */
+ virtual void save();
+
+ /**
+ * Restore saved dialog surface
+ */
+ virtual void restore();
+
+ /**
+ * Draws the content of a dialog with a gravelly alternating color.
+ */
+ void drawContent(const Common::Rect &r, int seed, byte color1, byte color2);
+public:
+ /**
+ * Constructor
+ */
+ Dialog(MADSEngine *vm);
+
+ /**
+ * Destructor
+ */
+ virtual ~Dialog();
+
+ /**
+ * Return the bounds of the dialog.
+ */
+ Common::Rect getBounds() const {
+ return Common::Rect(_position.x, _position.y,
+ _position.x + _width, _position.y + _height);
+ }
+};
+
+#define TEXT_DIALOG_MAX_LINES 20
+
+class TextDialog : protected Dialog {
+private:
+ /**
+ * Append text to the currently end line.
+ */
+ void appendLine(const Common::String &line);
+
+ /**
+ * Clean up after finishing displaying the dialog
+ */
+ void restorePalette();
+protected:
+ Font *_font;
+ int _innerWidth;
+ int _lineWidth;
+ int _currentX;
+ int _numLines;
+ int _lineSize;
+ int _askXp;
+ int _askLineNum;
+ Common::String _lines[TEXT_DIALOG_MAX_LINES];
+ int _lineXp[TEXT_DIALOG_MAX_LINES];
+
+ /**
+ * Calculate the bounds for the dialog
+ */
+ virtual void calculateBounds();
+public:
+ /**
+ * Constructor
+ * @param vm Engine reference
+ * @param fontName Font to use for display
+ * @param pos Position for window top-left
+ * @param maxChars Horizontal width of window in characters
+ */
+ TextDialog(MADSEngine *vm, const Common::String &fontName, const Common::Point &pos,
+ int maxChars);
+
+ /**
+ * Destructor
+ */
+ virtual ~TextDialog();
+
+ /**
+ * Draw the dialog
+ */
+ virtual void draw();
+
+ /**
+ * Draw the dialog along with any input box
+ */
+ void drawWithInput();
+
+ /**
+ * Add a new line to the dialog
+ */
+ void addLine(const Common::String &line, bool underline = false);
+
+ /**
+ * Adds one or more lines, word wrapping the passed text
+ */
+ void wordWrap(const Common::String &line);
+
+ /**
+ * Increments the number of text lines the text dialog uses
+ */
+ void incNumLines();
+
+ /**
+ * Adds an input area following previously added text
+ */
+ void addInput();
+
+ /**
+ * Adds a bar line to separate sections of text
+ */
+ void addBarLine();
+
+ /**
+ * Flags the previously added line to be underlined
+ */
+ void underlineLine();
+
+ void downPixelLine();
+
+ /**
+ * Set the x position for the given line
+ */
+ void setLineXp(int xp);
+
+ /**
+ * Show the dialog, and wait until a key or mouse press.
+ */
+ virtual void show();
+};
+
+class MessageDialog : public TextDialog {
+public:
+ MessageDialog(MADSEngine *vm, int lines, ...);
+
+ virtual ~MessageDialog() {}
+};
+
+enum DialogId {
+ DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3,
+ DIALOG_OPTIONS = 4, DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6
+};
+
+class Dialogs {
+protected:
+ MADSEngine *_vm;
+
+ Dialogs(MADSEngine *vm);
+public:
+ static Dialogs *init(MADSEngine *vm);
+public:
+ Common::Point _defaultPosition;
+ DialogId _pendingDialog;
+ int _indexList[10];
+
+ virtual ~Dialogs() {}
+
+ virtual void showDialog() = 0;
+ virtual void showItem(int objectId, int messageId, int speech = 0) = 0;
+ virtual Common::String getVocab(int vocabId) = 0;
+ virtual bool show(int messageId, int objectId = -1) = 0;
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_DIALOGS_H */
diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.cpp b/engines/mads/dragonsphere/dragonsphere_scenes.cpp
new file mode 100644
index 0000000000..59d7914378
--- /dev/null
+++ b/engines/mads/dragonsphere/dragonsphere_scenes.cpp
@@ -0,0 +1,236 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/resources.h"
+#include "mads/scene.h"
+#include "mads/dragonsphere/game_dragonsphere.h"
+#include "mads/dragonsphere/dragonsphere_scenes.h"
+
+namespace MADS {
+
+namespace Dragonsphere {
+
+SceneLogic *SceneFactory::createScene(MADSEngine *vm) {
+ Scene &scene = vm->_game->_scene;
+
+ // TODO
+ //scene.addActiveVocab(NOUN_DROP);
+
+ switch (scene._nextSceneId) {
+ // Scene group #1 (Castle, river and caves)
+ case 101: // king's bedroom
+ return new DummyScene(vm); // TODO
+ case 102: // queen's bedroom
+ return new DummyScene(vm); // TODO
+ case 103: // outside king's bedroom
+ return new DummyScene(vm); // TODO
+ case 104: // fireplace / bookshelf
+ return new DummyScene(vm); // TODO
+ case 105: // dining room
+ return new DummyScene(vm); // TODO
+ case 106: // throne room
+ return new DummyScene(vm); // TODO
+ case 107: // council chamber
+ return new DummyScene(vm); // TODO
+ case 108: // dungeon, cell entrance
+ return new DummyScene(vm); // TODO
+ case 109: // cell
+ return new DummyScene(vm); // TODO
+ case 110: // outside castle, merchants and well
+ return new DummyScene(vm); // TODO
+ case 111: // Dragonsphere closeup
+ return new DummyScene(vm); // TODO
+ case 112: // well descend
+ return new DummyScene(vm); // TODO
+ case 113: // bottom of well, river and trap door
+ return new DummyScene(vm); // TODO
+ case 114: // cave
+ return new DummyScene(vm); // TODO
+ case 115: // cave with passageway to west
+ return new DummyScene(vm); // TODO
+ case 116: // cave with pedestral
+ return new DummyScene(vm); // TODO
+ case 117: // river
+ return new DummyScene(vm); // TODO
+ case 118: // castle courtyard and gate
+ return new DummyScene(vm); // TODO
+ case 119: // castle stairs
+ return new DummyScene(vm); // TODO
+ case 120: // map
+ return new DummyScene(vm); // TODO
+
+ // Scene group #2 (Slathan ni Patan, land of shapeshifters)
+ case 201: // guardhouse, entrance to Slathan ni Patan
+ return new DummyScene(vm); // TODO
+ case 203: // forest
+ return new DummyScene(vm); // TODO
+ case 204: // cave
+ return new DummyScene(vm); // TODO
+ case 205: // outside village
+ return new DummyScene(vm); // TODO
+ case 206: // village
+ return new DummyScene(vm); // TODO
+
+ // Scene group #3 (Brynn-Fann, Land of faeries)
+ case 301: // maze entrance
+ return new DummyScene(vm); // TODO
+ case 302: // maze
+ return new DummyScene(vm); // TODO
+ case 303: // toads
+ return new DummyScene(vm); // TODO
+
+ // Scene group #4 (The Desert)
+ case 401: // desert
+ return new DummyScene(vm); // TODO
+ case 402: // desert
+ return new DummyScene(vm); // TODO
+ case 403: // desert
+ return new DummyScene(vm); // TODO
+ case 404: // desert with dunes
+ return new DummyScene(vm); // TODO
+ case 405: // oasis
+ return new DummyScene(vm); // TODO
+ case 406: // inside tent
+ return new DummyScene(vm); // TODO
+ case 407: // gem sack closeup
+ return new DummyScene(vm); // TODO
+ case 408: // spirit plane
+ return new DummyScene(vm); // TODO
+ case 409: // spirit plane top down view, disks
+ return new DummyScene(vm); // TODO
+ case 410: // snake pit and spirit tree
+ return new DummyScene(vm); // TODO
+ case 411: // nest
+ return new DummyScene(vm); // TODO
+ case 412: // desert
+ return new DummyScene(vm); // TODO
+ case 454: // cutscene
+ return new DummyScene(vm); // TODO
+
+ // Scene group #5 (The Mountain)
+ case 501: // base of mountain / wall
+ return new DummyScene(vm); // TODO
+ case 502: // base of mountain
+ return new DummyScene(vm); // TODO
+ case 503: // waterfall
+ return new DummyScene(vm); // TODO
+ case 504: // hermit's cave
+ return new DummyScene(vm); // TODO
+ case 505: // rock trees
+ return new DummyScene(vm); // TODO
+ case 506: // nest
+ return new DummyScene(vm); // TODO
+ case 507: // above nest
+ return new DummyScene(vm); // TODO
+ case 508: // ledge, right
+ return new DummyScene(vm); // TODO
+ case 509: // ledge, left
+ return new DummyScene(vm); // TODO
+ case 510: // nest top down view and pillars
+ return new DummyScene(vm); // TODO
+ case 511: // pillars
+ return new DummyScene(vm); // TODO
+ case 512: // nest
+ return new DummyScene(vm); // TODO
+ case 557: // cutscene
+ return new DummyScene(vm); // TODO
+
+ // Scene group #6 (The Tower)
+ case 601: // ??? (tile count mismatch)
+ return new DummyScene(vm); // TODO
+ case 603: // eye chamber
+ return new DummyScene(vm); // TODO
+ case 604: // room of magic
+ return new DummyScene(vm); // TODO
+ case 605: // science room
+ return new DummyScene(vm); // TODO
+ case 606: // doorway
+ return new DummyScene(vm); // TODO
+ case 607: // prison
+ return new DummyScene(vm); // TODO
+ case 609: // stone pedestral chamber
+ return new DummyScene(vm); // TODO
+ case 612: // infernal machine room
+ return new DummyScene(vm); // TODO
+ case 613: // room with lava floor
+ return new DummyScene(vm); // TODO
+ case 614: // sorcerer's room
+ return new DummyScene(vm); // TODO
+
+ default:
+ error("Invalid scene %d called", scene._nextSceneId);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+DragonsphereScene::DragonsphereScene(MADSEngine *vm) : SceneLogic(vm),
+ _globals(static_cast<GameDragonsphere *>(vm->_game)->_globals),
+ _game(*static_cast<GameDragonsphere *>(vm->_game)),
+ _action(vm->_game->_scene._action) {
+}
+
+Common::String DragonsphereScene::formAnimName(char sepChar, int suffixNum) {
+ return Resources::formatName(_scene->_currentSceneId, sepChar, suffixNum,
+ EXT_NONE, "");
+}
+
+/*------------------------------------------------------------------------*/
+
+void SceneInfoDragonsphere::loadCodes(MSurface &depthSurface, int variant) {
+ File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT"));
+ MadsPack codesPack(&f);
+ Common::SeekableReadStream *stream = codesPack.getItemStream(variant + 1);
+
+ loadCodes(depthSurface, stream);
+
+ delete stream;
+ f.close();
+}
+
+void SceneInfoDragonsphere::loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) {
+ byte *destP = depthSurface.getData();
+ byte *endP = depthSurface.getBasePtr(0, depthSurface.h);
+
+ byte runLength = stream->readByte();
+ while (destP < endP && runLength > 0) {
+ byte runValue = stream->readByte();
+
+ // Write out the run length
+ Common::fill(destP, destP + runLength, runValue);
+ destP += runLength;
+
+ // Get the next run length
+ runLength = stream->readByte();
+ }
+
+ if (destP < endP)
+ Common::fill(destP, endP, 0);
+}
+
+} // End of namespace Dragonsphere
+
+} // End of namespace MADS
diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.h b/engines/mads/dragonsphere/dragonsphere_scenes.h
new file mode 100644
index 0000000000..a6c778eca7
--- /dev/null
+++ b/engines/mads/dragonsphere/dragonsphere_scenes.h
@@ -0,0 +1,695 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_DRAGONSPHERE_SCENES_H
+#define MADS_DRAGONSPHERE_SCENES_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/dragonsphere/game_dragonsphere.h"
+//#include "mads/dragonsphere/globals_dragonsphere.h"
+
+
+namespace MADS {
+
+namespace Dragonsphere {
+
+enum Noun {
+ NOUN_GAME = 0x1,
+ NOUN_QSAVE = 0x2,
+ NOUN_LOOK = 0x3,
+ NOUN_TAKE = 0x4,
+ NOUN_PUSH = 0x5,
+ NOUN_OPEN = 0x6,
+ NOUN_PUT = 0x7,
+ NOUN_TALK_TO = 0x8,
+ NOUN_GIVE = 0x9,
+ NOUN_PULL = 0xA,
+ NOUN_CLOSE = 0xB,
+ NOUN_THROW = 0xC,
+ NOUN_WALK_TO = 0xD,
+ NOUN_NOTHING = 0xE,
+ NOUN_ = 0xF,
+ NOUN_FLOOR = 0x10,
+ NOUN_WALK_ACROSS = 0x11,
+ NOUN_RUG = 0x12,
+ NOUN_CARPET = 0x13,
+ NOUN_WALL = 0x14,
+ NOUN_BED = 0x15,
+ NOUN_PILLOW = 0x16,
+ NOUN_CHEST = 0x17,
+ NOUN_WINDOW = 0x18,
+ NOUN_NIGHTSTAND = 0x19,
+ NOUN_TAPESTRY = 0x1A,
+ NOUN_DRESSING_SCREEN = 0x1B,
+ NOUN_WALK_BEHIND = 0x1C,
+ NOUN_ROYAL_CREST = 0x1D,
+ NOUN_LOOK_AT = 0x1E,
+ NOUN_WASHBASIN = 0x1F,
+ NOUN_WASH_AT = 0x20,
+ NOUN_BOOK = 0x21,
+ NOUN_FIREPLACE = 0x22,
+ NOUN_FIREPLACE_SCREEN = 0x23,
+ NOUN_DOOR_TO_QUEENS_ROOM = 0x24,
+ NOUN_WALK_THROUGH = 0x25,
+ NOUN_HALL_TO_SOUTH = 0x26,
+ NOUN_WALK_INTO = 0x27,
+ NOUN_WALL_PLAQUE = 0x28,
+ NOUN_DECORATION = 0x29,
+ NOUN_SWORDS = 0x2A,
+ NOUN_WALL_SCONCE = 0x2B,
+ NOUN_BUST_ON_WALL = 0x2C,
+ NOUN_WALL_ARCH = 0x2D,
+ NOUN_SIGNET_RING = 0x2E,
+ NOUN_INVOKE = 0x2F,
+ NOUN_POLISH = 0x30,
+ NOUN_GANGBANG = 0x31,
+ NOUN_BIRD_FIGURINE = 0x32,
+ NOUN_RUB = 0x33,
+ NOUN_BIRDCALL = 0x34,
+ NOUN_USE = 0x35,
+ NOUN_MAKE_NOISE = 0x36,
+ NOUN_SHIELDSTONE = 0x37,
+ NOUN_SWORD = 0x38,
+ NOUN_ATTACK = 0x39,
+ NOUN_CARVE_UP = 0x3A,
+ NOUN_GOBLET = 0x3B,
+ NOUN_FILL = 0x3C,
+ NOUN_DRINK_FROM = 0x3D,
+ NOUN_BONE = 0x3E,
+ NOUN_GNAW = 0x3F,
+ NOUN_FRUIT = 0x40,
+ NOUN_EAT = 0x41,
+ NOUN_DOLL = 0x42,
+ NOUN_PLAY_WITH = 0x43,
+ NOUN_HEAL = 0x44,
+ NOUN_HEAL_THYSELF = 0x45,
+ NOUN_HEAL_SELF = 0x46,
+ NOUN_POLYSTONE = 0x47,
+ NOUN_MIMIC = 0x48,
+ NOUN_RED_POWERSTONE = 0x49,
+ NOUN_YELLOW_POWERSTONE = 0x4A,
+ NOUN_BLUE_POWERSTONE = 0x4B,
+ NOUN_KEY_CROWN = 0x4C,
+ NOUN_WEAR = 0x4D,
+ NOUN_DATES = 0x4E,
+ NOUN_STATUE = 0x4F,
+ NOUN_BOTTLE_OF_FLIES = 0x50,
+ NOUN_LISTEN_TO = 0x51,
+ NOUN_SOUL_EGG = 0x52,
+ NOUN_BREAK = 0x53,
+ NOUN_MAGIC_BELT = 0x54,
+ NOUN_ADJUST = 0x55,
+ NOUN_AMULET = 0x56,
+ NOUN_THRUST = 0x57,
+ NOUN_MUD = 0x58,
+ NOUN_FEEL = 0x59,
+ NOUN_TASTE = 0x5A,
+ NOUN_FEATHERS = 0x5B,
+ NOUN_TICKLE = 0x5C,
+ NOUN_TORCH = 0x5D,
+ NOUN_WAVE = 0x5E,
+ NOUN_FLASK = 0x5F,
+ NOUN_FLASK_FULL_OF_ACID = 0x60,
+ NOUN_POUR_CONTENTS = 0x61,
+ NOUN_POUR = 0x62,
+ NOUN_POUR_CONTENTS_OF = 0x63,
+ NOUN_DRINK = 0x64,
+ NOUN_ROPE = 0x65,
+ NOUN_TIE = 0x66,
+ NOUN_POWER_VACUUM_STONE = 0x67,
+ NOUN_TAKE_MAGIC_FROM = 0x68,
+ NOUN_DEAD_RAT = 0x69,
+ NOUN_PET = 0x6A,
+ NOUN_MAP = 0x6B,
+ NOUN_FOLD = 0x6C,
+ NOUN_CRYSTAL_BALL = 0x6D,
+ NOUN_GAZE_INTO = 0x6E,
+ NOUN_INVOKE_POWER_OF = 0x6F,
+ NOUN_BLACK_SPHERE = 0x70,
+ NOUN_SOPTUS_SOPORIFIC = 0x71,
+ NOUN_SHIFTER_RING = 0x72,
+ NOUN_SHIFT_SELF = 0x73,
+ NOUN_SHIFT_INTO_BEAR = 0x74,
+ NOUN_SHIFT_INTO_SEAL = 0x75,
+ NOUN_SHIFT_INTO_SNAKE = 0x76,
+ NOUN_REVERT = 0x77,
+ NOUN_MEDICINE_BUNDLE = 0x78,
+ NOUN_SHAKE = 0x79,
+ NOUN_PARTLY_BUILT_BUNDLE = 0x7A,
+ NOUN_RATSICLE = 0x7B,
+ NOUN_LICK = 0x7C,
+ NOUN_TENTACLE_PARTS = 0x7D,
+ NOUN_CHEW = 0x7E,
+ NOUN_TELEPORT_DOOR = 0x7F,
+ NOUN_UNROLL = 0x80,
+ NOUN_RARE_COIN = 0x81,
+ NOUN_ADMIRE = 0x82,
+ NOUN_CRYSTAL_FLOWER = 0x83,
+ NOUN_DIAMOND_DUST = 0x84,
+ NOUN_RUBY_RING = 0x85,
+ NOUN_GOLD_NUGGET = 0x86,
+ NOUN_MAGIC_MUSIC_BOX = 0x87,
+ NOUN_EMERALD = 0x88,
+ NOUN_PIECE_OF_PAPER = 0x89,
+ NOUN_SPEAK_WORDS_ON = 0x8A,
+ NOUN_VORTEX_STONE = 0x8B,
+ NOUN_RUG2 = 0x8C,
+ NOUN_FIREPLACE_SCREEN2 = 0x8D,
+ NOUN_BUST_ON_WALL2 = 0x8E,
+ NOUN_LOOK_AT2 = 0x8F,
+ NOUN_DRAGON = 0x90,
+ NOUN_DRAGONSPHERE = 0x91,
+ NOUN_TOUCH = 0x92,
+ NOUN_THRONE_ROOM = 0x93,
+ NOUN_RETURN_TO = 0x94,
+ NOUN_CAVE = 0x95,
+ NOUN_PASSAGEWAY_TO_WEST = 0x96,
+ NOUN_PASSAGEWAY_TO_EAST = 0x97,
+ NOUN_CAVE_FLOOR = 0x98,
+ NOUN_STONE_COLUMN = 0x99,
+ NOUN_ABYSS = 0x9A,
+ NOUN_LOOK_INTO = 0x9B,
+ NOUN_CASTLE = 0x9C,
+ NOUN_CASTLE_GATE = 0x9D,
+ NOUN_GROUND = 0x9E,
+ NOUN_BARREL = 0x9F,
+ NOUN_BARRELS = 0xA0,
+ NOUN_HAYSTACK = 0xA1,
+ NOUN_ROOT_THROUGH = 0xA2,
+ NOUN_BATTLEMENTS = 0xA3,
+ NOUN_GATE_TO_THRONE_ROOM = 0xA4,
+ NOUN_CASTLE_WALL = 0xA5,
+ NOUN_DOOR = 0xA6,
+ NOUN_WALL_SWITCH = 0xA7,
+ NOUN_STAIRS = 0xA8,
+ NOUN_WALK_DOWN = 0xA9,
+ NOUN_EDGE_OF_ABYSS = 0xAA,
+ NOUN_COURTYARD = 0xAB,
+ NOUN_ROCK = 0xAC,
+ NOUN_CAVE_CEILING = 0xAD,
+ NOUN_CAVE_WALL = 0xAE,
+ NOUN_BRAZIER = 0xAF,
+ NOUN_DOOR_TO_THRONE_ROOM = 0xB0,
+ NOUN_GO_THROUGH = 0xB1,
+ NOUN_DINING_TABLE = 0xB2,
+ NOUN_ACTIVATE = 0xB3,
+ NOUN_BATTLEMENT = 0xB4,
+ NOUN_DOOR_TO_GAURDROOM = 0xB5,
+ NOUN_DUNGEON_FLOOR = 0xB6,
+ NOUN_DUNGEON_WALLS = 0xB7,
+ NOUN_DUNGEON_CEILING = 0xB8,
+ NOUN_BEDDING = 0xB9,
+ NOUN_FLOOR_GRATE = 0xBA,
+ NOUN_MANACLES = 0xBB,
+ NOUN_CALENDAR = 0xBC,
+ NOUN_DOOR_TO_GUARDROOM = 0xBD,
+ NOUN_DOOR_TO_COUNCIL_ROOM = 0xBE,
+ NOUN_GUARD_STATION = 0xBF,
+ NOUN_DOOR_TO_DUNGEON_CELL = 0xC0,
+ NOUN_DOORWAY_TO_CELL = 0xC1,
+ NOUN_DUNGEON_DOOR = 0xC2,
+ NOUN_DUNGEON_WALL = 0xC3,
+ NOUN_CEILING = 0xC4,
+ NOUN_DOOR_TO_HALLWAY = 0xC5,
+ NOUN_TABLE = 0xC6,
+ NOUN_BOOKSHELF = 0xC7,
+ NOUN_TROPHY = 0xC8,
+ NOUN_READING_BENCH = 0xC9,
+ NOUN_CHAIR = 0xCA,
+ NOUN_LOVESEAT = 0xCB,
+ NOUN_WOOD_BASKET = 0xCC,
+ NOUN_STOOL = 0xCD,
+ NOUN_GUARD_STOOL = 0xCE,
+ NOUN_ROCKS = 0xCF,
+ NOUN_DIVIDING_WALL = 0xD0,
+ NOUN_ARCHWAY = 0xD1,
+ NOUN_MARKET_GROUNDS = 0xD2,
+ NOUN_HEDGE = 0xD3,
+ NOUN_SKY = 0xD4,
+ NOUN_PLAINS = 0xD5,
+ NOUN_FIELDS = 0xD6,
+ NOUN_GATE_TO_COURTYARD = 0xD7,
+ NOUN_ROAD_TO_EAST = 0xD8,
+ NOUN_TREES = 0xD9,
+ NOUN_CLOUDS = 0xDA,
+ NOUN_MERCHANTS_STALL = 0xDB,
+ NOUN_WELL = 0xDC,
+ NOUN_DOWN_WELL = 0xDD,
+ NOUN_GO = 0xDE,
+ NOUN_GO_DOWN = 0xDF,
+ NOUN_CRANK = 0xE0,
+ NOUN_BUCKET = 0xE1,
+ NOUN_JUMP_DOWN = 0xE2,
+ NOUN_WALLS = 0xE3,
+ NOUN_DOORWAY_TO_SOUTH = 0xE4,
+ NOUN_PEDESTAL = 0xE5,
+ NOUN_DOOR_TO_NORTH = 0xE6,
+ NOUN_PAINTING = 0xE7,
+ NOUN_DOCUMENT = 0xE8,
+ NOUN_INK_BOTTLE = 0xE9,
+ NOUN_QUILL_PEN = 0xEA,
+ NOUN_CHANDELIER = 0xEB,
+ NOUN_COUNCIL_TABLE = 0xEC,
+ NOUN_CANDLESTICK = 0xED,
+ NOUN_DESK = 0xEE,
+ NOUN_TURN = 0xEF,
+ NOUN_POLE = 0xF0,
+ NOUN_THE_SCENE = 0xF1,
+ NOUN_LEAVE = 0xF2,
+ NOUN_END_TABLE = 0xF3,
+ NOUN_BATTLE_AXES = 0xF4,
+ NOUN_DOOR_TO_KINGS_ROOM = 0xF5,
+ NOUN_COAT_OF_ARMS = 0xF6,
+ NOUN_LARGE_WINDOW = 0xF7,
+ NOUN_SMALL_WINDOW = 0xF8,
+ NOUN_DOOR_TO_MEETING_ROOM = 0xF9,
+ NOUN_DOOR_TO_BALLROOM = 0xFA,
+ NOUN_FLOWERS = 0xFB,
+ NOUN_SHUTTERS = 0xFC,
+ NOUN_BOOKCASE = 0xFD,
+ NOUN_DOOR_TO_COURTYARD = 0xFE,
+ NOUN_PLATFORM = 0xFF,
+ NOUN_STEP = 0x100,
+ NOUN_RED_CARPET = 0x101,
+ NOUN_KINGS_THRONE = 0x102,
+ NOUN_SIT_IN = 0x103,
+ NOUN_QUEENS_THRONE = 0x104,
+ NOUN_TRAPDOOR = 0x105,
+ NOUN_GRATE = 0x106,
+ NOUN_RIVER = 0x107,
+ NOUN_DIARIES = 0x108,
+ NOUN_SWIM_DOWN = 0x109,
+ NOUN_SCULLERY_MAID = 0x10A,
+ NOUN_DOORWAY_TO_DUNGEON = 0x10B,
+ NOUN_WARD = 0x10C,
+ NOUN_DARKNESS_BEAST = 0x10D,
+ NOUN_BEAST = 0x10E,
+ NOUN_PUT_MAGIC_INTO = 0x10F,
+ NOUN_GUARD = 0x110,
+ NOUN_CROWN = 0x111,
+ NOUN_BOOKS = 0x112,
+ NOUN_SECRET_DOOR = 0x113,
+ NOUN_WALL_PANEL = 0x114,
+ NOUN_DOORWAY = 0x115,
+ NOUN_FAERIE = 0x116,
+ NOUN_SOPTUS_ECLIPTUS = 0x117,
+ NOUN_GUARD_CAPTAIN = 0x118,
+ NOUN_MERCHANT = 0x119,
+ NOUN_SHAPECHANGER = 0x11A,
+ NOUN_RED_STONE = 0x11B,
+ NOUN_YELLOW_STONE = 0x11C,
+ NOUN_BLUE_STONE = 0x11D,
+ NOUN_FLIES = 0x11E,
+ NOUN_FLASK_OF_ACID = 0x11F,
+ NOUN_PARTIAL_BUNDLE = 0x120,
+ NOUN_SOPORIFIC = 0x121,
+ NOUN_PARCHMENT = 0x122,
+ NOUN_KING = 0x123,
+ NOUN_MACMORN = 0x124,
+ NOUN_MOUNTAINSIDE = 0x125,
+ NOUN_PATH_TO_SOUTH = 0x126,
+ NOUN_ROUGH_STONE = 0x127,
+ NOUN_CLIMB_UP = 0x128,
+ NOUN_LARGE_ROCK = 0x129,
+ NOUN_SMALL_ROCK = 0x12A,
+ NOUN_PATH_TO_WEST = 0x12B,
+ NOUN_CAVE_ENTRANCE = 0x12C,
+ NOUN_PALLET = 0x12D,
+ NOUN_BLANKET = 0x12E,
+ NOUN_FIREPIT = 0x12F,
+ NOUN_FLAT_STONE = 0x130,
+ NOUN_MOVE = 0x131,
+ NOUN_SPIRIT_BUNDLE = 0x132,
+ NOUN_TRAIL_LEADING_UP = 0x133,
+ NOUN_FOLLOW = 0x134,
+ NOUN_TRAIL_LEADING_DOWN = 0x135,
+ NOUN_NEST = 0x136,
+ NOUN_REACH_IN = 0x137,
+ NOUN_TRAIL_LEADING_WEST = 0x138,
+ NOUN_PATH_TO_EAST = 0x139,
+ NOUN_WATERFALL = 0x13A,
+ NOUN_PUDDLE = 0x13B,
+ NOUN_EDGE_OF_CLIFF = 0x13C,
+ NOUN_LEDGE = 0x13D,
+ NOUN_CLIMB_DOWN = 0x13E,
+ NOUN_LANDING = 0x13F,
+ NOUN_BOULDERS = 0x140,
+ NOUN_ROCK_TUMBLE = 0x141,
+ NOUN_ROCK_TREE = 0x142,
+ NOUN_PILLAR = 0x143,
+ NOUN_JUMP_TO = 0x144,
+ NOUN_CLIFF = 0x145,
+ NOUN_PILLARS = 0x146,
+ NOUN_SPECIAL_ROCK = 0x147,
+ NOUN_GAZE_UPON = 0x148,
+ NOUN_SCONCE = 0x149,
+ NOUN_LADDER = 0x14A,
+ NOUN_STAIRWAY = 0x14B,
+ NOUN_MECHANISM = 0x14C,
+ NOUN_SPEARHEADS = 0x14D,
+ NOUN_TRAP_DOOR = 0x14E,
+ NOUN_SWIM = 0x14F,
+ NOUN_DOWN_RIVER = 0x150,
+ NOUN_SWIM_UP = 0x151,
+ NOUN_UP_RIVER = 0x152,
+ NOUN_SHORE = 0x153,
+ NOUN_SWIM_TO = 0x154,
+ NOUN_SWIM_TOWARDS = 0x155,
+ NOUN_KING_CALLASH = 0x156,
+ NOUN_KINGS_THRONE2 = 0x157,
+ NOUN_KING2 = 0x158,
+ NOUN_GROTTO = 0x159,
+ NOUN_CLIMB_THROUGH = 0x15A,
+ NOUN_QUEEN_MOTHER = 0x15B,
+ NOUN_MACMORN2 = 0x15C,
+ NOUN_SMALL_LEDGE = 0x15D,
+ NOUN_MACMORN3 = 0x15E,
+ NOUN_TO_110 = 0x15F,
+ NOUN_TO_KITTY_HEAVEN = 0x160,
+ NOUN_KITTY_HEAVEN = 0x161,
+ NOUN_ROOM_110 = 0x162,
+ NOUN_LLANIE = 0x163,
+ NOUN_CW = 0x164,
+ NOUN_HERMIT = 0x165,
+ NOUN_TROU = 0x166,
+ NOUN_SHAK = 0x167,
+ NOUN_ROOM_501 = 0x168,
+ NOUN_MOON = 0x169,
+ NOUN_UFO = 0x16A,
+ NOUN_SIT_ON = 0x16B,
+ NOUN_STRANGER = 0x16C,
+ NOUN_TOWER_DOOR = 0x16D,
+ NOUN_DOOR_TO_EAST = 0x16E,
+ NOUN_DOOR_TO_WEST = 0x16F,
+ NOUN_EYE = 0x170,
+ NOUN_DOORWAY_TO_EAST = 0x171,
+ NOUN_DOORWAY_TO_WEST = 0x172,
+ NOUN_SKULL = 0x173,
+ NOUN_DOOR_TO_MAGIC_ROOM = 0x174,
+ NOUN_ANCIENT_BARREL = 0x175,
+ NOUN_COBWEBS = 0x176,
+ NOUN_SHELF = 0x177,
+ NOUN_MUSTY_CHART = 0x178,
+ NOUN_LAB_TABLE = 0x179,
+ NOUN_PETCOCK = 0x17A,
+ NOUN_NOZZLE = 0x17B,
+ NOUN_TUBING = 0x17C,
+ NOUN_BEAKER = 0x17D,
+ NOUN_FLAME = 0x17E,
+ NOUN_METAL_PLATE = 0x17F,
+ NOUN_SHAFT_OF_LIGHT = 0x180,
+ NOUN_CABINET = 0x181,
+ NOUN_BALANCE = 0x182,
+ NOUN_CAGE = 0x183,
+ NOUN_FREEZER = 0x184,
+ NOUN_CONTENTS_OF_FREEZER = 0x185,
+ NOUN_CAGE_WITH_RATS = 0x186,
+ NOUN_DOOR_TO_SOUTH = 0x187,
+ NOUN_TRAIL_OF_GREEN_SLIME = 0x188,
+ NOUN_NECK_LOCK = 0x189,
+ NOUN_BENCH = 0x18A,
+ NOUN_SKELETON = 0x18B,
+ NOUN_LEG_CLAMPS = 0x18C,
+ NOUN_LEG_LOCK = 0x18D,
+ NOUN_WAIST_LOCK = 0x18E,
+ NOUN_NER_TOM = 0x18F,
+ NOUN_BELT = 0x190,
+ NOUN_JUMP_INTO = 0x191,
+ NOUN_CLOSET = 0x192,
+ NOUN_DOOR_TO_EYE_CHAMBER = 0x193,
+ NOUN_DRESSER = 0x194,
+ NOUN_SCROLL = 0x195,
+ NOUN_WITCH_PARAPHERNALIA = 0x196,
+ NOUN_SHELVES = 0x197,
+ NOUN_MAGIC_TOMES = 0x198,
+ NOUN_MAGIC_PARAPHERNALIA = 0x199,
+ NOUN_BOOK_OF_MAGIC = 0x19A,
+ NOUN_HOURGLASS = 0x19B,
+ NOUN_STONE_SPHERE = 0x19C,
+ NOUN_SHADOW_OF_WINDOW = 0x19D,
+ NOUN_MUSIC_BOX = 0x19E,
+ NOUN_LARGE_SPIDER_WEB = 0x19F,
+ NOUN_INFERNAL_MACHINE = 0x1A0,
+ NOUN_WATER_SOURCE = 0x1A1,
+ NOUN_FLOW_OF_WATER = 0x1A2,
+ NOUN_RETORT = 0x1A3,
+ NOUN_DOORWAY_TO_CORRIDOR = 0x1A4,
+ NOUN_TELESCOPE = 0x1A5,
+ NOUN_STRANGE_MAP = 0x1A6,
+ NOUN_CIRCLE_OF_SPHERES = 0x1A7,
+ NOUN_STONE_BED = 0x1A8,
+ NOUN_DRAGON_SCULPTURE = 0x1A9,
+ NOUN_RAT = 0x1AA,
+ NOUN_RAT_CAGE = 0x1AB,
+ NOUN_DOWN_BUTTON = 0x1AC,
+ NOUN_DOOR_TO_MACHINE_ROOM = 0x1AD,
+ NOUN_STRANGE_PORTAL = 0x1AE,
+ NOUN_DOOR_FRAME = 0x1AF,
+ NOUN_ELEVATOR_HOLE = 0x1B0,
+ NOUN_UP_BUTTON = 0x1B1,
+ NOUN_DOORWAY_TO_DARK_ROOM = 0x1B2,
+ NOUN_BIG_SKULL = 0x1B3,
+ NOUN_ELEVATOR_PLATFORM = 0x1B4,
+ NOUN_BUTTON = 0x1B5,
+ NOUN_TOP_BUTTON = 0x1B6,
+ NOUN_BOTTOM_BUTTON = 0x1B7,
+ NOUN_TELEPORTAL = 0x1B8,
+ NOUN_EYE_CHAMBER_DOORWAY = 0x1B9,
+ NOUN_MACHINE_ROOM_DOORWAY = 0x1BA,
+ NOUN_GLOWING_FLOOR = 0x1BB,
+ NOUN_BRYNN_FANN = 0x1BC,
+ NOUN_GRAN_CALLAHACH = 0x1BD,
+ NOUN_SLATHAN_NI_PATAN = 0x1BE,
+ NOUN_HIGHTOWER = 0x1BF,
+ NOUN_SOPTUS_ECLIPTUS2 = 0x1C0,
+ NOUN_TOWER = 0x1C1,
+ NOUN_MOUNTAIN_PATH = 0x1C2,
+ NOUN_PATH_BEHIND_TOWER = 0x1C3,
+ NOUN_VINES = 0x1C4,
+ NOUN_SLATHAN_NI_PATAN2 = 0x1C5,
+ NOUN_SICK = 0x1C6,
+ NOUN_PATH_AROUND_TOWER = 0x1C7,
+ NOUN_PATH_TO_HIGHTOWER = 0x1C8,
+ NOUN_SPIRIT_PLANE = 0x1C9,
+ NOUN_SPIRIT_TREE = 0x1CA,
+ NOUN_WALK = 0x1CB,
+ NOUN_REMAINS = 0x1CC,
+ NOUN_DOORWAY_TO_ELEVATOR = 0x1CD,
+ NOUN_DRAGON_DOOR = 0x1CE,
+ NOUN_DRAGON_BONES = 0x1CF,
+ NOUN_IRON_FLOOR = 0x1D0,
+ NOUN_HOLE = 0x1D1,
+ NOUN_STONE = 0x1D2,
+ NOUN_HOMEMADE_BUNDLE = 0x1D3,
+ NOUN_LEFT = 0x1D4,
+ NOUN_RIGHT = 0x1D5,
+ NOUN_UP = 0x1D6,
+ NOUN_DOWN = 0x1D7,
+ NOUN_WEST = 0x1D8,
+ NOUN_DESERT_TO_WEST = 0x1D9,
+ NOUN_CROSS = 0x1DA,
+ NOUN_DESERT_TO_EAST = 0x1DB,
+ NOUN_DESERT_TO_SOUTH = 0x1DC,
+ NOUN_DESERT_TO_NORTH = 0x1DD,
+ NOUN_DESERT = 0x1DE,
+ NOUN_POWERSTONE = 0x1DF,
+ NOUN_BONES = 0x1E0,
+ NOUN_TENT = 0x1E1,
+ NOUN_BUSH = 0x1E2,
+ NOUN_SANWE = 0x1E3,
+ NOUN_TANGLE = 0x1E4,
+ NOUN_SAND = 0x1E5,
+ NOUN_MAGIC_GRAPES = 0x1E6,
+ NOUN_ROCS_NEST = 0x1E7,
+ NOUN_GRAPE_VINE = 0x1E8,
+ NOUN_STRANGE_SQUARE = 0x1E9,
+ NOUN_WATER_SPHERE = 0x1EA,
+ NOUN_EAST_END_OF_ISLAND = 0x1EB,
+ NOUN_ISLAND = 0x1EC,
+ NOUN_SECRET_MESSAGE = 0x1ED,
+ NOUN_FIND = 0x1EE,
+ NOUN_SAND_NEAR_STONES = 0x1EF,
+ NOUN_DESERT_SKY = 0x1F0,
+ NOUN_POOL = 0x1F1,
+ NOUN_PALM_TREE = 0x1F2,
+ NOUN_OASIS = 0x1F3,
+ NOUN_LEAN_TO = 0x1F4,
+ NOUN_TRADER = 0x1F5,
+ NOUN_SIGN = 0x1F6,
+ NOUN_WATER_FLOW = 0x1F7,
+ NOUN_FLOATING_DISK = 0x1F8,
+ NOUN_GNARLED_ROOT = 0x1F9,
+ NOUN_SNAKE_PIT = 0x1FA,
+ NOUN_MARKER = 0x1FB,
+ NOUN_SHAMAN = 0x1FC,
+ NOUN_GUARDHOUSE = 0x1FD,
+ NOUN_BONE_TREE = 0x1FE,
+ NOUN_EAR_ROCK = 0x1FF,
+ NOUN_MOUTH_ROCK = 0x200,
+ NOUN_NOSE_ROCK = 0x201,
+ NOUN_NEW_BUNDLE = 0x202,
+ NOUN_LIZARD = 0x203,
+ NOUN_ROC = 0x204,
+ NOUN_ROCS_NEST2 = 0x205,
+ NOUN_SELECT = 0x206,
+ NOUN_PURPLE_GEM = 0x207,
+ NOUN_PURPLE_STONE = 0x208,
+ NOUN_GREEN_STONE = 0x209,
+ NOUN_PATH = 0x20A,
+ NOUN_GUARDS = 0x20B,
+ NOUN_LAMP = 0x20C,
+ NOUN_SCIMITAR = 0x20D,
+ NOUN_SITTING_PILLOW = 0x20E,
+ NOUN_WATER_GOURD = 0x20F,
+ NOUN_JAR = 0x210,
+ NOUN_TENT_POLE = 0x211,
+ NOUN_EXIT = 0x212,
+ NOUN_PARAPHERNALIA = 0x213,
+ NOUN_SLATHAN_NI_PATAN3 = 0x214,
+ NOUN_EYE_ROCK = 0x215,
+ NOUN_BODY_TREE = 0x216,
+ NOUN_CLEARING = 0x217,
+ NOUN_TENTACLES = 0x218,
+ NOUN_SPELL_SHIELD = 0x219,
+ NOUN_POOL_MONSTER = 0x21A,
+ NOUN_SHIFTER_BOULDER = 0x21B,
+ NOUN_DEAD_TREE = 0x21C,
+ NOUN_PIT = 0x21D,
+ NOUN_SHIFTER_VILLAGE = 0x21E,
+ NOUN_SLATHAN_SKY = 0x21F,
+ NOUN_SHIFTER = 0x220,
+ NOUN_WALK_AROUND = 0x221,
+ NOUN_WRECKED_BRIDGE = 0x222,
+ NOUN_SHACK = 0x223,
+ NOUN_WRECKED_SHACK = 0x224,
+ NOUN_WISE_SHIFTER = 0x225,
+ NOUN_GRASS = 0x226,
+ NOUN_ENTRANCE_TO_MAZE = 0x227,
+ NOUN_TOPIARY_TOAD = 0x228,
+ NOUN_BOULDER = 0x229,
+ NOUN_MUSHROOM = 0x22A,
+ NOUN_SLATHAN_SKY2 = 0x22B,
+ NOUN_GRETA = 0x22C,
+ NOUN_TREE_STUMP = 0x22D,
+ NOUN_SANCTUARY_WOODS = 0x22E,
+ NOUN_TOADS = 0x22F,
+ NOUN_DOOFUS = 0x230,
+ NOUN_SHIFTING_MONSTER = 0x231,
+ NOUN_SPRITE = 0x232,
+ NOUN_MAZE = 0x233,
+ NOUN_TOPIARY_TOADSTOOL = 0x234,
+ NOUN_TOPIARY_GARGOYLE = 0x235,
+ NOUN_TOPIARY_DRAGON = 0x236,
+ NOUN_GUARDIAN = 0x237,
+ NOUN_BUTTERFLY_KING = 0x238,
+ NOUN_ROBE = 0x239,
+ NOUN_CEDAR_CHEST = 0x23A,
+ NOUN_DRAGONSPHERE2 = 0x23B,
+ NOUN_PATH_TO_HIGHTOWER2 = 0x23C,
+ NOUN_CALIPH = 0x23D
+};
+
+class SceneFactory {
+public:
+ static SceneLogic *createScene(MADSEngine *vm);
+};
+
+/**
+ * Specialized base class for Dragonsphere game scenes
+ */
+class DragonsphereScene : public SceneLogic {
+protected:
+ DragonsphereGlobals &_globals;
+ GameDragonsphere &_game;
+ MADSAction &_action;
+
+ /**
+ * Forms an animation resource name
+ */
+ Common::String formAnimName(char sepChar, int suffixNum);
+
+ /**
+ * Plays appropriate sound for entering varous rooms
+ */
+ void lowRoomsEntrySound();
+public:
+ /**
+ * Constructor
+ */
+ DragonsphereScene(MADSEngine *vm);
+
+ void sub7178C();
+};
+
+class SceneInfoDragonsphere : public SceneInfo {
+ friend class SceneInfo;
+protected:
+ virtual void loadCodes(MSurface &depthSurface, int variant);
+
+ virtual void loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream);
+
+ /**
+ * Constructor
+ */
+ SceneInfoDragonsphere(MADSEngine *vm) : SceneInfo(vm) {}
+};
+
+// TODO: Temporary, remove once implemented properly
+class Scene1xx : public DragonsphereScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void sceneEntrySound() {}
+
+ /**
+ *Sets the AA file to use for the scene
+ */
+ void setAAName() {}
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix() {}
+public:
+ Scene1xx(MADSEngine *vm) : DragonsphereScene(vm) {}
+};
+
+// TODO: Temporary, remove once implemented properly
+class DummyScene : public DragonsphereScene {
+public:
+ DummyScene(MADSEngine *vm) : DragonsphereScene(vm) {
+ warning("Unimplemented scene");
+ }
+
+ virtual void setup() {}
+ virtual void enter() {}
+ virtual void actions() {}
+};
+
+} // End of namespace Dragonsphere
+
+} // End of namespace MADS
+
+#endif /* MADS_DRAGONSPHERE_SCENES_H */
diff --git a/engines/mads/dragonsphere/game_dragonsphere.cpp b/engines/mads/dragonsphere/game_dragonsphere.cpp
new file mode 100644
index 0000000000..c6097125b1
--- /dev/null
+++ b/engines/mads/dragonsphere/game_dragonsphere.cpp
@@ -0,0 +1,173 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/game.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/dragonsphere/game_dragonsphere.h"
+//#include "mads/nebular/dialogs_nebular.h"
+//#include "mads/nebular/globals_nebular.h"
+#include "mads/dragonsphere/dragonsphere_scenes.h"
+
+namespace MADS {
+
+namespace Dragonsphere {
+
+GameDragonsphere::GameDragonsphere(MADSEngine *vm)
+ : Game(vm) {
+ _surface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+ _storyMode = STORYMODE_NAUGHTY;
+}
+
+ProtectionResult GameDragonsphere::checkCopyProtection() {
+ /*
+ // DEBUG: Flag copy protection failure
+ _globals[5] = -1;
+
+ if (!ConfMan.getBool("copy_protection"))
+ return true;
+
+ * DEBUG: Disabled for now
+ CopyProtectionDialog *dlg = new CopyProtectionDialog(_vm, false);
+ dlg->show();
+ delete dlg;
+ */
+
+ // DEBUG: Return that copy protection failed
+ return PROTECTION_SUCCEED;
+}
+
+void GameDragonsphere::initializeGlobals() {
+ //int count, count2;
+ //int bad;
+
+ _globals.reset();
+ //_globals[kTalkInanimateCount] = 8;
+
+ /* Section #1 variables */
+ // TODO
+
+ /* Section #2 variables */
+ // TODO
+
+ /* Section #3 variables */
+ // TODO
+
+ /* Section #4 variables */
+ // TODO
+
+ /* Section #5 variables */
+ // TODO
+
+ /* Section #6 variables */
+ // TODO
+
+ /* Section #9 variables */
+ // TODO
+
+ _player._facing = FACING_NORTH;
+ _player._turnToFacing = FACING_NORTH;
+
+ //Player::preloadSequences("RXM", 1);
+ //Player::preloadSequences("ROX", 1);
+}
+
+void GameDragonsphere::setSectionHandler() {
+ delete _sectionHandler;
+
+ switch (_sectionNumber) {
+ case 1:
+ _sectionHandler = new Section1Handler(_vm);
+ break;
+ case 2:
+ _sectionHandler = new Section2Handler(_vm);
+ break;
+ case 3:
+ _sectionHandler = new Section3Handler(_vm);
+ break;
+ case 4:
+ _sectionHandler = new Section4Handler(_vm);
+ break;
+ case 5:
+ _sectionHandler = new Section5Handler(_vm);
+ break;
+ case 6:
+ _sectionHandler = new Section6Handler(_vm);
+ break;
+ case 7:
+ _sectionHandler = new Section7Handler(_vm);
+ break;
+ case 8:
+ _sectionHandler = new Section8Handler(_vm);
+ break;
+ default:
+ break;
+ }
+}
+
+void GameDragonsphere::checkShowDialog() {
+ // TODO: Copied from Nebular
+ if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[5]) {
+ _player.releasePlayerSprites();
+ _vm->_dialogs->showDialog();
+ _vm->_dialogs->_pendingDialog = DIALOG_NONE;
+ }
+}
+
+void GameDragonsphere::doObjectAction() {
+ // TODO: Copied from Nebular
+ //Scene &scene = _scene;
+ MADSAction &action = _scene._action;
+ //Dialogs &dialogs = *_vm->_dialogs;
+ //int id;
+
+ action._inProgress = false;
+}
+
+void GameDragonsphere::unhandledAction() {
+ // TODO
+}
+
+void GameDragonsphere::step() {
+ if (_player._visible && _player._stepEnabled && !_player._moving &&
+ (_player._facing == _player._turnToFacing)) {
+
+ // TODO
+ }
+
+}
+
+void GameDragonsphere::synchronize(Common::Serializer &s, bool phase1) {
+ Game::synchronize(s, phase1);
+
+ // TODO: Copied from Nebular
+ if (!phase1) {
+ _globals.synchronize(s);
+ }
+}
+
+} // End of namespace Dragonsphere
+
+} // End of namespace MADS
diff --git a/engines/mads/dragonsphere/game_dragonsphere.h b/engines/mads/dragonsphere/game_dragonsphere.h
new file mode 100644
index 0000000000..5147f75178
--- /dev/null
+++ b/engines/mads/dragonsphere/game_dragonsphere.h
@@ -0,0 +1,151 @@
+/* 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 MADS_GAME_DRAGONSPHERE_H
+#define MADS_GAME_DRAGONSPHERE_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/globals.h"
+//#include "mads/nebular/globals_nebular.h"
+
+namespace MADS {
+
+namespace Dragonsphere {
+
+// TODO: Adapt for Dragonsphere's difficulty setting
+enum StoryMode { STORYMODE_NAUGHTY = 1, STORYMODE_NICE = 2 };
+
+enum InventoryObject {
+ OBJ_NONE = -1,
+ OBJ_SIGNET_RING = 0,
+ OBJ_BIRD_FIGURINE = 1,
+ OBJ_BIRDCALL = 2,
+ OBJ_SHIELDSTONE = 3,
+ OBJ_SWORD = 4,
+ OBJ_GOBLET = 5,
+ OBJ_BONE = 6,
+ OBJ_FRUIT = 7,
+ OBJ_DOLL = 8,
+ OBJ_POLYSTONE = 9,
+ OBJ_RED_STONE = 10,
+ OBJ_YELLOW_STONE = 11,
+ OBJ_BLUE_STONE = 12,
+ OBJ_KEY_CROWN = 13,
+ OBJ_DATES = 14,
+ OBJ_STATUE = 15,
+ OBJ_FLIES = 16,
+ OBJ_SOUL_EGG = 17,
+ OBJ_MAGIC_BELT = 18,
+ OBJ_AMULET = 19,
+ OBJ_MUD = 20,
+ OBJ_FEATHERS = 21,
+ OBJ_TORCH = 22,
+ OBJ_FLASK = 23,
+ OBJ_FLASK_OF_ACID = 24,
+ OBJ_ROPE = 25,
+ OBJ_VORTEX_STONE = 26,
+ OBJ_DEAD_RAT = 27,
+ OBJ_MAP = 28,
+ OBJ_CRYSTAL_BALL = 29,
+ OBJ_BLACK_SPHERE = 30,
+ OBJ_SOPORIFIC = 31,
+ OBJ_SHIFTER_RING = 32,
+ OBJ_SPIRIT_BUNDLE = 33,
+ OBJ_PARTIAL_BUNDLE = 34,
+ OBJ_RATSICLE = 35,
+ OBJ_TENTACLE_PARTS = 36,
+ OBJ_TELEPORT_DOOR = 37,
+ OBJ_RARE_COIN = 38,
+ OBJ_CRYSTAL_FLOWER = 39,
+ OBJ_DIAMOND_DUST = 40,
+ OBJ_RUBY_RING = 41,
+ OBJ_GOLD_NUGGET = 42,
+ OBJ_MUSIC_BOX = 43,
+ OBJ_EMERALD = 44,
+ OBJ_PARCHMENT = 45,
+ OBJ_GAME = 46,
+ OBJ_GAME2 = 47,
+ OBJ_NEW_BUNDLE = 48
+};
+
+// HACK: A stub for now, remove from here once it's implemented properly
+class DragonsphereGlobals : public Globals {
+public:
+ DragonsphereGlobals() {
+ resize(210); // Rex has 210 globals
+ }
+ virtual ~DragonsphereGlobals() {}
+};
+
+class GameDragonsphere : public Game {
+ friend class Game;
+protected:
+ GameDragonsphere(MADSEngine *vm);
+
+ virtual ProtectionResult checkCopyProtection();
+
+ virtual void initializeGlobals();
+
+ virtual void setSectionHandler();
+
+ virtual void checkShowDialog();
+public:
+ DragonsphereGlobals _globals;
+ StoryMode _storyMode;
+
+ virtual Globals &globals() { return _globals; }
+
+ virtual void doObjectAction();
+
+ virtual void unhandledAction();
+
+ virtual void step();
+
+ virtual void synchronize(Common::Serializer &s, bool phase1);
+};
+
+
+class Section1Handler : public SectionHandler {
+public:
+ Section1Handler(MADSEngine *vm) : SectionHandler(vm) {}
+
+ // TODO: Properly implement handler methods
+ virtual void preLoadSection() {}
+ virtual void sectionPtr2() {}
+ virtual void postLoadSection() {}
+};
+
+// TODO: Properly implement handler classes
+typedef Section1Handler Section2Handler;
+typedef Section1Handler Section3Handler;
+typedef Section1Handler Section4Handler;
+typedef Section1Handler Section5Handler;
+typedef Section1Handler Section6Handler;
+typedef Section1Handler Section7Handler;
+typedef Section1Handler Section8Handler;
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_GAME_DRAGONSPHERE_H */
diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp
new file mode 100644
index 0000000000..c3e6d5c122
--- /dev/null
+++ b/engines/mads/events.cpp
@@ -0,0 +1,256 @@
+/* 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 "common/scummsys.h"
+#include "graphics/cursorman.h"
+#include "common/events.h"
+#include "engines/util.h"
+#include "mads/mads.h"
+#include "mads/events.h"
+#include "mads/scene.h"
+
+namespace MADS {
+
+EventsManager::EventsManager(MADSEngine *vm) {
+ _vm = vm;
+ _cursorSprites = nullptr;
+ _cursorId = CURSOR_NONE;
+ _newCursorId = CURSOR_NONE;
+ _frameCounter = 10;
+ _priorFrameTime = 0;
+ _mouseClicked = false;
+ _mouseReleased = false;
+ _mouseButtons = 0;
+ _mouseStatus = 0;
+ _vD2 = 0;
+ _mouseStatusCopy = 0;
+ _mouseMoved = false;
+ _vD8 = 0;
+ _rightMousePressed = false;
+}
+
+EventsManager::~EventsManager() {
+ freeCursors();
+}
+
+void EventsManager::loadCursors(const Common::String &spritesName) {
+ delete _cursorSprites;
+ _cursorSprites = new SpriteAsset(_vm, spritesName, 0x4000);
+}
+
+void EventsManager::setCursor(CursorType cursorId) {
+ _cursorId = cursorId;
+ changeCursor();
+}
+
+void EventsManager::setCursor2(CursorType cursorId) {
+ _cursorId = cursorId;
+ _newCursorId = cursorId;
+ changeCursor();
+}
+
+void EventsManager::showCursor() {
+ CursorMan.showMouse(true);
+}
+
+void EventsManager::hideCursor() {
+ CursorMan.showMouse(false);
+}
+
+bool EventsManager::isCursorVisible() {
+ return CursorMan.isVisible();
+}
+
+void EventsManager::waitCursor() {
+ CursorType cursorId = (CursorType)MIN(_cursorSprites->getCount(), (int)CURSOR_WAIT);
+ _newCursorId = cursorId;
+ if (_cursorId != _newCursorId) {
+ changeCursor();
+ _cursorId = _newCursorId;
+ }
+}
+
+void EventsManager::changeCursor() {
+ if (_cursorSprites) {
+ MSprite *cursor = _cursorSprites->getFrame(_cursorId - 1);
+ assert(cursor->w == cursor->h);
+ byte transIndex = cursor->getTransparencyIndex();
+
+ // Check for hotspot indication pixels along the right-hand and bottom
+ // row. Put together, these give the cursor's hotspot x,y
+ int hotspotX = 0, hotspotY = 0;
+ byte *cursorData = cursor->getData();
+ for (int idx = 0; idx < cursor->w; ++idx) {
+ if (cursorData[(cursor->h - 1) * cursor->w + idx] != transIndex)
+ hotspotX = idx;
+
+ if (cursorData[(idx + 1) * cursor->w - 1] != transIndex)
+ hotspotY = idx;
+ }
+
+ // Reduce the cursor data to remove the last column from each row, since
+ // the cursor routines don't have a pitch option
+ byte *destCursor = new byte[(cursor->w - 1) * (cursor->h - 1)];
+ byte *srcP = cursorData;
+ byte *destP = destCursor;
+
+ for (int idx = 0; idx < (cursor->h - 1); ++idx) {
+ Common::copy(srcP, srcP + cursor->w - 1, destP);
+ srcP += cursor->w;
+ destP += cursor->w - 1;
+ }
+
+ // Set the raw cursor data to use
+ CursorMan.replaceCursor(destCursor, cursor->w - 1, cursor->h - 1,
+ hotspotX, hotspotY, transIndex);
+ showCursor();
+ delete[] destCursor;
+ }
+}
+
+void EventsManager::freeCursors() {
+ delete _cursorSprites;
+ _cursorSprites = nullptr;
+}
+
+void EventsManager::pollEvents() {
+ checkForNextFrameCounter();
+ _mouseMoved = false;
+
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ // Handle keypress
+ switch (event.type) {
+ case Common::EVENT_QUIT:
+ case Common::EVENT_RTL:
+ return;
+
+ case Common::EVENT_KEYDOWN:
+ // Check for debugger
+ if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _vm->_debugger->attach();
+ _vm->_debugger->onFrame();
+ } else {
+ _pendingKeys.push(event);
+ }
+ return;
+ case Common::EVENT_KEYUP:
+ return;
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseClicked = true;
+ _mouseButtons = 1;
+ _mouseMoved = true;
+ if (event.type == Common::EVENT_RBUTTONDOWN) {
+ _rightMousePressed = true;
+ _mouseStatus |= 2;
+ } else {
+ _mouseStatus |= 1;
+ }
+ return;
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_RBUTTONUP:
+ _mouseClicked = false;
+ _mouseReleased = true;
+ _mouseMoved = true;
+ _rightMousePressed = false;
+ if (event.type == Common::EVENT_RBUTTONUP) {
+ _mouseStatus &= ~2;
+ } else {
+ _mouseStatus &= ~1;
+ }
+ return;
+ case Common::EVENT_MOUSEMOVE:
+ _mousePos = event.mouse;
+ _currentPos = event.mouse;
+ _mouseMoved = true;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void EventsManager::checkForNextFrameCounter() {
+ // Check for next game frame
+ uint32 milli = g_system->getMillis();
+ if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
+ ++_frameCounter;
+ _priorFrameTime = milli;
+
+ // Do any palette cycling
+ _vm->_game->_scene.animatePalette();
+
+ // Give time to the debugger
+ _vm->_debugger->onFrame();
+
+ // Display the frame
+ _vm->_screen.updateScreen();
+
+ // Signal the ScummVM debugger
+ _vm->_debugger->onFrame();
+ }
+}
+
+void EventsManager::delay(int cycles) {
+ uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE;
+ uint32 delayEnd = g_system->getMillis() + totalMilli;
+
+ while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) {
+ g_system->delayMillis(10);
+
+ pollEvents();
+ }
+}
+
+void EventsManager::waitForNextFrame() {
+ _mouseClicked = false;
+ _mouseReleased = false;
+ _mouseButtons = 0;
+
+ bool mouseClicked = false;
+ bool mouseReleased = false;
+ int mouseButtons = 0;
+
+ uint32 frameCtr = getFrameCounter();
+ while (!_vm->shouldQuit() && frameCtr == _frameCounter) {
+ delay(1);
+
+ mouseClicked |= _mouseClicked;
+ mouseReleased |= _mouseReleased;
+ mouseButtons |= _mouseButtons;
+ }
+
+ _mouseClicked = mouseClicked;
+ _mouseReleased = mouseReleased;
+ _mouseButtons = mouseButtons;
+ _mouseMoved |= _mouseClicked || _mouseReleased;
+}
+
+void EventsManager::initVars() {
+ _mousePos = Common::Point(-1, -1);
+ _mouseStatusCopy = _mouseStatus;
+ _vD2 = _vD8 = 0;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/events.h b/engines/mads/events.h
new file mode 100644
index 0000000000..3d7504c0bd
--- /dev/null
+++ b/engines/mads/events.h
@@ -0,0 +1,164 @@
+/* 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 MADS_EVENTS_H
+#define MADS_EVENTS_H
+
+#include "common/scummsys.h"
+#include "common/events.h"
+#include "common/stack.h"
+#include "mads/assets.h"
+#include "mads/sprites.h"
+
+namespace MADS {
+
+enum CursorType { CURSOR_NONE = 0, CURSOR_ARROW = 1, CURSOR_WAIT = 2, CURSOR_GO_DOWN = 3,
+ CURSOR_GO_UP = 4, CURSOR_GO_LEFT = 5, CURSOR_GO_RIGHT = 6 };
+
+#define GAME_FRAME_RATE 50
+#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
+
+class MADSEngine;
+
+class EventsManager {
+private:
+ MADSEngine *_vm;
+ uint32 _frameCounter;
+ uint32 _priorFrameTime;
+ Common::Point _mousePos;
+ Common::Point _currentPos;
+
+ /**
+ * Updates the cursor image when the current cursor changes
+ */
+ void changeCursor();
+
+ /**
+ * Checks for whether the next game frame number has been reached.
+ */
+ void checkForNextFrameCounter();
+public:
+ SpriteAsset *_cursorSprites;
+ CursorType _cursorId;
+ CursorType _newCursorId;
+ bool _mouseClicked;
+ bool _mouseReleased;
+ byte _mouseButtons;
+ bool _rightMousePressed;
+ int _mouseStatus;
+ int _vD2;
+ int _mouseStatusCopy;
+ bool _mouseMoved;
+ int _vD8;
+ Common::Stack<Common::Event> _pendingKeys;
+public:
+ /**
+ * Constructor
+ */
+ EventsManager(MADSEngine *vm);
+
+ /**
+ * Destructor
+ */
+ ~EventsManager();
+
+ /**
+ * Loads the sprite set containing the cursors
+ */
+ void loadCursors(const Common::String &spritesName);
+
+ /**
+ * Sets the cursor
+ */
+ void setCursor(CursorType cursorId);
+
+ /**
+ * Sets the cursor
+ */
+ void setCursor2(CursorType cursorId);
+
+ /**
+ * Show the mouse cursor
+ */
+ void showCursor();
+
+ /**
+ * Hide the mouse cursor
+ */
+ void hideCursor();
+
+ /**
+ * Returns if the mouse cursor is visible
+ */
+ bool isCursorVisible();
+
+ /**
+ * Shows the wait cursor
+ */
+ void waitCursor();
+
+ /**
+ * Free currently loaded cursors
+ */
+ void freeCursors();
+
+ /**
+ * Poll any pending events
+ */
+ void pollEvents();
+
+ /**
+ * Return the current mouse position
+ */
+ Common::Point mousePos() const { return _mousePos; }
+
+ /**
+ * Return the current mouse position
+ */
+ Common::Point currentPos() const { return _currentPos; }
+
+ /**
+ * Delay for a given number of frames
+ */
+ void delay(int amount);
+
+ /**
+ * Wait for the next frame
+ */
+ void waitForNextFrame();
+
+ /**
+ * Gets the current frame counter
+ */
+ uint32 getFrameCounter() const { return _frameCounter; }
+
+ void initVars();
+
+ /**
+ * Returns true if there's any pending keys to be processed
+ */
+ bool isKeyPressed() const { return !_pendingKeys.empty(); }
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_EVENTS_H */
diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp
new file mode 100644
index 0000000000..6af1346f01
--- /dev/null
+++ b/engines/mads/font.cpp
@@ -0,0 +1,252 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/font.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+MADSEngine *Font::_vm;
+
+Common::HashMap<Common::String, Font *> *Font::_fonts;
+
+uint8 Font::_fontColors[4];
+
+void Font::init(MADSEngine *vm) {
+ _vm = vm;
+ _fontColors[0] = 0xFF;
+ _fontColors[1] = 0xF;
+ _fontColors[2] = 7;
+ _fontColors[3] = 8;
+
+ _fonts = new Common::HashMap<Common::String, Font *>();
+}
+
+void Font::deinit() {
+ Common::HashMap<Common::String, Font *>::iterator i;
+ for (i = _fonts->begin(); i != _fonts->end(); ++i)
+ delete (*i)._value;
+
+ delete _fonts;
+}
+
+Font *Font::getFont(const Common::String &fontName) {
+ if (_fonts->contains(fontName)) {
+ return _fonts->getVal(fontName);
+ } else {
+ Font *font = new Font(fontName);
+ _fonts->setVal(fontName, font);
+ return font;
+ }
+}
+
+Font::Font() {
+ _charWidths = nullptr;
+ _charOffs = nullptr;
+ _charData = nullptr;
+ setFont(FONT_INTERFACE);
+}
+
+Font::Font(const Common::String &filename) {
+ _charWidths = nullptr;
+ _charOffs = nullptr;
+ _charData = nullptr;
+ setFont(filename);
+}
+
+Font::~Font() {
+ delete[] _charWidths;
+ delete[] _charOffs;
+ delete[] _charData;
+}
+
+void Font::setFont(const Common::String &filename) {
+ if (!_filename.empty() && (filename == _filename))
+ // Already using specified font, so don't bother reloading
+ return;
+
+ _filename = filename;
+
+ MadsPack fontData(filename, _vm);
+ Common::SeekableReadStream *fontFile = fontData.getItemStream(0);
+
+ _maxHeight = fontFile->readByte();
+ _maxWidth = fontFile->readByte();
+
+ _charWidths = new uint8[128];
+ // Char data is shifted by 1
+ _charWidths[0] = 0;
+ fontFile->read(_charWidths + 1, 127);
+ fontFile->readByte(); // remainder
+
+ _charOffs = new uint16[128];
+
+ uint startOffs = 2 + 128 + 256;
+ uint fontSize = fontFile->size() - startOffs;
+
+ // Char data is shifted by 1
+ _charOffs[0] = 0;
+ for (int i = 1; i < 128; i++)
+ _charOffs[i] = fontFile->readUint16LE() - startOffs;
+ fontFile->readUint16LE(); // remainder
+
+ _charData = new uint8[fontSize];
+ fontFile->read(_charData, fontSize);
+
+ delete fontFile;
+}
+
+void Font::setColors(uint8 v1, uint8 v2, uint8 v3, uint8 v4) {
+ _fontColors[0] = v1;
+ _fontColors[1] = v2;
+ _fontColors[2] = v3;
+ _fontColors[3] = v4;
+}
+
+void Font::setColorMode(SelectionMode mode) {
+ switch (mode) {
+ case SELMODE_UNSELECTED:
+ setColors(0xFF, 4, 4, 0);
+ break;
+ case SELMODE_HIGHLIGHTED:
+ setColors(0xFF, 5, 5, 0);
+ break;
+ case SELMODE_SELECTED:
+ setColors(0xFF, 6, 6, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+int Font::writeString(MSurface *surface, const Common::String &msg, const Common::Point &pt,
+ int spaceWidth, int width) {
+ int xEnd;
+ if (width > 0)
+ xEnd = MIN((int)surface->w, pt.x + width);
+ else
+ xEnd = surface->w;
+
+ int x = pt.x;
+ int y = pt.y;
+
+ int skipY = 0;
+ if (y < 0) {
+ skipY = -y;
+ y = 0;
+ }
+
+ int height = MAX(0, _maxHeight - skipY);
+ if (height == 0)
+ return x;
+
+ int bottom = y + height - 1;
+ if (bottom > surface->getHeight() - 1) {
+ height -= MIN(height, bottom - (surface->getHeight() - 1));
+ }
+
+ if (height <= 0)
+ return x;
+
+ byte *destPtr = surface->getBasePtr(x, y);
+ uint8 *oldDestPtr = destPtr;
+
+ int xPos = x;
+
+ const char *text = msg.c_str();
+ while (*text) {
+ char theChar = (*text++) & 0x7F;
+ int charWidth = _charWidths[(byte)theChar];
+
+ if (charWidth > 0) {
+
+ if (xPos + charWidth > xEnd)
+ return xPos;
+
+ uint8 *charData = &_charData[_charOffs[(byte)theChar]];
+ int bpp = getBpp(charWidth);
+
+ if (skipY != 0)
+ charData += bpp * skipY;
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < bpp; j++) {
+ if (*charData & 0xc0)
+ *destPtr = _fontColors[(*charData & 0xc0) >> 6];
+ destPtr++;
+ if (*charData & 0x30)
+ *destPtr = _fontColors[(*charData & 0x30) >> 4];
+ destPtr++;
+ if (*charData & 0x0C)
+ *destPtr = _fontColors[(*charData & 0x0C) >> 2];
+ destPtr++;
+ if (*charData & 0x03)
+ *destPtr = _fontColors[*charData & 0x03];
+ destPtr++;
+ charData++;
+ }
+
+ destPtr += surface->getWidth() - bpp * 4;
+
+ }
+
+ destPtr = oldDestPtr + charWidth + spaceWidth;
+ oldDestPtr = destPtr;
+
+ }
+
+ xPos += charWidth + spaceWidth;
+
+ }
+
+ return xPos;
+
+}
+
+int Font::getWidth(const Common::String &msg, int spaceWidth) {
+ int width = 0;
+ const char *text = msg.c_str();
+
+ if (msg.size() > 0) {
+ while (*text)
+ width += _charWidths[*text++ & 0x7F] + spaceWidth;
+ width -= spaceWidth;
+ }
+
+ return width;
+}
+
+int Font::getBpp(int charWidth) {
+ if (charWidth > 12)
+ return 4;
+ else if (charWidth > 8)
+ return 3;
+ else if (charWidth > 4)
+ return 2;
+ else
+ return 1;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/font.h b/engines/mads/font.h
new file mode 100644
index 0000000000..47df647637
--- /dev/null
+++ b/engines/mads/font.h
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_FONT_H
+#define MADS_FONT_H
+
+#include "common/scummsys.h"
+#include "common/hashmap.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+#define FONT_CONVERSATION "*FONTCONV.FF"
+#define FONT_INTERFACE "*FONTINTR.FF"
+#define FONT_MAIN "*FONTMAIN.FF"
+#define FONT_MENU "*FONTMENU.FF" // Not in Rex (uses bitmap files for menu strings)
+#define FONT_MISC "*FONTMISC.FF"
+#define FONT_TELE "*FONTTELE.FF" // Not in Phantom
+#define FONT_PHAN "*FONTPHAN.FF" // Phantom only
+
+enum SelectionMode {
+ SELMODE_UNSELECTED = 0, SELMODE_HIGHLIGHTED = 1, SELMODE_SELECTED = 2
+};
+
+class MADSEngine;
+
+class Font {
+private:
+ static uint8 _fontColors[4];
+ static MADSEngine *_vm;
+ static Common::HashMap<Common::String, Font *> *_fonts;
+public:
+ /**
+ * Initialize the font system
+ */
+ static void init(MADSEngine *vm);
+
+ /**
+ * Free up the resources used by the font
+ */
+ static void deinit();
+
+ /**
+ * Returns a new Font instance using the specified font name
+ */
+ static Font *getFont(const Common::String &fontName);
+private:
+ uint8 _maxWidth, _maxHeight;
+ uint8 *_charWidths;
+ uint16 *_charOffs;
+ uint8 *_charData;
+ Common::String _filename;
+
+ int getBpp(int charWidth);
+
+ void setFont(const Common::String &filename);
+public:
+ Font();
+ Font(const Common::String &filename);
+ virtual ~Font();
+
+ void setColors(uint8 v1, uint8 v2, uint8 v3, uint8 v4);
+ void setColorMode(SelectionMode mode);
+
+ int maxWidth() const { return _maxWidth; }
+ int getWidth(const Common::String &msg, int spaceWidth = -1);
+ int getHeight() const { return _maxHeight; }
+ int writeString(MSurface *surface, const Common::String &msg, const Common::Point &pt,
+ int spaceWidth = 0, int width = 0);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_FONT_H */
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
new file mode 100644
index 0000000000..05dd932482
--- /dev/null
+++ b/engines/mads/game.cpp
@@ -0,0 +1,608 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/memstream.h"
+#include "common/serializer.h"
+#include "graphics/palette.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/game.h"
+#include "mads/game_data.h"
+#include "mads/events.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/resources.h"
+#include "mads/dragonsphere/game_dragonsphere.h"
+#include "mads/nebular/game_nebular.h"
+#include "mads/phantom/game_phantom.h"
+
+namespace MADS {
+
+Game *Game::init(MADSEngine *vm) {
+ switch (vm->getGameID()) {
+ case GType_RexNebular:
+ return new Nebular::GameNebular(vm);
+ case GType_Dragonsphere:
+ return new Dragonsphere::GameDragonsphere(vm);
+ case GType_Phantom:
+ return new Phantom::GamePhantom(vm);
+ default:
+ error("Game: Unknown game");
+ }
+
+ return nullptr;
+}
+
+Game::Game(MADSEngine *vm)
+ : _vm(vm), _surface(nullptr), _objects(vm), _scene(vm),
+ _screenObjects(vm), _player(vm) {
+ _sectionNumber = _priorSectionNumber = 0;
+ _loadGameSlot = -1;
+ _lastSave = -1;
+ _saveFile = nullptr;
+ _statusFlag = 0;
+ _sectionHandler = nullptr;
+ _sectionNumber = 1;
+ _priorSectionNumber = 0;
+ _currentSectionNumber = -1;
+ _kernelMode = KERNEL_GAME_LOAD;
+ _quoteEmergency = false;
+ _vocabEmergency = false;
+ _aaName = "*I0.AA";
+ _priorFrameTimer = 0;
+ _anyEmergency = false;
+ _triggerMode = SEQUENCE_TRIGGER_PARSER;
+ _triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _trigger = 0;
+ _winStatus = 0;
+ _widepipeCtr = 0;
+ _fx = kTransitionNone;
+
+ // Load the inventory object list
+ _objects.load();
+ if (_objects._inventoryList.size() > 0)
+ // At least one item in default inventory, so select first item for display
+ _scene._userInterface._selectedInvIndex = 0;
+
+ // Load the quotes
+ loadQuotes();
+}
+
+Game::~Game() {
+ delete _saveFile;
+ delete _surface;
+ delete _sectionHandler;
+}
+
+void Game::run() {
+ initializeGlobals();
+
+ // If requested, load a savegame instead of showing the intro
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 999)
+ _loadGameSlot = saveSlot;
+ }
+
+ _statusFlag = true;
+ int protectionResult = -1;
+
+ if (_loadGameSlot == -1) {
+ protectionResult = checkCopyProtection();
+ switch (protectionResult) {
+ case PROTECTION_FAIL:
+ // Copy protection failed
+ _scene._nextSceneId = 804;
+ break;
+ case PROTECTION_ESCAPE:
+ // User escaped out of copy protection dialog
+ _vm->quitGame();
+ break;
+ default:
+ // Copy protection check succeeded
+ _scene._nextSceneId = 101;
+ _scene._priorSceneId = -1;
+ break;
+ }
+ }
+
+ // Get the initial starting time for the first scene
+ _scene._frameStartTime = _vm->_events->getFrameCounter();
+
+ if (_saveFile == nullptr && protectionResult != -1 && protectionResult != -2) {
+ initSection(_sectionNumber);
+ _statusFlag = true;
+
+ _vm->_dialogs->_pendingDialog = DIALOG_DIFFICULTY;
+ _vm->_dialogs->showDialog();
+ _vm->_dialogs->_pendingDialog = DIALOG_NONE;
+
+ _priorSectionNumber = 0;
+ _priorSectionNumber = -1;
+ _scene._priorSceneId = 0;
+ _scene._currentSceneId = -1;
+ }
+
+ if (protectionResult != 1 && protectionResult != 2) {
+ initializeGlobals();
+ }
+
+ if (_statusFlag)
+ gameLoop();
+}
+
+void Game::splitQuote(const Common::String &source, Common::String &line1, Common::String &line2) {
+ // Make the first line up the end of the word at the half-way point
+ const char *strP = source.c_str() + source.size() / 2;
+ while (*strP != ' ') ++strP;
+
+ line1 = Common::String(source.c_str(), strP);
+
+ // The rest of the string goes in the second line
+ while (*strP == ' ') ++strP;
+ line2 = Common::String(strP);
+}
+
+void Game::gameLoop() {
+ while (!_vm->shouldQuit() && _statusFlag) {
+ if (_loadGameSlot != -1) {
+ loadGame(_loadGameSlot);
+ _loadGameSlot = -1;
+ }
+
+ setSectionHandler();
+ _sectionHandler->preLoadSection();
+ initSection(_sectionNumber);
+ _vm->_sound->init(_sectionNumber);
+ _sectionHandler->postLoadSection();
+
+ _scene._spriteSlots.reset();
+
+ if (_sectionNumber == _currentSectionNumber)
+ sectionLoop();
+
+ _player.releasePlayerSprites();
+ assert(_scene._sprites._assetCount == 0);
+
+ _vm->_palette->unlock();
+ _vm->_events->waitCursor();
+ _vm->_events->freeCursors();
+ _vm->_sound->closeDriver();
+ }
+
+ _vm->_palette->close();
+}
+
+void Game::sectionLoop() {
+ while (!_vm->shouldQuit() && _statusFlag && (_sectionNumber == _currentSectionNumber)) {
+ _kernelMode = KERNEL_ROOM_PRELOAD;
+ _player._spritesChanged = true;
+ _quoteEmergency = false;
+ _vocabEmergency = false;
+ _vm->_events->waitCursor();
+
+ _scene.clearVocab();
+ _scene._dynamicHotspots.clear();
+ _scene.loadSceneLogic();
+
+ _player._walkAnywhere = false;
+ _player._stepEnabled = true;
+ _player._visible = true;
+ _vm->_dialogs->_defaultPosition = Common::Point(-1, -1);
+ _visitedScenes.add(_scene._nextSceneId);
+
+ // Reset the user interface
+ _screenObjects._forceRescan = true;
+ _screenObjects._inputMode = kInputBuildingSentences;
+ _scene._userInterface._scrollbarActive = SCROLLBAR_NONE;
+
+ _player._loadsFirst = true;
+
+ _scene._sceneLogic->setup();
+ if (_player._spritesChanged || _player._loadsFirst) {
+ if (_player._spritesLoaded)
+ _player.releasePlayerSprites();
+ _vm->_palette->resetGamePalette(18, 10);
+ _scene._spriteSlots.reset();
+ } else {
+ _vm->_palette->initPalette();
+ }
+
+ // Set up scene palette usage
+ _scene._scenePaletteUsage.clear();
+ _scene._scenePaletteUsage.push_back(PaletteUsage::UsageEntry(0xF0));
+ _scene._scenePaletteUsage.push_back(PaletteUsage::UsageEntry(0xF1));
+ _scene._scenePaletteUsage.push_back(PaletteUsage::UsageEntry(0xF2));
+ _vm->_palette->_paletteUsage.load(&_scene._scenePaletteUsage);
+
+ if (!_player._spritesLoaded && _player._loadsFirst) {
+ if (_player.loadSprites(""))
+ _vm->quitGame();
+ _player._loadedFirst = true;
+ }
+
+ _scene.loadScene(_scene._nextSceneId, _aaName, 0);
+ _vm->_sound->pauseNewCommands();
+
+ if (!_player._spritesLoaded) {
+ if (_player.loadSprites(""))
+ _vm->quitGame();
+ _player._loadedFirst = false;
+ }
+
+ _vm->_events->initVars();
+ _scene._userInterface._highlightedCommandIndex = -1;
+ _scene._userInterface._highlightedInvIndex = -1;
+ _scene._userInterface._highlightedItemVocabIndex = -1;
+
+ _scene._action.clear();
+ _player.setFinalFacing();
+ _player._facing = _player._turnToFacing;
+ _player.cancelCommand();
+ _kernelMode = KERNEL_ROOM_INIT;
+
+ switch (_vm->_screenFade) {
+ case SCREEN_FADE_SMOOTH:
+ _fx = kTransitionFadeOutIn;
+ break;
+ case SCREEN_FADE_FAST:
+ _fx = kCenterVertTransition;
+ break;
+ default:
+ _fx = kTransitionNone;
+ break;
+ }
+
+ _trigger = 0;
+ _priorFrameTimer = _scene._frameStartTime;
+
+ // Call the scene logic for entering the given scene
+ _triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene._sceneLogic->enter();
+
+ // If in the middle of restoring a game, handle the rest of the loading
+ if (_saveFile != nullptr) {
+ Common::Serializer s(_saveFile, nullptr);
+ synchronize(s, false);
+ delete _saveFile;
+ _saveFile = nullptr;
+ }
+
+ // Set player data
+ _player._targetPos = _player._playerPos;
+ _player._turnToFacing = _player._facing;
+ _player._targetFacing = _player._facing;
+ _player.selectSeries();
+ _player.updateFrame();
+
+ _player._beenVisible = _player._visible;
+ _player._special = _scene.getDepthHighBits(_player._playerPos);
+ _player._priorTimer = _scene._frameStartTime - _player._ticksAmount;
+ _player.idle();
+
+ if (_scene._userInterface._selectedInvIndex >= 0) {
+ _scene._userInterface.loadInventoryAnim(
+ _objects._inventoryList[_scene._userInterface._selectedInvIndex]);
+ } else {
+ _scene._userInterface.noInventoryAnim();
+ }
+
+ _kernelMode = KERNEL_ACTIVE_CODE;
+ _scene._roomChanged = false;
+
+ if ((_quoteEmergency || _vocabEmergency) && !_anyEmergency) {
+ _scene._currentSceneId = _scene._priorSceneId;
+ _anyEmergency = true;
+ } else {
+ _anyEmergency = false;
+ _scene.loop();
+ }
+
+ _vm->_events->waitCursor();
+ _kernelMode = KERNEL_ROOM_PRELOAD;
+
+ delete _scene._activeAnimation;
+ _scene._activeAnimation = nullptr;
+
+ _scene._reloadSceneFlag = false;
+
+ _scene._userInterface.noInventoryAnim();
+ _scene.removeSprites();
+
+ if (!_player._loadedFirst) {
+ _player._spritesLoaded = false;
+ _player._spritesChanged = true;
+ }
+
+ // Clear the scene
+ _scene.freeCurrentScene();
+ _sectionNumber = _scene._nextSceneId / 100;
+
+ // Check whether to show a dialog
+ checkShowDialog();
+ }
+}
+
+void Game::initSection(int sectionNumber) {
+ _priorSectionNumber = _currentSectionNumber;
+ _currentSectionNumber = sectionNumber;
+
+ _vm->_palette->resetGamePalette(18, 10);
+ _vm->_palette->setLowRange();
+
+ if (_scene._layer == LAYER_GUI)
+ _vm->_palette->setPalette(_vm->_palette->_mainPalette, 0, 4);
+
+ _vm->_events->loadCursors("*CURSOR.SS");
+
+ assert(_vm->_events->_cursorSprites);
+ _vm->_events->setCursor2((_vm->_events->_cursorSprites->getCount() <= 1) ?
+ CURSOR_ARROW : CURSOR_WAIT);
+}
+
+void Game::loadQuotes() {
+ File f("*QUOTES.DAT");
+
+ Common::String msg;
+ while (true) {
+ uint8 b = f.readByte();
+
+ msg += b;
+ if (f.eos() || b == '\0') {
+ // end of string, add it to the strings list
+ _quotes.push_back(msg);
+ msg = "";
+ }
+
+ if (f.eos()) break;
+ }
+
+ f.close();
+}
+
+Common::StringArray Game::getMessage(uint32 id) {
+ File f("*MESSAGES.DAT");
+ int count = f.readUint16LE();
+
+ for (int idx = 0; idx < count; ++idx) {
+ uint32 itemId = f.readUint32LE();
+ uint32 offset = f.readUint32LE();
+ uint16 size = f.readUint16LE();
+
+ if (itemId == id) {
+ // Get the source buffer size
+ uint16 sizeIn;
+ if (idx == (count - 1)) {
+ sizeIn = f.size() - offset;
+ } else {
+ f.skip(4);
+ uint32 nextOffset = f.readUint32LE();
+ sizeIn = nextOffset - offset;
+ }
+
+ // Get the compressed data
+ f.seek(offset);
+ byte *bufferIn = new byte[sizeIn];
+ f.read(bufferIn, sizeIn);
+
+ // Decompress it
+ char *bufferOut = new char[size];
+ FabDecompressor fab;
+ fab.decompress(bufferIn, sizeIn, (byte *)bufferOut, size);
+
+ // Form the output string list
+ Common::StringArray result;
+ const char *p = bufferOut;
+ while (p < (bufferOut + size)) {
+ result.push_back(p);
+ p += strlen(p) + 1;
+ }
+
+ delete[] bufferIn;
+ delete[] bufferOut;
+ return result;
+ }
+ }
+
+ error("Invalid message Id specified");
+}
+
+static const char *const DEBUG_STRING = "WIDEPIPE";
+
+void Game::handleKeypress(const Common::Event &event) {
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ if (_widepipeCtr == 8) {
+ // Implement original game cheating keys here someday
+ } else {
+ if (event.kbd.keycode == (Common::KEYCODE_a +
+ (DEBUG_STRING[_widepipeCtr] - 'a'))) {
+ if (++_widepipeCtr == 8) {
+ MessageDialog *dlg = new MessageDialog(_vm, 2,
+ "CHEATING ENABLED", "(for your convenience).");
+ dlg->show();
+ delete dlg;
+ }
+ }
+ }
+ }
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F1:
+ _vm->_dialogs->_pendingDialog = DIALOG_GAME_MENU;
+ break;
+ case Common::KEYCODE_F5:
+ _vm->_dialogs->_pendingDialog = DIALOG_SAVE;
+ break;
+ case Common::KEYCODE_F7:
+ _vm->_dialogs->_pendingDialog = DIALOG_RESTORE;
+ break;
+ default:
+ break;
+ }
+
+ warning("TODO: handleKeypress - %d", (int)event.kbd.keycode);
+}
+
+void Game::synchronize(Common::Serializer &s, bool phase1) {
+ if (phase1) {
+ s.syncAsSint16LE(_fx);
+ s.syncAsSint16LE(_trigger);
+ s.syncAsUint16LE(_triggerSetupMode);
+ s.syncAsUint16LE(_triggerMode);
+ s.syncString(_aaName);
+ s.syncAsSint16LE(_lastSave);
+
+ _scene.synchronize(s);
+ _objects.synchronize(s);
+ _visitedScenes.synchronize(s);
+ _player.synchronize(s);
+ _screenObjects.synchronize(s);
+ } else {
+ // Load scene specific data for the loaded scene
+ _scene._sceneLogic->synchronize(s);
+ }
+}
+
+void Game::loadGame(int slotNumber) {
+ _saveFile = g_system->getSavefileManager()->openForLoading(
+ _vm->generateSaveName(slotNumber));
+
+ Common::Serializer s(_saveFile, nullptr);
+
+ // Load the savaegame header
+ MADSSavegameHeader header;
+ if (!readSavegameHeader(_saveFile, header))
+ error("Invalid savegame");
+
+ if (header._thumbnail) {
+ header._thumbnail->free();
+ delete header._thumbnail;
+ }
+
+ // Load most of the savegame data with the exception of scene specific info
+ synchronize(s, true);
+
+ // Set up section/scene and other initial states for post-load
+ _currentSectionNumber = -2;
+ _scene._currentSceneId = -2;
+ _sectionNumber = _scene._nextSceneId / 100;
+ _scene._frameStartTime = _vm->_events->getFrameCounter();
+ _vm->_screen._shakeCountdown = -1;
+
+ // Default the selected inventory item to the first one, if the player has any
+ _scene._userInterface._selectedInvIndex = _objects._inventoryList.size() > 0 ? 0 : -1;
+
+ // Set player sprites sets flags
+ _player._spritesLoaded = false;
+ _player._spritesChanged = true;
+}
+
+void Game::saveGame(int slotNumber, const Common::String &saveName) {
+ Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
+ _vm->generateSaveName(slotNumber));
+
+ MADSSavegameHeader header;
+ header._saveName = saveName;
+ writeSavegameHeader(out, header);
+
+ Common::Serializer s(nullptr, out);
+ synchronize(s, true);
+ synchronize(s, false);
+
+ out->finalize();
+ delete out;
+}
+
+const char *const SAVEGAME_STR = "MADS";
+#define SAVEGAME_STR_SIZE 4
+
+bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header) {
+ char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
+ header._thumbnail = nullptr;
+
+ // Validate the header Id
+ in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
+ if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE))
+ return false;
+
+ header._version = in->readByte();
+ if (header._version > MADS_SAVEGAME_VERSION)
+ return false;
+
+ // Read in the string
+ header._saveName.clear();
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
+
+ // Get the thumbnail
+ header._thumbnail = Graphics::loadThumbnail(*in);
+ if (!header._thumbnail)
+ return false;
+
+ // Read in save date/time
+ header._year = in->readSint16LE();
+ header._month = in->readSint16LE();
+ header._day = in->readSint16LE();
+ header._hour = in->readSint16LE();
+ header._minute = in->readSint16LE();
+ header._totalFrames = in->readUint32LE();
+
+ return true;
+}
+
+void Game::writeSavegameHeader(Common::OutSaveFile *out, MADSSavegameHeader &header) {
+ // Write out a savegame header
+ out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
+
+ out->writeByte(MADS_SAVEGAME_VERSION);
+
+ // Write savegame name
+ out->write(header._saveName.c_str(), header._saveName.size());
+ out->writeByte('\0');
+
+ // Get the active palette
+ uint8 thumbPalette[256 * 3];
+ g_system->getPaletteManager()->grabPalette(thumbPalette, 0, 256);
+
+ // Create a thumbnail and save it
+ Graphics::Surface *thumb = new Graphics::Surface();
+ ::createThumbnail(thumb, _vm->_screen.getData(), MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, thumbPalette);
+ Graphics::saveThumbnail(*out, *thumb);
+ thumb->free();
+ delete thumb;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ out->writeSint16LE(td.tm_year + 1900);
+ out->writeSint16LE(td.tm_mon + 1);
+ out->writeSint16LE(td.tm_mday);
+ out->writeSint16LE(td.tm_hour);
+ out->writeSint16LE(td.tm_min);
+ out->writeUint32LE(_vm->_events->getFrameCounter());
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/game.h b/engines/mads/game.h
new file mode 100644
index 0000000000..1b06f847d0
--- /dev/null
+++ b/engines/mads/game.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 MADS_GAME_H
+#define MADS_GAME_H
+
+#include "common/scummsys.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/serializer.h"
+#include "mads/audio.h"
+#include "mads/scene.h"
+#include "mads/game_data.h"
+#include "mads/globals.h"
+#include "mads/inventory.h"
+#include "mads/player.h"
+#include "mads/screen.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+enum {
+ PLAYER_INVENTORY = 2
+};
+
+enum KernelMode {
+ KERNEL_GAME_LOAD = 0, KERNEL_SECTION_PRELOAD = 1, KERNEL_SECTION_INIT = 2,
+ KERNEL_ROOM_PRELOAD = 3, KERNEL_ROOM_INIT = 4, KERNEL_ACTIVE_CODE = 5
+};
+
+enum ProtectionResult {
+ PROTECTION_SUCCEED = 0, PROTECTION_FAIL = 1, PROTECTION_ESCAPE = 2
+};
+
+#define MADS_SAVEGAME_VERSION 1
+
+struct MADSSavegameHeader {
+ uint8 _version;
+ Common::String _saveName;
+ Graphics::Surface *_thumbnail;
+ int _year, _month, _day;
+ int _hour, _minute;
+ int _totalFrames;
+};
+
+class Game {
+private:
+ /**
+ * Main game loop
+ */
+ void gameLoop();
+
+ /**
+ * Inner game loop for executing gameplay within a game section
+ */
+ void sectionLoop();
+
+ /**
+ * Load quotes data
+ */
+ void loadQuotes();
+protected:
+ MADSEngine *_vm;
+ MSurface *_surface;
+ int _statusFlag;
+ Common::StringArray _quotes;
+ bool _quoteEmergency;
+ bool _vocabEmergency;
+ bool _anyEmergency;
+ int _lastSave;
+ Common::String _saveName;
+ Common::InSaveFile *_saveFile;
+
+ /**
+ * Constructor
+ */
+ Game(MADSEngine *vm);
+
+ /**
+ * Initializes the current section number of the game
+ */
+ void initSection(int sectionNumber);
+
+ //@{
+ /** @name Virtual Method list */
+
+ /**
+ * Perform any copy protection check
+ */
+ virtual ProtectionResult checkCopyProtection() = 0;
+
+ /**
+ * Initializes global variables for a new game
+ */
+ virtual void initializeGlobals() = 0;
+
+ /**
+ * Set up the section handler specific to each section
+ */
+ virtual void setSectionHandler() = 0;
+
+ /**
+ * Checks for whether to show a dialog
+ */
+ virtual void checkShowDialog() = 0;
+
+ //@}
+
+public:
+ static Game *init(MADSEngine *vm);
+
+public:
+ Player _player;
+ ScreenObjects _screenObjects;
+ int _sectionNumber;
+ int _priorSectionNumber;
+ int _currentSectionNumber;
+ InventoryObjects _objects;
+ SectionHandler *_sectionHandler;
+ VisitedScenes _visitedScenes;
+ Scene _scene;
+ KernelMode _kernelMode;
+ int _trigger;
+ ScreenTransition _fx;
+ TriggerMode _triggerMode;
+ TriggerMode _triggerSetupMode;
+ uint32 _priorFrameTimer;
+ Common::String _aaName;
+ int _winStatus;
+ int _widepipeCtr;
+ int _loadGameSlot;
+
+public:
+ virtual ~Game();
+
+ /**
+ * Main outer loop for the game
+ */
+ void run();
+
+ /**
+ * Return the number of quotes
+ */
+ uint32 getQuotesSize() { return _quotes.size(); }
+
+ /**
+ * Get a specific quote string
+ */
+ const Common::String &getQuote(uint32 index) { return _quotes[index - 1]; }
+
+ /**
+ * Split a quote into two lines for display on-screen
+ */
+ void splitQuote(const Common::String &source, Common::String &line1, Common::String &line2);
+
+ Common::StringArray getMessage(uint32 id);
+
+ /**
+ * Returns the globals for the game
+ */
+ virtual Globals &globals() = 0;
+
+ /**
+ * Standard object handling across the game
+ */
+ virtual void doObjectAction() = 0;
+
+ /**
+ * Fallback handler for any action that isn't explicitly handled
+ */
+ virtual void unhandledAction() = 0;
+
+ /**
+ * Global game step
+ */
+ virtual void step() = 0;
+
+ /**
+ * Synchronize the game data
+ * @param s Serializer
+ * @param phase1 If true, it's synchronizing the basic scene information
+ */
+ virtual void synchronize(Common::Serializer &s, bool phase1);
+
+ // DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs
+ void clearQuotes() {}
+ void loadQuoteRange(int startNum, int endNum) {}
+ void loadQuoteSet(...) {}
+ void loadQuote(int quoteNum) {}
+
+ /**
+ * Handle a keyboard event
+ */
+ void handleKeypress(const Common::Event &event);
+
+ /**
+ * Starts a savegame loading.
+ * @remarks Due to the way the engine is implemented, loading is done in two
+ * parts, the second part after the specific scene has been loaded
+ */
+ void loadGame(int slotNumber);
+
+ /**
+ * Save the current game
+ */
+ void saveGame(int slotNumber, const Common::String &saveName);
+
+ /**
+ * Write out a savegame header
+ */
+ void writeSavegameHeader(Common::OutSaveFile *out, MADSSavegameHeader &header);
+
+ /**
+ * Read in a savegame header
+ */
+ static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_GAME_H */
diff --git a/engines/mads/game_data.cpp b/engines/mads/game_data.cpp
new file mode 100644
index 0000000000..0e2dcec70f
--- /dev/null
+++ b/engines/mads/game_data.cpp
@@ -0,0 +1,54 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/game.h"
+#include "mads/nebular/game_nebular.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/resources.h"
+
+namespace MADS {
+
+void VisitedScenes::add(int sceneId) {
+ _sceneRevisited = exists(sceneId);
+
+ if (!_sceneRevisited)
+ push_back(sceneId);
+}
+
+bool VisitedScenes::exists(int sceneId) {
+ for (uint i = 0; i < size(); ++i) {
+ if ((*this)[i] == sceneId)
+ return true;
+ }
+
+ return false;
+}
+
+void VisitedScenes::synchronize(Common::Serializer &s) {
+ SynchronizedList::synchronize(s);
+ s.syncAsByte(_sceneRevisited);
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/game_data.h b/engines/mads/game_data.h
new file mode 100644
index 0000000000..f15cd1a8f0
--- /dev/null
+++ b/engines/mads/game_data.h
@@ -0,0 +1,73 @@
+/* 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 MADS_GAME_DATA_H
+#define MADS_GAME_DATA_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/resources.h"
+
+namespace MADS {
+
+class MADSEngine;
+class Game;
+
+class VisitedScenes : public SynchronizedList {
+public:
+ /**
+ * Stores true when a previously visited scene is revisited
+ */
+ bool _sceneRevisited;
+
+ /**
+ * Returns true if a given Scene Id exists in the listed of previously visited scenes.
+ */
+ bool exists(int sceneId);
+
+ /**
+ * Adds a scene Id to the list of previously visited scenes, if it doesn't already exist
+ */
+ void add(int sceneId);
+
+ /**
+ * Synchronizes the list
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+class SectionHandler {
+protected:
+ MADSEngine *_vm;
+public:
+ SectionHandler(MADSEngine *vm) : _vm(vm) {}
+ virtual ~SectionHandler() {}
+
+ virtual void preLoadSection() = 0;
+ virtual void sectionPtr2() = 0;
+ virtual void postLoadSection() = 0;
+ virtual void step() {}
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_GAME_DATA_H */
diff --git a/engines/mads/globals.cpp b/engines/mads/globals.cpp
new file mode 100644
index 0000000000..1d088992ea
--- /dev/null
+++ b/engines/mads/globals.cpp
@@ -0,0 +1,33 @@
+/* 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 "common/scummsys.h"
+#include "mads/globals.h"
+
+namespace MADS {
+
+void Globals::reset() {
+ for (uint i = 0; i < size(); ++i)
+ (*this)[i] = 0;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/globals.h b/engines/mads/globals.h
new file mode 100644
index 0000000000..a6c9b628dd
--- /dev/null
+++ b/engines/mads/globals.h
@@ -0,0 +1,47 @@
+/* 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 MADS_GLOBALS_H
+#define MADS_GLOBALS_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/serializer.h"
+#include "mads/resources.h"
+
+namespace MADS {
+
+class Globals : public SynchronizedList {
+public:
+ Globals() {}
+
+ virtual ~Globals() {}
+
+ /*
+ * Resets all the globals to empty
+ */
+ void reset();
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_GLOBALS_H */
diff --git a/engines/mads/hotspots.cpp b/engines/mads/hotspots.cpp
new file mode 100644
index 0000000000..365f30985b
--- /dev/null
+++ b/engines/mads/hotspots.cpp
@@ -0,0 +1,207 @@
+/* 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 "mads/mads.h"
+#include "mads/hotspots.h"
+
+namespace MADS {
+
+DynamicHotspot::DynamicHotspot() {
+ _seqIndex = 0;
+ _facing = FACING_NONE;
+ _descId = 0;
+ _verbId = 0;
+ _articleNumber = 0;
+ _cursor = CURSOR_NONE;
+ _active = false;
+}
+
+void DynamicHotspot::synchronize(Common::Serializer &s) {
+
+}
+
+/*------------------------------------------------------------------------*/
+
+DynamicHotspots::DynamicHotspots(MADSEngine *vm) : _vm(vm) {
+ for (int i = 0; i < DYNAMIC_HOTSPOTS_SIZE; ++i) {
+ DynamicHotspot rec;
+ rec._active = false;
+ _entries.push_back(rec);
+ }
+
+ _changed = true;
+ _count = 0;
+}
+
+int DynamicHotspots::add(int descId, int verbId, int seqIndex, const Common::Rect &bounds) {
+ // Find a free slot
+ uint idx = 0;
+ while ((idx < _entries.size()) && _entries[idx]._active)
+ ++idx;
+ if (idx == _entries.size())
+ error("DynamicHotspots overflow");
+
+ _entries[idx]._active = true;
+ _entries[idx]._descId = descId;
+ _entries[idx]._seqIndex = seqIndex;
+ _entries[idx]._bounds = bounds;
+ _entries[idx]._feetPos = Common::Point(-3, 0);
+ _entries[idx]._facing = FACING_NONE;
+ _entries[idx]._verbId = verbId;
+ _entries[idx]._articleNumber = PREP_IN;
+ _entries[idx]._cursor = CURSOR_NONE;
+
+ ++_count;
+ _changed = true;
+
+ if (seqIndex >= 0)
+ _vm->_game->_scene._sequences[seqIndex]._dynamicHotspotIndex = idx;
+
+ return idx;
+}
+
+int DynamicHotspots::setPosition(int index, const Common::Point &pos, Facing facing) {
+ if (index >= 0) {
+ _entries[index]._feetPos = pos;
+ _entries[index]._facing = facing;
+ }
+
+ return index;
+}
+
+int DynamicHotspots::setCursor(int index, CursorType cursor) {
+ if (index >= 0)
+ _entries[index]._cursor = cursor;
+
+ return index;
+}
+
+void DynamicHotspots::remove(int index) {
+ Scene &scene = _vm->_game->_scene;
+
+ if (index >= 0 && _entries[index]._active) {
+ if (_entries[index]._seqIndex >= 0)
+ scene._sequences[_entries[index]._seqIndex]._dynamicHotspotIndex = -1;
+ _entries[index]._active = false;
+
+ --_count;
+ _changed = true;
+ }
+}
+
+void DynamicHotspots::clear() {
+ for (uint i = 0; i < _entries.size(); ++i)
+ _entries[i]._active = false;
+
+ _changed = false;
+ _count = 0;
+}
+
+void DynamicHotspots::reset() {
+ for (uint i = 0; i < _entries.size(); ++i)
+ remove(i);
+
+ _count = 0;
+ _changed = false;
+}
+
+void DynamicHotspots::refresh() {
+ // Reset the screen objects back to only contain UI elements
+ ScreenObjects &scrObjects = _vm->_game->_screenObjects;
+ scrObjects.resize(scrObjects._uiCount);
+
+ // Loop through adding hotspots
+ for (uint i = 0; i < _entries.size(); ++i) {
+ DynamicHotspot &dh = (*this)[i];
+
+ if ((*this)[i]._active) {
+ switch (scrObjects._inputMode) {
+ case kInputBuildingSentences:
+ case kInputLimitedSentences:
+ scrObjects.add(dh._bounds, _vm->_game->_scene._layer, CAT_12, dh._descId);
+ scrObjects._forceRescan = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // Reset the list's changed flag
+ _changed = false;
+}
+
+void DynamicHotspots::synchronize(Common::Serializer &s) {
+ int count = _entries.size();
+ s.syncAsSint16LE(count);
+
+ // The MIN in the below loop is a workaround to fix earlier savegame
+ // loading accidentally adding new dynamic hotspots to the fixed list
+ for (int i = 0; i < count; ++i) {
+ _entries[MIN(i, (int)_entries.size() - 1)].synchronize(s);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Hotspot::Hotspot() {
+ _facing = FACING_NONE;
+ _articleNumber = 0;
+ _cursor = CURSOR_NONE;
+ _vocabId = 0;
+ _verbId = 0;
+ _active = false;
+}
+
+Hotspot::Hotspot(Common::SeekableReadStream &f, bool isV2) {
+ _bounds.left = f.readSint16LE();
+ _bounds.top = f.readSint16LE();
+ _bounds.right = f.readSint16LE();
+ _bounds.bottom = f.readSint16LE();
+ _feetPos.x = f.readSint16LE();
+ _feetPos.y = f.readSint16LE();
+ _facing = (Facing)f.readByte();
+ _articleNumber = f.readByte();
+ _active = f.readByte() != 0;
+ _cursor = (CursorType)f.readByte();
+ if (isV2) {
+ // This looks to be some sort of bitmask. Perhaps it signifies
+ // the valid verbs for this hotspot
+ f.skip(2); // unknown
+ }
+ _vocabId = f.readUint16LE();
+ _verbId = f.readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+void Hotspots::activate(int vocabId, bool active) {
+ for (uint idx = 0; idx < size(); ++idx) {
+ Hotspot &hotspot = (*this)[idx];
+ if (hotspot._vocabId == vocabId) {
+ hotspot._active = active;
+ _vm->_game->_screenObjects.setActive(CAT_HOTSPOT, idx, active);
+ }
+ }
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/hotspots.h b/engines/mads/hotspots.h
new file mode 100644
index 0000000000..5fd910e1aa
--- /dev/null
+++ b/engines/mads/hotspots.h
@@ -0,0 +1,114 @@
+/* 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 MADS_HOTSPOTS_H
+#define MADS_HOTSPOTS_H
+
+#include "common/scummsys.h"
+#include "mads/events.h"
+#include "mads/player.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+class DynamicHotspot {
+public:
+ bool _active;
+ int _seqIndex;
+ Common::Rect _bounds;
+ Common::Point _feetPos;
+ Facing _facing;
+ int _descId;
+ int _verbId;
+ int _articleNumber;
+ CursorType _cursor;
+
+ /**
+ * Constructor
+ */
+ DynamicHotspot();
+
+ /**
+ * Synchronize the data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+#define DYNAMIC_HOTSPOTS_SIZE 8
+
+class DynamicHotspots {
+private:
+ MADSEngine *_vm;
+ Common::Array<DynamicHotspot> _entries;
+ int _count;
+public:
+ bool _changed;
+public:
+ DynamicHotspots(MADSEngine *vm);
+
+ Common::Array<MADS::DynamicHotspot>::size_type size() const { return _entries.size(); }
+ DynamicHotspot &operator[](uint idx) { return _entries[idx]; }
+ int add(int descId, int verbId, int seqIndex, const Common::Rect &bounds);
+ int setPosition(int index, const Common::Point &pos, Facing facing);
+ int setCursor(int index, CursorType cursor);
+ void remove(int index);
+ void clear();
+ void reset();
+ void refresh();
+
+ /**
+ * Synchronize the data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+class Hotspot {
+public:
+ Common::Rect _bounds;
+ Common::Point _feetPos;
+ Facing _facing;
+ int _articleNumber;
+ bool _active;
+ CursorType _cursor;
+ int _vocabId;
+ int _verbId;
+
+ Hotspot();
+ Hotspot(Common::SeekableReadStream &f, bool isV2);
+};
+
+class Hotspots : public Common::Array<Hotspot> {
+private:
+ MADSEngine *_vm;
+public:
+ Hotspots(MADSEngine *vm) : _vm(vm) {}
+
+ /**
+ * Sets the active state of a given hotspot
+ */
+ void activate(int vocabId, bool active);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_HOTSPOTS_H */
diff --git a/engines/mads/inventory.cpp b/engines/mads/inventory.cpp
new file mode 100644
index 0000000000..b7864bc6a7
--- /dev/null
+++ b/engines/mads/inventory.cpp
@@ -0,0 +1,226 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/inventory.h"
+
+namespace MADS {
+
+void InventoryObject::synchronize(Common::Serializer &s) {
+ s.syncAsUint16LE(_descId);
+ s.syncAsUint16LE(_roomNumber);
+ s.syncAsByte(_article);
+ s.syncAsByte(_vocabCount);
+ s.syncAsByte(_qualitiesCount);
+ s.skip(1);
+
+ for (int i = 0; i < MAX_VOCAB; ++i) {
+ s.syncAsUint16LE(_vocabList[i]._vocabId);
+ s.syncAsByte(_vocabList[i]._verbType);
+ s.syncAsByte(_vocabList[i]._prepType);
+ }
+
+ for (int i = 0; i < MAX_QUALITIES; ++i)
+ s.syncAsByte(_qualityId[i]);
+ for (int i = 0; i < MAX_QUALITIES; ++i)
+ s.syncAsSint32LE(_qualityValue[i]);
+}
+
+bool InventoryObject::hasQuality(int qualityId) const {
+ for (int i = 0; i < _qualitiesCount; ++i) {
+ if (_qualityId[i] == qualityId)
+ return true;
+ }
+
+ return false;
+}
+
+void InventoryObject::setQuality(int qualityId, int qualityValue) {
+ for (int i = 0; i < _qualitiesCount; ++i) {
+ if (_qualityId[i] == qualityId) {
+ _qualityValue[i] = qualityValue;
+ }
+ }
+}
+
+int InventoryObject::getQuality(int qualityId) const {
+ for (int i = 0; i < _qualitiesCount; ++i) {
+ if (_qualityId[i] == qualityId) {
+ return _qualityValue[i];
+ }
+ }
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+void InventoryObjects::load() {
+ File f("*OBJECTS.DAT");
+ int count = f.readUint16LE();
+ Common::Serializer s(&f, nullptr);
+
+ // Load the objects data
+ reserve(count);
+ for (int i = 0; i < count; ++i) {
+ InventoryObject obj;
+ obj.synchronize(s);
+ push_back(obj);
+
+ // If it's for the player's inventory, add the index to the inventory list
+ if (obj._roomNumber == PLAYER_INVENTORY) {
+ _inventoryList.push_back(i);
+ assert(_inventoryList.size() <= 32);
+ }
+ }
+}
+
+void InventoryObjects::synchronize(Common::Serializer &s) {
+ int count = size();
+ s.syncAsUint16LE(count);
+
+ if (s.isSaving()) {
+ // Store the data for each object in the inventory lsit
+ for (int idx = 0; idx < count; ++idx)
+ (*this)[idx].synchronize(s);
+
+ // Synchronize the player's inventory
+ _inventoryList.synchronize(s);
+ } else {
+ clear();
+
+ // Read in each object
+ reserve(count);
+ for (int i = 0; i < count; ++i) {
+ InventoryObject obj;
+ obj.synchronize(s);
+ push_back(obj);
+ }
+
+ // Synchronize the player's inventory
+ _inventoryList.synchronize(s);
+ }
+}
+
+void InventoryObjects::setRoom(int objectId, int sceneNumber) {
+ InventoryObject &obj = (*this)[objectId];
+
+ if (obj._roomNumber == PLAYER_INVENTORY)
+ removeFromInventory(objectId, 1);
+
+ if (sceneNumber == PLAYER_INVENTORY)
+ addToInventory(objectId);
+ else
+ obj._roomNumber = sceneNumber;
+}
+
+bool InventoryObjects::isInRoom(int objectId) const {
+ return objectId >= 0 && (*this)[objectId]._roomNumber == _vm->_game->_scene._currentSceneId;
+}
+
+bool InventoryObjects::isInInventory(int objectId) const {
+ return objectId >= 0 && (*this)[objectId]._roomNumber == PLAYER_INVENTORY;
+}
+
+void InventoryObjects::addToInventory(int objectId) {
+ assert(_inventoryList.size() < 32);
+ UserInterface &userInterface = _vm->_game->_scene._userInterface;
+
+ if (!isInInventory(objectId)) {
+ _inventoryList.push_back(objectId);
+ userInterface._selectedInvIndex = _inventoryList.size() - 1;
+ userInterface._inventoryTopIndex = CLIP(userInterface._inventoryTopIndex,
+ 0, userInterface._selectedInvIndex);
+
+ if ((userInterface._inventoryTopIndex + 5) <= (int)_inventoryList.size())
+ userInterface._inventoryTopIndex = _inventoryList.size() - 5;
+ userInterface._inventoryChanged = true;
+
+ (*this)[objectId]._roomNumber = PLAYER_INVENTORY;
+
+ if (_vm->_game->_kernelMode == KERNEL_ACTIVE_CODE &&
+ _vm->_game->_screenObjects._inputMode == kInputBuildingSentences) {
+ userInterface.categoryChanged();
+ userInterface.selectObject(userInterface._selectedInvIndex);
+ }
+ }
+}
+
+void InventoryObjects::removeFromInventory(int objectId, int newScene) {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+
+ // Scan the inventory list for the object
+ int invIndex = -1;
+ for (int idx = 0; idx < (int)_inventoryList.size() && invIndex == -1; ++idx) {
+ if (_inventoryList[idx] == objectId)
+ invIndex = idx;
+ }
+
+ // If the object isn't in the player's inventory, stop here
+ if (invIndex < 0)
+ return;
+
+ int selectedIndex = userInterface._selectedInvIndex;
+ bool noSelection = selectedIndex < 0;
+
+ if (_vm->_game->_kernelMode == KERNEL_ACTIVE_CODE &&
+ _vm->_game->_screenObjects._inputMode == kInputBuildingSentences)
+ userInterface.selectObject(-1);
+
+ // Remove the item from the inventory list
+ _inventoryList.remove_at(invIndex);
+
+ if (invIndex > userInterface._inventoryTopIndex) {
+ userInterface._inventoryTopIndex = MAX(userInterface._inventoryTopIndex, 0);
+ }
+
+ userInterface._inventoryChanged = true;
+ (*this)[objectId]._roomNumber = newScene;
+
+ int newIndex = selectedIndex;
+ if (!noSelection) {
+ if (newIndex >= invIndex)
+ --newIndex;
+ if (newIndex < 0 && size() > 0)
+ newIndex = 0;
+ }
+
+ if (_vm->_game->_kernelMode == KERNEL_ACTIVE_CODE &&
+ _vm->_game->_screenObjects._inputMode == kInputBuildingSentences) {
+ userInterface.categoryChanged();
+ userInterface.selectObject(newIndex);
+ }
+}
+
+int InventoryObjects::getIdFromDesc(int descId) {
+ for (int i = 0; i < (int)size(); ++i) {
+ InventoryObject &obj = (*this)[i];
+ if (obj._descId == descId)
+ return i;
+ }
+
+ return -1;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/inventory.h b/engines/mads/inventory.h
new file mode 100644
index 0000000000..09ed67a826
--- /dev/null
+++ b/engines/mads/inventory.h
@@ -0,0 +1,141 @@
+/* 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 MADS_INVENTORY_H
+#define MADS_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/serializer.h"
+
+namespace MADS {
+
+enum {
+ NOWHERE = 1
+};
+
+class MADSEngine;
+
+#define MAX_VOCAB 5
+#define MAX_QUALITIES 4
+
+class InventoryObject {
+public:
+ int _descId;
+ int _roomNumber;
+ int _article;
+ int _vocabCount;
+ int _qualitiesCount;
+ int syntax;
+
+ struct {
+ int _vocabId;
+ VerbType _verbType;
+ PrepType _prepType;
+ } _vocabList[MAX_VOCAB];
+
+ int _qualityId[MAX_QUALITIES];
+ int _qualityValue[MAX_QUALITIES];
+
+ /**
+ * Synchronizes the data for a given object
+ */
+ void synchronize(Common::Serializer &s);
+
+ /**
+ * Returns true if the given object has the specified quality
+ */
+ bool hasQuality(int qualityId) const;
+
+ /**
+ * Sets the quality value for a given quality Id
+ */
+ void setQuality(int qualityId, int qualityValue);
+
+ /**
+ * Gets the quality value for a given quality Id
+ */
+ int getQuality(int qualityId) const;
+};
+
+class InventoryObjects : public Common::Array<InventoryObject> {
+private:
+ MADSEngine *_vm;
+
+public:
+ SynchronizedList _inventoryList;
+
+ /**
+ * Constructor
+ */
+ InventoryObjects(MADSEngine *vm) : _vm(vm) {}
+
+ /**
+ * Loads the game's object list
+ */
+ void load();
+
+ /**
+ * Synchronize the objects list in a savegame
+ */
+ void synchronize(Common::Serializer &s);
+
+ /**
+ * Returns the inventory item from the player's inventory
+ */
+ InventoryObject &getItem(int itemIndex) {
+ return (*this)[_inventoryList[itemIndex]];
+ }
+
+ /**
+ * Sets an item's scene number
+ */
+ void setRoom(int objectId, int sceneNumber);
+
+ /**
+ * Returns true if a given object is in the player's current scene
+ */
+ bool isInRoom(int objectId) const;
+
+ /**
+ * Returns true if a given object is in the player's inventory
+ */
+ bool isInInventory(int objectId) const;
+
+ /**
+ * Removes the specified object from the player's inventory
+ */
+ void addToInventory(int objectId);
+
+ /**
+ * Removes the specified object to the player's inventory
+ * @param objectId Object to remove
+ * @param newScene Specifies the new scene to set the item to
+ */
+ void removeFromInventory(int objectId, int newScene);
+
+ int getIdFromDesc(int objectId);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_INVENTORY_H */
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
new file mode 100644
index 0000000000..31e9b0dbe2
--- /dev/null
+++ b/engines/mads/mads.cpp
@@ -0,0 +1,157 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug-channels.h"
+#include "common/events.h"
+#include "engines/util.h"
+#include "mads/mads.h"
+#include "mads/game.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/resources.h"
+#include "mads/sound.h"
+#include "mads/sprites.h"
+
+namespace MADS {
+
+MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
+ _gameDescription(gameDesc), Engine(syst), _randomSource("MADS") {
+
+ // Initialize fields
+ _easyMouse = true;
+ _invObjectsAnimated = true;
+ _textWindowStill = false;
+ _screenFade = SCREEN_FADE_SMOOTH;
+ _musicFlag = true;
+ _dithering = false;
+
+ _debugger = nullptr;
+ _dialogs = nullptr;
+ _events = nullptr;
+ _font = nullptr;
+ _game = nullptr;
+ _palette = nullptr;
+ _resources = nullptr;
+ _sound = nullptr;
+ _audio = nullptr;
+}
+
+MADSEngine::~MADSEngine() {
+ delete _debugger;
+ delete _dialogs;
+ delete _events;
+ delete _font;
+ Font::deinit();
+ delete _game;
+ delete _palette;
+ delete _resources;
+ delete _sound;
+}
+
+void MADSEngine::initialize() {
+ // Set up debug channels
+ DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level");
+ DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
+ DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");
+
+ // Initial sub-system engine references
+ MSurface::setVm(this);
+ MSprite::setVm(this);
+
+ Resources::init(this);
+ Conversation::init(this);
+ _debugger = new Debugger(this);
+ _dialogs = Dialogs::init(this);
+ _events = new EventsManager(this);
+ _palette = new Palette(this);
+ Font::init(this);
+ _font = new Font();
+ _screen.init();
+ _sound = new SoundManager(this, _mixer);
+ _audio = new AudioPlayer(_mixer, getGameID());
+ _game = Game::init(this);
+
+ _screen.empty();
+}
+
+Common::Error MADSEngine::run() {
+ initGraphics(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, false);
+ initialize();
+
+ // Run the game
+ _game->run();
+
+ // Dummy loop to keep application active
+ _events->delay(9999);
+
+ return Common::kNoError;
+}
+
+int MADSEngine::getRandomNumber(int maxNumber) {
+ return _randomSource.getRandomNumber(maxNumber);
+}
+
+int MADSEngine::getRandomNumber(int minNumber, int maxNumber) {
+ int range = maxNumber - minNumber;
+
+ return minNumber + _randomSource.getRandomNumber(range);
+}
+
+int MADSEngine::hypotenuse(int xv, int yv) {
+ return (int)sqrt((double)(xv * xv + yv * yv));
+}
+
+bool MADSEngine::canLoadGameStateCurrently() {
+ return !_game->_winStatus && !_game->globals()[5]
+ && _dialogs->_pendingDialog == DIALOG_NONE
+ && _events->_cursorId != CURSOR_WAIT;
+}
+
+bool MADSEngine::canSaveGameStateCurrently() {
+ return !_game->_winStatus && !_game->globals()[5]
+ && _dialogs->_pendingDialog == DIALOG_NONE
+ && _events->_cursorId != CURSOR_WAIT;
+}
+
+/**
+* Support method that generates a savegame name
+* @param slot Slot number
+*/
+Common::String MADSEngine::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+Common::Error MADSEngine::loadGameState(int slot) {
+ _game->_loadGameSlot = slot;
+ _game->_scene._currentSceneId = -1;
+ _game->_currentSectionNumber = -1;
+ return Common::kNoError;
+}
+
+Common::Error MADSEngine::saveGameState(int slot, const Common::String &desc) {
+ _game->saveGame(slot, desc);
+ return Common::kNoError;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/mads.h b/engines/mads/mads.h
new file mode 100644
index 0000000000..9a8f2152a1
--- /dev/null
+++ b/engines/mads/mads.h
@@ -0,0 +1,152 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_MADS_H
+#define MADS_MADS_H
+
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/error.h"
+#include "common/random.h"
+#include "common/util.h"
+#include "engines/engine.h"
+#include "graphics/surface.h"
+#include "mads/debugger.h"
+#include "mads/dialogs.h"
+#include "mads/events.h"
+#include "mads/font.h"
+#include "mads/game.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/resources.h"
+#include "mads/sound.h"
+
+/**
+ * This is the namespace of the MADS engine.
+ *
+ * Status of this engine: In Development
+ *
+ * Games using this engine:
+ * - Rex Nebular and the Cosmic Gender Bender
+ */
+namespace MADS {
+
+#define DEBUG_BASIC 1
+#define DEBUG_INTERMEDIATE 2
+#define DEBUG_DETAILED 3
+
+enum MADSDebugChannels {
+ kDebugPath = 1 << 0,
+ kDebugScripts = 1 << 1,
+ kDebugGraphics = 1 << 2
+};
+
+enum {
+ GType_RexNebular = 0,
+ GType_Dragonsphere = 1,
+ GType_Phantom = 2
+};
+
+enum ScreenFade {
+ SCREEN_FADE_SMOOTH = 0,
+ SCREEN_FADE_MEDIUM = 1,
+ SCREEN_FADE_FAST = 2
+};
+
+struct MADSGameDescription;
+
+
+class MADSEngine : public Engine {
+private:
+ const MADSGameDescription *_gameDescription;
+ Common::RandomSource _randomSource;
+
+ /**
+ * Handles basic initialisation
+ */
+ void initialize();
+protected:
+ // Engine APIs
+ virtual Common::Error run();
+ virtual bool hasFeature(EngineFeature f) const;
+public:
+ Debugger *_debugger;
+ Dialogs *_dialogs;
+ EventsManager *_events;
+ Font *_font;
+ Game *_game;
+ Palette *_palette;
+ Resources *_resources;
+ ScreenSurface _screen;
+ SoundManager *_sound;
+ AudioPlayer *_audio;
+ bool _easyMouse;
+ bool _invObjectsAnimated;
+ bool _textWindowStill;
+ ScreenFade _screenFade;
+ bool _musicFlag;
+ bool _dithering;
+public:
+ MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc);
+ virtual ~MADSEngine();
+
+ uint32 getFeatures() const;
+ Common::Language getLanguage() const;
+ Common::Platform getPlatform() const;
+ uint16 getVersion() const;
+ uint32 getGameID() const;
+ uint32 getGameFeatures() const;
+
+ int getRandomNumber(int maxNumber);
+ int getRandomNumber(int minNumber, int maxNumber);
+ int hypotenuse(int xv, int yv);
+
+ /**
+ * Returns true if it is currently okay to restore a game
+ */
+ bool canLoadGameStateCurrently();
+
+ /**
+ * Returns true if it is currently okay to save the game
+ */
+ bool canSaveGameStateCurrently();
+
+ /**
+ * Support method that generates a savegame name
+ * @param slot Slot number
+ */
+ Common::String generateSaveName(int slot);
+
+ /**
+ * Handles loading a game via the GMM
+ */
+ virtual Common::Error loadGameState(int slot);
+
+ /**
+ * Handles saving the game via the GMM
+ */
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_MADS_H */
diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp
new file mode 100644
index 0000000000..9b2d6f3114
--- /dev/null
+++ b/engines/mads/messages.cpp
@@ -0,0 +1,570 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/font.h"
+#include "mads/screen.h"
+#include "mads/messages.h"
+#include "mads/scene_data.h"
+
+namespace MADS {
+
+RandomMessages::RandomMessages() {
+ reserve(RANDOM_MESSAGE_SIZE);
+ _randomSpacing = 0;
+ _color = -1;
+ _duration = 0;
+ _scrollRate = -1;
+}
+
+void RandomMessages::reset() {
+ for (uint i = 0; i < size(); ++i) {
+ (*this)[i]._handle = -1;
+ (*this)[i]._quoteId = -1;
+ }
+}
+
+
+KernelMessages::KernelMessages(MADSEngine *vm)
+ : _vm(vm) {
+ for (int i = 0; i < KERNEL_MESSAGES_SIZE; ++i) {
+ KernelMessage rec;
+ _entries.push_back(rec);
+ }
+
+ _talkFont = _vm->_font->getFont(FONT_CONVERSATION);
+}
+
+KernelMessages::~KernelMessages() {
+}
+
+void KernelMessages::clear() {
+ Scene &scene = _vm->_game->_scene;
+
+ for (uint i = 0; i < _entries.size(); ++i)
+ _entries[i]._flags = 0;
+
+ _talkFont = _vm->_font->getFont(FONT_CONVERSATION);
+ scene._textSpacing = -1;
+}
+
+int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags,
+ uint8 abortTimers, uint32 timeout, const Common::String &msg) {
+ Scene &scene = _vm->_game->_scene;
+
+ // Find a free slot
+ uint idx = 0;
+ while ((idx < _entries.size()) && ((_entries[idx]._flags & KMSG_ACTIVE) != 0))
+ ++idx;
+ if (idx == _entries.size()) {
+ if (abortTimers == 0)
+ return -1;
+
+ error("KernelMessages overflow");
+ }
+
+ KernelMessage &rec = _entries[idx];
+ rec._msg = msg;
+ rec._flags = flags | KMSG_ACTIVE;
+ rec._color1 = fontColor & 0xff;
+ rec._color2 = fontColor >> 8;
+ rec._position = pt;
+ rec._textDisplayIndex = -1;
+ rec._timeout = timeout;
+ rec._frameTimer = _vm->_game->_priorFrameTimer;
+ rec._trigger = abortTimers;
+ rec._abortMode = _vm->_game->_triggerSetupMode;
+
+ rec._actionDetails = scene._action._activeAction;
+
+ if (flags & KMSG_PLAYER_TIMEOUT)
+ rec._frameTimer = _vm->_game->_player._ticksAmount +
+ _vm->_game->_player._priorTimer;
+
+ return idx;
+}
+
+int KernelMessages::addQuote(int quoteId, int abortTimers, uint32 timeout) {
+ Common::String quoteStr = _vm->_game->getQuote(quoteId);
+ return add(Common::Point(), 0x1110, KMSG_PLAYER_TIMEOUT | KMSG_CENTER_ALIGN,
+ abortTimers, timeout, quoteStr);
+}
+
+void KernelMessages::scrollMessage(int msgIndex, int numTicks, bool quoted) {
+ if (msgIndex < 0)
+ return;
+
+ _entries[msgIndex]._flags |= quoted ? (KMSG_SCROLL | KMSG_QUOTED) : KMSG_SCROLL;
+ _entries[msgIndex]._msgOffset = 0;
+ _entries[msgIndex]._numTicks = numTicks;
+ _entries[msgIndex]._frameTimer2 = _vm->_game->_priorFrameTimer;
+
+ Common::String msg = _entries[msgIndex]._msg;
+
+ if (_entries[msgIndex]._flags & KMSG_PLAYER_TIMEOUT)
+ _entries[msgIndex]._frameTimer2 = _vm->_game->_player._ticksAmount +
+ _vm->_game->_player._priorTimer;
+
+ _entries[msgIndex]._frameTimer = _entries[msgIndex]._frameTimer2;
+}
+
+void KernelMessages::setSeqIndex(int msgIndex, int seqIndex) {
+ if (msgIndex >= 0) {
+ _entries[msgIndex]._flags |= KMSG_SEQ_ENTRY;
+ _entries[msgIndex]._sequenceIndex = seqIndex;
+ }
+}
+
+void KernelMessages::remove(int msgIndex) {
+ KernelMessage &rec = _entries[msgIndex];
+ Scene &scene = _vm->_game->_scene;
+
+ if (rec._flags & KMSG_ACTIVE) {
+ if (rec._flags & KMSG_SCROLL) {
+ // WORKAROUND: Code here no longer needed in ScummVM
+ }
+
+ if (rec._textDisplayIndex >= 0)
+ scene._textDisplay.expire(rec._textDisplayIndex);
+
+ rec._flags &= ~KMSG_ACTIVE;
+ }
+}
+
+void KernelMessages::reset() {
+ for (uint i = 0; i < _entries.size(); ++i)
+ remove(i);
+
+ _randomMessages.clear();
+}
+
+void KernelMessages::update() {
+ uint32 currentTimer = _vm->_game->_scene._frameStartTime;
+
+ for (uint i = 0; i < _entries.size() && !_vm->_game->_trigger; ++i) {
+ KernelMessage &msg = _entries[i];
+
+ if (((msg._flags & KMSG_ACTIVE) != 0) && (currentTimer >= msg._frameTimer))
+ processText(i);
+ }
+}
+
+void KernelMessages::processText(int msgIndex) {
+ Scene &scene = _vm->_game->_scene;
+ KernelMessage &msg = _entries[msgIndex];
+ uint32 currentTimer = _vm->_game->_priorFrameTimer;
+ bool flag = false;
+
+ if ((msg._flags & KMSG_EXPIRE) != 0) {
+ scene._textDisplay.expire(msg._textDisplayIndex);
+ msg._flags &= ~KMSG_ACTIVE;
+ return;
+ }
+
+ if ((msg._flags & KMSG_SCROLL) == 0) {
+ msg._timeout -= 3;
+ }
+
+ if (msg._flags & KMSG_SEQ_ENTRY) {
+ SequenceEntry &seqEntry = scene._sequences[msg._sequenceIndex];
+ if (seqEntry._doneFlag || !seqEntry._active)
+ msg._timeout = 0;
+ }
+
+ if ((msg._timeout <= 0) && (_vm->_game->_trigger == 0)) {
+ msg._flags |= KMSG_EXPIRE;
+ if (msg._trigger != 0) {
+ _vm->_game->_trigger = msg._trigger;
+ _vm->_game->_triggerMode = msg._abortMode;
+
+ if (_vm->_game->_triggerMode != SEQUENCE_TRIGGER_DAEMON) {
+ scene._action._activeAction = msg._actionDetails;
+ }
+ }
+ }
+
+ msg._frameTimer = currentTimer + 3;
+ int x1 = 0, y1 = 0;
+
+ if (msg._flags & KMSG_SEQ_ENTRY) {
+ SequenceEntry &seqEntry = scene._sequences[msg._sequenceIndex];
+ if (!seqEntry._nonFixed) {
+ SpriteAsset &spriteSet = *scene._sprites[seqEntry._spritesIndex];
+ MSprite *frame = spriteSet.getFrame(seqEntry._frameIndex - 1);
+ x1 = frame->getBounds().left;
+ y1 = frame->getBounds().top;
+ } else {
+ x1 = seqEntry._position.x;
+ y1 = seqEntry._position.y;
+ }
+ }
+
+ Player &player = _vm->_game->_player;
+ if (msg._flags & KMSG_PLAYER_TIMEOUT) {
+ if (player._beenVisible) {
+ SpriteAsset &asset = *_vm->_game->_scene._sprites[player._spritesStart + player._spritesIdx];
+ MSprite *frame = asset.getFrame(player._frameNumber - 1);
+
+ int yAmount = player._currentScale * player._centerOfGravity / 100;
+ x1 = player._playerPos.x;
+ y1 = (frame->h * player._currentScale / -100) + yAmount +
+ player._playerPos.y - 15;
+ } else {
+ x1 = 160;
+ y1 = 78;
+ }
+ }
+
+ x1 += msg._position.x;
+ y1 += msg._position.y;
+
+ Common::String displayMsg = msg._msg;
+
+ if ((msg._flags & KMSG_SCROLL) && (msg._frameTimer >= currentTimer)) {
+ ++msg._msgOffset;
+
+ if (msg._msgOffset >= msg._msg.size()) {
+ // End of message
+ msg._flags &= ~KMSG_SCROLL;
+ } else {
+ displayMsg = Common::String(msg._msg.c_str(), msg._msg.c_str() + msg._msgOffset);
+ }
+
+ msg._frameTimer = msg._frameTimer2 = currentTimer + msg._numTicks;
+ flag = true;
+ }
+
+ int strWidth = _talkFont->getWidth(displayMsg, scene._textSpacing);
+
+ if (msg._flags & (KMSG_RIGHT_ALIGN | KMSG_CENTER_ALIGN)) {
+ x1 -= (msg._flags & KMSG_CENTER_ALIGN) ? strWidth / 2 : strWidth;
+ }
+
+ // Make sure text appears entirely on-screen
+ int x2 = x1 + strWidth;
+ if (x2 > MADS_SCREEN_WIDTH)
+ x1 -= x2 - MADS_SCREEN_WIDTH;
+ if (x1 > (MADS_SCREEN_WIDTH - 1))
+ x1 = MADS_SCREEN_WIDTH - 1;
+ if (x1 < 0)
+ x1 = 0;
+
+ if (y1 >(MADS_SCENE_HEIGHT - 1))
+ y1 = MADS_SCENE_HEIGHT - 1;
+ if (y1 < 0)
+ y1 = 0;
+
+ if (msg._textDisplayIndex >= 0) {
+ TextDisplay &textEntry = scene._textDisplay[msg._textDisplayIndex];
+
+ if (flag || (textEntry._bounds.left != x1) || (textEntry._bounds.top != y1)) {
+ // Mark the associated text entry as deleted, so it can be re-created
+ scene._textDisplay.expire(msg._textDisplayIndex);
+ msg._textDisplayIndex = -1;
+ }
+ }
+
+ if (msg._textDisplayIndex < 0) {
+ // Need to create a new text display entry for this message
+ int idx = scene._textDisplay.add(x1, y1, msg._color1 | (msg._color2 << 8),
+ scene._textSpacing, displayMsg, _talkFont);
+ if (idx >= 0)
+ msg._textDisplayIndex = idx;
+ }
+}
+
+void KernelMessages::delay(uint32 priorFrameTime, uint32 currentTime) {
+ for (uint i = 0; i < _entries.size(); ++i) {
+ _entries[i]._timeout += currentTime - priorFrameTime;
+ }
+}
+
+void KernelMessages::setQuoted(int msgIndex, int numTicks, bool quoted) {
+ if (msgIndex >= 0) {
+ KernelMessage &msg = _entries[msgIndex];
+
+ msg._flags |= KMSG_SCROLL;
+ if (quoted)
+ msg._flags |= KMSG_QUOTED;
+
+ msg._msgOffset = 0;
+ msg._numTicks = numTicks;
+ msg._frameTimer2 = _vm->_game->_scene._frameStartTime;
+
+ if (msg._flags & KMSG_PLAYER_TIMEOUT) {
+ msg._frameTimer2 = _vm->_game->_player._priorTimer +
+ _vm->_game->_player._ticksAmount;
+ }
+
+ msg._frameTimer = msg._frameTimer2;
+ }
+}
+
+#define RANDOM_MESSAGE_TRIGGER 240
+
+void KernelMessages::randomServer() {
+ if ((_vm->_game->_trigger >= RANDOM_MESSAGE_TRIGGER) &&
+ (_vm->_game->_trigger < (RANDOM_MESSAGE_TRIGGER + (int)_randomMessages.size()))) {
+ _randomMessages[_vm->_game->_trigger - RANDOM_MESSAGE_TRIGGER]._handle = -1;
+ _randomMessages[_vm->_game->_trigger - RANDOM_MESSAGE_TRIGGER]._quoteId = -1;
+ }
+}
+
+int KernelMessages::checkRandom() {
+ int total = 0;
+
+ for (uint i = 0; i < _randomMessages.size(); ++i) {
+ if (_randomMessages[i]._handle >= 0)
+ ++total;
+ }
+
+ return total;
+}
+
+bool KernelMessages::generateRandom(int major, int minor) {
+ bool generatedMessage = false;
+
+ // Scan through the random messages array
+ for (uint msgCtr = 0; msgCtr < _randomMessages.size(); msgCtr++) {
+ // Find currently active random messages
+ if (_randomMessages[msgCtr]._handle < 0) {
+ // Check whether there's any existing 'scrolling in' message
+ bool bad = false;
+ for (uint scanCtr = 0; scanCtr < _randomMessages.size(); ++scanCtr) {
+ if (_randomMessages[scanCtr]._handle >= 0) {
+ if (_entries[_randomMessages[scanCtr]._handle]._flags & KMSG_SCROLL) {
+ bad = true;
+ break;
+ }
+ }
+ }
+
+ // Do a random check for a new message to appear
+ if (_vm->getRandomNumber(major) <= minor && !bad) {
+ int quoteId;
+
+ // Pick a random quote to display from the available list
+ do {
+ int quoteIdx = _vm->getRandomNumber(_randomQuotes.size() - 1);
+ quoteId = _randomQuotes[quoteIdx];
+
+ // Ensure the quote isn't already in use
+ bad = false;
+ for (uint scanCtr = 0; scanCtr < _randomMessages.size(); ++scanCtr) {
+ if (quoteId == _randomMessages[scanCtr]._quoteId) {
+ bad = true;
+ break;
+ }
+ }
+ } while (bad);
+
+ // Store the quote Id to be used
+ _randomMessages[msgCtr]._quoteId = quoteId;
+
+ // Position the message at a random position
+ Common::Point textPos;
+ textPos.x = _vm->getRandomNumber(_randomMessages._bounds.left,
+ _randomMessages._bounds.right);
+
+ // Figure out Y position, making sure not to be overlapping with
+ // any other on-screen message
+ int abortCounter = 0;
+
+ do {
+ // Ensure we don't get stuck in an infinite loop if too many messages
+ // are alrady on-screen
+ if (abortCounter++ > 100) goto done;
+ bad = false;
+
+ // Set potential new Y position
+ textPos.y = _vm->getRandomNumber(_randomMessages._bounds.top,
+ _randomMessages._bounds.bottom);
+
+ // Ensure it doesn't overlap an existing on-screen message
+ for (uint msgCtr2 = 0; msgCtr2 < _randomMessages.size(); ++msgCtr2) {
+ if (_randomMessages[msgCtr2]._handle >= 0) {
+ int lastY = _entries[_randomMessages[msgCtr2]._handle]._position.y;
+
+ if ((textPos.y >= (lastY - _randomMessages._randomSpacing)) &&
+ (textPos.y <= (lastY + _randomMessages._randomSpacing))) {
+ bad = true;
+ }
+ }
+ }
+ } while (bad);
+
+ // Add the message
+ _randomMessages[msgCtr]._handle = add(textPos, _randomMessages._color, 0,
+ RANDOM_MESSAGE_TRIGGER + msgCtr, _randomMessages._duration,
+ _vm->_game->getQuote(_randomMessages[msgCtr]._quoteId));
+
+ if (_randomMessages._scrollRate > 0) {
+ if (_randomMessages[msgCtr]._handle >= 0) {
+ setQuoted(_randomMessages[msgCtr]._handle,
+ _randomMessages._scrollRate, true);
+ }
+ }
+
+ generatedMessage = true;
+ break;
+ }
+ }
+ }
+
+done:
+ return generatedMessage;
+}
+
+void KernelMessages::initRandomMessages(int maxSimultaneousMessages,
+ const Common::Rect &bounds, int minYSpacing, int scrollRate,
+ int color, int duration, int quoteId, ...) {
+ // Reset the random messages list
+ _randomMessages.clear();
+ _randomMessages.resize(maxSimultaneousMessages);
+
+ // Store passed parameters
+ _randomMessages._bounds = bounds;
+ _randomMessages._randomSpacing = minYSpacing;
+ _randomMessages._scrollRate = scrollRate;
+ _randomMessages._color = color;
+ _randomMessages._duration = duration;
+
+ // Store the variable length random quote list
+ va_list va;
+ va_start(va, quoteId);
+ _randomQuotes.clear();
+
+ while (quoteId > 0) {
+ _randomQuotes.push_back(quoteId);
+ assert(_randomQuotes.size() < 100);
+ quoteId = va_arg(va, int);
+ }
+
+ va_end(va);
+}
+
+
+/*------------------------------------------------------------------------*/
+
+TextDisplay::TextDisplay() {
+ _active = false;
+ _expire = 0;
+ _spacing = 0;
+ _color1 = 0;
+ _color2 = 0;
+ _font = nullptr;
+}
+
+/*------------------------------------------------------------------------*/
+
+TextDisplayList::TextDisplayList(MADSEngine *vm) : _vm(vm) {
+ for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i) {
+ TextDisplay rec;
+ rec._active = false;
+ rec._expire = 0;
+ push_back(rec);
+ }
+}
+
+void TextDisplayList::reset() {
+ for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i)
+ (*this)[i]._active = false;
+}
+
+int TextDisplayList::add(int xp, int yp, uint fontColor, int charSpacing,
+ const Common::String &msg, Font *font) {
+ int usedSlot = -1;
+
+ for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) {
+ TextDisplay &td = (*this)[idx];
+ if (!td._active) {
+ usedSlot = idx;
+
+ td._bounds.left = xp;
+ td._bounds.top = yp;
+ td._font = font;
+ td._msg = msg;
+ td._bounds.setWidth(font->getWidth(msg, charSpacing));
+ td._bounds.setHeight(font->getHeight());
+ td._color1 = fontColor & 0xff;
+ td._color2 = fontColor >> 8;
+ td._spacing = charSpacing;
+ td._expire = 1;
+ td._active = true;
+ break;
+ }
+ }
+
+ return usedSlot;
+}
+
+void TextDisplayList::setDirtyAreas() {
+ Scene &scene = _vm->_game->_scene;
+
+ for (uint idx = 0, dirtyIdx = SPRITE_SLOTS_MAX_SIZE; dirtyIdx < size(); ++idx, ++dirtyIdx) {
+ if (((*this)[idx]._expire >= 0) || !(*this)[idx]._active) {
+ scene._dirtyAreas[dirtyIdx]._active = false;
+ } else {
+ scene._dirtyAreas[dirtyIdx]._textActive = true;
+ scene._dirtyAreas[dirtyIdx].setTextDisplay(&(*this)[idx]);
+ }
+ }
+}
+
+void TextDisplayList::setDirtyAreas2() {
+ Scene &scene = _vm->_game->_scene;
+
+ for (uint idx = 0, dirtyIdx = SPRITE_SLOTS_MAX_SIZE; idx < size(); ++idx, ++dirtyIdx) {
+ if ((*this)[idx]._active && ((*this)[idx]._expire >= 0)) {
+ scene._dirtyAreas[dirtyIdx].setTextDisplay(&(*this)[idx]);
+ scene._dirtyAreas[dirtyIdx]._textActive = ((*this)[idx]._expire <= 0) ? 0 : 1;
+ }
+ }
+}
+
+void TextDisplayList::draw(MSurface *s) {
+ for (uint idx = 0; idx < size(); ++idx) {
+ TextDisplay &td = (*this)[idx];
+ if (td._active && (td._expire >= 0)) {
+ td._font->setColors(0xFF, td._color1, td._color2, 0);
+ td._font->writeString(s, td._msg,
+ Common::Point(td._bounds.left, td._bounds.top),
+ td._spacing, td._bounds.width());
+ }
+ }
+}
+
+void TextDisplayList::cleanUp() {
+ for (uint idx = 0; idx < size(); ++idx) {
+ if ((*this)[idx]._expire < 0) {
+ (*this)[idx]._active = false;
+ (*this)[idx]._expire = 0;
+ }
+ }
+}
+
+void TextDisplayList::expire(int idx) {
+ (*this)[idx]._expire = -1;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/messages.h b/engines/mads/messages.h
new file mode 100644
index 0000000000..a7411d98d1
--- /dev/null
+++ b/engines/mads/messages.h
@@ -0,0 +1,192 @@
+/* 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 MADS_MESSAGES_H
+#define MADS_MESSAGES_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/action.h"
+#include "mads/font.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+#define KERNEL_MESSAGES_SIZE 10
+#define INDEFINITE_TIMEOUT 9999999
+#define TEXT_DISPLAY_SIZE 40
+#define RANDOM_MESSAGE_SIZE 4
+
+enum KernelMessageFlags {
+ KMSG_QUOTED = 1, KMSG_PLAYER_TIMEOUT = 2, KMSG_SEQ_ENTRY = 4, KMSG_SCROLL = 8,
+ KMSG_RIGHT_ALIGN = 0x10, KMSG_CENTER_ALIGN = 0x20, KMSG_EXPIRE = 0x40,
+ KMSG_ACTIVE = 0x80
+};
+
+class MADSEngine;
+
+class KernelMessage {
+public:
+ uint8 _flags;
+ int _sequenceIndex;
+ int _color1;
+ int _color2;
+ Common::Point _position;
+ int _textDisplayIndex;
+ uint32 _msgOffset;
+ int _numTicks;
+ uint32 _frameTimer2;
+ uint32 _frameTimer;
+ int32 _timeout;
+ int _trigger;
+ TriggerMode _abortMode;
+ ActionDetails _actionDetails;
+ Common::String _msg;
+
+ KernelMessage();
+};
+
+struct RandomEntry {
+ int _handle;
+ int _quoteId;
+
+ RandomEntry() { _handle = _quoteId = -1; }
+};
+
+class RandomMessages : public Common::Array<RandomEntry> {
+public:
+ Common::Rect _bounds;
+ int _randomSpacing;
+ int _color;
+ int _duration;
+ int _scrollRate;
+public:
+ RandomMessages();
+
+ void reset();
+};
+
+class KernelMessages {
+private:
+ MADSEngine *_vm;
+
+ Common::Array<int> _randomQuotes;
+ RandomMessages _randomMessages;
+public:
+ Common::Array<KernelMessage> _entries;
+ Font *_talkFont;
+public:
+ KernelMessages(MADSEngine *vm);
+ ~KernelMessages();
+
+ void clear();
+ int add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers,
+ uint32 timeout, const Common::String &msg);
+ int addQuote(int quoteId, int abortTimers, uint32 timeout);
+ void scrollMessage(int msgIndex, int numTicks, bool quoted);
+ void setSeqIndex(int msgIndex, int seqIndex);
+ void remove(int msgIndex);
+ void reset();
+ void update();
+ void processText(int msgIndex);
+ void delay(uint32 priorFrameTime, uint32 currentTime);
+ void setQuoted(int msgIndex, int numTicks, bool quoted);
+
+ void initRandomMessages(int maxSimultaneousMessages,
+ const Common::Rect &bounds, int minYSpacing, int scrollRate,
+ int color, int duration, int quoteId, ...);
+
+ /**
+ * Handles expiring any active random messages as necessary
+ */
+ void randomServer();
+
+ /**
+ * Return the number of currently active random messages
+ */
+ int checkRandom();
+
+ /**
+ * Handles generating new random messages
+ */
+ bool generateRandom(int major, int minor);
+};
+
+class TextDisplay {
+public:
+ bool _active;
+ int _expire;
+ int _spacing;
+ Common::Rect _bounds;
+ uint8 _color1;
+ uint8 _color2;
+ Font *_font;
+ Common::String _msg;
+
+ TextDisplay();
+};
+
+#define TEXT_DISPLAY_SIZE 40
+
+class TextDisplayList : public Common::Array<TextDisplay> {
+private:
+ MADSEngine *_vm;
+public:
+ TextDisplayList(MADSEngine *vm);
+
+ /**
+ * Expire a given text display entry
+ */
+ void expire(int idx);
+
+ int add(int xp, int yp, uint fontColor, int charSpacing, const Common::String &, Font *font);
+
+ /**
+ * Reset all of the text display entries in the list to inactive
+ */
+ void reset();
+
+ /**
+ * Draw any text in the list to the specified surface
+ * @param surface Surface
+ */
+ void draw(MSurface *s);
+
+ /**
+ * Determine dirty areas for active text areas
+ */
+ void setDirtyAreas();
+
+ /**
+ * Secondary setup dirty areas for the text areas
+ */
+ void setDirtyAreas2();
+
+ /**
+ * Deactivates any text display entries that are finished
+ */
+ void cleanUp();
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_MESSAGES_H */
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
new file mode 100644
index 0000000000..61e810e215
--- /dev/null
+++ b/engines/mads/module.mk
@@ -0,0 +1,58 @@
+MODULE := engines/mads
+
+MODULE_OBJS := \
+ dragonsphere/game_dragonsphere.o \
+ dragonsphere/dragonsphere_scenes.o \
+ phantom/game_phantom.o \
+ phantom/phantom_scenes.o \
+ nebular/dialogs_nebular.o \
+ nebular/game_nebular.o \
+ nebular/globals_nebular.o \
+ nebular/sound_nebular.o \
+ nebular/nebular_scenes.o \
+ nebular/nebular_scenes1.o \
+ nebular/nebular_scenes2.o \
+ nebular/nebular_scenes3.o \
+ nebular/nebular_scenes4.o \
+ nebular/nebular_scenes5.o \
+ nebular/nebular_scenes6.o \
+ nebular/nebular_scenes7.o \
+ nebular/nebular_scenes8.o \
+ action.o \
+ animation.o \
+ assets.o \
+ audio.o \
+ compression.o \
+ debugger.o \
+ detection.o \
+ dialogs.o \
+ events.o \
+ font.o \
+ game.o \
+ game_data.o \
+ globals.o \
+ hotspots.o \
+ inventory.o \
+ mads.o \
+ messages.o \
+ msurface.o \
+ palette.o \
+ player.o \
+ rails.o \
+ resources.o \
+ scene.o \
+ scene_data.o \
+ screen.o \
+ sequence.o \
+ sound.o \
+ sprites.o \
+ staticres.o \
+ user_interface.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_MADS), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp
new file mode 100644
index 0000000000..839882a354
--- /dev/null
+++ b/engines/mads/msurface.cpp
@@ -0,0 +1,572 @@
+/* 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 "engines/util.h"
+#include "mads/compression.h"
+#include "mads/screen.h"
+#include "mads/mads.h"
+#include "mads/msurface.h"
+#include "mads/resources.h"
+#include "mads/sprites.h"
+
+namespace MADS {
+
+MADSEngine *MSurface::_vm = nullptr;
+
+MSurface::MSurface() {
+ pixels = nullptr;
+ _freeFlag = false;
+}
+
+MSurface::MSurface(int width, int height) {
+ pixels = nullptr;
+ _freeFlag = false;
+ setSize(width, height);
+}
+
+MSurface::~MSurface() {
+ if (_freeFlag)
+ Graphics::Surface::free();
+}
+
+void MSurface::setSize(int width, int height) {
+ if (_freeFlag)
+ Graphics::Surface::free();
+ Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ _freeFlag = true;
+}
+
+void MSurface::setPixels(byte *pData, int horizSize, int vertSize) {
+ _freeFlag = false;
+ pixels = pData;
+ w = pitch = horizSize;
+ h = vertSize;
+ format.bytesPerPixel = 1;
+}
+
+int MSurface::scaleValue(int value, int scale, int err) {
+ int scaled = 0;
+ while (value--) {
+ err -= scale;
+ while (err < 0) {
+ scaled++;
+ err += 100;
+ }
+ }
+ return scaled;
+}
+
+void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Common::Rect &clipRect) {
+
+ enum {
+ kStatusSkip,
+ kStatusScale,
+ kStatusDraw
+ };
+
+ // NOTE: The current clipping code assumes that the top left corner of the clip
+ // rectangle is always 0, 0
+ assert(clipRect.top == 0 && clipRect.left == 0);
+
+ // TODO: Put err* and scaled* into SpriteInfo
+ int errX = info.hotX * info.scaleX % 100;
+ int errY = info.hotY * info.scaleY % 100;
+ int scaledWidth = scaleValue(info.width, info.scaleX, errX);
+ int scaledHeight = scaleValue(info.height, info.scaleY, errY);
+
+ int x = pt.x, y = pt.y;
+ int clipX = 0, clipY = 0;
+ // Clip the sprite's width and height according to the clip rectangle's dimensions
+ // This clips the sprite to the bottom and right
+ if (x >= 0) {
+ scaledWidth = MIN<int>(x + scaledWidth, clipRect.right) - x;
+ } else {
+ clipX = x;
+ scaledWidth = x + scaledWidth;
+ }
+ if (y >= 0) {
+ scaledHeight = MIN<int>(y + scaledHeight, clipRect.bottom) - y;
+ } else {
+ clipY = y;
+ scaledHeight = y + scaledHeight;
+ }
+
+ // Check if sprite is inside the screen. If it's not, there's no need to draw it
+ if (scaledWidth + x <= 0 || scaledHeight + y <= 0) // check left and top (in case x,y are negative)
+ return;
+ if (scaledWidth <= 0 || scaledHeight <= 0) // check right and bottom
+ return;
+ int heightAmt = scaledHeight;
+
+ byte *src = info.sprite->getData();
+ byte *dst = getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);
+
+ int status = kStatusSkip;
+ byte *scaledLineBuf = new byte[scaledWidth];
+
+ while (heightAmt > 0) {
+
+ if (status == kStatusSkip) {
+ // Skip line
+ errY -= info.scaleY;
+ if (errY < 0)
+ status = kStatusScale;
+ else
+ src += info.width;
+ } else {
+
+ if (status == kStatusScale) {
+ // Scale current line
+ byte *lineDst = scaledLineBuf;
+ int curErrX = errX;
+ int width = scaledWidth;
+ byte *tempSrc = src;
+ int startX = clipX;
+ while (width > 0) {
+ byte pixel = *tempSrc++;
+ curErrX -= info.scaleX;
+ while (curErrX < 0) {
+ if (startX == 0) {
+ *lineDst++ = pixel;
+ width--;
+ } else {
+ startX++;
+ }
+ curErrX += 100;
+ }
+ }
+ src += info.width;
+ status = kStatusDraw;
+ }
+
+ if (status == kStatusDraw && clipY == 0) {
+ // Draw previously scaled line
+ // TODO Implement different drawing types (depth, shadow etc.)
+ byte *tempDst = dst;
+ for (int lineX = 0; lineX < scaledWidth; lineX++) {
+ byte pixel = scaledLineBuf[lineX];
+
+ if (info.encoding & 0x80) {
+
+ if (pixel == 0x80) {
+ pixel = 0;
+ } else {
+ byte destPixel = *tempDst;
+ byte r, g, b;
+ r = CLIP((info.palette[destPixel * 3] * pixel) >> 10, 0, 31);
+ g = CLIP((info.palette[destPixel * 3 + 1] * pixel) >> 10, 0, 31);
+ b = CLIP((info.palette[destPixel * 3 + 2] * pixel) >> 10, 0, 31);
+ pixel = info.inverseColorTable[(b << 10) | (g << 5) | r];
+ }
+ }
+
+ if (pixel)
+ *tempDst = pixel;
+
+ tempDst++;
+ }
+ dst += pitch;
+ heightAmt--;
+ // TODO depth etc.
+ //depthAddress += Destination -> Width;
+
+ errY += 100;
+ if (errY >= 0)
+ status = kStatusSkip;
+ } else if (status == kStatusDraw && clipY < 0) {
+ clipY++;
+
+ errY += 100;
+ if (errY >= 0)
+ status = kStatusSkip;
+ }
+
+ }
+
+ }
+
+ delete[] scaledLineBuf;
+
+}
+
+void MSurface::empty() {
+ Common::fill(getBasePtr(0, 0), getBasePtr(0, h), 0);
+}
+
+void MSurface::copyFrom(MSurface *src, const Common::Rect &srcBounds,
+ const Common::Point &destPos, int transparentColor) {
+ // Validation of the rectangle and position
+ int destX = destPos.x, destY = destPos.y;
+ if ((destX >= w) || (destY >= h))
+ return;
+
+ Common::Rect copyRect = srcBounds;
+ if (destX < 0) {
+ copyRect.left += -destX;
+ destX = 0;
+ } else if (destX + copyRect.width() > w) {
+ copyRect.right -= destX + copyRect.width() - w;
+ }
+ if (destY < 0) {
+ copyRect.top += -destY;
+ destY = 0;
+ } else if (destY + copyRect.height() > h) {
+ copyRect.bottom -= destY + copyRect.height() - h;
+ }
+
+ if (!copyRect.isValidRect())
+ return;
+
+ // Copy the specified area
+
+ byte *data = src->getData();
+ byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
+ byte *destPtr = (byte *)pixels + (destY * getWidth()) + destX;
+
+ for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
+ if (transparentColor == -1) {
+ // No transparency, so copy line over
+ Common::copy(srcPtr, srcPtr + copyRect.width(), destPtr);
+ } else {
+ // Copy each byte one at a time checking for the transparency color
+ for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr)
+ if (srcPtr[xCtr] != transparentColor) destPtr[xCtr] = srcPtr[xCtr];
+ }
+
+ srcPtr += src->getWidth();
+ destPtr += getWidth();
+ }
+}
+
+void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
+ DepthSurface *depthSurface, int scale, int transparentColor) {
+
+ int destX = destPos.x, destY = destPos.y;
+ if (scale == 100) {
+ // Copy the specified area
+ Common::Rect copyRect(0, 0, src->getWidth(), src->getHeight());
+
+ if (destX < 0) {
+ copyRect.left += -destX;
+ destX = 0;
+ }
+ else if (destX + copyRect.width() > w) {
+ copyRect.right -= destX + copyRect.width() - w;
+ }
+ if (destY < 0) {
+ copyRect.top += -destY;
+ destY = 0;
+ }
+ else if (destY + copyRect.height() > h) {
+ copyRect.bottom -= destY + copyRect.height() - h;
+ }
+
+ if (!copyRect.isValidRect())
+ return;
+
+ byte *data = src->getData();
+ byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
+ byte *destPtr = (byte *)pixels + (destY * pitch) + destX;
+
+ // 100% scaling variation
+ for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
+ // Copy each byte one at a time checking against the depth
+ for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr) {
+ int pixelDepth = depthSurface == nullptr ? 15 :
+ depthSurface->getDepth(Common::Point(destX + xCtr, destY + rowCtr));
+ if ((depth <= pixelDepth) && (srcPtr[xCtr] != transparentColor))
+ destPtr[xCtr] = srcPtr[xCtr];
+ }
+
+ srcPtr += src->getWidth();
+ destPtr += getWidth();
+ }
+
+ return;
+ }
+
+ // Start of draw logic for scaled sprites
+ const byte *srcPixelsP = src->getData();
+
+ int destRight = this->getWidth() - 1;
+ int destBottom = this->getHeight() - 1;
+ bool normalFrame = true;
+ int frameWidth = src->getWidth();
+ int frameHeight = src->getHeight();
+
+ int highestDim = MAX(frameWidth, frameHeight);
+ bool lineDist[MADS_SCREEN_WIDTH];
+ int distIndex = 0;
+ int distXCount = 0, distYCount = 0;
+
+ int distCtr = 0;
+ do {
+ distCtr += scale;
+ if (distCtr < 100) {
+ lineDist[distIndex] = false;
+ } else {
+ lineDist[distIndex] = true;
+ distCtr -= 100;
+
+ if (distIndex < frameWidth)
+ ++distXCount;
+
+ if (distIndex < frameHeight)
+ ++distYCount;
+ }
+ } while (++distIndex < highestDim);
+
+ destX -= distXCount / 2;
+ destY -= distYCount - 1;
+
+ // Check x bounding area
+ int spriteLeft = 0;
+ int spriteWidth = distXCount;
+ int widthAmount = destX + distXCount - 1;
+
+ if (destX < 0) {
+ spriteWidth += destX;
+ spriteLeft -= destX;
+ }
+ widthAmount -= destRight;
+ if (widthAmount > 0)
+ spriteWidth -= widthAmount;
+
+ int spriteRight = spriteLeft + spriteWidth;
+ if (spriteWidth <= 0)
+ return;
+ if (!normalFrame) {
+ destX += distXCount - 1;
+ spriteLeft = -(distXCount - spriteRight);
+ spriteRight = (-spriteLeft + spriteWidth);
+ }
+
+ // Check y bounding area
+ int spriteTop = 0;
+ int spriteHeight = distYCount;
+ int heightAmount = destY + distYCount - 1;
+
+ if (destY < 0) {
+ spriteHeight += destY;
+ spriteTop -= destY;
+ }
+ heightAmount -= destBottom;
+ if (heightAmount > 0)
+ spriteHeight -= heightAmount;
+ int spriteBottom = spriteTop + spriteHeight;
+
+ if (spriteHeight <= 0)
+ return;
+
+ byte *destPixelsP = this->getBasePtr(destX + spriteLeft, destY + spriteTop);
+
+ spriteLeft = (spriteLeft * (normalFrame ? 1 : -1));
+
+ // Loop through the lines of the sprite
+ for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src->pitch) {
+ if (!lineDist[yp])
+ // Not a display line, so skip it
+ continue;
+ // Check whether the sprite line is in the display range
+ ++sprY;
+ if ((sprY >= spriteBottom) || (sprY < spriteTop))
+ continue;
+
+ // Found a line to display. Loop through the pixels
+ const byte *srcP = srcPixelsP;
+ byte *destP = destPixelsP;
+
+ for (int xp = 0, sprX = 0; xp < frameWidth; ++xp, ++srcP) {
+ if (xp < spriteLeft)
+ // Not yet reached start of display area
+ continue;
+ if (!lineDist[sprX++])
+ // Not a display pixel
+ continue;
+
+ // Get depth of current output pixel in depth surface
+ Common::Point pt((destP - (byte *)this->pixels) % this->pitch,
+ (destP - (byte *)this->pixels) / this->pitch);
+ int pixelDepth = (depthSurface == nullptr) ? 15 : depthSurface->getDepth(pt);
+
+ if ((*srcP != transparentColor) && (depth <= pixelDepth))
+ *destP = *srcP;
+
+ ++destP;
+ }
+
+ // Move to the next destination line
+ destPixelsP += this->pitch;
+ }
+}
+
+void MSurface::copyFromScaled(MSurface *src, const Common::Point &destPos, int depth,
+ DepthSurface *depthSurface, int scale, int transparentColor) {
+ int distXCount = 0, distYCount = 0;
+ int highestDim = MAX(src->w, src->h);
+ int accum = 0;
+
+ for (int idx = 0; idx < highestDim; ++idx) {
+ accum += scale;
+ if (accum >= 100) {
+ accum -= 100;
+ if (idx < src->w)
+ ++distXCount;
+ if (idx < src->h)
+ ++distYCount;
+ }
+ }
+
+ Common::Point newPos(destPos.x - distXCount / 2, destPos.y - distYCount);
+ copyFrom(src, src->getBounds(), newPos, transparentColor);
+}
+
+void MSurface::scrollX(int xAmount) {
+ if (xAmount == 0)
+ return;
+
+ byte buffer[80];
+ int direction = (xAmount > 0) ? -1 : 1;
+ int xSize = ABS(xAmount);
+ assert(xSize <= 80);
+
+ byte *srcP = getBasePtr(0, 0);
+
+ for (int y = 0; y < this->h; ++y, srcP += pitch) {
+ if (direction < 0) {
+ // Copy area to be overwritten
+ Common::copy(srcP, srcP + xSize, &buffer[0]);
+ // Shift the remainder of the line over the given area
+ Common::copy(srcP + xSize, srcP + this->w, srcP);
+ // Move buffered area to the end of the line
+ Common::copy(&buffer[0], &buffer[xSize], srcP + this->w - xSize);
+ } else {
+ // Copy area to be overwritten
+ Common::copy_backward(srcP + this->w - xSize, srcP + this->w, &buffer[80]);
+ // Shift the remainder of the line over the given area
+ Common::copy_backward(srcP, srcP + this->w - xSize, srcP + this->w);
+ // Move buffered area to the start of the line
+ Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize);
+ }
+ }
+}
+
+void MSurface::scrollY(int yAmount) {
+ if (yAmount == 0)
+ return;
+
+ int direction = (yAmount > 0) ? 1 : -1;
+ int ySize = ABS(yAmount);
+ assert(ySize < (this->h / 2));
+ assert(this->w == pitch);
+
+ int blockSize = ySize * this->w;
+ byte *tempData = new byte[blockSize];
+ byte *pixelsP = getBasePtr(0, 0);
+
+ if (direction > 0) {
+ // Buffer the lines to be overwritten
+ byte *srcP = (byte *)getBasePtr(0, this->h - ySize);
+ Common::copy(srcP, srcP + (pitch * ySize), tempData);
+ // Vertically shift all the lines
+ Common::copy_backward(pixelsP, pixelsP + (pitch * (this->h - ySize)),
+ pixelsP + (pitch * this->h));
+ // Transfer the buffered lines top the top of the screen
+ Common::copy(tempData, tempData + blockSize, pixelsP);
+ } else {
+ // Buffer the lines to be overwritten
+ Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData);
+ // Vertically shift all the lines
+ Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * this->h), pixelsP);
+ // Transfer the buffered lines to the bottom of the screen
+ Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (this->h - ySize)));
+ }
+
+ delete[] tempData;
+}
+
+
+void MSurface::translate(Common::Array<RGB6> &palette) {
+ for (int y = 0; y < this->h; ++y) {
+ byte *pDest = getBasePtr(0, y);
+
+ for (int x = 0; x < this->w; ++x, ++pDest) {
+ if (*pDest < 255) // scene 752 has some palette indices of 255
+ *pDest = palette[*pDest]._palIndex;
+ }
+ }
+}
+
+void MSurface::translate(byte map[PALETTE_COUNT]) {
+ for (int y = 0; y < this->h; ++y) {
+ byte *pDest = getBasePtr(0, y);
+
+ for (int x = 0; x < this->w; ++x, ++pDest) {
+ *pDest = map[*pDest];
+ }
+ }
+}
+
+MSurface *MSurface::flipHorizontal() const {
+ MSurface *dest = new MSurface(this->w, this->h);
+
+ for (int y = 0; y < this->h; ++y) {
+ const byte *srcP = getBasePtr(this->w - 1, y);
+ byte *destP = dest->getBasePtr(0, y);
+
+ for (int x = 0; x < this->w; ++x)
+ *destP++ = *srcP--;
+ }
+
+ return dest;
+}
+
+/*------------------------------------------------------------------------*/
+
+int DepthSurface::getDepth(const Common::Point &pt) {
+ if (_vm->_game->_scene._sceneInfo->_depthStyle == 2) {
+ int bits = (3 - (pt.x % 4)) * 2;
+ byte v = *getBasePtr(pt.x >> 2, pt.y);
+ return v >> bits;
+ } else {
+ if (pt.x < 0 || pt.y < 0 || pt.x >= this->w || pt.y >= this->h)
+ return 0;
+
+ return *getBasePtr(pt.x, pt.y) & 0xF;
+ }
+}
+
+int DepthSurface::getDepthHighBit(const Common::Point &pt) {
+ if (_vm->_game->_scene._sceneInfo->_depthStyle == 2) {
+ int bits = (3 - (pt.x % 4)) * 2;
+ byte v = *getBasePtr(pt.x >> 2, pt.y);
+ return (v >> bits) & 2;
+ } else {
+ if (pt.x < 0 || pt.y < 0 || pt.x >= this->w || pt.y >= this->h)
+ return 0;
+
+ return *getBasePtr(pt.x, pt.y) & 0x80;
+ }
+}
+
+
+} // End of namespace MADS
diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h
new file mode 100644
index 0000000000..985a097d4a
--- /dev/null
+++ b/engines/mads/msurface.h
@@ -0,0 +1,255 @@
+/* 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 MADS_MSURFACE_H
+#define MADS_MSURFACE_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+#include "mads/palette.h"
+
+namespace MADS {
+
+class MADSEngine;
+class MSprite;
+class DepthSurface;
+
+/**
+ * Basic sprite information
+ */
+struct SpriteInfo {
+ MSprite *sprite;
+ int hotX, hotY;
+ int width, height;
+ int scaleX, scaleY;
+ uint8 encoding;
+ byte *inverseColorTable;
+ byte *palette;
+};
+
+/*
+ * MADS graphics surface
+ */
+class MSurface : public Graphics::Surface {
+private:
+ bool _freeFlag;
+protected:
+ static MADSEngine *_vm;
+public:
+ /**
+ * Sets the engine refrence used all surfaces
+ */
+ static void setVm(MADSEngine *vm) { _vm = vm; }
+
+ /**
+ * Helper method for calculating new dimensions when scaling a sprite
+ */
+ static int scaleValue(int value, int scale, int err);
+public:
+ /**
+ * Basic constructor
+ */
+ MSurface();
+
+ /**
+ * Constructor for a surface with fixed dimensions
+ */
+ MSurface(int width, int height);
+
+ /**
+ * Destructor
+ */
+ virtual ~MSurface();
+
+ /**
+ * Reinitializes a surface to have a given set of dimensions
+ */
+ void setSize(int width, int height);
+
+ /**
+ * Sets the pixels the surface is associated with
+ * @remarks The surface will not free the data block
+ */
+ void setPixels(byte *pData, int horizSize, int vertSize);
+
+ /**
+ * Draws an arbitrary line on the screen using a specified color
+ * @param startPos Starting position
+ * @param endPos Ending position
+ * @param color Color to use
+ */
+ void line(const Common::Point &startPos, const Common::Point &endPos, byte color);
+
+ /**
+ * Draws a sprite
+ * @param pt Position to draw sprite at
+ * @param info General sprite details
+ * @param clipRect Clipping rectangle to constrain sprite drawing within
+ */
+ void drawSprite(const Common::Point &pt, SpriteInfo &info, const Common::Rect &clipRect);
+
+ /**
+ * Returns the width of the surface
+ */
+ int getWidth() const { return w; }
+
+ /**
+ * Returns the height of the surface
+ */
+ int getHeight() const { return h; }
+
+ /**
+ * Returns the size of the surface as a Rect
+ */
+ Common::Rect getBounds() const {
+ return Common::Rect(0, 0, w, h);
+ }
+
+ /**
+ * Returns a pointer to the surface data
+ */
+ byte *getData() { return (byte *)Graphics::Surface::getPixels(); }
+
+ /**
+ * Returns a pointer to a given position within the surface
+ */
+ byte *getBasePtr(int x, int y) { return (byte *)Graphics::Surface::getBasePtr(x, y); }
+
+ /**
+ * Returns a pointer to a given position within the surface
+ */
+ const byte *getBasePtr(int x, int y) const { return (const byte *)Graphics::Surface::getBasePtr(x, y); }
+
+ /**
+ * Clears the surface
+ */
+ void empty();
+
+ /**
+ * Copys a sub-section of another surface into the current one.
+ * @param src Source surface
+ * @param srcBounds Area of source surface to copy
+ * @param destPos Destination position to draw in current surface
+ * @param transparentColor Transparency palette index
+ */
+ void copyFrom(MSurface *src, const Common::Rect &srcBounds, const Common::Point &destPos,
+ int transparentColor = -1);
+
+ /**
+ * Copys a sub-section of another surface into the current one.
+ * @param src Source surface
+ * @param destPos Destination position to draw in current surface
+ * @param depth Depth of sprite
+ * @param depthSurface Depth surface to use with sprite depth
+ * @param scale Scale for image
+ * @param transparentColor Transparency palette index
+ */
+ void copyFrom(MSurface *src, const Common::Point &destPos, int depth, DepthSurface *depthSurface,
+ int scale, int transparentColor = -1);
+
+ /**
+ * Copys a sub-section of another surface into the current one, taking into
+ * account variation in the destination copy position based on item size
+ * and scaling.
+ * @param src Source surface
+ * @param destPos Destination position to draw in current surface
+ * @param depth Depth of sprite
+ * @param depthSurface Depth surface to use with sprite depth
+ * @param scale Scale for image
+ * @param transparentColor Transparency palette index
+ */
+ void copyFromScaled(MSurface *src, const Common::Point &destPos, int depth, DepthSurface *depthSurface,
+ int scale, int transparentColor = -1);
+
+ /**
+ * Copies the surface to a given destination surface
+ */
+ void copyTo(MSurface *dest, int transparentColor = -1) {
+ dest->copyFrom(this, Common::Rect(w, h), Common::Point(), transparentColor);
+ }
+
+ /**
+ * Copies the surface to a given destination surface
+ */
+ void copyTo(MSurface *dest, const Common::Point &pt, int transparentColor = -1) {
+ dest->copyFrom(this, Common::Rect(w, h), pt, transparentColor);
+ }
+
+ /**
+ * Copies the surface to a given destination surface
+ */
+ void copyTo(MSurface *dest, const Common::Rect &srcBounds, const Common::Point &destPos,
+ int transparentColor = -1) {
+ dest->copyFrom(this, srcBounds, destPos, transparentColor);
+ }
+
+ /**
+ * Scroll the screen horizontally by a given amount
+ * @param xAmount Horizontal amount
+ */
+ void scrollX(int xAmount);
+
+ /**
+ * Scroll the screen vertically by a given amount
+ * @param yAmount Vertical amount
+ */
+ void scrollY(int yAmount);
+
+ /**
+ * Translates the pixels of an image used the passed palette with RGB mapping
+ */
+ void translate(Common::Array<RGB6> &palette);
+
+ /**
+ * Translates the pixels of an image used the passed palette with RGB mapping
+ */
+ void translate(byte map[PALETTE_COUNT]);
+
+ /**
+ * Create a new surface which is a flipped horizontal copy of the current one
+ */
+ MSurface *flipHorizontal() const;
+};
+
+class DepthSurface : public MSurface {
+private:
+ MADSEngine *_vm;
+public:
+ /**
+ * Constructor
+ */
+ DepthSurface(MADSEngine *vm) : _vm(vm) {}
+
+ /**
+ * Returns the depth at a given position
+ */
+ int getDepth(const Common::Point &pt);
+
+ /**
+ */
+ int getDepthHighBit(const Common::Point &pt);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_MSURFACE_H */
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
new file mode 100644
index 0000000000..d8a85d472d
--- /dev/null
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -0,0 +1,698 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/util.h"
+#include "mads/mads.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/staticres.h"
+#include "mads/nebular/dialogs_nebular.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+bool DialogsNebular::show(int messageId, int objectId) {
+ MADSAction &action = _vm->_game->_scene._action;
+ Common::StringArray msg = _vm->_game->getMessage(messageId);
+ Common::String title;
+ Common::String commandText;
+ Common::String valStr;
+ Common::String dialogText;
+ bool result = true;
+ bool centerFlag = false;
+ bool underlineFlag = false;
+ bool commandFlag = false;
+ bool crFlag = false;
+ TextDialog *dialog = nullptr;
+ _dialogWidth = 17;
+ _capitalizationMode = kUppercase;
+
+ // Loop through the lines of the returned text
+ for (uint idx = 0; idx < msg.size(); ++idx) {
+ Common::String srcLine = msg[idx];
+ const char *srcP = srcLine.c_str();
+
+ // Loop through the text of the line
+ while (srcP < srcLine.c_str() + srcLine.size()) {
+ if (*srcP == '[') {
+ // Starting a command
+ commandText = "";
+ commandFlag = true;
+ } else if (*srcP == ']') {
+ // Ending a command
+ if (commandFlag) {
+ if (commandCheck("CENTER", valStr, commandText)) {
+ centerFlag = true;
+ } else if (commandCheck("TITLE", valStr, commandText)) {
+ centerFlag = true;
+ underlineFlag = true;
+ crFlag = true;
+ int v = atoi(valStr.c_str());
+ if (v != 0)
+ _dialogWidth = v;
+ } else if (commandCheck("CR", valStr, commandText)) {
+ if (centerFlag) {
+ crFlag = true;
+ } else {
+ if (objectId == -1) {
+ dialog = new TextDialog(_vm, FONT_INTERFACE, _defaultPosition, _dialogWidth);
+ } else {
+ dialog = new PictureDialog(_vm, _defaultPosition, _dialogWidth, objectId);
+ }
+ dialog->wordWrap(dialogText);
+ dialog->incNumLines();
+ }
+ } else if (commandCheck("ASK", valStr, commandText)) {
+ dialog->addInput();
+ } else if (commandCheck("VERB", valStr, commandText)) {
+ dialogText += getVocab(action._activeAction._verbId);
+ } else if (commandCheck("INDEX", valStr, commandText)) {
+ int idxLocal = atoi(valStr.c_str());
+ if (_indexList[idxLocal])
+ dialogText += getVocab(_indexList[idxLocal]);
+ } else if (commandCheck("NUMBER", valStr, commandText)) {
+ int idxLocal = atoi(valStr.c_str());
+ dialogText += Common::String::format("%.4d", _indexList[idxLocal]);
+ } else if (commandCheck("NOUN1", valStr, commandText)) {
+ if (!textNoun(dialogText, 1, valStr))
+ dialogText += getVocab(action._activeAction._objectNameId);
+ } else if (commandCheck("NOUN2", valStr, commandText)) {
+ if (!textNoun(dialogText, 2, valStr))
+ dialogText += getVocab(action._activeAction._indirectObjectId);
+ } else if (commandCheck("PREP", valStr, commandText)) {
+ dialogText += kArticleList[action._savedFields._articleNumber];
+ } else if (commandCheck("SENTENCE", valStr, commandText)) {
+ dialogText += action._sentence;
+ } else if (commandCheck("WIDTH", valStr, commandText)) {
+ _dialogWidth = atoi(valStr.c_str());
+ } else if (commandCheck("BAR", valStr, commandText)) {
+ dialog->addBarLine();
+ } else if (commandCheck("UNDER", valStr, commandText)) {
+ underlineFlag = true;
+ } else if (commandCheck("DOWN", valStr, commandText)) {
+ dialog->downPixelLine();
+ } else if (commandCheck("TAB", valStr, commandText)) {
+ int xp = atoi(valStr.c_str());
+ dialog->setLineXp(xp);
+ }
+ }
+
+ commandFlag = false;
+ } else if (commandFlag) {
+ // Add the next character to the command
+ commandText += *srcP;
+ } else {
+ // Add to the text to be displayed in the dialog
+ dialogText += *srcP;
+ }
+
+ ++srcP;
+ }
+
+ if (!dialog) {
+ if (objectId == -1) {
+ dialog = new TextDialog(_vm, FONT_INTERFACE, _defaultPosition, _dialogWidth);
+ } else {
+ dialog = new PictureDialog(_vm, _defaultPosition, _dialogWidth, objectId);
+ }
+ }
+
+ if (centerFlag) {
+ dialog->addLine(dialogText, underlineFlag);
+ if (crFlag)
+ dialog->incNumLines();
+ } else {
+ dialog->wordWrap(dialogText);
+ }
+
+ // Reset line processing flags in preparation for next line
+ dialogText = "";
+ commandFlag = false;
+ underlineFlag = false;
+ centerFlag = false;
+ crFlag = false;
+ }
+
+ if (!centerFlag)
+ dialog->incNumLines();
+
+ // Show the dialog
+ _vm->_events->setCursor(CURSOR_ARROW);
+ dialog->show();
+
+ delete dialog;
+ return result;
+}
+
+void DialogsNebular::showItem(int objectId, int messageId, int speech) {
+ // MADS engine doesn't currently support speech
+ assert(!speech);
+
+ show(messageId, objectId);
+}
+
+Common::String DialogsNebular::getVocab(int vocabId) {
+ assert(vocabId > 0);
+
+ Common::String vocab = _vm->_game->_scene.getVocab(vocabId);
+
+ switch (_capitalizationMode) {
+ case kUppercase:
+ vocab.toUppercase();
+ break;
+ case kLowercase:
+ vocab.toLowercase();
+ break;
+ case kUpperAndLower:
+ vocab.toLowercase();
+ vocab.setChar(toupper(vocab[0]), 0);
+ default:
+ break;
+ }
+
+ return vocab;
+}
+
+bool DialogsNebular::textNoun(Common::String &dest, int nounId, const Common::String &source) {
+ // Ensure the destination has parameter specifications
+ if (!source.hasPrefix(":"))
+ return false;
+
+ // Extract the first (singular) result value
+ Common::String param1 = Common::String(source.c_str() + 1);
+ Common::String param2;
+ const char *sepChar = strchr(source.c_str() + 1, ':');
+ if (sepChar) {
+ param1 = Common::String(source.c_str() + 1, sepChar);
+
+ // Get the second, plural form
+ param2 = Common::String(sepChar + 1);
+ }
+
+ // Get the vocab to use
+ MADSAction &action = _vm->_game->_scene._action;
+ Common::String vocab = _vm->_dialogs->getVocab(action._activeAction._verbId);
+ Common::String *str;
+
+ if (vocab.hasSuffix("s") || vocab.hasSuffix("S")) {
+ str = &param2;
+ } else {
+ str = &param1;
+
+ if (param1 == "a ") {
+ switch (toupper(vocab[0])) {
+ case 'A':
+ case 'E':
+ case 'I':
+ case 'O':
+ case 'U':
+ param1 = "an ";
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ dest += *str;
+ return true;
+}
+
+bool DialogsNebular::commandCheck(const char *idStr, Common::String &valStr,
+ const Common::String &command) {
+ uint idLen = strlen(idStr);
+
+ valStr = (command.size() <= idLen) ? "" : Common::String(command.c_str() + idLen);
+
+ // Check whether the command starts with the given Id
+ int result = scumm_strnicmp(idStr, command.c_str(), idLen) == 0;
+ if (!result)
+ return false;
+
+ // It does, so set the command case mode
+ if (Common::isUpper(command[0]) && Common::isUpper(command[1])) {
+ _capitalizationMode = kUppercase;
+ } else if (Common::isUpper(command[0])) {
+ _capitalizationMode = kUpperAndLower;
+ } else {
+ _capitalizationMode = kLowercase;
+ }
+
+ return true;
+}
+
+void DialogsNebular::showDialog() {
+ switch (_pendingDialog) {
+ case DIALOG_GAME_MENU:
+ //GameMenuDialog::show();
+ break;
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+CopyProtectionDialog::CopyProtectionDialog(MADSEngine *vm, bool priorAnswerWrong) :
+TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) {
+ getHogAnusEntry(_hogEntry);
+
+ if (priorAnswerWrong) {
+ addLine("ANSWER INCORRECT!", true);
+ wordWrap("\n");
+ addLine("(But we'll give you another chance!)");
+ }
+ else {
+ addLine("REX NEBULAR version 8.43", true);
+ wordWrap("\n");
+ addLine("(Copy Protection, for your convenience)");
+ }
+ wordWrap("\n");
+
+ wordWrap("Now comes the part that everybody hates. But if we don't");
+ wordWrap("do this, nasty rodent-like people will pirate this game");
+ wordWrap("and a whole generation of talented designers, programmers,");
+ wordWrap("artists, and playtesters will go hungry, and will wander");
+ wordWrap("aimlessly through the land at night searching for peace.");
+ wordWrap("So let's grit our teeth and get it over with. Just get");
+
+ Common::String line = "out your copy of ";
+ line += _hogEntry._bookId == 103 ? "the GAME MANUAL" : "REX'S LOGBOOK";
+ line += ". See! That was easy. ";
+ wordWrap(line);
+
+ line = Common::String::format("Next, just turn to page %d. On line %d, find word number %d, ",
+ _hogEntry._pageNum, _hogEntry._lineNum, _hogEntry._wordNum);
+ wordWrap(line);
+
+ wordWrap("and type it on the line below (we',27h,'ve even given you");
+ wordWrap("first letter as a hint). As soon as you do that, we can get");
+ wordWrap("right into this really COOL adventure game!\n");
+ wordWrap("\n");
+ wordWrap(" ");
+ addInput();
+ wordWrap("\n");
+}
+
+void CopyProtectionDialog::show() {
+ draw();
+ _vm->_events->showCursor();
+
+ // TODO: Replace with text input
+ while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed() &&
+ !_vm->_events->_mouseClicked) {
+ _vm->_events->delay(1);
+ }
+
+ _vm->_events->_pendingKeys.clear();
+}
+
+bool CopyProtectionDialog::getHogAnusEntry(HOGANUS &entry) {
+ File f;
+ f.open("*HOGANUS.DAT");
+
+ // Read in the total number of entries, and randomly pick an entry to use
+ int numEntries = f.readUint16LE();
+ int entryIndex = _vm->getRandomNumber(1, numEntries);
+
+ // Read in the encrypted entry
+ f.seek(28 * entryIndex + 2);
+ byte entryData[28];
+ f.read(entryData, 28);
+
+ // Decrypt it
+ for (int i = 0; i < 28; ++i)
+ entryData[i] = ~entryData[i];
+
+ // Fill out the fields
+ entry._bookId = entryData[0];
+ entry._pageNum = READ_LE_UINT16(&entryData[2]);
+ entry._lineNum = READ_LE_UINT16(&entryData[4]);
+ entry._wordNum = READ_LE_UINT16(&entryData[6]);
+ entry._word = Common::String((char *)&entryData[8]);
+
+ f.close();
+ return true;
+}
+
+/*------------------------------------------------------------------------*/
+
+PictureDialog::PictureDialog(MADSEngine *vm, const Common::Point &pos,
+ int maxChars, int objectId) :
+ TextDialog(vm, FONT_INTERFACE, pos, maxChars), _objectId(objectId) {
+ // Turn off cycling if active
+ Scene &scene = _vm->_game->_scene;
+ _cyclingActive = scene._cyclingActive;
+ scene._cyclingActive = false;
+}
+
+PictureDialog::~PictureDialog() {
+ // Restore cycling flag
+ Scene &scene = _vm->_game->_scene;
+ scene._cyclingActive = _cyclingActive;
+}
+
+void PictureDialog::save() {
+ Palette &palette = *_vm->_palette;
+ byte map[PALETTE_COUNT];
+
+ // Save the entire screen
+ _savedSurface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT);
+ _vm->_screen.copyTo(_savedSurface);
+
+ // Save palette information
+ Common::copy(&palette._mainPalette[0], &palette._mainPalette[PALETTE_SIZE], &_palette[0]);
+ Common::copy(&palette._palFlags[0], &palette._palFlags[PALETTE_COUNT], &_palFlags[0]);
+ _rgbList.copy(palette._rgbList);
+
+ // Set up palette allocation
+ Common::fill(&palette._colorFlags[0], &palette._colorFlags[3], true);
+
+ uint32 *palFlagP = &palette._palFlags[0];
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx, ++palFlagP) {
+ if (idx < PALETTE_RESERVED_LOW_COUNT ||
+ idx >= (PALETTE_COUNT - PALETTE_RESERVED_HIGH_COUNT - 10)) {
+ *palFlagP = 1;
+ map[idx] = idx;
+ } else {
+ *palFlagP = 0;
+ }
+ }
+
+ // Reset the flag list
+ palette._rgbList.reset();
+
+ // Fade the screen to grey
+ int numColors = PALETTE_COUNT - PALETTE_RESERVED_LOW_COUNT - PALETTE_RESERVED_HIGH_COUNT;
+ palette.fadeOut(palette._mainPalette, &map[PALETTE_RESERVED_LOW_COUNT],
+ PALETTE_RESERVED_LOW_COUNT, numColors, 248, 8, 1, 16);
+
+ // Remap the greyed out screen to use the small greyscale range
+ // at the top end of the palette
+ _vm->_screen.translate(map);
+
+ // Load the inventory picture
+ Common::String setName = Common::String::format("*OB%.3d.SS", _objectId);
+ SpriteAsset *asset = new SpriteAsset(_vm, setName, 0x8000);
+ palette.setFullPalette(palette._mainPalette);
+
+ // Get the inventory frame, and adjust the dialog position to allow for it
+ MSprite *frame = asset->getFrame(0);
+ _position.y = frame->h + 12;
+
+ // Draw the inventory picture
+ frame->copyTo(&_vm->_screen, Common::Point(160 - frame->w / 2, 6),
+ frame->getTransparencyIndex());
+ _vm->_screen.copyRectToScreen(_vm->_screen.getBounds());
+
+ // Adjust the dialog colors to use
+ TEXTDIALOG_CONTENT1 -= 10;
+ TEXTDIALOG_CONTENT2 -= 10;
+ TEXTDIALOG_EDGE -= 10;
+ TEXTDIALOG_BACKGROUND -= 10;
+ TEXTDIALOG_FC -= 10;
+ TEXTDIALOG_FD -= 10;
+ TEXTDIALOG_FE -= 10;
+}
+
+void PictureDialog::restore() {
+ if (_savedSurface) {
+ _savedSurface->copyTo(&_vm->_screen);
+ delete _savedSurface;
+ _savedSurface = nullptr;
+
+ _vm->_screen.copyRectToScreen(_vm->_screen.getBounds());
+
+ // Restore palette information
+ Palette &palette = *_vm->_palette;
+ Common::copy(&_palette[0], &_palette[PALETTE_SIZE], &palette._mainPalette[0]);
+ _vm->_palette->setFullPalette(palette._mainPalette);
+ Common::copy(&_palFlags[0], &_palFlags[PALETTE_COUNT], &palette._palFlags[0]);
+ palette._rgbList.copy(_rgbList);
+
+ _vm->_dialogs->_defaultPosition.y = -1;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+ScreenDialog::DialogLine::DialogLine() {
+ _state = 0;
+ _textDisplayIndex = -1;
+ _font = nullptr;
+ _widthAdjust = 0;
+}
+
+ScreenDialog::DialogLine::DialogLine(const Common::String &s) {
+ _state = 0;
+ _textDisplayIndex = -1;
+ _font = nullptr;
+ _widthAdjust = -1;
+ _msg = s;
+}
+
+/*------------------------------------------------------------------------*/
+
+ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm),
+ _savedSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT) {
+ Game &game = *_vm->_game;
+ Scene &scene = game._scene;
+
+ _v1 = 0;
+ _selectedLine = 0;
+ _dirFlag = false;
+ _textLineCount = 0;
+ _screenId = 920;
+
+ game.loadQuoteSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0);
+ game._kernelMode = KERNEL_ROOM_PRELOAD;
+ _vm->_events->waitCursor();
+ scene.clearVocab();
+ scene._dynamicHotspots.clear();
+ _vm->_dialogs->_defaultPosition = Common::Point(-1, -1);
+
+ bool palFlag = false;
+ int nextSceneId = scene._nextSceneId;
+ int currentSceneId = scene._currentSceneId;
+ int priorSceneId = scene._priorSceneId;
+
+ if (_vm->_dialogs->_pendingDialog == DIALOG_DIFFICULTY) {
+ palFlag = true;
+ } else {
+ _vm->_palette->initPalette();
+ }
+ scene.loadScene(_screenId, game._aaName, palFlag);
+
+ scene._priorSceneId = priorSceneId;
+ scene._currentSceneId = currentSceneId;
+ scene._nextSceneId = nextSceneId;
+ _vm->_screen._offset.y = 22;
+ _vm->_sound->pauseNewCommands();
+ _vm->_events->initVars();
+ game._kernelMode = KERNEL_ROOM_INIT;
+
+ SpriteAsset *menuSprites = new SpriteAsset(_vm, "*MENU", 0);
+ _menuSpritesIndex = scene._sprites.add(menuSprites);
+
+ byte pal[768];
+ if (_vm->_screenFade) {
+ Common::fill(&pal[0], &pal[PALETTE_SIZE], 0);
+ _vm->_palette->setFullPalette(pal);
+ } else {
+ _vm->_palette->getFullPalette(pal);
+ _vm->_palette->fadeOut(pal, nullptr, 0, PALETTE_COUNT, 0, 1, 1, 16);
+ }
+
+ _vm->_screen.copyTo(&_savedSurface);
+ /*
+ _vm->_screen.hLine(0, 0, MADS_SCREEN_WIDTH, 2);
+ _vm->_screen.copyRectToScreen(Common::Rect(0, _vm->_screen._offset.y,
+ MADS_SCREEN_WIDTH, _vm->_screen._offset.y + 1));
+ _vm->_screen.copyRectToScreen(Common::Rect(0, _vm->_screen._offset.y + 157,
+ MADS_SCREEN_WIDTH, _vm->_screen._offset.y + 157));
+ */
+
+ game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ?
+ kCenterVertTransition : kTransitionFadeIn;
+ game._trigger = 0;
+ _vm->_events->setCursor(CURSOR_ARROW);
+
+ _vm->_palette->setEntry(10, 0, 63, 0);
+ _vm->_palette->setEntry(11, 0, 45, 0);
+ _vm->_palette->setEntry(12, 63, 63, 0);
+ _vm->_palette->setEntry(13, 45, 45, 0);
+ _vm->_palette->setEntry(14, 63, 63, 63);
+ _vm->_palette->setEntry(15, 45, 45, 45);
+
+ _lineIndex = -1;
+}
+
+void ScreenDialog::clearLines() {
+ Scene &scene = _vm->_game->_scene;
+ _lines.clear();
+ scene._spriteSlots.fullRefresh(true);
+}
+
+void ScreenDialog::addQuote(int id1, int id2, DialogTextAlign align,
+ const Common::Point &pt, Font *font) {
+ Common::String msg = _vm->_game->getQuote(id1);
+
+ if (id2 > 0) {
+ msg += " ";
+ msg += _vm->_game->getQuote(id2);
+ }
+
+ addLine(msg, align, pt, font);
+}
+
+void ScreenDialog::addLine(const Common::String &msg, DialogTextAlign align,
+ const Common::Point &pt, Font *font) {
+ Scene &scene = _vm->_game->_scene;
+ DialogLine *line;
+
+ if (_lineIndex < (int)_lines.size()) {
+ if (_lines.size() >= 20) {
+ ++_lineIndex;
+ return;
+ }
+
+ _lines.push_back(msg);
+ line = &_lines[_lines.size() - 1];
+ } else {
+ line = &_lines[_lineIndex];
+ if (msg.compareToIgnoreCase(msg)) {
+ ++_lineIndex;
+ return;
+ }
+
+ if (line->_textDisplayIndex >= 0) {
+ TextDisplay &textDisplay = scene._textDisplay[line->_textDisplayIndex];
+ if (textDisplay._active) {
+ textDisplay._expire = -1;
+ if (_textLineCount < 20) {
+ textDisplay._msg = msg;
+ ++_textLineCount;
+ }
+ }
+ }
+ }
+
+ line->_font = font;
+ line->_state = 0;
+ line->_pos = pt;
+ line->_widthAdjust = -1;
+ line->_textDisplayIndex = -1;
+
+ int xOffset;
+ switch (align) {
+ case ALIGN_CENTER:
+ xOffset = (MADS_SCREEN_WIDTH / 2) - font->getWidth(msg, -1) / 2;
+ line->_pos.x += xOffset;
+ break;
+
+ case ALIGN_AT_CENTER: {
+ const char *msgP = msg.c_str();
+ const char *ch = strchr(msgP, '@');
+ if (ch) {
+ xOffset = (MADS_SCREEN_WIDTH / 2) - font->getWidth(
+ Common::String(msgP, ch), line->_widthAdjust);
+ line->_pos.x += xOffset;
+ }
+ break;
+ }
+
+ case ALIGN_RIGHT:
+ xOffset = font->getWidth(msg, -1);
+ line->_pos.x -= xOffset;
+ break;
+
+ default:
+ break;
+ }
+
+ ++_lineIndex;
+}
+
+void ScreenDialog::initVars() {
+ _v1 = -1;
+ _selectedLine = -1;
+ _lineIndex = 0;
+ _textLineCount = 0;
+}
+
+void ScreenDialog::chooseBackground() {
+ switch (_vm->_game->_currentSectionNumber) {
+ case 1:
+ case 2:
+ _screenId = 921;
+ break;
+ case 3:
+ case 4:
+ _screenId = 922;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ _screenId = 923;
+ break;
+ case 8:
+ _screenId = 924;
+ break;
+ default:
+ _screenId = 920;
+ break;
+ }
+}
+
+void ScreenDialog::setFrame(int frameNumber, int depth) {
+ Scene &scene = _vm->_game->_scene;
+ SpriteSlot &spriteSlot = scene._spriteSlots[scene._spriteSlots.add()];
+ spriteSlot._flags = IMG_UPDATE;
+ spriteSlot._seqIndex = 1;
+ spriteSlot._spritesIndex = _menuSpritesIndex;
+ spriteSlot._frameNumber = frameNumber;
+
+}
+
+/*------------------------------------------------------------------------*/
+
+GameMenuDialog::GameMenuDialog(MADSEngine *vm) : ScreenDialog(vm) {
+ clearLines();
+ setFrame(1, 2);
+}
+
+void GameMenuDialog::addLines() {
+ initVars();
+ Font *font = _vm->_font->getFont(FONT_CONVERSATION);
+ int top = 78 - (font->getHeight() + 2) * 12;
+ addQuote(10, 0, ALIGN_CENTER, Common::Point(0, top), font);
+ // TODO
+}
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
new file mode 100644
index 0000000000..0554becea4
--- /dev/null
+++ b/engines/mads/nebular/dialogs_nebular.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 MADS_DIALOGS_NEBULAR_H
+#define MADS_DIALOGS_NEBULAR_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/dialogs.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+enum CapitalizationMode { kUppercase = 0, kLowercase = 1, kUpperAndLower = 2 };
+
+class DialogsNebular : public Dialogs {
+ friend class Dialogs;
+private:
+ int _dialogWidth;
+ CapitalizationMode _capitalizationMode;
+
+ DialogsNebular(MADSEngine *vm): Dialogs(vm), _capitalizationMode(kUppercase) {}
+
+ virtual Common::String getVocab(int vocabId);
+
+ bool textNoun(Common::String &dest, int nounId, const Common::String &source);
+
+ bool commandCheck(const char *idStr, Common::String &valStr, const Common::String &command);
+public:
+ virtual void showDialog();
+
+ virtual void showItem(int objectId, int messageId, int speech = -1);
+
+ virtual bool show(int messageId, int objectId = -1);
+};
+
+struct HOGANUS {
+ int _bookId;
+ int _pageNum;
+ int _lineNum;
+ int _wordNum;
+ Common::String _word;
+};
+
+class CopyProtectionDialog : public TextDialog {
+private:
+ HOGANUS _hogEntry;
+
+ /**
+ * Get a random copy protection entry from the HOGANUS resource
+ */
+ bool getHogAnusEntry(HOGANUS &entry);
+public:
+ /**
+ * Constructor
+ */
+ CopyProtectionDialog(MADSEngine *vm, bool priorAnswerWrong);
+
+ /**
+ * Show the dialog
+ */
+ virtual void show();
+};
+
+class PictureDialog : public TextDialog {
+private:
+ int _objectId;
+ bool _cyclingActive;
+ byte _palette[PALETTE_SIZE];
+ uint32 _palFlags[PALETTE_COUNT];
+ RGBList _rgbList;
+protected:
+ virtual void save();
+
+ virtual void restore();
+public:
+ PictureDialog(MADSEngine *vm, const Common::Point &pos, int maxChars, int objectId);
+
+ virtual ~PictureDialog();
+};
+
+enum DialogTextAlign { ALIGN_CENTER = -1, ALIGN_AT_CENTER = -2, ALIGN_RIGHT = -3 };
+
+class ScreenDialog {
+ struct DialogLine {
+ int _state;
+ Common::Point _pos;
+ int _textDisplayIndex;
+ Common::String _msg;
+ Font *_font;
+ int _widthAdjust;
+
+ DialogLine();
+ DialogLine(const Common::String &s);
+ };
+protected:
+ MADSEngine *_vm;
+ MSurface _savedSurface;
+ Common::Array<DialogLine> _lines;
+ int _v1;
+ int _selectedLine;
+ bool _dirFlag;
+ int _screenId;
+ int _menuSpritesIndex;
+ int _lineIndex;
+ int _textLineCount;
+
+ /**
+ * Reset the lines list for the dialog
+ */
+ void clearLines();
+
+ /**
+ * Add a quote to the lines list
+ */
+ void addQuote(int id1, int id2, DialogTextAlign align, const Common::Point &pt, Font *font);
+
+ /**
+ * Adds a line to the lines list
+ */
+ void addLine(const Common::String &msg, DialogTextAlign align, const Common::Point &pt, Font *font);
+
+ /**
+ * Initializes variables
+ */
+ void initVars();
+
+ /**
+ * Sets the display for the screen background behind the dialog
+ */
+ void setFrame(int frameNumber, int depth);
+
+ /**
+ * Choose the background to display for the dialog
+ */
+ void chooseBackground();
+public:
+ /**
+ * Constructor
+ */
+ ScreenDialog(MADSEngine *vm);
+};
+
+class GameMenuDialog : public ScreenDialog {
+private:
+ /**
+ * Add the lines for the Game Menu dialog
+ */
+ void addLines();
+public:
+ GameMenuDialog(MADSEngine *vm);
+
+};
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_DIALOGS_NEBULAR_H */
diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp
new file mode 100644
index 0000000000..e5a59a0050
--- /dev/null
+++ b/engines/mads/nebular/game_nebular.cpp
@@ -0,0 +1,819 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/game.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/nebular/game_nebular.h"
+#include "mads/nebular/dialogs_nebular.h"
+#include "mads/nebular/globals_nebular.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+GameNebular::GameNebular(MADSEngine *vm)
+ : Game(vm) {
+ _surface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+ _storyMode = STORYMODE_NAUGHTY;
+ _difficulty = DIFFICULTY_EASY;
+}
+
+ProtectionResult GameNebular::checkCopyProtection() {
+ /*
+ // DEBUG: Flag copy protection failure
+ _globals[kCopyProtectFailed] = -1;
+
+ if (!ConfMan.getBool("copy_protection"))
+ return true;
+
+ * DEBUG: Disabled for now
+ CopyProtectionDialog *dlg = new CopyProtectionDialog(_vm, false);
+ dlg->show();
+ delete dlg;
+ */
+
+ // DEBUG: Return that copy protection failed
+ return PROTECTION_SUCCEED;
+}
+
+void GameNebular::initializeGlobals() {
+ int count, count2;
+ int bad;
+
+ _globals.reset();
+ _globals[kTalkInanimateCount] = 8;
+
+ /* Section #1 variables */
+ _globals[kNeedToStandUp] = true;
+ _globals[kTurkeyExploded] = false;
+ _globals[kMedicineCabinetOpen] = false;
+ _globals[kMedicineCabinetVirgin] = true;
+ _globals[kWatchedViewScreen] = false;
+ _globals[kHoovicAlive] = true;
+ _globals[kWaterInAPuddle] = false;
+
+ _globals[kFishIn105] = true;
+ _globals[kFishIn107] = true;
+ _globals[kFishIn108] = true;
+
+ /* Section #2 variables */
+ _globals[kLadderBroken] = false;
+ _globals[kBone202Status] = 0;
+ _globals[kRhotundaStatus] = RHOTUNDA_HUNGRY;
+ _globals[kMonkeyStatus] = MONKEY_AMBUSH_READY;
+ _globals[kMeteorologistStatus] = METEOROLOGIST_PRESENT;
+ _globals[kMeteorologistEverSeen] = false;
+ _globals[kMeteorologistWatch] = METEOROLOGIST_NORMAL;
+ _globals[kTeleporterCommand] = TELEPORTER_NONE;
+ _globals[kTeleporterUnderstood] = false;
+ _globals[kTwinklesStatus] = TWINKLES_AT_HOME;
+ _globals[kTwinklesApproached] = 0;
+
+ /* Section #3 variables */
+ _globals[kAfterHavoc] = false;
+ _globals[kKickedIn391Grate] = false;
+
+ /* Section #4 variables */
+ _globals[kBadFirstIngredient] = -1;
+ _objects[OBJ_CHARGE_CASES].setQuality(EXPLOSIVES_INSIDE, 0);
+ _globals[kHasPurchased] = false;
+ _globals[kBeenThruHelgaScene] = false;
+ _globals[kNextIngredient] = 0;
+ _globals[kHasSaidTimer] = false;
+ _globals[kHasSaidBinocs] = false;
+ _globals[kBottleDisplayed] = false;
+ _globals[kHasBeenScanned] = false;
+ _globals[kSomeoneHasExploded] = false;
+
+ // Generate a random ingredient list
+ for (count = 0; count < 4; ++count) {
+ do {
+ _globals[kIngredientList + count] = _vm->getRandomNumber(3);
+ bad = false;
+ for (count2 = 0; count2 < count; ++count2) {
+ if (_globals[kIngredientList + count] == _globals[kIngredientList + count2]) {
+ bad = true;
+ }
+ }
+ } while (bad);
+ }
+
+ // Generate random ingredient quantities
+ for (count = 0; count < 4; ++count) {
+ do {
+ _globals[kIngredientQuantity + count] = _vm->getRandomNumber(3);
+ bad = false;
+ for (count2 = 0; count2 < count; ++count2) {
+ if (_globals[kIngredientQuantity + count] == _globals[kIngredientQuantity + count2]) {
+ bad = true;
+ }
+ }
+ } while (bad);
+ }
+
+
+ /* Section #5 variables */
+ _globals[kHoverCarLocation] = 501;
+ _globals[kHoverCarDestination] = -1;
+ _globals[kCityFlooded] = false;
+ _globals[kBoatRaised] = true;
+ _globals[kLaserHoleIsThere] = false;
+ _globals[kLineStatus] = LINE_NOT_DROPPED;
+
+
+ /* Section #6 variables */
+ _globals[kHasTalkedToHermit] = false;
+ _globals[kHandsetCellStatus] = FIRST_TIME_PHONE_CELLS;
+ _globals[kTimebombStatus] = TIMEBOMB_DEACTIVATED;
+ _globals[kWarnedFloodCity] = false;
+ _globals._timebombClock = 0;
+ _globals._timebombTimer = 0;
+
+
+ /* Section #7 variables */
+ _globals[kBottleStatus] = BOTTLE_EMPTY;
+ _globals[kBoatStatus] = BOAT_UNFLOODED;
+
+
+ /* Section #8 variables */
+ _globals[kWindowFixed] = false;
+ _globals[kInSpace] = false;
+ _globals[kReturnFromCut] = false;
+ _globals[kBeamIsUp] = false;
+ _globals[kForceBeamDown] = false;
+ _globals[kCameFromCut] = false;
+ _globals[kDontRepeat] = false;
+ _globals[kHoppyDead] = false;
+ _globals[kHasWatchedAntigrav] = false;
+ _globals[kRemoteSequenceRan] = false;
+ _globals[kRemoteOnGround] = false;
+ _globals[kFromCockpit] = false;
+ _globals[kExitShip] = false;
+ _globals[kBetweenRooms] = false;
+ _globals[kTopButtonPushed] = false;
+ _globals[kShieldModInstalled] = false;
+ _globals[kTargetModInstalled] = false;
+ _globals[kUpBecauseOfRemote] = false;
+
+
+ /* Set up the game's teleporters */
+ _globals[kTeleporterRoom] = 201;
+ _globals[kTeleporterRoom + 1] = 301;
+ _globals[kTeleporterRoom + 2] = 413;
+ _globals[kTeleporterRoom + 3] = 706;
+ _globals[kTeleporterRoom + 4] = 801;
+ _globals[kTeleporterRoom + 5] = 551;
+ _globals[kTeleporterRoom + 6] = 752;
+ _globals[kTeleporterRoom + 7] = 0;
+ _globals[kTeleporterRoom + 8] = 0;
+ _globals[kTeleporterRoom + 9] = 0;
+
+ for (count = 0; count < TELEPORTER_COUNT; ++count) {
+ do {
+ _globals[kTeleporterCode + count] = _vm->getRandomNumber(9999);
+ bad = false;
+ for (count2 = 0; count2 < count; ++count2) {
+ if (_globals[kTeleporterCode + count] == _globals[kTeleporterCode + count2]) {
+ bad = true;
+ }
+ }
+ } while (bad);
+ }
+
+ // Final setup based on selected difficulty level
+ switch (_difficulty) {
+ case DIFFICULTY_HARD:
+ _objects.setRoom(OBJ_PLANT_STALK, NOWHERE);
+ _objects.setRoom(OBJ_PENLIGHT, NOWHERE);
+
+ _globals[kLeavesStatus] = LEAVES_ON_TRAP;
+ break;
+
+ case DIFFICULTY_MEDIUM:
+ _objects.setRoom(OBJ_PLANT_STALK, NOWHERE);
+
+ _globals[kLeavesStatus] = LEAVES_ON_GROUND;
+ _globals[kDurafailRecharged] = true;
+ _globals[kPenlightCellStatus] = FIRST_TIME_CHARGED_DURAFAIL;
+ break;
+
+ case DIFFICULTY_EASY:
+ _objects.setRoom(OBJ_BLOWGUN, NOWHERE);
+ _objects.setRoom(OBJ_NOTE, NOWHERE);
+
+ _globals[kLeavesStatus] = LEAVES_ON_GROUND;
+ _globals[kPenlightCellStatus] = FIRST_TIME_UNCHARGED_DURAFAIL;
+ _globals[kDurafailRecharged] = false;
+ break;
+ }
+
+ _player._facing = FACING_NORTH;
+ _player._turnToFacing = FACING_NORTH;
+
+ Player::preloadSequences("RXM", 1);
+ Player::preloadSequences("ROX", 1);
+}
+
+void GameNebular::setSectionHandler() {
+ delete _sectionHandler;
+
+ switch (_sectionNumber) {
+ case 1:
+ _sectionHandler = new Section1Handler(_vm);
+ break;
+ case 2:
+ _sectionHandler = new Section2Handler(_vm);
+ break;
+ case 3:
+ _sectionHandler = new Section3Handler(_vm);
+ break;
+ case 4:
+ _sectionHandler = new Section4Handler(_vm);
+ break;
+ case 5:
+ _sectionHandler = new Section5Handler(_vm);
+ break;
+ case 6:
+ _sectionHandler = new Section6Handler(_vm);
+ break;
+ case 7:
+ _sectionHandler = new Section7Handler(_vm);
+ break;
+ case 8:
+ _sectionHandler = new Section8Handler(_vm);
+ break;
+ default:
+ break;
+ }
+}
+
+void GameNebular::checkShowDialog() {
+ if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[kCopyProtectFailed]) {
+ _player.releasePlayerSprites();
+ _vm->_dialogs->showDialog();
+ _vm->_dialogs->_pendingDialog = DIALOG_NONE;
+ }
+}
+
+void GameNebular::showRecipe() {
+ Dialogs &dialogs = *_vm->_dialogs;
+ int count;
+
+ for (count = 0; count < 4; count++) {
+ switch(_globals[kIngredientQuantity + count]) {
+ case 0:
+ dialogs._indexList[count] = NOUN_DROP;
+ break;
+ case 1:
+ dialogs._indexList[count] = NOUN_DOLLOP;
+ break;
+ case 2:
+ dialogs._indexList[count] = NOUN_DASH;
+ break;
+ case 3:
+ dialogs._indexList[count] = NOUN_SPLASH;
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (count = 0; count < 4; count++) {
+ switch(_globals[kIngredientList + count]) {
+ case 0:
+ dialogs._indexList[count + 4] = NOUN_ALCOHOL;
+ break;
+ case 1:
+ dialogs._indexList[count + 4] = NOUN_LECITHIN;
+ break;
+ case 2:
+ dialogs._indexList[count + 4] = NOUN_PETROX;
+ break;
+ case 3:
+ dialogs._indexList[count + 4] = NOUN_FORMALDEHYDE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ _vm->_dialogs->show(401);
+}
+
+void GameNebular::doObjectAction() {
+ Scene &scene = _scene;
+ MADSAction &action = _scene._action;
+ Dialogs &dialogs = *_vm->_dialogs;
+ int id;
+
+ if (action.isAction(VERB_SMELL) && scene._currentSceneId > 103 && scene._currentSceneId < 111) {
+ dialogs.show(440);
+ } else if (action.isAction(VERB_EAT) && scene._currentSceneId > 103 && scene._currentSceneId < 111) {
+ dialogs.show(441);
+ } else if (action.isAction(VERB_SMELL, NOUN_BURGER)) {
+ dialogs.show(442);
+ } else if (action.isAction(VERB_EAT, NOUN_BURGER)) {
+ dialogs.show(443);
+ } else if (action.isAction(VERB_SMELL, NOUN_STUFFED_FISH)) {
+ dialogs.show(444);
+ } else if (action.isAction(VERB_EAT, NOUN_STUFFED_FISH)) {
+ dialogs.show(445);
+ } else if (action.isAction(VERB_WEAR, NOUN_REBREATHER)) {
+ dialogs.show(scene._currentSceneId > 103 && scene._currentSceneId < 111 ? 446 : 447);
+ } else if (action.isAction(VERB_SET, NOUN_TIMER_MODULE)) {
+ dialogs.show(448);
+ } else if (action.isAction(VERB_NIBBLE_ON, NOUN_BIG_LEAVES)) {
+ dialogs.show(449);
+ } else if (action.isAction(VERB_LICK, NOUN_POISON_DARTS)) {
+ dialogs.show(450);
+ } else if (action.isAction(VERB_EAT, NOUN_TWINKIFRUIT)) {
+ _objects.setRoom(OBJ_TWINKIFRUIT, PLAYER_INVENTORY);
+ dialogs.show(451);
+ } else if (action.isAction(VERB_GORGE_ON, NOUN_TWINKIFRUIT)) {
+ _objects.setRoom(OBJ_TWINKIFRUIT, PLAYER_INVENTORY);
+ dialogs.show(452);
+ } else if (action.isAction(VERB_GNAW_ON)) {
+ dialogs.show(453);
+ } else if (action.isAction(VERB_MASSAGE, NOUN_AUDIO_TAPE)) {
+ dialogs.show(454);
+ } else if (action.isAction(VERB_MANGLE, NOUN_CREDIT_CHIP)) {
+ dialogs.show(455);
+ } else if (action.isAction(VERB_FONDLE, NOUN_CHARGE_CASES)) {
+ dialogs.show(456);
+ } else if (action.isAction(VERB_RUB, NOUN_BOMB)) {
+ dialogs.show(457);
+ } else if (action.isAction(VERB_SET, NOUN_TIMEBOMB)) {
+ dialogs.show(458);
+ } else if (action.isAction(VERB_GUZZLE, NOUN_ALIEN_LIQUOR)) {
+ dialogs.show(459);
+ } else if (action.isAction(VERB_SMASH, NOUN_TARGET_MODULE)) {
+ dialogs.show(460);
+ } else if (action.isAction(VERB_JUGGLE)) {
+ dialogs.show(461);
+ } else if (action.isAction(VERB_APPLY, NOUN_POLYCEMENT)) {
+ dialogs.show(462);
+ } else if (action.isAction(VERB_SNIFF, NOUN_POLYCEMENT)) {
+ dialogs.show(465);
+ } else if (action.isAction(VERB_TIE, NOUN_FISHING_LINE)) {
+ dialogs.show(463);
+ } else if (action.isAction(VERB_ATTACH, NOUN_FISHING_LINE)) {
+ dialogs.show(463);
+ } else if (action.isAction(VERB_UNLOCK)) {
+ dialogs.show(464);
+ } else if (action.isAction(VERB_REFLECT)) {
+ dialogs.show(466);
+ } else if (action.isAction(VERB_GAZE_INTO, NOUN_REARVIEW_MIRROR)) {
+ dialogs.show(467);
+ } else if (action.isAction(VERB_EAT, NOUN_CHICKEN_BOMB)) {
+ dialogs.show(469);
+ } else if (action.isAction(VERB_BREAK, NOUN_VASE)) {
+ dialogs.show(471);
+ } else if (action.isAction(VERB_SHAKE_HANDS, NOUN_GUARDS_ARM2)) {
+ dialogs.show(472);
+ } else if (action.isAction(VERB_READ, NOUN_LOG)) {
+ dialogs.show(473);
+ } else if (action.isAction(VERB_RUB, NOUN_BOMBS)) {
+ dialogs.show(474);
+ } else if (action.isAction(VERB_DRINK, NOUN_FORMALDEHYDE)) {
+ dialogs.show(475);
+ } else if (action.isAction(VERB_DRINK, NOUN_PETROX)) {
+ dialogs.show(476);
+ } else if (action.isAction(VERB_DRINK, NOUN_LECITHIN)) {
+ dialogs.show(477);
+ } else if (action.isAction(VERB_PUT, NOUN_POISON_DARTS, NOUN_PLANT_STALK) && _objects.isInInventory(OBJ_POISON_DARTS)
+ && _objects.isInInventory(OBJ_PLANT_STALK)) {
+ _objects.addToInventory(OBJ_BLOWGUN);
+ _objects.setRoom(OBJ_PLANT_STALK, NOWHERE);
+ _globals[kBlowgunStatus] = 0;
+ dialogs.showItem(OBJ_BLOWGUN, 809);
+ } else if (action.isAction(VERB_PUT, NOUN_POISON_DARTS, NOUN_BLOWGUN) && _objects.isInInventory(OBJ_POISON_DARTS)
+ && _objects.isInInventory(OBJ_BLOWGUN)) {
+ dialogs.show(433);
+ } else if (action.isAction(VERB_DEFACE) && action.isAction(VERB_FOLD) && action.isAction(VERB_MUTILATE)) {
+ dialogs.show(434);
+ } else if (action.isAction(VERB_SPINDLE)) {
+ dialogs.show(479);
+ } else if ((action.isAction(VERB_READ) || action.isAction(VERB_LOOK_AT) || action.isAction(VERB_LOOK)) &&
+ action.isObject(NOUN_NOTE) && _objects.isInInventory(OBJ_NOTE)) {
+ _objects.setRoom(OBJ_NOTE, PLAYER_INVENTORY);
+ _objects.addToInventory(OBJ_COMBINATION);
+ dialogs.showItem(OBJ_COMBINATION, 851);
+ } else if ((action.isAction(VERB_LOOK) || action.isAction(VERB_READ)) &&
+ ((id = _objects.getIdFromDesc(action._activeAction._objectNameId)) > 0 ||
+ (action._activeAction._indirectObjectId > 0 &&
+ (id = _objects.getIdFromDesc(action._activeAction._indirectObjectId)))) &&
+ _objects.isInInventory(id)) {
+ if (id == OBJ_REPAIR_LIST) {
+ dialogs._indexList[0] = _globals[kTeleporterCode + 7];
+ dialogs._indexList[1] = _globals[kTeleporterCode + 8];
+ dialogs._indexList[2] = _globals[kTeleporterCode + 6];
+ dialogs._indexList[3] = _globals[kTeleporterCode + 9];
+ dialogs._indexList[4] = _globals[kTeleporterCode + 0];
+ dialogs._indexList[5] = _globals[kTeleporterCode + 1];
+ dialogs._indexList[6] = _globals[kTeleporterCode + 4];
+ dialogs._indexList[7] = _globals[kTeleporterCode + 5];
+ dialogs._indexList[8] = _globals[kTeleporterCode + 2];
+
+ dialogs.showItem(id, 402);
+ } else {
+ int messageId = 800 + id;
+ if ((id == OBJ_CHARGE_CASES) && _objects[OBJ_CHARGE_CASES].getQuality(3) != 0) {
+ messageId = 860;
+ }
+
+ if (id == OBJ_TAPE_PLAYER && _objects[OBJ_AUDIO_TAPE]._roomNumber == OBJ_TAPE_PLAYER)
+ messageId = 867;
+
+ if (id == 32 && _objects[OBJ_FISHING_LINE]._roomNumber == 3)
+ messageId = 862;
+
+ if (id == OBJ_BOTTLE && _globals[kBottleStatus] != 0)
+ messageId = 862 + _globals[kBottleStatus];
+
+ if (id == OBJ_PHONE_HANDSET && _globals[kHandsetCellStatus])
+ messageId = 861;
+
+ dialogs.showItem(id, messageId);
+ }
+ } else if (action.isAction(VERB_PUT, NOUN_BURGER, NOUN_DEAD_FISH)) {
+ if (_objects.isInInventory(OBJ_BURGER) || _objects.isInInventory(OBJ_DEAD_FISH)) {
+ _objects.removeFromInventory(OBJ_DEAD_FISH, PLAYER_INVENTORY);
+ _objects.removeFromInventory(OBJ_BURGER, PLAYER_INVENTORY);
+ _objects.addToInventory(OBJ_STUFFED_FISH);
+ dialogs.showItem(OBJ_STUFFED_FISH, 803);
+ }
+ } else if (action.isAction(VERB_PUT, NOUN_AUDIO_TAPE, NOUN_TAPE_PLAYER) && _objects.isInInventory(OBJ_AUDIO_TAPE) &&
+ _objects.isInInventory(OBJ_TAPE_PLAYER)) {
+ _objects.setRoom(OBJ_AUDIO_TAPE, OBJ_TAPE_PLAYER);
+ } else if (action.isAction(VERB_ACTIVATE, NOUN_TAPE_PLAYER) && _objects.isInInventory(OBJ_TAPE_PLAYER)) {
+ if (_objects[OBJ_AUDIO_TAPE]._roomNumber == OBJ_TAPE_PLAYER) {
+ showRecipe();
+ } else {
+ dialogs.show(406);
+ }
+ } else if (action.isAction(VERB_EJECT, NOUN_TAPE_PLAYER) && _objects.isInInventory(OBJ_TAPE_PLAYER)) {
+ if (_objects[OBJ_AUDIO_TAPE]._roomNumber == OBJ_TAPE_PLAYER) {
+ _objects.addToInventory(OBJ_AUDIO_TAPE);
+ } else {
+ dialogs.show(407);
+ }
+ } else if (action.isAction(VERB_DISASSEMBLE, NOUN_TAPE_PLAYER)) {
+ dialogs.show(408);
+ } else if (action.isAction(VERB_ACTIVATE, NOUN_REMOTE)) {
+ dialogs.show(_globals[kTopButtonPushed] ? 502 : 501);
+ } else if ((action.isAction(VERB_ATTACH, NOUN_DETONATORS, NOUN_CHARGE_CASES) || action.isAction(VERB_PUT, NOUN_DETONATORS, NOUN_CHARGE_CASES)) &&
+ _objects.isInInventory(OBJ_DETONATORS) && _objects.isInInventory(OBJ_CHARGE_CASES)) {
+ if (_objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ _objects.setRoom(OBJ_CHARGE_CASES, 1);
+ _objects.setRoom(OBJ_DETONATORS, 1);
+ _objects.addToInventory(OBJ_BOMBS);
+ dialogs.showItem(OBJ_BOMBS, 403);
+ } else {
+ dialogs.show(405);
+ }
+ } else if (action.isAction(VERB_ATTACH, NOUN_DETONATORS)) {
+ dialogs.show(470);
+ } else if ((action.isAction(VERB_ATTACH, NOUN_TIMER_MODULE, NOUN_BOMBS) || action.isAction(VERB_PUT, NOUN_TIMER_MODULE, NOUN_BOMBS) || action.isAction(VERB_ATTACH, NOUN_TIMER_MODULE, NOUN_BOMB)
+ || action.isAction(VERB_PUT, NOUN_TIMER_MODULE, NOUN_BOMB)) && _objects.isInInventory(OBJ_TIMER_MODULE) && (
+ _objects.isInInventory(OBJ_BOMBS) || _objects.isInInventory(OBJ_BOMB))) {
+ if (_objects.isInInventory(OBJ_BOMBS)) {
+ _objects.setRoom(OBJ_BOMBS, PLAYER_INVENTORY);
+ _objects.addToInventory(OBJ_BOMB);
+ } else {
+ _objects.setRoom(OBJ_BOMB, PLAYER_INVENTORY);
+ }
+
+ _objects.setRoom(OBJ_TIMER_MODULE, PLAYER_INVENTORY);
+ _objects.addToInventory(OBJ_TIMEBOMB);
+ dialogs.showItem(OBJ_TIMEBOMB, 404);
+ } else if (action.isAction(VERB_FONDLE, NOUN_PLANT_STALK)) {
+ dialogs.show(410);
+ } else if (action.isAction(VERB_EMPTY, NOUN_BOTTLE)) {
+ _globals[kBottleStatus] = 0;
+ dialogs.show(432);
+ } else if (action.isAction(VERB_DISASSEMBLE, NOUN_FISHING_ROD)) {
+ if (_objects[OBJ_FISHING_LINE]._roomNumber == 3) {
+ _objects.addToInventory(OBJ_FISHING_LINE);
+ dialogs.showItem(OBJ_FISHING_LINE, 409);
+ } else {
+ dialogs.show(428);
+ }
+ } else if (action.isAction(VERB_DISASSEMBLE, NOUN_PENLIGHT)) {
+ switch (_globals[kPenlightCellStatus]) {
+ case 1:
+ case 2:
+ _objects.addToInventory(OBJ_DURAFAIL_CELLS);
+ dialogs.showItem(OBJ_DURAFAIL_CELLS, 412);
+ break;
+ case 3:
+ _objects.addToInventory(OBJ_PHONE_CELLS);
+ dialogs.showItem(OBJ_DURAFAIL_CELLS, 413);
+ break;
+ case 5:
+ _objects.addToInventory(OBJ_DURAFAIL_CELLS);
+ dialogs.showItem(OBJ_DURAFAIL_CELLS, 411);
+ break;
+ case 6:
+ _objects.addToInventory(OBJ_DURAFAIL_CELLS);
+ dialogs.showItem(OBJ_DURAFAIL_CELLS, 429);
+ break;
+ default:
+ dialogs.show(478);
+ break;
+ }
+ } else if (action.isAction(VERB_DISASSEMBLE, NOUN_PHONE_HANDSET)) {
+ switch (_globals[kHandsetCellStatus]) {
+ case 1:
+ _objects.addToInventory(OBJ_DURAFAIL_CELLS);
+ dialogs.showItem(OBJ_DURAFAIL_CELLS,
+ _difficulty != 1 || _globals[kDurafailRecharged] ? 415 : 414);
+ break;
+ case 2:
+ _objects.addToInventory(OBJ_DURAFAIL_CELLS);
+ if (_difficulty == 1) {
+ dialogs.showItem(OBJ_DURAFAIL_CELLS, 416);
+ } else {
+ _globals[kHandsetCellStatus] = 0;
+ }
+ break;
+ case 3:
+ _objects.addToInventory(OBJ_PHONE_CELLS);
+ dialogs.showItem(OBJ_PHONE_CELLS, 418);
+ break;
+ case 4:
+ _objects.addToInventory(OBJ_PHONE_CELLS);
+ dialogs.showItem(OBJ_PHONE_CELLS, 417);
+ break;
+ default:
+ dialogs.show(478);
+ break;
+ }
+ } else if (action.isAction(VERB_PUT, NOUN_PHONE_CELLS, NOUN_PENLIGHT)) {
+ if (_globals[kPenlightCellStatus] == 0) {
+ _globals[kPenlightCellStatus] = 3;
+ _objects.setRoom(OBJ_PHONE_CELLS, PLAYER_INVENTORY);
+ dialogs.show(419);
+ } else {
+ dialogs.show(420);
+ }
+ } else if (action.isAction(VERB_PUT, NOUN_PHONE_CELLS, NOUN_PHONE_HANDSET)) {
+ if (_globals[kHandsetCellStatus] == 0) {
+ _globals[kHandsetCellStatus] = 3;
+ _objects.setRoom(OBJ_PHONE_CELLS, PLAYER_INVENTORY);
+ dialogs.show(421);
+ } else {
+ dialogs.show(422);
+ }
+ } else if (action.isAction(VERB_PUT, NOUN_DURAFAIL_CELLS, NOUN_PENLIGHT)) {
+ if (_globals[kPenlightCellStatus]) {
+ dialogs.show(424);
+ } else {
+ _objects.setRoom(OBJ_DURAFAIL_CELLS, PLAYER_INVENTORY);
+ _globals[kPenlightCellStatus] = _difficulty != 1 || _globals[kDurafailRecharged] ? 1 : 2;
+ dialogs.show(423);
+ }
+ } else if (action.isAction(VERB_PUT, NOUN_DURAFAIL_CELLS, NOUN_PHONE_HANDSET)) {
+ if (_globals[kHandsetCellStatus]) {
+ dialogs.show(424);
+ } else {
+ _objects.setRoom(OBJ_DURAFAIL_CELLS, PLAYER_INVENTORY);
+ _globals[kDurafailRecharged] = _difficulty != 1 || _globals[kHandsetCellStatus] ? 1 : 2;
+ dialogs.show(425);
+ }
+ } else if (action.isAction(VERB_SET, NOUN_TIMEBOMB)) {
+ dialogs.show(427);
+ } else if (action.isAction(VERB_PUT, NOUN_BOMB, NOUN_CHICKEN) || action.isAction(VERB_PUT, NOUN_BOMBS, NOUN_CHICKEN)) {
+ _objects.setRoom(OBJ_CHICKEN, PLAYER_INVENTORY);
+ if (_objects.isInInventory(OBJ_BOMBS)) {
+ _objects.setRoom(OBJ_BOMBS, PLAYER_INVENTORY);
+ _objects.addToInventory(OBJ_BOMB);
+ } else {
+ _objects.setRoom(OBJ_BOMB, PLAYER_INVENTORY);
+ }
+
+ _objects.addToInventory(OBJ_CHICKEN_BOMB);
+ dialogs.showItem(OBJ_CHICKEN_BOMB, 430);
+ } else {
+ return;
+ }
+
+ action._inProgress = false;
+}
+
+void GameNebular::unhandledAction() {
+ int randVal = _vm->getRandomNumber(1, 1000);
+ MADSAction &action = _scene._action;
+
+ if (action.isAction(VERB_THROW, NOUN_BOMB) || action.isAction(VERB_THROW, NOUN_BOMBS)
+ || action.isAction(VERB_THROW, NOUN_TIMEBOMB) || action.isAction(VERB_THROW, NOUN_CHICKEN_BOMB))
+ _vm->_dialogs->show(42);
+ else if (action.isAction(VERB_DISASSEMBLE))
+ _vm->_dialogs->show(435);
+ else if ((action.isAction(VERB_EAT, NOUN_DEAD_FISH) || action.isAction(VERB_EAT, NOUN_STUFFED_FISH)) && _vm->_game->_objects.isInInventory(_vm->_game->_objects.getIdFromDesc(action._activeAction._objectNameId)))
+ _vm->_dialogs->show(12);
+ else if ((action.isAction(VERB_SMELL, NOUN_DEAD_FISH) || action.isAction(VERB_SMELL, NOUN_STUFFED_FISH)) && _vm->_game->_objects.isInInventory(_vm->_game->_objects.getIdFromDesc(action._activeAction._objectNameId)))
+ _vm->_dialogs->show(13);
+ else if (action.isAction(VERB_EAT, NOUN_CHICKEN) && _vm->_game->_objects.isInInventory(OBJ_CHICKEN))
+ _vm->_dialogs->show(912);
+ else if ((action.isAction(VERB_SHOOT) || action.isAction(VERB_HOSE_DOWN)) && action.isObject(NOUN_BLOWGUN)) {
+ if ((_scene._currentSceneId >= 104) && (_scene._currentSceneId <= 111))
+ _vm->_dialogs->show(38);
+ else if (action.isObject(NOUN_PIRANHA))
+ _vm->_dialogs->show(41);
+ else if (action.isObject(NOUN_CHICKEN) || action.isObject(NOUN_VULTURE) || action.isObject(NOUN_SPIDER)
+ || action.isObject(NOUN_YELLOW_BIRD) || action.isObject(NOUN_SWOOPING_CREATURE) || action.isObject(NOUN_CAPTIVE_CREATURE)) {
+ _vm->_dialogs->show(40);
+ } else
+ _vm->_dialogs->show(39);
+ } else if (action.isAction(VERB_TALKTO)) {
+ _globals[kTalkInanimateCount] = (_globals[kTalkInanimateCount] + 1) % 16;
+ if (!_globals[kTalkInanimateCount]) {
+ _vm->_dialogs->show(2);
+ } else {
+ Common::String tmpMsg = "\"Greetings, ";
+ tmpMsg += _vm->_game->_scene.getVocab(action._activeAction._objectNameId);
+ tmpMsg += "!\"";
+ _scene._kernelMessages.reset();
+ _scene._kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, tmpMsg);
+ }
+ } else if (action.isAction(VERB_GIVE, NOUN_DOOR, NOUN_CEILING) || action.isAction(VERB_CLOSE, NOUN_CHAIR))
+ _vm->_dialogs->show(3);
+ else if (action.isAction(VERB_THROW)) {
+ int objId = _vm->_game->_objects.getIdFromDesc(action._activeAction._objectNameId);
+ if (objId < 0)
+ _vm->_dialogs->show(4);
+ else if (_vm->_game->_objects[objId]._roomNumber != 2)
+ _vm->_dialogs->show(5);
+ else
+ _vm->_dialogs->show(6);
+ } else if (action.isAction(VERB_LOOK)) {
+ if (action.isObject(NOUN_BINOCULARS) && (action._activeAction._indirectObjectId > 0))
+ _vm->_dialogs->show(10);
+ else if (randVal < 600)
+ _vm->_dialogs->show(7);
+ else
+ _vm->_dialogs->show(21);
+ } else if (action.isAction(VERB_TAKE)) {
+ int objId = _vm->_game->_objects.getIdFromDesc(action._activeAction._objectNameId);
+ if (_vm->_game->_objects.isInInventory(objId))
+ _vm->_dialogs->show(16);
+ else if (randVal <= 333)
+ _vm->_dialogs->show(8);
+ else if (randVal <= 666)
+ _vm->_dialogs->show(22);
+ else
+ _vm->_dialogs->show(23);
+ } else if (action.isAction(VERB_CLOSE)) {
+ if (randVal <= 333)
+ _vm->_dialogs->show(9);
+ else
+ _vm->_dialogs->show(33);
+ } else if (action.isAction(VERB_OPEN)) {
+ if (randVal <= 500)
+ _vm->_dialogs->show(30);
+ else if (randVal <= 750)
+ _vm->_dialogs->show(31);
+ else
+ _vm->_dialogs->show(32);
+ } else if (action.isAction(VERB_PULL))
+ _vm->_dialogs->show(18);
+ else if (action.isAction(VERB_PUSH)) {
+ if (randVal < 750)
+ _vm->_dialogs->show(19);
+ else
+ _vm->_dialogs->show(20);
+ } else if (action.isAction(VERB_PUT)) {
+ int objId = _vm->_game->_objects.getIdFromDesc(action._activeAction._objectNameId);
+ if (_vm->_game->_objects.isInInventory(objId))
+ _vm->_dialogs->show(25);
+ else
+ _vm->_dialogs->show(24);
+ } else if (action.isAction(VERB_GIVE)) {
+ int objId = _vm->_game->_objects.getIdFromDesc(action._activeAction._objectNameId);
+ if (!_vm->_game->_objects.isInInventory(objId))
+ _vm->_dialogs->show(26);
+ else if (randVal <= 500)
+ _vm->_dialogs->show(28);
+ else
+ _vm->_dialogs->show(29);
+ } else if (!action.isAction(VERB_WALKTO) && !action.isAction(VERB_WALK_ACROSS) && !action.isAction(VERB_WALK_TOWARDS) && !action.isAction(VERB_WALK_DOWN)
+ && !action.isAction(VERB_SWIM_TO) && !action.isAction(VERB_SWIM_ACROSS) && !action.isAction(VERB_SWIM_INTO) && !action.isAction(VERB_SWIM_THROUGH)
+ && !action.isAction(VERB_SWIM_UNDER)) {
+ if (randVal <= 100)
+ _vm->_dialogs->show(36);
+ else if (randVal <= 200)
+ _vm->_dialogs->show(1);
+ else if (randVal <= 475)
+ _vm->_dialogs->show(34);
+ else if (randVal <= 750)
+ _vm->_dialogs->show(35);
+ else
+ _vm->_dialogs->show(37);
+ }
+}
+
+void GameNebular::step() {
+ if (_player._visible && _player._stepEnabled && !_player._moving &&
+ (_player._facing == _player._turnToFacing)) {
+ if (_scene._frameStartTime >= *((uint32 *)&_globals[kWalkerTiming])) {
+ if (!_player._stopWalkerIndex) {
+ int randomVal = _vm->getRandomNumber(29999);;
+ if (_globals[kSexOfRex] == REX_MALE) {
+ switch (_player._facing) {
+ case FACING_SOUTHWEST:
+ case FACING_SOUTHEAST:
+ case FACING_NORTHWEST:
+ case FACING_NORTHEAST:
+ if (randomVal < 200) {
+ _player.addWalker(-1, 0);
+ _player.addWalker(1, 0);
+ }
+ break;
+
+ case FACING_WEST:
+ case FACING_EAST:
+ if (randomVal < 500) {
+ for (int count = 0; count < 10; ++count) {
+ _player.addWalker(1, 0);
+ }
+ }
+ break;
+
+ case FACING_SOUTH:
+ if (randomVal < 500) {
+ for (int count = 0; count < 10; ++count) {
+ _player.addWalker((randomVal < 250) ? 1 : 2, 0);
+ }
+ } else if (randomVal < 750) {
+ for (int count = 0; count < 5; ++count) {
+ _player.addWalker(1, 0);
+ }
+
+ _player.addWalker(0, 0);
+ _player.addWalker(0, 0);
+
+ for (int count = 0; count < 5; ++count) {
+ _player.addWalker(2, 0);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ *((uint32 *)&_globals[kWalkerTiming]) += 6;
+ }
+ }
+
+ // Below is countdown to set the timebomb off in room 604
+ if (_globals[kTimebombStatus] == TIMEBOMB_ACTIVATED) {
+ int diff = _scene._frameStartTime - *((uint32 *)&_globals[kTimebombClock]);
+ if ((diff >= 0) && (diff <= 60)) {
+ *((uint32 *)&_globals[kTimebombTimer]) += diff;
+ } else {
+ ++*((uint32 *)&_globals[kTimebombTimer]);
+ }
+ *((uint32 *)&_globals[kTimebombClock]) = _scene._frameStartTime;
+ }
+}
+
+void GameNebular::synchronize(Common::Serializer &s, bool phase1) {
+ Game::synchronize(s, phase1);
+
+ if (phase1) {
+ _globals.synchronize(s);
+ s.syncAsByte(_storyMode);
+ s.syncAsByte(_difficulty);
+ }
+}
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
diff --git a/engines/mads/nebular/game_nebular.h b/engines/mads/nebular/game_nebular.h
new file mode 100644
index 0000000000..6620deaea6
--- /dev/null
+++ b/engines/mads/nebular/game_nebular.h
@@ -0,0 +1,153 @@
+/* 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 MADS_GAME_NEBULAR_H
+#define MADS_GAME_NEBULAR_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/globals.h"
+#include "mads/nebular/globals_nebular.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+enum StoryMode { STORYMODE_NAUGHTY = 1, STORYMODE_NICE = 2 };
+
+enum Difficulty {
+ DIFFICULTY_HARD = 1, DIFFICULTY_MEDIUM = 2, DIFFICULTY_EASY = 3
+};
+
+enum InventoryObject {
+ OBJ_NONE = -1,
+ OBJ_BINOCULARS = 0,
+ OBJ_BURGER = 1,
+ OBJ_DEAD_FISH = 2,
+ OBJ_STUFFED_FISH = 3,
+ OBJ_REBREATHER = 4,
+ OBJ_TIMER_MODULE = 5,
+ OBJ_BIG_LEAVES = 6,
+ OBJ_POISON_DARTS = 7,
+ OBJ_PLANT_STALK = 8,
+ OBJ_BLOWGUN = 9,
+ OBJ_TWINKIFRUIT = 10,
+ OBJ_BONE = 11,
+ OBJ_CHICKEN = 12,
+ OBJ_SCALPEL = 13,
+ OBJ_AUDIO_TAPE = 14,
+ OBJ_CREDIT_CHIP = 15,
+ OBJ_SECURITY_CARD = 16,
+ OBJ_CHARGE_CASES = 17,
+ OBJ_ESTROTOXIN = 18,
+ OBJ_BOMB = 19,
+ OBJ_TIMEBOMB = 20,
+ OBJ_REPAIR_LIST = 21,
+ OBJ_ALIEN_LIQUOR = 22,
+ OBJ_TARGET_MODULE = 23,
+ OBJ_SHIELD_MODULATOR = 24,
+ OBJ_TAPE_PLAYER = 25,
+ OBJ_PHONE_CELLS = 26,
+ OBJ_PENLIGHT = 27,
+ OBJ_DURAFAIL_CELLS = 28,
+ OBJ_FAKE_ID = 29,
+ OBJ_ID_CARD = 30,
+ OBJ_POLYCEMENT = 31,
+ OBJ_FISHING_ROD = 32,
+ OBJ_FISHING_LINE = 33,
+ OBJ_PADLOCK_KEY = 34,
+ OBJ_DOOR_KEY = 35,
+ OBJ_REARVIEW_MIRROR = 36,
+ OBJ_COMPACT_CASE = 37,
+ OBJ_DETONATORS = 39,
+ OBJ_BOTTLE = 40,
+ OBJ_CHICKEN_BOMB = 41,
+ OBJ_VASE = 42,
+ OBJ_REMOTE = 43,
+ OBJ_COMPUTER_GAME = 44,
+ OBJ_PHONE_HANDSET = 45,
+ OBJ_BONES = 46,
+ OBJ_GUARDS_ARM = 47,
+ OBJ_LOG = 48,
+ OBJ_BOMBS = 49,
+ OBJ_NOTE = 50,
+ OBJ_COMBINATION = 51,
+ OBJ_FORMALDEHYDE = 52,
+ OBJ_PETROX = 53,
+ OBJ_LECITHIN = 54
+};
+
+class GameNebular : public Game {
+ friend class Game;
+protected:
+ GameNebular(MADSEngine *vm);
+
+ virtual ProtectionResult checkCopyProtection();
+
+ virtual void initializeGlobals();
+
+ virtual void setSectionHandler();
+
+ virtual void checkShowDialog();
+public:
+ NebularGlobals _globals;
+ StoryMode _storyMode;
+ Difficulty _difficulty;
+
+ virtual Globals &globals() { return _globals; }
+
+ virtual void doObjectAction();
+
+ void showRecipe();
+
+ virtual void unhandledAction();
+
+ virtual void step();
+
+ virtual void synchronize(Common::Serializer &s, bool phase1);
+};
+
+
+class Section1Handler : public SectionHandler {
+public:
+ Section1Handler(MADSEngine *vm) : SectionHandler(vm) {}
+
+ // TODO: Properly implement handler methods
+ virtual void preLoadSection() {}
+ virtual void sectionPtr2() {}
+ virtual void postLoadSection() {}
+};
+
+// TODO: Properly implement handler classes
+typedef Section1Handler Section2Handler;
+typedef Section1Handler Section3Handler;
+typedef Section1Handler Section4Handler;
+typedef Section1Handler Section5Handler;
+typedef Section1Handler Section6Handler;
+typedef Section1Handler Section7Handler;
+typedef Section1Handler Section8Handler;
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_GAME_NEBULAR_H */
diff --git a/engines/mads/nebular/globals_nebular.cpp b/engines/mads/nebular/globals_nebular.cpp
new file mode 100644
index 0000000000..9f8b8a7888
--- /dev/null
+++ b/engines/mads/nebular/globals_nebular.cpp
@@ -0,0 +1,55 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/nebular/globals_nebular.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+NebularGlobals::NebularGlobals()
+ : Globals() {
+ // Initialize lists
+ resize(210);
+ _spriteIndexes.resize(30);
+ _sequenceIndexes.resize(30);
+
+ // Initialize game flags
+ _timebombClock = 0;
+ _timebombTimer = 0;
+}
+
+void NebularGlobals::synchronize(Common::Serializer &s) {
+ Globals::synchronize(s);
+
+ s.syncAsUint32LE(_timebombClock);
+ s.syncAsUint32LE(_timebombTimer);
+ _spriteIndexes.synchronize(s);
+ _sequenceIndexes.synchronize(s);
+}
+
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
diff --git a/engines/mads/nebular/globals_nebular.h b/engines/mads/nebular/globals_nebular.h
new file mode 100644
index 0000000000..88605a290e
--- /dev/null
+++ b/engines/mads/nebular/globals_nebular.h
@@ -0,0 +1,305 @@
+/* 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 MADS_GLOBALS_NEBULAR_H
+#define MADS_GLOBALS_NEBULAR_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/game.h"
+#include "mads/resources.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+enum GlobalId {
+ kSexOfRex = 0,
+ kOldSexOfRex = 1,
+ kWalkerTiming = 2,
+// kWalkerTiming0 = 3,
+ kTalkInanimateCount = 4,
+ kCopyProtectFailed = 5,
+
+ /* Section #1 variables */
+ kNeedToStandUp = 10,
+ kTurkeyExploded = 11,
+ kMedicineCabinetOpen = 12,
+ kMedicineCabinetVirgin = 13,
+ kWatchedViewScreen = 14,
+ kHoovicAlive = 15,
+ kHoovicSated = 16,
+ kHoovicFishEaten = 17,
+ kWaterInAPuddle = 18,
+ kFishIn105 = 19,
+ kFishIn107 = 20,
+ kFishIn108 = 21,
+ kRandomNumber = 29,
+
+ /* Section #2 variables */
+ kCurtainOpen = 30,
+ kLadderBroken = 31,
+ kBone202Status = 32,
+ kMeteorologistStatus = 33,
+ kRhotundaStatus = 34,
+ kLeavesStatus = 35,
+ kMonkeyStatus = 36,
+ kMeteorologistEverSeen = 37,
+ kMeteorologistWatch = 38,
+ kTeleporterCommand = 39,
+
+ kTeleporterDestination = 40,
+ kTeleporterUnderstood = 41,
+ kConv205 = 42,
+ kChickenPermitted = 43,
+ kTwinklesStatus = 44,
+ kTwinklesApproached = 45,
+ kConvTwinkles1 = 46,
+ kConvTwinkles2 = 47,
+ kConvTwinkles3 = 48,
+ kConvTwinkles5 = 49,
+
+ kConvTwinkles6 = 50,
+ kConvTwinkles7 = 51,
+ kConvTwinkles8 = 52,
+ kBlowgunStatus = 53,
+
+ /* Section #3 Variables */
+ kAfterHavoc = 60,
+ kHaveYourStuff = 61,
+ kRightView320 = 62,
+ kConvBuddy1 = 63,
+ kConvBuddy2 = 64,
+ kMetBuddyBeast = 65,
+ kKnowsBuddyBeast = 66,
+ kConvSlache1 = 67,
+ kConvSlache2 = 68,
+ kConvSlache3 = 69,
+
+ kRexHasMetSlache = 70,
+ kConvIntern = 71,
+ kHasSeenProfPyro = 72,
+ kKickedIn391Grate = 73,
+
+ /* Section #4 Variables */
+ kArmoryDoorOpen = 80,
+ kStorageDoorOpen = 81,
+ kNextIngredient = 82,
+ kIngredientList = 83,
+ kIngredientList1 = 84,
+ kIngredientList2 = 85,
+ kIngredientList3 = 86,
+ kIngredientQuantity = 87,
+ kIngredientQuantity1 = 88,
+ kIngredientQuantity2 = 89,
+
+ kIngredientQuantity3 = 90,
+ kconvPyro_1 = 91,
+ kconvPyro_2 = 92,
+ kconvPyro_3 = 93,
+ kconvPyro_4 = 94,
+ kBadFirstIngredient = 95,
+ kConvBartender1 = 96,
+ kConvBartender2 = 97,
+ kConvBartender3 = 98,
+ kConvBartender4 = 99,
+
+ kHasPurchased = 100,
+ kBeenThruHelgaScene = 101,
+ kHasSaidBinocs = 102,
+ kHasSaidTimer = 103,
+ kBottleDisplayed = 104,
+ kHasBeenScanned = 105,
+ kSomeoneHasExploded = 106,
+
+ /* Section #5 Variables */
+ kBoatRaised = 110,
+ kCarStatus = 111,
+ kCityFlooded = 112,
+ kLaserOn = 113,
+ kLaserHoleIsThere = 114,
+ kCarIsGone = 115,
+ kRegisterOpen = 116,
+ kSafeStatus = 117,
+ kDogStatus = 118,
+ kLineStatus = 119,
+
+ kHoverCarLocation = 120,
+ kHoverCarDestination = 121,
+
+ /* Section #6 Variables */
+ kConvHermit1 = 130,
+ kconvHermit2 = 131,
+ kHasTalkedToHermit = 132,
+ kExecuted_1_11 = 133,
+ kHandsetCellStatus = 134,
+ kBeenInVideoStore = 135,
+ kDurafailRecharged = 136,
+ kPenlightCellStatus = 137,
+ kTimebombStatus = 138,
+ kCheckDaemonTimebomb = 140,
+
+ kResurrectRoom = 141,
+
+ /* Section #6 Time-Bomb Variables */
+ kTimebombClock = 142,
+// kTimebombClock0 = 143,
+ kTimebombTimer = 144,
+// kTimebombTimer0 = 145,
+ kWarnedFloodCity = 146,
+
+ /* Section #7 Variables */
+ kBottleStatus = 150,
+ kMonsterAlive = 151,
+ kConvBottleFillNode = 152,
+ kBoatStatus = 153,
+
+ /* Section #8 Variables */
+ kAntigravClock = 160,
+// kAntigravClock0 = 161,
+ kAntigravTiming = 162,
+// kAntigravTiming0 = 163,
+ kWindowFixed = 164,
+ kInSpace = 165,
+ kReturnFromCut = 166,
+ kBeamIsUp = 167,
+ kForceBeamDown = 168,
+ kCameFromCut = 169,
+
+ kCutX = 170,
+ kCutY = 171,
+ kCutFacing = 172,
+ kDontRepeat = 173,
+ kHoppyDead = 174,
+ kHasWatchedAntigrav = 175,
+ kRemoteSequenceRan = 176,
+ kRemoteOnGround = 177,
+ kFromCockpit = 178,
+ kExitShip = 179,
+
+ kBetweenRooms = 180,
+ kTopButtonPushed = 181,
+ kTargetModInstalled = 182,
+ kShieldModInstalled = 183,
+ kUpBecauseOfRemote = 184,
+
+ kTeleporterRoom = 190,
+ kTeleporterCode = 200
+};
+
+/* Enums used for specific individual globals */
+/* Section #1 */
+// Rex's sex/swimming state
+enum { REX_MALE = 0, REX_MALE_SWIMMER = 1, REX_FEMALE = 2 };
+// State of Meteorologist in the outpost
+enum { METEOROLOGIST_ABSENT = 0, METEOROLOGIST_PRESENT = 1, METEOROLOGIST_GONE = 2 };
+
+// State of watching the Meteorologist
+enum { METEOROLOGIST_NORMAL = 0, METEOROLOGIST_GROUND = 1, METEOROLOGIST_TOWER = 2 };
+
+// The fat bouncy lady that can squish you on the plains
+enum { RHOTUNDA_HUNGRY = 0, RHOTUNDA_STUCK = 1, RHOTUNDA_GONE = 2 };
+
+// Flags for the bones you can take
+enum { BONE_202_LEFT_GONE = 1, BONE_202_RIGHT_GONE = 2 };
+
+// Leaves used to cover the trap
+enum { LEAVES_ON_GROUND = 0, LEAVES_WITH_PLAYER = 1, LEAVES_ON_TRAP = 2 };
+
+// Monkey ambush state
+enum { MONKEY_AMBUSH_READY = 0, MONKEY_HAS_BINOCULARS = 1, MONKEY_IS_GONE = 2 };
+
+// Teleporter status flags
+enum {
+ TELEPORTER_NONE = 0, TELEPORTER_BEAM_IN = 1, TELEPORTER_BEAM_OUT = 2,
+ TELEPORTER_STEP_OUT = 3, TELEPORTER_WRONG = 4
+};
+
+// TWinkies status
+enum { TWINKLES_AT_HOME = 0, TWINKLES_GONE = 1 };
+
+/* Section #4 */
+// Status of the explosives
+enum { EXPLOSIVES_INSIDE = 3 };
+
+/* Section # 5 */
+enum { LINE_NOT_DROPPED = 1, LINE_DROPPED = 2, LINE_TIED = 3, LINE_NOW_UNTIED = 4 };
+
+/* Section #6 */
+enum {
+ NO_CELLS = 0, // Handset doesn't contain any cells
+ CHARGED_DURAFAIL = 1, // Handset has charged durafail cells
+ UNCHARGED_DURAFAIL = 2, // Handset has uncharged durafail cells */
+ PHONE_CELLS = 3, // Handset has already charged phone cells
+ FIRST_TIME_PHONE_CELLS = 4, // First time phone cells are in the handset
+ FIRST_TIME_UNCHARGED_DURAFAIL = 5, // First time uncharged cells are in penlight
+ FIRST_TIME_CHARGED_DURAFAIL = 6 // First time charged cells are in penlight
+};
+
+// Time bomb status
+enum {
+ TIMEBOMB_DEACTIVATED = 0, TIMEBOMB_ACTIVATED = 1,
+ TIMEBOMB_BLOW_UP = 2, TIMEBOMB_DEAD = 3
+};
+
+/* Section #7 */
+// Status of the the bottle
+enum {
+ BOTTLE_EMPTY = 0, BOTTLE_ONE_QUARTER_FULL = 1, BOTTLE_HALF_FULL = 2,
+ BOTTLE_THREE_QUARTERS_FULL = 3, BOTTLE_FULL = 4
+};
+
+// Status of the boat
+enum {
+ BOAT_UNFLOODED = 0, BOAT_ADRIFT = 1, BOAT_TIED_FLOATING = 2,
+ BOAT_TIED = 3, BOAT_GONE = 4
+};
+
+
+/* Miscellaneous defines */
+#define TELEPORTER_COUNT 10 // Total number of teleporters
+#define TELEPORTER_WORK_COUNT 6 // Total number that actually work
+
+
+class NebularGlobals : public Globals {
+public:
+ SynchronizedList _spriteIndexes;
+ SynchronizedList _sequenceIndexes;
+
+ int _timebombClock, _timebombTimer;
+public:
+ /**
+ * Constructor
+ */
+ NebularGlobals();
+
+ /**
+ * Synchronize the globals data
+ */
+ virtual void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_GLOBALS_NEBULAR_H */
diff --git a/engines/mads/nebular/nebular_scenes.cpp b/engines/mads/nebular/nebular_scenes.cpp
new file mode 100644
index 0000000000..52b565016f
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes.cpp
@@ -0,0 +1,628 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/resources.h"
+#include "mads/scene.h"
+#include "mads/nebular/game_nebular.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes1.h"
+#include "mads/nebular/nebular_scenes2.h"
+#include "mads/nebular/nebular_scenes3.h"
+#include "mads/nebular/nebular_scenes4.h"
+#include "mads/nebular/nebular_scenes5.h"
+#include "mads/nebular/nebular_scenes6.h"
+#include "mads/nebular/nebular_scenes7.h"
+#include "mads/nebular/nebular_scenes8.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+SceneLogic *SceneFactory::createScene(MADSEngine *vm) {
+ Scene &scene = vm->_game->_scene;
+
+ scene.addActiveVocab(NOUN_DROP);
+ scene.addActiveVocab(NOUN_DOLLOP);
+ scene.addActiveVocab(NOUN_DASH);
+ scene.addActiveVocab(NOUN_SPLASH);
+ scene.addActiveVocab(NOUN_ALCOHOL);
+
+ switch (scene._nextSceneId) {
+ // Scene group #1 (ship, ocean, cave)
+ case 101: // Ship, cockpit
+ return new Scene101(vm);
+ case 102: // Ship, dining room
+ return new Scene102(vm);
+ case 103: // Ship, engine room
+ return new Scene103(vm);
+ case 104: // Ocean, northwest cliff
+ return new Scene104(vm);
+ case 105: // Ocean, northeast cliff with mine
+ return new Scene105(vm);
+ case 106: // Ocean, outside ship
+ return new Scene106(vm);
+ case 107: // Ocean, bushes
+ return new Scene107(vm);
+ case 108: // Ocean, southwest cliff
+ return new Scene108(vm);
+ case 109: // Ocean, tunnel
+ return new Scene109(vm);
+ case 110: // Ocean, cave with tunnel
+ return new Scene110(vm);
+ case 111: // Cave with pool and opening
+ return new Scene111(vm);
+ case 112: // cutscene, looking at view screen
+ return new Scene112(vm);
+
+ // Scene group #2 (island)
+ case 201: // outside teleporter
+ return new Scene201(vm);
+ case 202: // village
+ return new Scene202(vm);
+ case 203: // tree with Rhotunda (fat woman)
+ return new Scene203(vm);
+ case 205: // village
+ return new Scene205(vm);
+ case 207: // outside witch doctor's hut
+ return new Scene207(vm);
+ case 208: // pit with leaves (trap)
+ return new Scene208(vm);
+ case 209: // palm tree and bamboo plant
+ return new Scene209(vm);
+ case 210: // outside native woman's hut
+ return new Scene210(vm);
+ case 211: // palm tree with monkey
+ return new Scene211(vm);
+ case 212: // outside cave
+ return new Scene212(vm);
+ case 213: // inside teleporter
+ return new Scene213(vm);
+ case 214: // inside witch doctor's hut
+ return new Scene214(vm);
+ case 215: // inside native woman's hut
+ return new Scene215(vm);
+ case 216: // cutscene, monitor showing Rex and native woman
+ return new Scene216(vm);
+
+ // Scene group #3 (women's base, cell block)
+ case 301: // outside teleporter (before chaos)
+ return new Scene301(vm);
+ case 302: // room with statue (before chaos)
+ return new Scene302(vm);
+ case 303: // western corridor (before chaos)
+ return new Scene303(vm);
+ case 304: // crossing with traffic light (before chaos)
+ return new Scene304(vm);
+ case 307: // Rex's cell (before chaos)
+ return new Scene307(vm);
+ case 308: // sauropod's cell (before chaos)
+ return new Scene308(vm);
+ case 309: // multihand monster's cell (before chaos)
+ return new Scene309(vm);
+ case 310: // empty cell (before chaos)
+ return new Scene310(vm);
+ case 311: // warden's desk (before chaos)
+ return new Scene311(vm);
+ case 313: // air shaft overview
+ return new Scene313(vm);
+ case 316: // Gender Bender
+ return new Scene316(vm);
+ case 318: // doctor's gurney
+ return new Scene318(vm);
+ case 319: // doctor Slache closeup (lying on the gurney)
+ return new Scene319(vm);
+ case 320: // warden's desk closeup / monitors
+ return new Scene320(vm);
+ case 321: // gender bender sex change sequence
+ return new Scene321(vm);
+ case 322: // inside teleporter
+ return new Scene322(vm);
+ case 351: // outside teleporter (after chaos)
+ return new Scene351(vm);
+ case 352: // room with statue (after chaos)
+ return new Scene352(vm);
+ case 353: // western corridor (after chaos)
+ return new Scene353(vm);
+ case 354: // crossing with traffic light (after chaos)
+ return new Scene354(vm);
+ case 357: // Rex's cell (after chaos)
+ return new Scene357(vm);
+ case 358: // sauropod's cell (after chaos)
+ return new Scene358(vm);
+ case 359: // multihand monster's cell (after chaos)
+ return new Scene359(vm);
+ case 360: // empty cell (after chaos)
+ return new Scene360(vm);
+ case 361: // warden's desk (after chaos)
+ return new Scene361(vm);
+ case 366: // air shaft ending at Gender Bender
+ return new Scene366(vm);
+ case 387: // air shaft ending at cell
+ return new Scene387(vm);
+ case 388: // air shaft ending at sauropod's cell
+ return new Scene388(vm);
+ case 389: // air shaft ending at multihand monster's cell (before chaos)
+ return new Scene389(vm);
+ case 390: // air shaft ending at cell
+ return new Scene390(vm);
+ case 391: // air shaft ending at warden's desk
+ return new Scene391(vm);
+ case 399: // air shaft ending at multihand monster's cell (after chaos)
+ return new Scene399(vm);
+
+ // Scene group #4 (women's base)
+ case 401: // outside bar
+ return new Scene401(vm);
+ case 402: // inside bar
+ return new Scene402(vm);
+ case 405: // outside armory
+ return new Scene405(vm);
+ case 406: // outside storage room
+ return new Scene406(vm);
+ case 407: // eastern corridor
+ return new Scene407(vm);
+ case 408: // inside armory
+ return new Scene408(vm);
+ case 409: // inside female only teleporter
+ return new Scene409(vm);
+ case 410: // inside storage room
+ return new Scene410(vm);
+ case 411: // lab
+ return new Scene411(vm);
+ case 413: // outside female only teleporter
+ return new Scene413(vm);
+
+ // Scene group #5 (men's city, lower floor)
+ case 501: // outside car
+ return new Scene501(vm);
+ case 502: // inside male only teleporter
+ return new Scene502(vm);
+ case 503: // guard tower
+ return new Scene503(vm);
+ case 504: // inside car
+ return new Scene504(vm);
+ case 505: // car view screen
+ return new Scene505(vm);
+ case 506: // shopping street
+ return new Scene506(vm);
+ case 507: // inside software house
+ return new Scene507(vm);
+ case 508: // laser cannon
+ return new Scene508(vm);
+ case 511: // outside pleasure dome
+ return new Scene511(vm);
+ case 512: // inside pleasure dome
+ return new Scene512(vm);
+ case 513: // outside mall
+ return new Scene513(vm);
+ case 515: // overview
+ return new Scene515(vm);
+ case 551: // outside teleporter (with skeleton)
+ return new Scene551(vm);
+
+ // Scene group #6 (men's city, upper floor)
+ case 601: // outside Bruce's house
+ return new Scene601(vm);
+ case 602: // Bruce's house, living room
+ return new Scene602(vm);
+ case 603: // Bruce's house, bedroom
+ return new Scene603(vm);
+ case 604: // viewport
+ return new Scene604(vm);
+ case 605: // viewport closeup
+ return new Scene605(vm);
+ case 607: // outside Abdul's garage
+ return new Scene607(vm);
+ case 608: // inside Abdul's garage
+ return new Scene608(vm);
+ case 609: // outside Buckluster video store
+ return new Scene609(vm);
+ case 610: // inside Buckluster video store
+ return new Scene610(vm);
+ case 611: // back alley
+ return new Scene611(vm);
+ case 612: // expressway / maintenance building
+ return new Scene612(vm);
+ case 620: // cutscene, viewport glass breaking
+ return new Scene620(vm);
+
+ // Scene group #7 (submerged men's city / upper floor)
+ case 701: // outside elevator (after city is submerged)
+ return new Scene701(vm);
+ case 702: // outside teleporter (after city is submerged)
+ return new Scene702(vm);
+ case 703: // water
+ return new Scene703(vm);
+ case 704: // water, building in the distance
+ return new Scene704(vm);
+ case 705: // water, outside building
+ return new Scene705(vm);
+ case 706: // inside building, pedestral room, outside teleporter
+ return new Scene706(vm);
+ case 707: // teleporter
+ return new Scene707(vm);
+ case 710: // looking at pedestral room through binoculars
+ return new Scene710(vm);
+ case 711: // inside teleporter
+ return new Scene711(vm);
+ case 751: // outside elevator (before city is submerged)
+ return new Scene751(vm);
+ case 752: // outside teleporter (before city is submerged)
+ return new Scene752(vm);
+
+ // Scene group #8
+ case 801: // control room, outside teleporter
+ return new Scene801(vm);
+ case 802: // launch pad with destroyed ship
+ return new Scene802(vm);
+ case 803: // empty launch pad
+ return new Scene803(vm);
+ case 804: // inside Rex's ship - cockpit
+ return new Scene804(vm);
+ case 805: // service panel
+ return new Scene805(vm);
+ case 807: // teleporter
+ return new Scene807(vm);
+ case 808: // antigrav control
+ return new Scene808(vm);
+ case 810: // cutscene: Rex's ship leaving the planet
+ return new Scene810(vm);
+
+ default:
+ error("Invalid scene %d called", scene._nextSceneId);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+NebularScene::NebularScene(MADSEngine *vm) : SceneLogic(vm),
+ _globals(static_cast<GameNebular *>(vm->_game)->_globals),
+ _game(*static_cast<GameNebular *>(vm->_game)),
+ _action(vm->_game->_scene._action) {
+}
+
+Common::String NebularScene::formAnimName(char sepChar, int suffixNum) {
+ return Resources::formatName(_scene->_currentSceneId, sepChar, suffixNum,
+ EXT_NONE, "");
+}
+
+/*------------------------------------------------------------------------*/
+
+void SceneInfoNebular::loadCodes(MSurface &depthSurface, int variant) {
+ File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT"));
+ MadsPack codesPack(&f);
+ Common::SeekableReadStream *stream = codesPack.getItemStream(variant + 1);
+
+ loadCodes(depthSurface, stream);
+
+ delete stream;
+ f.close();
+}
+
+void SceneInfoNebular::loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) {
+ byte *destP = depthSurface.getData();
+ byte *endP = depthSurface.getBasePtr(0, depthSurface.h);
+
+ byte runLength = stream->readByte();
+ while (destP < endP && runLength > 0) {
+ byte runValue = stream->readByte();
+
+ // Write out the run length
+ Common::fill(destP, destP + runLength, runValue);
+ destP += runLength;
+
+ // Get the next run length
+ runLength = stream->readByte();
+ }
+
+ if (destP < endP)
+ Common::fill(destP, endP, 0);
+}
+
+/*------------------------------------------------------------------------*/
+
+SceneTeleporter::SceneTeleporter(MADSEngine *vm) : NebularScene(vm) {
+ _buttonTyped = -1;
+ _curCode = -1;
+ _digitCount = -1;
+ _curMessageId = -1;
+ _handSpriteId = -1;
+ _handSequenceId = -1;
+ _finishedCodeCounter = -1;
+ _meteorologistNextPlace = -1;
+ _meteorologistCurPlace = -1;
+ _teleporterSceneId = -1;
+}
+
+int SceneTeleporter::teleporterAddress(int code, bool working) {
+ int limit = working ? 6 : 10;
+
+ for (int i = 0; i < limit; i++) {
+ if (code == _globals[kTeleporterCode + i])
+ return _globals[kTeleporterRoom + i];
+ }
+
+ return -1;
+}
+
+Common::Point SceneTeleporter::teleporterComputeLocation() {
+ Common::Point result;
+
+ switch (_buttonTyped) {
+ case 0:
+ result = Common::Point(179, 200);
+ break;
+
+ case 1:
+ result = Common::Point(166, 170);
+ break;
+
+ case 2:
+ result = Common::Point(179, 170);
+ break;
+
+ case 3:
+ result = Common::Point(192, 170);
+ break;
+
+ case 4:
+ result = Common::Point(166, 180);
+ break;
+
+ case 5:
+ result = Common::Point(179, 180);
+ break;
+
+ case 6:
+ result = Common::Point(192, 180);
+ break;
+
+ case 7:
+ result = Common::Point(166, 190);
+ break;
+
+ case 8:
+ result = Common::Point(179, 190);
+ break;
+
+ case 9:
+ result = Common::Point(192, 190);
+ break;
+
+ case 10:
+ result = Common::Point(194, 200);
+ break;
+
+ case 11:
+ result = Common::Point(164, 200);
+ break;
+
+ default:
+ error("teleporterComputeLocation() - Unexpected button pressed");
+ }
+
+ return result;
+}
+
+void SceneTeleporter::teleporterHandleKey() {
+ switch (_game._trigger) {
+ case 0: {
+ _game._player._stepEnabled = false;
+ Common::Point msgPos = teleporterComputeLocation();
+ _handSequenceId = _scene->_sequences.startReverseCycle(_handSpriteId, false, 4, 2, 0, 0);
+ _scene->_sequences.setPosition(_handSequenceId, msgPos);
+ _scene->_sequences.setDepth(_handSequenceId, 2);
+ _scene->_sequences.addSubEntry(_handSequenceId, SEQUENCE_TRIGGER_LOOP, 0, 1);
+ _scene->_sequences.addSubEntry(_handSequenceId, SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+
+ if (_globals[kMeteorologistWatch] == METEOROLOGIST_NORMAL)
+ _vm->_events->hideCursor();
+
+ }
+ break;
+
+ case 1:
+ _scene->_sequences.addSubEntry(_handSequenceId, SEQUENCE_TRIGGER_SPRITE, 3, 3);
+ if (_buttonTyped <= 9) {
+ if (_digitCount < 4) {
+ _curCode *= 10;
+ _curCode += _buttonTyped;
+ _digitCount++;
+ _msgText = Common::String::format("%d", _curCode);
+ if (_digitCount < 4)
+ _msgText += "_";
+
+ if (_scene->_currentSceneId != 711)
+ _vm->_sound->command(32);
+ }
+ } else if (_buttonTyped == 11) {
+ _digitCount = 0;
+ _curCode = 0;
+ _msgText = "_";
+ if (_scene->_currentSceneId != 711)
+ _vm->_sound->command(33);
+ } else if (_digitCount == 4) {
+ if (_scene->_currentSceneId != 711)
+ _finishedCodeCounter = 1;
+
+ if (teleporterAddress(_curCode, true) > 0) {
+ _vm->_palette->setEntry(252, 0, 63, 0);
+ if (_scene->_currentSceneId != 711)
+ _vm->_sound->command(34);
+ } else {
+ _vm->_palette->setEntry(252, 63, 0, 0);
+ if (_scene->_currentSceneId != 711)
+ _vm->_sound->command(35);
+ }
+ }
+
+ if (_scene->_currentSceneId != 711) {
+ if (_curMessageId >= 0)
+ _scene->_kernelMessages.remove(_curMessageId);
+ _curMessageId = _scene->_kernelMessages.add(Common::Point(143, 61), 0xFDFC, 16, 0, 9999999, _msgText);
+ }
+ break;
+
+ case 2:
+ if (_finishedCodeCounter == 1) {
+ _finishedCodeCounter++;
+
+ if (_globals[kMeteorologistWatch] != METEOROLOGIST_NORMAL)
+ _scene->_nextSceneId = 202;
+ else {
+ _vm->_events->showCursor();
+ int destination = teleporterAddress(_curCode, true);
+
+ if (destination > 0) {
+ _globals[kTeleporterCommand] = 2;
+ _scene->_nextSceneId = _teleporterSceneId;
+ _globals[kTeleporterDestination] = destination;
+ } else {
+ _globals[kTeleporterCommand] = 4;
+ _scene->_nextSceneId = _teleporterSceneId;
+ }
+ }
+ } else if (_globals[kMeteorologistWatch] != METEOROLOGIST_NORMAL)
+ _scene->_sequences.addTimer(30, 230 + _meteorologistCurPlace);
+
+ break;
+
+ case 3:
+ if (!_finishedCodeCounter) {
+ if (_globals[kMeteorologistWatch] == METEOROLOGIST_NORMAL) {
+ _game._player._stepEnabled = true;
+ _vm->_events->showCursor();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void SceneTeleporter::teleporterEnter() {
+ _game._player._visible = false;
+ _game._player._stepEnabled = (_globals[kMeteorologistWatch] == METEOROLOGIST_NORMAL);
+ _scene->_kernelMessages._talkFont = _vm->_font->getFont(FONT_TELE);
+ _scene->_textSpacing = 0;
+ _curCode = 0;
+ _digitCount = 0;
+ _finishedCodeCounter = 0;
+ _curMessageId = -1;
+ _msgText = "_";
+
+ if (_scene->_priorSceneId == -2)
+ _scene->_priorSceneId = _globals[kTeleporterDestination];
+
+ if (_scene->_priorSceneId < 101)
+ _scene->_priorSceneId = 201;
+
+ _globals[kTeleporterDestination] = _scene->_priorSceneId;
+ _vm->_palette->setEntry(252, 63, 63, 0);
+ _vm->_palette->setEntry(253, 0, 0, 0);
+ _teleporterSceneId = _scene->_priorSceneId;
+ if (_teleporterSceneId == 202)
+ _teleporterSceneId = 201;
+
+ int tmpVal = 0;
+ for (int i = 0; i < 10; i++) {
+ if (_teleporterSceneId == _globals[kTeleporterRoom + i])
+ tmpVal = _globals[kTeleporterRoom + i];
+
+ if (_globals[kTeleporterRoom + i] == 301)
+ _meteorologistNextPlace = _globals[kTeleporterCode + i];
+ }
+
+ Common::String msgText2 = Common::String::format("#%.4d", tmpVal);
+
+ if (_scene->_currentSceneId != 711) {
+ _scene->_kernelMessages.add(Common::Point(133, 34), 0, 32, 0, 9999999, msgText2);
+ _scene->_kernelMessages.add(Common::Point(143, 61), 0xFDFC, 16, 0, 9999999, _msgText);
+ }
+
+ _meteorologistCurPlace = 0;
+
+ if (_globals[kMeteorologistWatch] != METEOROLOGIST_NORMAL)
+ _scene->_sequences.addTimer(30, 230);
+
+ _vm->_sound->command(36);
+}
+
+bool SceneTeleporter::teleporterActions() {
+ bool retVal = false;
+ static int _buttonList[12] = { NOUN_0_KEY, NOUN_1_KEY, NOUN_2_KEY, NOUN_3_KEY, NOUN_4_KEY, NOUN_5_KEY, NOUN_6_KEY, NOUN_7_KEY, NOUN_8_KEY, NOUN_9_KEY, NOUN_SMILE_KEY, NOUN_FROWN_KEY };
+
+ if (_action.isAction(VERB_PRESS) || _action.isAction(VERB_PUSH)) {
+ for (int i = 0; i < 12; i++) {
+ if (_action._activeAction._objectNameId == _buttonList[i])
+ _buttonTyped = i;
+ }
+ teleporterHandleKey();
+ retVal = true;
+ }
+
+ if (_action.isAction(VERB_EXIT_FROM, NOUN_DEVICE)) {
+ _globals[kTeleporterCommand] = 3;
+ _scene->_nextSceneId = _teleporterSceneId;
+ retVal = true;
+ }
+
+ return (retVal);
+}
+
+void SceneTeleporter::teleporterStep() {
+ if (_globals[kMeteorologistWatch] == METEOROLOGIST_NORMAL)
+ return;
+
+ if (_game._trigger >= 230) {
+ int place = _game._trigger - 230;
+ int digit;
+
+ if (place < 4) {
+ digit = _meteorologistNextPlace;
+ for (int i = 0; i < (3 - place); i++)
+ digit = digit / 10;
+
+ digit = digit % 10;
+ } else {
+ digit = 10;
+ }
+ _buttonTyped = digit;
+ _meteorologistCurPlace = place + 1;
+ _game._trigger = -1;
+ }
+
+ if (_game._trigger) {
+ if (_game._trigger == -1)
+ _game._trigger = 0;
+ teleporterHandleKey();
+ }
+}
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes.h b/engines/mads/nebular/nebular_scenes.h
new file mode 100644
index 0000000000..6195395fd6
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes.h
@@ -0,0 +1,1417 @@
+/* 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 MADS_NEBULAR_SCENES_H
+#define MADS_NEBULAR_SCENES_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/game_nebular.h"
+#include "mads/nebular/globals_nebular.h"
+
+
+namespace MADS {
+
+namespace Nebular {
+
+enum {
+ SEX_MALE = 0, SEX_UNKNOWN = 1, SEX_FEMALE = 2
+};
+
+enum Verb {
+ VERB_ACTIVATE = 0x00E,
+ VERB_ATTACH = 0x019,
+ VERB_BREAK = 0x032,
+ VERB_BREATHE_AIR = 0x033,
+ VERB_CAST = 0x03D,
+ VERB_CLIMB_DOWN = 0x04E,
+ VERB_CLIMB_THROUGH = 0x04F,
+ VERB_CLIMB_UP = 0x050,
+ VERB_CUT = 0x061,
+ VERB_DAMPEN = 0x064,
+ VERB_DISASSEMBLE = 0x06C,
+ VERB_DIVE_INTO = 0x06D,
+ VERB_DRINK = 0x072,
+ VERB_EAT = 0x075,
+ VERB_EJECT = 0x076,
+ VERB_EMPTY = 0x077,
+ VERB_EXAMINE = 0x07D,
+ VERB_FILL = 0x085,
+ VERB_FONDLE = 0x08C,
+ VERB_HOSE_DOWN = 0x0A6,
+ VERB_IGNITE = 0x0B4,
+ VERB_INFLATE = 0x0B5,
+ VERB_INSERT = 0x0B6,
+ VERB_INSPECT = 0x0B7,
+ VERB_GNAW_ON = 0x098,
+ VERB_GORGE_ON = 0x099,
+ VERB_HURL = 0x0A9,
+ VERB_LICK = 0x0CB,
+ VERB_LOOK_AT = 0x0D1,
+ VERB_LOOK_IN = 0x0D2,
+ VERB_LOOK_THROUGH = 0x0D3,
+ VERB_PEER_THROUGH = 0x103,
+ VERB_PLAY = 0x112,
+ VERB_PRESS = 0x11A,
+ VERB_PRY = 0x11C,
+ VERB_READ = 0x11F,
+ VERB_SET = 0x132,
+ VERB_SHAKE_HANDS = 0x133,
+ VERB_SHARPEN = 0x134,
+ VERB_SHOOT = 0x13A,
+ VERB_SIT_IN = 0x13F,
+ VERB_SMELL = 0x147,
+ VERB_SNIFF = 0x149,
+ VERB_STARE_AT = 0x155,
+ VERB_SWIM_ACROSS = 0x159,
+ VERB_SWIM_INTO = 0x15A,
+ VERB_SWIM_THROUGH = 0x15B,
+ VERB_SWIM_TO = 0x15C,
+ VERB_SWIM_TOWARDS = 0x15D,
+ VERB_SWIM_UNDER = 0x15E,
+ VERB_TIE = 0x170,
+ VERB_UNLOCK = 0x17B,
+ VERB_WALK_ACROSS = 0x187,
+ VERB_WALK_INSIDE = 0x188,
+ VERB_WALK_OUTSIDE = 0x18A,
+ VERB_WALK_THROUGH = 0x18B,
+ VERB_WALK_TOWARDS = 0x18C,
+ VERB_WEAR = 0x191,
+ VERB_WALK_DOWN = 0x1AD,
+ VERB_LEAVE = 0x1CD,
+ VERB_EXIT_FROM = 0x1CE,
+ VERB_USE = 0x20C,
+ VERB_GAZE_INTO = 0x212,
+ VERB_SIT_AT = 0x21F,
+ VERB_WALK_UP = 0x227,
+ VERB_WALK_INTO = 0x242,
+ VERB_EXIT = 0x298,
+ VERB_WALK_ONTO = 0x2B5,
+ VERB_RETURN_TO = 0x2D5,
+ VERB_CLIMB_INTO = 0x2F7,
+ VERB_STEP_INTO = 0x2F9,
+ VERB_CRAWL_TO = 0x2FB,
+ VERB_CRAWL_DOWN = 0x301,
+ VERB_SIT_ON = 0x30B,
+ VERB_WALK_ALONG = 0x312,
+ VERB_GET_INSIDE = 0x325,
+ VERB_WALK = 0x32F,
+ VERB_REFLECT = 0x365,
+ VERB_GET_INTO = 0x36A,
+ VERB_APPLY = 0x3A6,
+ VERB_STEER_TOWARDS = 0x3B1,
+ VERB_NIBBLE_ON = 0x3B7,
+ VERB_ENTER = 0x3B8,
+ VERB_PUT_DOWN = 0x46F,
+ VERB_INSTALL = 0x474,
+ VERB_REMOVE = 0x476,
+ VERB_DEFACE = 0x489,
+ VERB_MASSAGE = 0x4A3,
+ VERB_MANGLE = 0x4A4,
+ VERB_RUB = 0x4A5,
+ VERB_JUGGLE = 0x4A6,
+ VERB_SMASH = 0x4A7,
+ VERB_GUZZLE = 0x4A8,
+ VERB_FOLD = 0x4AB,
+ VERB_SPINDLE = 0x4AC,
+ VERB_MUTILATE = 0x4AD
+};
+
+enum Noun {
+ //NOUN_GAME = 0x1,
+ //NOUN_QSAVE = 0x2,
+ //NOUN_LOOK = 0x3,
+ //NOUN_TAKE = 0x4,
+ //NOUN_PUSH = 0x5,
+ //NOUN_OPEN = 0x6,
+ //NOUN_PUT = 0x7,
+ //NOUN_TALK_TO = 0x8,
+ //NOUN_GIVE = 0x9,
+ //NOUN_PULL = 0xA,
+ //NOUN_CLOSE = 0xB,
+ //NOUN_THROW = 0xC,
+ //NOUN_WALK_TO = 0xD,
+ //NOUN_ACTIVATE = 0xE,
+ //NOUN_ADMIRE = 0xF,
+ NOUN_ADSM = 0x10,
+ NOUN_AIR_VENT = 0x11,
+ NOUN_ALOE_PLANT = 0x12,
+ NOUN_ANEMONE = 0x13,
+ NOUN_ANOMOMETER = 0x14,
+ NOUN_AREA_AROUND_HUT = 0x15,
+ NOUN_AREA_TO_SOUTH = 0x16,
+ NOUN_AREA_TO_WEST = 0x17,
+ NOUN_AROMATIC_MEAT = 0x18,
+ //NOUN_ATTACH = 0x19,
+ NOUN_AUDIO_TAPE = 0x1A,
+ NOUN_AUXILIARY_POWER = 0x1B,
+ NOUN_BADMITTON_BRAT = 0x1C,
+ NOUN_BAG = 0x1D,
+ NOUN_BAMBOO_TREE = 0x1E,
+ NOUN_BATS = 0x1F,
+ NOUN_BAWLEMER_ORIOLE_HUN = 0x20,
+ NOUN_BEAR_RUG = 0x21,
+ NOUN_BEASTLY_TROPHY = 0x22,
+ NOUN_BIG_LEAVES = 0x23,
+ NOUN_BIG_PIPES = 0x24,
+ NOUN_BIG_SKY = 0x25,
+ NOUN_BIG_STONE = 0x26,
+ NOUN_BINOCULARS = 0x27,
+ NOUN_BIRDIES = 0x28,
+ NOUN_BLOWGUN = 0x29,
+ NOUN_BOMB = 0x2A,
+ NOUN_BOMBS = 0x2B,
+ NOUN_BONE = 0x2C,
+ NOUN_BONES = 0x2D,
+ NOUN_BOTTLE = 0x2E,
+ NOUN_BOULDER = 0x2F,
+ NOUN_BOULDERS = 0x30,
+ NOUN_BRA = 0x31,
+ //NOUN_BREAK = 0x32,
+ //NOUN_BREATHE_AIR = 0x33,
+ NOUN_BULKHEAD = 0x34,
+ NOUN_BURGER = 0x35,
+ NOUN_BURN = 0x36,
+ NOUN_BURNT_OUT_WARP_COIL = 0x37,
+ NOUN_BUSH_LIKE_FORMATION = 0x38,
+ NOUN_BUSHES = 0x39,
+ NOUN_BUSHY_FERN = 0x3A,
+ NOUN_CACTUS = 0x3B,
+ NOUN_CARD = 0x3C,
+ //NOUN_CAST = 0x3D,
+ NOUN_CAULDRON = 0x3E,
+ NOUN_CAVE = 0x3F,
+ NOUN_CAVE_CEILING = 0x40,
+ NOUN_CAVE_ENTRANCE = 0x41,
+ NOUN_CAVE_EXIT = 0x42,
+ NOUN_CAVE_FLOOR = 0x43,
+ NOUN_CAVE_TO_EAST = 0x44,
+ NOUN_CAVE_WALL = 0x45,
+ NOUN_CEILING = 0x46,
+ NOUN_CHAIR = 0x47,
+ NOUN_CHARGE_CASES = 0x48,
+ NOUN_CHICKEN = 0x49,
+ NOUN_CHICKEN_BOMB = 0x4A,
+ NOUN_CLEARING_TO_EAST = 0x4B,
+ NOUN_CLEARING_TO_SOUTH = 0x4C,
+ NOUN_CLIFF_FACE = 0x4D,
+ NOUN_CLIMB_DOWN = 0x4E,
+ NOUN_CLIMB_THROUGH = 0x4F,
+ NOUN_CLIMB_UP = 0x50,
+ NOUN_CLOCK = 0x51,
+ NOUN_CLOSET = 0x52,
+ NOUN_CLOTHESLINE = 0x53,
+ NOUN_CLUMP_OF_TREES = 0x54,
+ NOUN_COAL = 0x55,
+ NOUN_COCOANUT = 0x56,
+ NOUN_COMPACT_CASE = 0x57,
+ NOUN_COMPUTER_GAME = 0x58,
+ NOUN_CONTROL_PANEL = 0x59,
+ NOUN_CORAL = 0x5A,
+ NOUN_CRAB = 0x5B,
+ NOUN_CREDIT_CHIP = 0x5C,
+ NOUN_CUMULOUS_CLOUD = 0x5D,
+ NOUN_CURIOUS_WEED_PATCH = 0x5E,
+ NOUN_CURTAIN = 0x5F,
+ NOUN_CURTAINS = 0x60,
+ //NOUN_CUT = 0x61,
+ NOUN_DAMAGE_CONTROL = 0x62,
+ NOUN_DAMAGE_CONTROL_PANEL = 0x63,
+ //NOUN_DAMPEN = 0x64,
+ NOUN_DEAD_FISH = 0x65,
+ NOUN_DEAD_PURPLE_MONSTER = 0x66,
+ NOUN_DECLIVITOUS_CHASM = 0x67,
+ NOUN_DEEP_DARK_FOREST = 0x68,
+ NOUN_DENSE_FOREST = 0x69,
+ NOUN_DETONATORS = 0x6A,
+ NOUN_DINO_MITE = 0x6B,
+ //NOUN_DISASSEMBLE = 0x6C,
+ //NOUN_DIVE_INTO = 0x6D,
+ NOUN_DOOR = 0x6E,
+ NOUN_DOOR_KEY = 0x6F,
+ NOUN_DOORWAY = 0x70,
+ NOUN_DRAWER = 0x71,
+ //NOUN_DRINK = 0x72,
+ NOUN_DURAFAIL_CELLS = 0x73,
+ NOUN_EASTERN_CLIFF_FACE = 0x74,
+ //NOUN_EAT = 0x75,
+ //NOUN_EJECT = 0x76,
+ //NOUN_EMPTY = 0x77,
+ NOUN_ENGINEERING_CONTROLS = 0x78,
+ NOUN_ENGINEERING_SECTION = 0x79,
+ NOUN_ENTER_KEY = 0x7A,
+ NOUN_ESCAPE_HATCH = 0x7B,
+ NOUN_ESTROTOXIN = 0x7C,
+ //NOUN_EXAMINE = 0x7D,
+ NOUN_EXPERIMENT_CAGE = 0x7E,
+ NOUN_EXTINGUISH = 0x7F,
+ NOUN_FACE_ID = 0x80,
+ NOUN_FERN = 0x81,
+ NOUN_FIELD_TO_NORTH = 0x82,
+ NOUN_FIELD_TO_SOUTH = 0x83,
+ NOUN_FIELD_TO_WEST = 0x84,
+ //NOUN_FILL = 0x85,
+ NOUN_FIRE_PIT = 0x86,
+ NOUN_FISHING_LINE = 0x87,
+ NOUN_FISHING_ROD = 0x88,
+ NOUN_FLOOR = 0x89,
+ NOUN_FLOOR_OF_HUT = 0x8A,
+ NOUN_FLOOR_TILE = 0x8B,
+ //NOUN_FONDLE = 0x8C,
+ NOUN_FOREST_TO_EAST = 0x8D,
+ NOUN_FRONT_WINDOW = 0x8E,
+ NOUN_FUNGOIDS = 0x8F,
+ NOUN_FURNACE = 0x90,
+ NOUN_FUZZY_DICE = 0x91,
+ //NOUN_GAZE = 0x92,
+ //NOUN_GAZE_AT = 0x93,
+ //NOUN_GAZE_IN = 0x94,
+ //NOUN_GLANCE_AT = 0x95,
+ NOUN_GLOVE = 0x96,
+ NOUN_GNARLY_SHRUB = 0x97,
+ //NOUN_GNAW_ON = 0x98,
+ //NOUN_GORGE_ON = 0x99,
+ NOUN_GRAIN_ALCHOHOL = 0x9A,
+ NOUN_GRASSLAND_TO_EAST = 0x9B,
+ NOUN_GRASSLAND_TO_SOUTH = 0x9C,
+ NOUN_GRASSY_AREA = 0x9D,
+ NOUN_GRASSY_AREA_TO_NORTH = 0x9E,
+ NOUN_GRASSY_KNOLL = 0x9F,
+ //NOUN_GRIND = 0xA0,
+ NOUN_GROOVILACTIC_TREE = 0xA1,
+ NOUN_GUARDS_ARM = 0xA2,
+ NOUN_HATCHWAY = 0xA3,
+ //NOUN_HOOK_UP = 0xA4,
+ NOUN_HORIZON = 0xA5,
+ //NOUN_HOSE_DOWN = 0xA6,
+ NOUN_HOTPANTS = 0xA7,
+ NOUN_HULL = 0xA8,
+ //NOUN_HURL = 0xA9,
+ NOUN_HUT = 0xAA,
+ NOUN_HUT_AREA = 0xAB,
+ NOUN_HUT_TO_EAST = 0xAC,
+ NOUN_HUT_TO_SOUTH = 0xAD,
+ NOUN_HUT_TO_THE_SOUTH = 0xAE,
+ NOUN_HUT_TO_WEST = 0xAF,
+ NOUN_HUTS_TO_NORTH = 0xB0,
+ NOUN_HYDROSPANNER = 0xB1,
+ NOUN_HYPERDRIVE_JUMP_UNIT = 0xB2,
+ NOUN_ID_CARD = 0xB3,
+ //NOUN_IGNITE = 0xB4,
+ //NOUN_INFLATE = 0xB5,
+ //NOUN_INSERT = 0xB6,
+ //NOUN_INSPECT = 0xB7,
+ NOUN_JUNGLE = 0xB8,
+ NOUN_JUNGLE_TO_EAST = 0xB9,
+ NOUN_JUNGLE_TO_WEST = 0xBA,
+ NOUN_KEY_1 = 0xBB,
+ NOUN_KEY_2 = 0xBC,
+ NOUN_KEY_3 = 0xBD,
+ NOUN_KEY_4 = 0xBE,
+ NOUN_KEY_5 = 0xBF,
+ NOUN_KEY_6 = 0xC0,
+ NOUN_KEY_7 = 0xC1,
+ NOUN_KEY_8 = 0xC2,
+ NOUN_KEY_9 = 0xC3,
+ NOUN_KEYPAD = 0xC4,
+ NOUN_KNEELING_WOMAN = 0xC5,
+ NOUN_KNIFE = 0xC6,
+ NOUN_LADDER = 0xC7,
+ NOUN_LARGE_STALAGMITE = 0xC8,
+ //NOUN_LEER_AT = 0xC9,
+ NOUN_LIBRARY_COMPUTER = 0xCA,
+ //NOUN_LICK = 0xCB,
+ NOUN_LIFE_SUPPORT_SECTION = 0xCC,
+ NOUN_LIGHT = 0xCD,
+ //NOUN_LOAD = 0xCE,
+ //NOUN_LOCK = 0xCF,
+ NOUN_LOG = 0xD0,
+ //NOUN_LOOK_AT = 0xD1,
+ //NOUN_LOOK_IN = 0xD2,
+ //NOUN_LOOK_THROUGH = 0xD3,
+ NOUN_LOUNGE_AREA = 0xD4,
+ NOUN_LOVE_ALTAR = 0xD5,
+ NOUN_LOWLANDS = 0xD6,
+ NOUN_MACHINE = 0xD7,
+ NOUN_MAGNET = 0xD8,
+ NOUN_MAIN_AIRLOCK = 0xD9,
+ NOUN_MANTA_RAY = 0xDA,
+ NOUN_MARSHY_WETLANDS = 0xDB,
+ NOUN_MATCH = 0xDC,
+ NOUN_MEDICAL_WASTE = 0xDD,
+ NOUN_MEDICINE_CABINET = 0xDE,
+ NOUN_MEN_WHO_CAME_BEFORE = 0xDF,
+ NOUN_MINE = 0xE0,
+ NOUN_MIRROR = 0xE1,
+ NOUN_MONITOR = 0xE2,
+ NOUN_MONKEY = 0xE3,
+ NOUN_MONKEY_LIVER_JUICE = 0xE4,
+ NOUN_MONSTER_SLUDGE = 0xE5,
+ NOUN_MOUNTAIN = 0xE6,
+ NOUN_MOUNTAIN_RANGE = 0xE7,
+ NOUN_MOUNTAINS = 0xE8,
+ NOUN_MTAM = 0xE9,
+ NOUN_MUSHROOMS = 0xEA,
+ NOUN_NAVIGATION_CONTROLS = 0xEB,
+ NOUN_NORTH_PATH = 0xEC,
+ NOUN_NORTHERN_EXPOSURE = 0xED,
+ NOUN_NORTHERN_SEA_CLIFF = 0xEE,
+ NOUN_OBSTACLE = 0xEF,
+ NOUN_OCEAN_FLOOR = 0xF0,
+ NOUN_ODD_ROCK_FORMATION = 0xF1,
+ NOUN_OOGLY_BOOGLY_JUICE = 0xF2,
+ NOUN_OPEN_AREA_TO_EAST = 0xF3,
+ NOUN_OPEN_AREA_TO_NORTH = 0xF4,
+ NOUN_OPEN_AREA_TO_SOUTH = 0xF5,
+ NOUN_OPEN_AREA_TO_WEST = 0xF6,
+ NOUN_OPEN_FIELD = 0xF7,
+ NOUN_OUTER_HULL = 0xF8,
+ NOUN_OUTSIDE = 0xF9,
+ NOUN_OVEN = 0xFA,
+ NOUN_OVERHANG_TO_EAST = 0xFB,
+ NOUN_OVERHANG_TO_WEST = 0xFC,
+ NOUN_OVERHEAD_LAMP = 0xFD,
+ NOUN_PAD_OF_PAPER = 0xFE,
+ NOUN_PADLOCK_KEY = 0xFF,
+ NOUN_PALM_TREE = 0x100,
+ NOUN_PASSAGE_WAY_TO_SOUTH = 0x101,
+ NOUN_PASSION_PUSS = 0x102,
+ NOUN_PEER_THROUGH = 0x103,
+ NOUN_PENCIL = 0x104,
+ NOUN_PENDULOUS_CRAG = 0x105,
+ NOUN_PENLIGHT = 0x106,
+ NOUN_PHONE_CELLS = 0x107,
+ NOUN_PHONE_HANDSET = 0x108,
+ NOUN_PILE_OF_ROCKS = 0x109,
+ NOUN_PILLOW = 0x10A,
+ NOUN_PILOTS_CHAIR = 0x10B,
+ NOUN_PIPE = 0x10C,
+ NOUN_PIRANHA = 0x10D,
+ NOUN_PLANT = 0x10E,
+ NOUN_PLANT_STALK = 0x10F,
+ NOUN_PLANTS = 0x110,
+ NOUN_PLASTIC_JESUS = 0x111,
+ //NOUN_PLAY = 0x112,
+ NOUN_PLUNGER = 0x113,
+ NOUN_POISON_DARTS = 0x114,
+ NOUN_POLYCEMENT = 0x115,
+ NOUN_POOL = 0x116,
+ NOUN_POSTER = 0x117,
+ NOUN_POWER_STATUS_PANEL = 0x118,
+ NOUN_PRECIPICE = 0x119,
+ //NOUN_PRESS = 0x11A,
+ NOUN_PRESSURE_GAUGE = 0x11B,
+ //NOUN_PRY = 0x11C,
+ NOUN_RAGING_RIVER = 0x11D,
+ NOUN_RAMOLYAN_RUGBY_RATS = 0x11E,
+ //NOUN_READ = 0x11F,
+ NOUN_REARVIEW_MIRROR = 0x120,
+ NOUN_REBREATHER = 0x121,
+ NOUN_REFRIGERATOR = 0x122,
+ NOUN_REMOTE = 0x123,
+ NOUN_REPAIR_LIST = 0x124,
+ NOUN_RIVER = 0x125,
+ NOUN_RIVER_TO_WEST = 0x126,
+ NOUN_ROBO_KITCHEN = 0x127,
+ NOUN_ROCK = 0x128,
+ NOUN_ROCKS = 0x129,
+ NOUN_ROCKY_AREA = 0x12A,
+ NOUN_ROLLING_HILL = 0x12B,
+ NOUN_SCALPEL = 0x12C,
+ NOUN_SCENIC_MOUNTAINS = 0x12D,
+ NOUN_SEA_CLIFF = 0x12E,
+ NOUN_SEAWEED = 0x12F,
+ NOUN_SEAWEED_BANK = 0x130,
+ NOUN_SECURITY_CARD = 0x131,
+ //NOUN_SET = 0x132,
+ //NOUN_SHAKE_HANDS = 0x133,
+ //NOUN_SHARPEN = 0x134,
+ NOUN_SHIELD_ACCESS_PANEL = 0x135,
+ NOUN_SHIELD_GENERATOR = 0x136,
+ NOUN_SHIELD_MODULATOR = 0x137,
+ NOUN_SHIELD_STATUS_PANEL = 0x138,
+ NOUN_SHIP = 0x139,
+ //NOUN_SHOOT = 0x13A,
+ NOUN_SHOVEL = 0x13B,
+ //NOUN_SHRED = 0x13C,
+ NOUN_SHRUNKEN_HEADS = 0x13D,
+ NOUN_SINGED_MEAT = 0x13E,
+ //NOUN_SIT_IN = 0x13F,
+ NOUN_SKULL = 0x140,
+ NOUN_SKULL_AND_CROSSBONES = 0x141,
+ NOUN_SKY = 0x142,
+ //NOUN_SLEEP_ON = 0x143,
+ NOUN_SLITHERING_SNAKE = 0x144,
+ NOUN_SLUG_SECRETION = 0x145,
+ NOUN_SMALL_HOLE = 0x146,
+ //NOUN_SMELL = 0x147,
+ NOUN_SNAKE = 0x148,
+ //NOUN_SNIFF = 0x149,
+ //NOUN_SOAK = 0x14A,
+ NOUN_SPECIAL_KEY_1 = 0x14B,
+ NOUN_SPECIAL_KEY_2 = 0x14C,
+ NOUN_SPIDER = 0x14D,
+ NOUN_SPILT_MILK = 0x14E,
+ NOUN_SPIT_FIRE = 0x14F,
+ //NOUN_SPRAY = 0x150,
+ //NOUN_STAB = 0x151,
+ NOUN_STAIRS = 0x152,
+ NOUN_STALAGMITES = 0x153,
+ //NOUN_STAND_INSIDE = 0x154,
+ //NOUN_STARE_AT = 0x155,
+ NOUN_STEPS = 0x156,
+ NOUN_STUFFED_FISH = 0x157,
+ NOUN_SURFACE = 0x158,
+ //NOUN_SWIM_ACROSS = 0x159,
+ //NOUN_SWIM_INTO = 0x15A,
+ //NOUN_SWIM_THROUGH = 0x15B,
+ //NOUN_SWIM_TO = 0x15C,
+ //NOUN_SWIM_TOWARDS = 0x15D,
+ //NOUN_SWIM_UNDER = 0x15E,
+ NOUN_SWOOPING_CREATURE = 0x15F,
+ NOUN_TABLE = 0x160,
+ //NOUN_TAKE_LIVER = 0x161,
+ //NOUN_TAKE_OFF = 0x162,
+ //NOUN_TAKE_PAGE = 0x163,
+ NOUN_TALL_GRASS = 0x164,
+ NOUN_TAPE_PLAYER = 0x165,
+ NOUN_TARGET_COMPUTER = 0x166,
+ NOUN_TARGET_MODULE = 0x167,
+ NOUN_TARGETTING_COMPUTER = 0x168,
+ NOUN_TASMANIAN_DEVIL = 0x169,
+ NOUN_TASTY_TURKEY = 0x16A,
+ NOUN_TELEPORT_DEVICE = 0x16B,
+ NOUN_TELEPORTER = 0x16C,
+ NOUN_THATCHED_ROOF = 0x16D,
+ NOUN_THORNS = 0x16E,
+ NOUN_THORNY_BUSH = 0x16F,
+ //NOUN_TIE = 0x170,
+ NOUN_TIMEBOMB = 0x171,
+ NOUN_TIMER = 0x172,
+ NOUN_TIMER_MODULE = 0x173,
+ NOUN_TREE = 0x174,
+ NOUN_TREES = 0x175,
+ NOUN_TRODDEN_PATH = 0x176,
+ NOUN_TUBE = 0x177,
+ NOUN_TUNNEL = 0x178,
+ NOUN_TWINKIE_BUSH = 0x179,
+ NOUN_TWINKIFRUIT = 0x17A,
+ //NOUN_UNLOCK = 0x17B,
+ NOUN_UZI = 0x17C,
+ NOUN_VASE = 0x17D,
+ NOUN_VIDEO_GAME = 0x17E,
+ //NOUN_VIEW = 0x17F,
+ NOUN_VIEW_SCREEN = 0x180,
+ NOUN_VIEWPORT = 0x181,
+ NOUN_VILLAGE_AREA = 0x182,
+ NOUN_VILLAGE_TO_WEST = 0x183,
+ NOUN_VOLCANO = 0x184,
+ NOUN_VULTURE = 0x185,
+ NOUN_WAD_OF_CATTLE_PARTS = 0x186,
+ //NOUN_WALK_ACROSS = 0x187,
+ //NOUN_WALK_INSIDE = 0x188,
+ //NOUN_WALK_ON = 0x189,
+ //NOUN_WALK_OUTSIDE = 0x18A,
+ //NOUN_WALK_THROUGH = 0x18B,
+ //NOUN_WALK_TOWARDS = 0x18C,
+ NOUN_WALL = 0x18D,
+ NOUN_WATCH_TOWER = 0x18E,
+ NOUN_WATER = 0x18F,
+ NOUN_WEAPONS_DISPLAY = 0x190,
+ //NOUN_WEAR = 0x191,
+ NOUN_WEATHER_STATION = 0x192,
+ NOUN_WEATHER_VANE = 0x193,
+ NOUN_WEIGHT_MACHINE = 0x194,
+ NOUN_WESTERN_CLIFF_FACE = 0x195,
+ NOUN_WHEEL = 0x196,
+ NOUN_WINDOW = 0x197,
+ NOUN_WITCHDOCTOR_HUT = 0x198,
+ NOUN_WORKBENCH = 0x199,
+ //NOUN_WRITE_ON = 0x19A,
+ NOUN_YELLOW_BIRDY = 0x19B,
+ NOUN_GRASS = 0x19C,
+ NOUN_BOUNCING_REPTILE = 0x19D,
+ NOUN_DEEP_PIT = 0x19E,
+ NOUN_LOWLANDS_TO_NORTH = 0x19F,
+ NOUN_SMALL_BUSH = 0x1A0,
+ NOUN_SMALL_CACTUS = 0x1A1,
+ NOUN_ROCKY_AREA_TO_NORTH = 0x1A2,
+ NOUN_BAMBOO_LIKE_PLANT = 0x1A3,
+ NOUN_MOUNTAINSIDE = 0x1A4,
+ NOUN_FIELD = 0x1A5,
+ NOUN_GRASSY_FIELD = 0x1A6,
+ NOUN_CRAG = 0x1A7,
+ NOUN_HUGE_LEGS = 0x1A8,
+ NOUN_LEAF_COVERED_PIT = 0x1A9,
+ NOUN_PILE_OF_LEAVES = 0x1AA,
+ NOUN_OPEN_FIELD_TO_EAST = 0x1AB,
+ NOUN_LAWN = 0x1AC,
+ //NOUN_WALK_DOWN = 0x1AD,
+ NOUN_PATH_TO_WEST = 0x1AE,
+ NOUN_HEDGE = 0x1AF,
+ NOUN_VILLAGE_PATH = 0x1B0,
+ NOUN_PATH_TO_NORTHEAST = 0x1B1,
+ NOUN_JUNGLE_PATH = 0x1B2,
+ NOUN_THICK_UNDERGROWTH = 0x1B3,
+ NOUN_OCEAN = 0x1B4,
+ NOUN_OCEAN_IN_DISTANCE = 0x1B5,
+ NOUN_STRANGE_DEVICE = 0x1B6,
+ NOUN_BUSH = 0x1B7,
+ NOUN_ANEMOMETER = 0x1B8,
+ NOUN_ISLAND_IN_DISTANCE = 0x1B9,
+ NOUN_PATH = 0x1BA,
+ NOUN_TROPHY = 0x1BB,
+ NOUN_SPECIMEN_JARS = 0x1BC,
+ NOUN_BOWL = 0x1BD,
+ NOUN_LARGE_BOWL = 0x1BE,
+ NOUN_PATH_TO_NORTH = 0x1BF,
+ NOUN_HUT_TO_NORTH = 0x1C0,
+ NOUN_PATH_TO_EAST = 0x1C1,
+ NOUN_CHICKEN_ON_SPIT = 0x1C2,
+ NOUN_CAPTIVE_CREATURE = 0x1C3,
+ NOUN_TWINKIFRUIT_BUSH = 0x1C4,
+ NOUN_STREAM = 0x1C5,
+ NOUN_OPPOSITE_SHORE = 0x1C6,
+ NOUN_PATH_TO_SOUTH = 0x1C7,
+ NOUN_OPPOSITE_BANK = 0x1C8,
+ NOUN_BROKEN_LADDER = 0x1C9,
+ NOUN_BAG_OF_TWINKIFRUITS = 0x1CA,
+ NOUN_BED = 0x1CB,
+ NOUN_DISPLAY = 0x1CC,
+ //NOUN_LEAVE = 0x1CD,
+ //NOUN_EXIT_FROM = 0x1CE,
+ NOUN_DEVICE = 0x1CF,
+ NOUN_0_KEY = 0x1D0,
+ NOUN_1_KEY = 0x1D1,
+ NOUN_2_KEY = 0x1D2,
+ NOUN_3_KEY = 0x1D3,
+ NOUN_4_KEY = 0x1D4,
+ NOUN_5_KEY = 0x1D5,
+ NOUN_6_KEY = 0x1D6,
+ NOUN_7_KEY = 0x1D7,
+ NOUN_8_KEY = 0x1D8,
+ NOUN_9_KEY = 0x1D9,
+ NOUN_FROWN_KEY = 0x1DA,
+ NOUN_SMILE_KEY = 0x1DB,
+ NOUN_NATIVE_WOMAN = 0x1DC,
+ NOUN_YELLOW_BIRD = 0x1DD,
+ NOUN_BLEEPER = 0x1DE,
+ NOUN_SIZEMOMETER = 0x1DF,
+ NOUN_PANEL = 0x1E0,
+ NOUN_PRINTER = 0x1E1,
+ NOUN_HARD_DRIVE = 0x1E2,
+ NOUN_BATHROOM = 0x1E3,
+ NOUN_DESK = 0x1E4,
+ NOUN_PASSAGEWAY = 0x1E5,
+ NOUN_FIRE_HYDRANT = 0x1E6,
+ NOUN_FREEZER = 0x1E7,
+ NOUN_EQUIDIGITIZER = 0x1E8,
+ NOUN_VISION_VIEW = 0x1E9,
+ NOUN_TELEDETECTOR = 0x1EA,
+ NOUN_POLE = 0x1EB,
+ NOUN_TRANSPOSITION_DEVICE = 0x1EC,
+ NOUN_STATUESQUE = 0x1ED,
+ NOUN_TEMPERATURE_GAUGE = 0x1EE,
+ NOUN_CHECK = 0x1EF,
+ NOUN_WATCH = 0x1F0,
+ NOUN_ELECTRO_SCANNER = 0x1F1,
+ NOUN_HALL = 0x1F2,
+ NOUN_SCANNER = 0x1F3,
+ //NOUN_PLACE_HAND_ON = 0x1F4,
+ NOUN_SECURITY_MONITOR = 0x1F5,
+ NOUN_DIGITORAMA = 0x1F6,
+ NOUN_RAIL_BEAM = 0x1F7,
+ NOUN_VAULT = 0x1F8,
+ NOUN_HALLWAY = 0x1F9,
+ NOUN_PIPES = 0x1FA,
+ NOUN_AIR_VENT_GRATE = 0x1FB,
+ NOUN_SECURITY_OFFICE = 0x1FC,
+ NOUN_SIGNAL = 0x1FD,
+ NOUN_BLEEP = 0x1FE,
+ NOUN_BLIP = 0x1FF,
+ NOUN_LOFT = 0x200,
+ NOUN_ELECTRONIC_ANT_FARM = 0x201,
+ NOUN_ELECTRIC_WIRING = 0x202,
+ NOUN_SECURITY_PANEL = 0x203,
+ NOUN_CORRIDOR = 0x204,
+ NOUN_CIRCUIT_CONTROLS = 0x205,
+ NOUN_AIR_DUCT = 0x206,
+ NOUN_CELL_WALL = 0x207,
+ NOUN_LIGHTS = 0x208,
+ //NOUN_STARE_INTO = 0x209,
+ NOUN_CELL_CONTROLS = 0x20A,
+ NOUN_COMMODE = 0x20B,
+ //NOUN_USE = 0x20C,
+ NOUN_BASIN = 0x20D,
+ //NOUN_JUMP_INSIDE = 0x20E,
+ NOUN_PREVIOUS_CELL = 0x20F,
+ NOUN_NEXT_ROOM = 0x210,
+ NOUN_ZINK = 0x211,
+ //NOUN_GAZE_INTO = 0x212,
+ NOUN_THRONE = 0x213,
+ NOUN_SACK = 0x214,
+ NOUN_LIMB = 0x215,
+ NOUN_SINK = 0x216,
+ NOUN_JOHNNY_ON_THE_SPOT = 0x217,
+ NOUN_DEBRIS = 0x218,
+ NOUN_BUNK = 0x219,
+ NOUN_NEXT_CELL = 0x21A,
+ NOUN_TOILET = 0x21B,
+ NOUN_MONITOR_AREA = 0x21C,
+ NOUN_SIDEWALL = 0x21D,
+ NOUN_COFFEE_MUG = 0x21E,
+ //NOUN_SIT_AT = 0x21F,
+ NOUN_LIGHTING_FIXTURE = 0x220,
+ NOUN_MONITORS = 0x221,
+ NOUN_GENDER_CONTROLS = 0x222,
+ NOUN_NEURO_ANALYZER = 0x223,
+ NOUN_MOLECULAR_RECORDER = 0x224,
+ NOUN_MAINTENANCE_PANEL = 0x225,
+ NOUN_RAMP = 0x226,
+ //NOUN_WALK_UP = 0x227,
+ NOUN_SUBSONIC_ATOMIZER = 0x228,
+ NOUN_EIGHT_BALL = 0x229,
+ NOUN_DNA_INVERTER = 0x22A,
+ NOUN_DNA_CONVERTER = 0x22B,
+ NOUN_PLATFORM = 0x22C,
+ NOUN_GUINEA_PIG_TEST_BOX = 0x22D,
+ NOUN_GASEOUS_PROBE_WARPER = 0x22E,
+ NOUN_TOOL_CABINET = 0x22F,
+ NOUN_SURGICAL_BOXES = 0x230,
+ NOUN_FETAL_HEART_MONITOR = 0x231,
+ NOUN_XRAY_CABINET = 0x232,
+ NOUN_STERILIZATION_SINK = 0x233,
+ NOUN_DRIPOLATOR = 0x234,
+ NOUN_SHOCK_MACHINE = 0x235,
+ NOUN_INTERROGATION_TABLE = 0x236,
+ NOUN_LIE_DOWN_ON = 0x237,
+ //NOUN_DECIPHER = 0x238,
+ NOUN_GUARD = 0x239,
+ NOUN_RIP_IN_FLOOR = 0x23A,
+ NOUN_TELEPORT_AREA = 0x23B,
+ NOUN_BROKEN_BEAM = 0x23C,
+ NOUN_ROCK_CHUNK = 0x23D,
+ NOUN_BLOODY_CELL_WALL = 0x23E,
+ NOUN_WALL_BOARD = 0x23F,
+ NOUN_GENDER_SCANNER = 0x240,
+ NOUN_BAR = 0x241,
+ //NOUN_WALK_INTO = 0x242,
+ NOUN_HALLWAY_TO_SOUTH = 0x243,
+ NOUN_SIGN = 0x244,
+ NOUN_HALLWAY_TO_NORTH = 0x245,
+ NOUN_BOTTLES = 0x246,
+ NOUN_UPPER_DANCE_FLOOR = 0x247,
+ NOUN_DANCE_FLOOR = 0x248,
+ NOUN_RAILING = 0x249,
+ NOUN_BAR_STOOL = 0x24A,
+ NOUN_LADY = 0x24B,
+ NOUN_UPPER_LEVEL = 0x24C,
+ NOUN_ALCOVE = 0x24D,
+ NOUN_DISCO_BALL = 0x24E,
+ NOUN_LADIES = 0x24F,
+ NOUN_COACH_LAMP = 0x250,
+ NOUN_CARD_SLOT = 0x251,
+ NOUN_HOOP = 0x252,
+ NOUN_CANNONBALLS = 0x253,
+ NOUN_WATER_FOUNTAIN = 0x254,
+ NOUN_HALLWAY_TO_EAST = 0x255,
+ NOUN_HALLWAY_TO_WEST = 0x256,
+ NOUN_SUPPORT = 0x257,
+ NOUN_BACKBOARD = 0x258,
+ NOUN_WIDE_DOOR = 0x259,
+ NOUN_SIGN_POST = 0x25A,
+ NOUN_FIRE_EXTINGUISHER = 0x25B,
+ NOUN_TRASH = 0x25C,
+ NOUN_MISSILES = 0x25D,
+ NOUN_TANK = 0x25E,
+ NOUN_TWO_TON_WEIGHT = 0x25F,
+ NOUN_ONE_TON_TOMATO = 0x260,
+ NOUN_ANVIL = 0x261,
+ NOUN_MINUTEMAN_IV_ICBM = 0x262,
+ NOUN_CHEST = 0x263,
+ NOUN_ARMOR = 0x264,
+ NOUN_CARTON = 0x265,
+ NOUN_POWDER = 0x266,
+ NOUN_RAFT = 0x267,
+ NOUN_WHATZIT = 0x268,
+ NOUN_CATAPULT = 0x269,
+ NOUN_HAND_GRENADE = 0x26A,
+ NOUN_BARRELS = 0x26B,
+ NOUN_LOADING_RAMP = 0x26C,
+ NOUN_BLIMP = 0x26D,
+ NOUN_FLOUR = 0x26E,
+ NOUN_FLY_PAPER = 0x26F,
+ NOUN_RUG = 0x270,
+ NOUN_CARPET = 0x271,
+ NOUN_CAN = 0x272,
+ NOUN_RUBBER_DUCKIE = 0x273,
+ NOUN_GOLF_CLUBS = 0x274,
+ NOUN_RAT = 0x275,
+ NOUN_BARREL = 0x276,
+ NOUN_BUCKET_OF_TAR = 0x277,
+ NOUN_SACKS = 0x278,
+ NOUN_STORAGE = 0x279,
+ NOUN_120V_3_PHASE_400HZ = 0x27A,
+ NOUN_LAB_EQUIPMENT = 0x27B,
+ NOUN_AIR_HORN = 0x27C,
+ NOUN_JAR = 0x27D,
+ NOUN_SEVERED_CABLE = 0x27E,
+ NOUN_PROBE_ASSEMBLY = 0x27F,
+ NOUN_KNIFE_SWITCH = 0x280,
+ NOUN_WORK_BENCH = 0x281,
+ NOUN_HEATER = 0x282,
+ NOUN_TOXIC_WASTE = 0x283,
+ NOUN_EXPERIMENT = 0x284,
+ NOUN_DRAWING_BOARD = 0x285,
+ NOUN_MISHAP = 0x286,
+ NOUN_AIR_PURIFIER = 0x287,
+ NOUN_DUMMY = 0x288,
+ NOUN_PICTURE = 0x289,
+ NOUN_BAGGAGE_CHECK = 0x28A,
+ NOUN_DEPARTURE_SCHEDULE = 0x28B,
+ NOUN_SHADE_OF_PALE = 0x28C,
+ NOUN_ITINERARY = 0x28D,
+ NOUN_BARGAIN_VAT = 0x28E,
+ NOUN_PENCILS = 0x28F,
+ NOUN_PAD_IF_PAPER = 0x290,
+ NOUN_DEEPEST_DEPTHS = 0x291,
+ NOUN_ROLODEX = 0x292,
+ NOUN_MONA_TISA = 0x293,
+ NOUN_ABSTRACT_ART = 0x294,
+ NOUN_SPACE_QUESTING_VIII = 0x295,
+ NOUN_THEATRICAL_ART = 0x296,
+ NOUN_METAL_POLE = 0x297,
+ NOUN_EXIT = 0x298,
+ NOUN_SWIRLING_LIGHT = 0x299,
+ NOUN_REGISTER = 0x29A,
+ NOUN_PEACHY_BUNS = 0x29B,
+ NOUN_OUR_TOWN = 0x29C,
+ NOUN_EMBROIDERED_ART = 0x29D,
+ NOUN_GEORGE_BUSH_ALIKE = 0x29E,
+ NOUN_COUNTER = 0x29F,
+ NOUN_SENSOR = 0x2A0,
+ NOUN_SOFTWARE_INFORMATION = 0x2A1,
+ NOUN_WALK_BEHIND = 0x2A2,
+ NOUN_BARGAINS = 0x2A3,
+ NOUN_SCAN_LIGHT = 0x2A4,
+ NOUN_OLD_SOFTWARE_STAND = 0x2A5,
+ NOUN_SOFTWARE_SHELF = 0x2A6,
+ NOUN_HOTTEST_SOFTWARE = 0x2A7,
+ NOUN_GREAT_PAINTBALL_ART = 0x2A8,
+ NOUN_SCENIC_VISTA = 0x2A9,
+ NOUN_LASER = 0x2AA,
+ NOUN_LASER_JET = 0x2AB,
+ NOUN_LEVER = 0x2AC,
+ NOUN_BULLSEYE = 0x2AD,
+ NOUN_STAND = 0x2AE,
+ NOUN_CONTROL_STATION = 0x2AF,
+ NOUN_STRANGE_MONSTER = 0x2B0,
+ NOUN_GHASTLY_BEAST = 0x2B1,
+ //NOUN_GAWK_AT = 0x2B2,
+ NOUN_CORRIDOR_TO_SOUTH = 0x2B3,
+ NOUN_CORRIDOR_TO_NORTH = 0x2B4,
+ NOUN_WALK_ONTO = 0x2B5,
+ NOUN_ROCK_WALL = 0x2B6,
+ NOUN_WOMAN = 0x2B7,
+ NOUN_WOMEN = 0x2B8,
+ NOUN_CORRIDOR_TO_EAST = 0x2B9,
+ NOUN_CORRIDOR_TO_WEST = 0x2BA,
+ NOUN_AMMUNITION = 0x2BB,
+ NOUN_ARMORED_VEHICLE = 0x2BC,
+ NOUN_TOMATO = 0x2BD,
+ NOUN_MISSILE = 0x2BE,
+ NOUN_SUIT_OF_ARMOR = 0x2BF,
+ NOUN_POWDER_CONTAINER = 0x2C0,
+ NOUN_INFLATABLE_RAFT = 0x2C1,
+ NOUN_GRENADE = 0x2C2,
+ NOUN_FENCE = 0x2C3,
+ NOUN_WOODEN_STATUE = 0x2C4,
+ NOUN_CONVEYER_BELT = 0x2C5,
+ NOUN_CONTROLS = 0x2C6,
+ NOUN_EQUIPMENT = 0x2C7,
+ NOUN_SHELF = 0x2C8,
+ NOUN_CABINETS = 0x2C9,
+ NOUN_CONTROL_CONSOLE = 0x2CA,
+ NOUN_FAUCET = 0x2CB,
+ NOUN_PANEL_BOX = 0x2CC,
+ NOUN_STATUE = 0x2CD,
+ NOUN_GAUGE = 0x2CE,
+ NOUN_CIRCUIT_PANEL = 0x2CF,
+ NOUN_CATWALK = 0x2D0,
+ NOUN_CIRCUITS = 0x2D1,
+ NOUN_BLOOD_STAIN = 0x2D2,
+ NOUN_GRATE = 0x2D3,
+ NOUN_AIR_SHAFT = 0x2D4,
+ //NOUN_RETURN_TO = 0x2D5,
+ NOUN_FORMALDEHYDE = 0x2D6,
+ NOUN_PETROX = 0x2D7,
+ NOUN_SODIUM_BENZOATE = 0x2D8,
+ NOUN_GURNEY = 0x2D9,
+ NOUN_IRONING_BOARD = 0x2DA,
+ NOUN_LEFT_MONITOR = 0x2DB,
+ NOUN_RIGHT_MONITOR = 0x2DC,
+ NOUN_RED_BUTTON = 0x2DD,
+ NOUN_GREEN_BUTTON = 0x2DE,
+ NOUN_RIGHT_ONE_KEY = 0x2DF,
+ NOUN_RIGHT_1_KEY = 0x2E0,
+ NOUN_RIGHT_2_KEY = 0x2E1,
+ NOUN_RIGHT_3_KEY = 0x2E2,
+ NOUN_RIGHT_4_KEY = 0x2E3,
+ NOUN_RIGHT_5_KEY = 0x2E4,
+ NOUN_RIGHT_6_KEY = 0x2E5,
+ NOUN_RIGHT_7_KEY = 0x2E6,
+ NOUN_RIGHT_8_KEY = 0x2E7,
+ NOUN_LEFT_1_KEY = 0x2E8,
+ NOUN_LEFT_2_KEY = 0x2E9,
+ NOUN_LEFT_3_KEY = 0x2EA,
+ NOUN_LEFT_4_KEY = 0x2EB,
+ NOUN_CORRIDOR_WALL = 0x2EC,
+ NOUN_MUG = 0x2ED,
+ NOUN_DOUGHNUT = 0x2EE,
+ NOUN_SECURITY_STATION = 0x2EF,
+ NOUN_NEWSPAPER = 0x2F0,
+ NOUN_MAGAZINE = 0x2F1,
+ NOUN_CLIPBOARD = 0x2F2,
+ NOUN_PAPER_FOOTBALL = 0x2F3,
+ NOUN_YOUR_STUFF = 0x2F4,
+ NOUN_OTHER_STUFF = 0x2F5,
+ NOUN_LAMP = 0x2F6,
+ NOUN_CLIMB_INTO = 0x2F7,
+ NOUN_LIGHT_BULB = 0x2F8,
+ //NOUN_STEP_INTO = 0x2F9,
+ NOUN_ROOM = 0x2FA,
+ //NOUN_CRAWL_TO = 0x2FB,
+ NOUN_FOURTH_CELL = 0x2FC,
+ NOUN_THIRD_CELL = 0x2FD,
+ NOUN_SECOND_CELL = 0x2FE,
+ NOUN_FIRST_CELL = 0x2FF,
+ NOUN_EQUIPMENT_ROOM = 0x300,
+ //NOUN_CRAWL_DOWN = 0x301,
+ NOUN_DESCENDING_SHAFT = 0x302,
+ NOUN_SAUROPOD = 0x303,
+ NOUN_MONSTER = 0x304,
+ NOUN_FAKE_ID = 0x305,
+ NOUN_ALIEN_LIQUOR = 0x306,
+ NOUN_INTERN = 0x307,
+ NOUN_INSTRUMENT_TABLE = 0x308,
+ NOUN_WOMAN_ON_BALCONY = 0x309,
+ NOUN_WOMAN_IN_CHAIR = 0x30A,
+ //NOUN_SIT_ON = 0x30B,
+ NOUN_WOMAN_IN_ALCOVE = 0x30C,
+ NOUN_KETTLE = 0x30D,
+ NOUN_BARTENDER = 0x30E,
+ NOUN_WHISKEY = 0x30F,
+ NOUN_ALCOHOL = 0x310,
+ NOUN_RIM = 0x311,
+ //NOUN_WALK_ALONG = 0x312,
+ NOUN_SUBMERGED_CITY = 0x313,
+ NOUN_GOVERNORS_HOUSE = 0x314,
+ NOUN_RIM_TOWARDS_EAST = 0x315,
+ NOUN_CEMENT_PYLON = 0x316,
+ NOUN_ELEVATOR = 0x317,
+ NOUN_ELEVATOR_SHAFT = 0x318,
+ NOUN_CONVEYOR_BELT = 0x319,
+ NOUN_CANNON_BALLS = 0x31A,
+ NOUN_ELECTRICAL_OVERHANG = 0x31B,
+ NOUN_GUTTER_PIPE = 0x31C,
+ NOUN_SIDEWALK = 0x31D,
+ NOUN_STREET = 0x31E,
+ NOUN_BARRICADE = 0x31F,
+ NOUN_DOOR_CONTROL_SLOT = 0x320,
+ NOUN_STREET_TO_EAST = 0x321,
+ NOUN_SIDEWALK_TO_EAST = 0x322,
+ NOUN_BUILDING = 0x323,
+ NOUN_CAR = 0x324,
+ //NOUN_GET_INSIDE = 0x325,
+ NOUN_MARQUEE = 0x326,
+ NOUN_BUILDING_ENTRANCE = 0x327,
+ NOUN_GUARD_STATION = 0x328,
+ NOUN_TECHNICAL_EQUIPMENT = 0x329,
+ NOUN_GUARD_TURRET = 0x32A,
+ NOUN_PILLAR = 0x32B,
+ NOUN_PAPERS = 0x32C,
+ NOUN_FILE_CABINET = 0x32D,
+ NOUN_WINDOWS = 0x32E,
+ //NOUN_WALK = 0x32F,
+ NOUN_STORAGE_BOX = 0x330,
+ NOUN_WATER_COOLER = 0x331,
+ NOUN_BOX = 0x332,
+ NOUN_RIFLES = 0x333,
+ NOUN_SLINGSHOT = 0x334,
+ NOUN_MAUSOLEUM = 0x335,
+ NOUN_SOFTWARE_STORE = 0x336,
+ NOUN_CONCRETE_BUILDING = 0x337,
+ NOUN_HUMONGOUS_MONITOR = 0x338,
+ NOUN_SPACE_BIKE = 0x339,
+ NOUN_BILLBOARD = 0x33A,
+ NOUN_LACK_OF_NOOKIE_MOTEL = 0x33B,
+ NOUN_BIDETS_XCREETZA_HUT = 0x33C,
+ NOUN_BUILDINGS = 0x33D,
+ NOUN_SKYSCRAPER = 0x33E,
+ NOUN_SOFTWARE_LOGO = 0x33F,
+ NOUN_GIANT_TELESCOPE = 0x340,
+ NOUN_HANDLE = 0x341,
+ NOUN_HOLE = 0x342,
+ NOUN_LASER_BEAM = 0x343,
+ NOUN_PEDESTAL = 0x344,
+ NOUN_BOAT = 0x345,
+ NOUN_GIANT_MONUMENT = 0x346,
+ NOUN_ROPE = 0x347,
+ NOUN_SAND_BAR_RESTAURANT = 0x348,
+ NOUN_PORTHOLE = 0x349,
+ NOUN_TICKET_BOOTH = 0x34A,
+ NOUN_POLLYS_ENTRANCE = 0x34B,
+ NOUN_RESTAURANT_ENTRANCE = 0x34C,
+ NOUN_THE_PLEASURE_DOME = 0x34D,
+ NOUN_STARFISH = 0x34E,
+ NOUN_FLIPPER = 0x34F,
+ NOUN_SAND_DOLLAR = 0x350,
+ NOUN_SHELL = 0x351,
+ NOUN_GUEST_LIST = 0x352,
+ NOUN_WEIRD_ANIMAL_HEAD = 0x353,
+ NOUN_SHIPS_WHEEL = 0x354,
+ NOUN_HANDICAP_SIGN = 0x355,
+ NOUN_ELEVATOR_CONTROLS = 0x356,
+ NOUN_BRICK_WALL = 0x357,
+ NOUN_BIKE_RACK = 0x358,
+ NOUN_ODONALDS_SIGN = 0x359,
+ NOUN_ELEVATOR_ENTRANCE = 0x35A,
+ NOUN_SPECIAL_SALE_SIGN = 0x35B,
+ NOUN_ATTORNEYS_AT_LAW = 0x35C,
+ NOUN_SLEDGE_MALL = 0x35D,
+ NOUN_SKELETON = 0x35E,
+ NOUN_STRANGE_EQUIPMENT = 0x35F,
+ NOUN_STREET_TO_WEST = 0x360,
+ NOUN_SIDEWALK_TO_WEST = 0x361,
+ NOUN_TELEPORTER_ENTRANCE = 0x362,
+ NOUN_SOFTWARE_DOOR = 0x363,
+ NOUN_SPINACH_PATCH_DOLL = 0x364,
+ //NOUN_REFLECT = 0x365,
+ NOUN_REGISTER_DRAWER = 0x366,
+ NOUN_ELEVATOR_DOOR = 0x367,
+ NOUN_HYDRAULIC_SUPPORT = 0x368,
+ NOUN_EQUIPMENT_OVERHEAD = 0x369,
+ //NOUN_GET_INTO = 0x36A,
+ NOUN_WARNING_LABEL = 0x36B,
+ NOUN_NUCLEAR_SLINGSHOT = 0x36C,
+ NOUN_DISPLAY_CASE = 0x36D,
+ NOUN_PHOTON_RIFLES = 0x36E,
+ NOUN_MONITORING_EQUIPMENT = 0x36F,
+ NOUN_TELESCOPE = 0x370,
+ NOUN_MOTEL = 0x371,
+ NOUN_RESTAURANT = 0x372,
+ NOUN_SOFTWARE_STORE_SIGN = 0x373,
+ NOUN_ADVERTISING_POSTER = 0x374,
+ NOUN_ADVERTISEMENT = 0x375,
+ NOUN_OLD_SOFTWARE = 0x376,
+ NOUN_CASH_REGISTER = 0x377,
+ NOUN_ENTRANCE = 0x378,
+ NOUN_LASER_CANNON = 0x379,
+ NOUN_SAND_BAGS = 0x37A,
+ NOUN_PLEASURE_DOME = 0x37B,
+ NOUN_DOME_ENTRANCE = 0x37C,
+ NOUN_LABORATORY = 0x37D,
+ NOUN_STREET_TO_SOUTH = 0x37E,
+ NOUN_ELEVATOR_ACCESS_SLOT = 0x37F,
+ NOUN_CAR_CONTROLS = 0x380,
+ NOUN_SCENT_PACKET = 0x381,
+ NOUN_KITTY = 0x382,
+ NOUN_GLOVE_COMPARTMENT = 0x383,
+ NOUN_MOLDY_SOCK = 0x384,
+ NOUN_SODA_CANS = 0x385,
+ NOUN_WINDSHIELD = 0x386,
+ NOUN_DASHBOARD = 0x387,
+ NOUN_INTERIOR_OF_CAR = 0x388,
+ NOUN_VIEW_RIGHT_BUTTON = 0x389,
+ NOUN_BLACK_BUTTON = 0x38A,
+ NOUN_WHITE_BUTTON = 0x38B,
+ NOUN_INSIDE_OF_CAR = 0x38C,
+ NOUN_RIM_TOWARDS_WEST = 0x38D,
+ NOUN_CEMENT_BLOCK = 0x38E,
+ NOUN_CITY = 0x38F,
+ NOUN_SPEAKER = 0x390,
+ NOUN_EYE_CHART = 0x391,
+ NOUN_LAUNCH_PAD = 0x392,
+ NOUN_BUILDING_TO_WEST = 0x393,
+ NOUN_PAD_TO_EAST = 0x394,
+ NOUN_PAD_TO_WEST = 0x395,
+ NOUN_TOWER = 0x396,
+ NOUN_LOOK_OUT = 0x397,
+ NOUN_SERVICE_PANEL = 0x398,
+ NOUN_CRACK = 0x399,
+ NOUN_THROTTLE = 0x39A,
+ NOUN_GRAB = 0x39B,
+ NOUN_INSTRUMENTATION = 0x39C,
+ NOUN_TP = 0x39D,
+ NOUN_SEAT = 0x39E,
+ NOUN_STATUS_PANEL = 0x39F,
+ NOUN_SHIPS_CONTROLS = 0x3A0,
+ NOUN_PROFESSOR = 0x3A1,
+ NOUN_PROFESSORS_GURNEY = 0x3A2,
+ NOUN_WELCOME_MAT = 0x3A3,
+ NOUN_MELON_MUSH = 0x3A4,
+ NOUN_BADMINTON_BRAT = 0x3A5,
+ //NOUN_APPLY = 0x3A6,
+ NOUN_COMBINATION = 0x3A7,
+ NOUN_NOTE = 0x3A8,
+ NOUN_LECITHIN = 0x3A9,
+ NOUN_REPAIR_WOMAN = 0x3AA,
+ NOUN_EXPLOSIVES = 0x3AB,
+ NOUN_DOLLOP = 0x3AC,
+ NOUN_DROP = 0x3AD,
+ NOUN_DASH = 0x3AE,
+ NOUN_SPLASH = 0x3AF,
+ NOUN_DOCK_TO_SOUTH = 0x3B0,
+ //NOUN_STEER_TOWARDS = 0x3B1,
+ NOUN_BUILDING_TO_NORTH = 0x3B2,
+ NOUN_VOLCANO_RIM = 0x3B3,
+ NOUN_OPEN_WATER_TO_SOUTH = 0x3B4,
+ NOUN_PROJECTOR = 0x3B5,
+ NOUN_GUARDS_ARM2 = 0x3B6,
+ //NOUN_NIBBLE_ON = 0x3B7,
+ //NOUN_ENTER = 0x3B8,
+ NOUN_ = 0x3B9,
+ NOUN_TIMER_BUTTON_1 = 0x3BA,
+ NOUN_REMOTE_BUTTON_1 = 0x3BB,
+ NOUN_START_BUTTON_2 = 0x3BC,
+ NOUN_REMOTE_BUTTON_2 = 0x3BD,
+ NOUN_TIMER_BUTTON_2 = 0x3BE,
+ NOUN_START_BUTTON_1 = 0x3BF,
+ NOUN_ANTIGRAV_CONTROLS = 0x3C0,
+ NOUN_BRUCES_TREE = 0x3C1,
+ NOUN_COLISEUM = 0x3C2,
+ NOUN_BRUCES_GARDEN_ROOM = 0x3C3,
+ NOUN_FOUNTAIN = 0x3C4,
+ NOUN_HOUSE_OF_BRUCE = 0x3C5,
+ NOUN_CITY_BACKDROP = 0x3C6,
+ NOUN_BRUCES_BALCONY = 0x3C7,
+ NOUN_BRUCES_ENTRANCE = 0x3C8,
+ NOUN_BRUCES_LOGO = 0x3C9,
+ NOUN_LOUNGE_CHAIR = 0x3CA,
+ NOUN_LIVING_ROOM_FLOOR = 0x3CB,
+ NOUN_LIVINGROOM_FLOOR = 0x3CC,
+ NOUN_PERFUME_BOTTLE = 0x3CD,
+ NOUN_COOL_NEON_LIGHT = 0x3CE,
+ NOUN_FLOWER_POT = 0x3CF,
+ NOUN_COFFEE_TABLE = 0x3D0,
+ NOUN_FLOWERS = 0x3D1,
+ NOUN_ART_DECO_CHAIR = 0x3D2,
+ NOUN_SAFE = 0x3D3,
+ NOUN_SPLASHY_DECOR = 0x3D4,
+ NOUN_THEATRICAL_FACES = 0x3D5,
+ NOUN_ART_DECO_PIECE = 0x3D6,
+ NOUN_END_OF_ROOM = 0x3D7,
+ NOUN_FIREPLACE = 0x3D8,
+ NOUN_ARTWORK = 0x3D9,
+ NOUN_COOL_NEON_LIGHTS = 0x3DA,
+ NOUN_GLASS_PLATED_WINDOW = 0x3DB,
+ NOUN_BEDROOM_FLOOR = 0x3DC,
+ NOUN_BAUBLE = 0x3DD,
+ NOUN_SNAPSHOT = 0x3DE,
+ NOUN_PERFUME = 0x3DF,
+ NOUN_CLAPBOARD = 0x3E0,
+ NOUN_BERET = 0x3E1,
+ NOUN_HORSE_WHIP = 0x3E2,
+ NOUN_CORNER_TABLE = 0x3E3,
+ NOUN_BOA = 0x3E4,
+ NOUN_WIG_STAND = 0x3E5,
+ NOUN_PARTITION = 0x3E6,
+ NOUN_MEGAPHONE = 0x3E7,
+ NOUN_SLIP = 0x3E8,
+ NOUN_SCONCE = 0x3E9,
+ NOUN_VANITY = 0x3EA,
+ NOUN_BEDBOARD = 0x3EB,
+ NOUN_LOVE_SEAT = 0x3EC,
+ NOUN_SOUVENIR_TICKETS = 0x3ED,
+ NOUN_REVIEW = 0x3EE,
+ NOUN_BRUCE_AT_THE_GALA = 0x3EF,
+ NOUN_ART_DECO_RUG = 0x3F0,
+ NOUN_LIVINGROOM = 0x3F1,
+ NOUN_SCULPTURE = 0x3F2,
+ NOUN_SPECIMEN_EPITHET = 0x3F3,
+ NOUN_VENT = 0x3F4,
+ NOUN_FLOWER_BOX = 0x3F5,
+ NOUN_LEDGE = 0x3F6,
+ NOUN_BOLT = 0x3F7,
+ NOUN_OBSERVATION_WINDOW = 0x3F8,
+ NOUN_AIR_HOSE = 0x3F9,
+ NOUN_AUTO_SHOP = 0x3FA,
+ NOUN_MANHOLE = 0x3FB,
+ NOUN_AUTO_SHOP_ENTRANCE = 0x3FC,
+ NOUN_BROKEN_WINDOW = 0x3FD,
+ NOUN_WOMANHOLE = 0x3FE,
+ NOUN_GARAGE_DOOR = 0x3FF,
+ NOUN_SCRATCH_PAD = 0x400,
+ NOUN_GAS_PRICES = 0x401,
+ NOUN_UP_BUTTON = 0x402,
+ NOUN_DOWN_BUTTON = 0x403,
+ NOUN_SPARE_PARTS_LIST = 0x404,
+ NOUN_SKYLIGHT = 0x405,
+ NOUN_TOOL_BOX = 0x406,
+ NOUN_CAR_LIFT = 0x407,
+ NOUN_CAR_SEAT = 0x408,
+ NOUN_GARAGE_FLOOR = 0x409,
+ NOUN_GARAGE_DOOR_CONTROLS = 0x40A,
+ NOUN_AMISH_HAT = 0x40B,
+ NOUN_JACK = 0x40C,
+ NOUN_COILS = 0x40D,
+ NOUN_OIL_CAN = 0x40E,
+ NOUN_FAN_BELTS = 0x40F,
+ NOUN_REAR_OF_GARAGE = 0x410,
+ NOUN_FRONT_OF_GARAGE = 0x411,
+ NOUN_MUFFLER = 0x412,
+ NOUN_SPARE_PART = 0x413,
+ NOUN_HUBCAP = 0x414,
+ NOUN_CANDLE = 0x415,
+ NOUN_RATES = 0x416,
+ NOUN_GREASE_CAN = 0x417,
+ NOUN_CALENDAR = 0x418,
+ NOUN_FORK_LIFT = 0x419,
+ NOUN_TRASH_CAN = 0x41A,
+ NOUN_SHAKER_CHAIR = 0x41B,
+ NOUN_QUARTER_PANEL = 0x41C,
+ NOUN_AREA_BEHIND_CAR = 0x41D,
+ NOUN_DANGER_ZONE = 0x41E,
+ NOUN_NEWSSTAND = 0x41F,
+ NOUN_LADY_GODIVA_MONUMENT = 0x420,
+ NOUN_SPOT_A_POT = 0x421,
+ NOUN_GUARD_RAIL = 0x422,
+ NOUN_ALLEY = 0x423,
+ NOUN_DITCH = 0x424,
+ NOUN_VIDEO_STORE_DOOR = 0x425,
+ NOUN_BUCKLUSTER_MARQUEE = 0x426,
+ NOUN_VIDEO_STORE = 0x427,
+ NOUN_HORMONE_BILLBOARD = 0x428,
+ NOUN_PHONE_ANTENNA = 0x429,
+ NOUN_RETURN_SLOT = 0x42A,
+ NOUN_NOOSE = 0x42B,
+ NOUN_COMEDY_VIDEOS = 0x42C,
+ NOUN_SMELLY_SNEAKER = 0x42D,
+ NOUN_PIPPYS_STOCKING = 0x42E,
+ NOUN_PHONE_CRADLE = 0x42F,
+ NOUN_DRAMA_VIDEOS = 0x430,
+ NOUN_SPOTLIGHT = 0x431,
+ NOUN_STOREROOM_FLOOR = 0x432,
+ NOUN_ALL_SALES_FINAL = 0x433,
+ NOUN_MACHOPROSE_TEE_SHIRT = 0x434,
+ NOUN_UNKNOWN_COMIC_HANDS = 0x435,
+ NOUN_WET_CEMENT = 0x436,
+ NOUN_PIPPYS_TINY_IMPRINT = 0x437,
+ NOUN_OBNOXIOUS_DOG_PAWS = 0x438,
+ NOUN_LEG_AND_A_LEG_JEANS = 0x439,
+ NOUN_VIDEO_STORE_EXIT = 0x43A,
+ NOUN_AISLE = 0x43B,
+ NOUN_VIDEO_MONITOR = 0x43C,
+ NOUN_POLLY_PIGS_IMPRINT = 0x43D,
+ NOUN_JOHN_WYNNS_IMPRINT = 0x43E,
+ NOUN_MR_NEDS_IMPRINT = 0x43F,
+ NOUN_PEG_LEG_PETE_IMPRINT = 0x440,
+ NOUN_MARX_BROS_POSTER = 0x441,
+ NOUN_PIPPY_BILLBOARD = 0x442,
+ NOUN_VIDEOS_NOONE_WANTS = 0x443,
+ NOUN_MORE_CLASSIC_VIDEOS = 0x444,
+ NOUN_JOIN_OUR_PRICE_CLUB = 0x445,
+ NOUN_EDUCATIONAL_VIDEOS = 0x446,
+ NOUN_DEEP_DISCOUNT_TITLES = 0x447,
+ NOUN_WORLD_CHAMPS_POSTER = 0x448,
+ NOUN_WORKOUT_VIDEOS = 0x449,
+ NOUN_20_PERCENT_OFF_SIGN = 0x44A,
+ NOUN_CIVILIZATION_AD = 0x44B,
+ NOUN_NEW_RELEASE_VIDEOS = 0x44C,
+ NOUN_PORNO_VIDEOS = 0x44D,
+ NOUN_FOREIGN_VIDEOS = 0x44E,
+ NOUN_CLASSIC_VIDEOS = 0x44F,
+ NOUN_ADVENTURE_VIDEOS = 0x450,
+ NOUN_BUCKLUSTER_LOGO = 0x451,
+ NOUN_WINE_BOTTLE = 0x452,
+ NOUN_DIRT_PILE = 0x453,
+ NOUN_MAMMOTH_PENCIL_HEAD = 0x454,
+ NOUN_WREAKY_PUMPKIN = 0x455,
+ NOUN_MILK_CARTON = 0x456,
+ NOUN_BUCKET = 0x457,
+ NOUN_EMPTY_BOX = 0x458,
+ NOUN_DIAPER_BOX = 0x459,
+ NOUN_HERMIT = 0x45A,
+ NOUN_METAL_PIPE = 0x45B,
+ NOUN_CONCRETE_SUPPORT = 0x45C,
+ NOUN_VARIOUS_TRASH = 0x45D,
+ NOUN_ARMATURE = 0x45E,
+ NOUN_CONTROL_BOX = 0x45F,
+ NOUN_TOP_OF_DOME = 0x460,
+ NOUN_EXPRESSWAY_TO_EAST = 0x461,
+ NOUN_GO_TOWARDS = 0x462,
+ NOUN_EXPRESSWAY_TO_WEST = 0x463,
+ NOUN_DOME = 0x464,
+ NOUN_VIEW_OF_CITY = 0x465,
+ NOUN_EXPRESSWAY = 0x466,
+ NOUN_HOOK = 0x467,
+ NOUN_SEA_MONSTER = 0x468,
+ NOUN_EDGE_OF_VOLCANO = 0x469,
+ NOUN_JUMP_THROUGH = 0x46A,
+ NOUN_OLD_TEA_CUP = 0x46B,
+ NOUN_NAME_PLATE = 0x46C,
+ NOUN_OLD_VASE = 0x46D,
+ NOUN_PORTRAIT = 0x46E,
+ //NOUN_PUT_DOWN = 0x46F,
+ NOUN_TALL_BUILDING = 0x470,
+ NOUN_OBNOXIOUS_DOG = 0x471,
+ NOUN_GUTS = 0x472,
+ NOUN_BIG_HEADS = 0x473,
+ NOUN_INSTALL = 0x474,
+ NOUN_LIFE_SUPPORT_MODULE = 0x475,
+ //NOUN_REMOVE = 0x476,
+ NOUN_LARGE_BLADE = 0x477,
+ NOUN_SIDE_ENTRANCE = 0x478,
+ NOUN_INDICATOR = 0x479,
+ NOUN_SIGNPOST = 0x47A,
+ NOUN_PIN = 0x47B,
+ NOUN_POWDER_PUFF = 0x47C,
+ NOUN_SHELVES = 0x47D,
+ NOUN_ELECTRODES = 0x47E,
+ NOUN_MISHAP2 = 0x47F,
+ NOUN_ISLD_SUPERSTRUCTURE = 0x480,
+ NOUN_FILE_CABINETS = 0x481,
+ NOUN_CYCLE_SHOP = 0x482,
+ NOUN_AIR_BIKE = 0x483,
+ NOUN_EMERGENCY_LIGHT = 0x484,
+ NOUN_TARGET_AREA = 0x485,
+ NOUN_ICE_CHESTS = 0x486,
+ NOUN_BIRDS = 0x487,
+ NOUN_DOCTORS_OFFICE = 0x488,
+ //NOUN_DEFACE = 0x489,
+ NOUN_LARGE_HEADS = 0x48A,
+ NOUN_SMALL_TABLE = 0x48B,
+ NOUN_COLLOSSEUM = 0x48C,
+ NOUN_HOUSE = 0x48D,
+ NOUN_BALCONY = 0x48E,
+ NOUN_GARDEN_ROOM = 0x48F,
+ NOUN_COVE_LIGHTS = 0x490,
+ NOUN_MASKS = 0x491,
+ NOUN_NEON_LIGHTS = 0x492,
+ NOUN_GLASS_BLOCK_WALL = 0x493,
+ NOUN_SCREEN = 0x494,
+ NOUN_SPARE_RIBS = 0x495,
+ NOUN_BANNER = 0x496,
+ NOUN_INSTRUCTIONAL_VIDEOS = 0x497,
+ NOUN_CEMENT = 0x498,
+ NOUN_STORE = 0x499,
+ NOUN_CARDBOARD_BOX = 0x49A,
+ NOUN_GRAFFITTI = 0x49B,
+ NOUN_GRAFFITI = 0x49C,
+ NOUN_PHOTOGRAPH = 0x49D,
+ NOUN_DIRECTORS_SLATE = 0x49E,
+ NOUN_CROP = 0x49F,
+ NOUN_HAT = 0x4A0,
+ NOUN_LOGO = 0x4A1,
+ NOUN_MAINTENANCE_BUILDING = 0x4A2,
+ //NOUN_MASSAGE = 0x4A3,
+ //NOUN_MANGLE = 0x4A4,
+ //NOUN_RUB = 0x4A5,
+ //NOUN_JUGGLE = 0x4A6,
+ //NOUN_SMASH = 0x4A7,
+ //NOUN_GUZZLE = 0x4A8,
+ NOUN_WEST_END_OF_PLATFORM = 0x4A9,
+ NOUN_EAST_END_OF_PLATFORM = 0x4AA
+ //NOUN_FOLD = 0x4AB,
+ //NOUN_SPINDLE = 0x4AC,
+ //NOUN_MUTILATE = 0x4AD
+};
+
+class SceneFactory {
+public:
+ static SceneLogic *createScene(MADSEngine *vm);
+};
+
+/**
+ * Specialized base class for Rex Nebular game scenes
+ */
+class NebularScene : public SceneLogic {
+protected:
+ NebularGlobals &_globals;
+ GameNebular &_game;
+ MADSAction &_action;
+
+ /**
+ * Forms an animation resource name
+ */
+ Common::String formAnimName(char sepChar, int suffixNum);
+
+ /**
+ * Plays appropriate sound for entering various rooms
+ */
+ void lowRoomsEntrySound();
+public:
+ /**
+ * Constructor
+ */
+ NebularScene(MADSEngine *vm);
+
+ void sub7178C();
+};
+
+class SceneInfoNebular : public SceneInfo {
+ friend class SceneInfo;
+protected:
+ virtual void loadCodes(MSurface &depthSurface, int variant);
+
+ virtual void loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream);
+
+ /**
+ * Constructor
+ */
+ SceneInfoNebular(MADSEngine *vm) : SceneInfo(vm) {}
+};
+
+class SceneTeleporter : public NebularScene {
+protected:
+ int _buttonTyped;
+ int _curCode;
+ int _digitCount;
+ int _curMessageId;
+ int _handSpriteId;
+ int _handSequenceId;
+ int _finishedCodeCounter;
+ int _meteorologistNextPlace;
+ int _meteorologistCurPlace;
+ int _teleporterSceneId;
+ Common::String _msgText;
+
+ int teleporterAddress(int code, bool working);
+
+ void teleporterHandleKey();
+ Common::Point teleporterComputeLocation();
+ void teleporterEnter();
+ bool teleporterActions();
+ void teleporterStep();
+
+protected:
+ /**
+ * Constructor
+ */
+ SceneTeleporter(MADSEngine *vm);
+};
+
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES_H */
diff --git a/engines/mads/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp
new file mode 100644
index 0000000000..8cf4107ad4
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes1.cpp
@@ -0,0 +1,3168 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes1.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene1xx::setAAName() {
+ int idx = (_scene->_nextSceneId > 103 && _scene->_nextSceneId < 112) ? 1 : 0;
+ _game._aaName = Resources::formatAAName(idx);
+}
+
+void Scene1xx::sceneEntrySound() {
+ if (_vm->_musicFlag) {
+ switch (_scene->_nextSceneId) {
+ case 101:
+ _vm->_sound->command(11);
+ break;
+ case 102:
+ _vm->_sound->command(12);
+ break;
+ case 103:
+ _vm->_sound->command(3);
+ _vm->_sound->command(25);
+ break;
+ case 109:
+ _vm->_sound->command(13);
+ break;
+ case 110:
+ _vm->_sound->command(10);
+ break;
+ case 111:
+ _vm->_sound->command(3);
+ break;
+ case 112:
+ _vm->_sound->command(15);
+ break;
+ default:
+ if (_scene->_priorSceneId < 104 || _scene->_priorSceneId > 108)
+ _vm->_sound->command(10);
+ break;
+ }
+ }
+}
+
+void Scene1xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+ Common::String oldName = _game._player._spritesPrefix;
+ if (_scene->_nextSceneId <= 103 || _scene->_nextSceneId == 111) {
+ if (_globals[kSexOfRex] == SEX_FEMALE)
+ _game._player._spritesPrefix = "ROX";
+ else {
+ _game._player._spritesPrefix = "RXM";
+ _globals[kSexOfRex] = SEX_MALE;
+ }
+ } else if (_scene->_nextSceneId <= 110) {
+ _game._player._spritesPrefix = "RXSW";
+ _globals[kSexOfRex] = SEX_UNKNOWN;
+ } else if (_scene->_nextSceneId == 112)
+ _game._player._spritesPrefix = "";
+
+ if (oldName == _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ if (_scene->_nextSceneId == 105 || (_scene->_nextSceneId == 109 && _globals[kHoovicAlive])) {
+ _game._player._spritesChanged = true;
+ _game._player._loadsFirst = false;
+ }
+
+ _game._player._trigger = 0;
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene101::Scene101(MADSEngine *vm) : Scene1xx(vm) {
+ _sittingFl = false;
+ _panelOpened = false;
+ _messageNum = 0;
+ _posY = 0;
+ _shieldSpriteIdx = 0;
+ _chairHotspotId = 0;
+ _oldSpecial = 0;
+}
+
+void Scene101::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_sittingFl);
+ s.syncAsByte(_panelOpened);
+ s.syncAsSint16LE(_messageNum);
+ s.syncAsSint16LE(_posY);
+ s.syncAsSint16LE(_shieldSpriteIdx);
+ s.syncAsSint16LE(_chairHotspotId);
+ s.syncAsSint16LE(_oldSpecial);
+}
+
+void Scene101::setup() {
+ _scene->_animationData->preLoad(formAnimName('A', -1), 3);
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene101::sayDang() {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+
+ switch (_game._trigger) {
+ case 0:
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 6, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 21);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ _vm->_sound->command(17);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 3, 2, 0, 0);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 17);
+ _scene->_kernelMessages.add(Common::Point(143, 61), 0x1110, 0, 0, 60, _game.getQuote(57));
+ _scene->_sequences.addTimer(120, 73);
+ break;
+
+ case 73:
+ _vm->_dialogs->show(10117);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene101::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 3));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 4));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('x', 5));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('x', 6));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('x', 7));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('m', -1));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('b', 2));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('x', 8));
+ _globals._spriteIndexes[14] = _scene->_sprites.addSprites(formAnimName('x', 0));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 0, 0, 25);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 4, 0, 1, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 2, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 7, 70);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 10, 0, 0, 60);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 5, 0, 1, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 10, 0, 2, 0);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 6, 0, 0, 0);
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 6, 0, 10, 4);
+ _globals._sequenceIndexes[10] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[10], false, 6, 0, 32, 47);
+
+ _scene->_hotspots.activate(NOUN_SHIELD_MODULATOR, false);
+ _panelOpened = false;
+
+ // HACK: set the prior scene to 102 for now when the game starts, to avoid Rex's getting up animation
+ if (_scene->_priorSceneId == -1)
+ _scene->_priorSceneId = 102;
+
+ if (_scene->_priorSceneId != -1)
+ _globals[kNeedToStandUp] = false;
+
+ if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(100, 152);
+
+ if ((_scene->_priorSceneId == 112) || ((_scene->_priorSceneId == -2) && _sittingFl )) {
+ _game._player._visible = false;
+ _sittingFl = true;
+ _game._player._playerPos = Common::Point(161, 123);
+ _game._player._facing = FACING_NORTHEAST;
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 3, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 17);
+ _scene->_hotspots.activate(NOUN_CHAIR, false);
+ _chairHotspotId = _scene->_dynamicHotspots.add(NOUN_CHAIR, VERB_SIT_IN, -1, Common::Rect(159, 84, 159 + 33, 84 + 36));
+ if (_scene->_priorSceneId == 112)
+ sayDang();
+ } else {
+ _globals._sequenceIndexes[12] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[12], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 4);
+ }
+
+ _game.loadQuoteSet(0x31, 0x32, 0x39, 0x36, 0x37, 0x38, 0);
+
+ if (_globals[kNeedToStandUp]) {
+ _scene->loadAnimation(Resources::formatName(101, 'S', -1, EXT_AA, ""), 71);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _game._player._playerPos = Common::Point(68, 140);
+ _game._player._facing = FACING_WEST;
+
+ _messageNum = 0;
+ _posY = 30;
+ }
+
+ _oldSpecial = false;
+
+ sceneEntrySound();
+}
+
+void Scene101::step() {
+ if (_oldSpecial != _game._player._special) {
+ _oldSpecial = _game._player._special;
+ if (_oldSpecial)
+ _vm->_sound->command(39);
+ else
+ _vm->_sound->command(11);
+ }
+
+ switch (_game._trigger) {
+ case 70:
+ _vm->_sound->command(9);
+ break;
+
+ case 71:
+ _globals[kNeedToStandUp] = false;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ break;
+
+ case 72:
+ case 73:
+ sayDang();
+ break;
+
+ default:
+ break;
+ }
+
+ if (_scene->_activeAnimation != nullptr) {
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 6) && (_messageNum == 0)) {
+ _messageNum++;
+ _scene->_kernelMessages.add(Common::Point(63, _posY), 0x1110, 0, 0, 240, _game.getQuote(49));
+ _posY += 14;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 7) && (_messageNum == 1)) {
+ _messageNum++;
+ _scene->_kernelMessages.add(Common::Point(63, _posY), 0x1110, 0, 0, 240, _game.getQuote(54));
+ _posY += 14;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 10) && (_messageNum == 2)) {
+ _messageNum++;
+ _scene->_kernelMessages.add(Common::Point(63, _posY), 0x1110, 0, 0, 240, _game.getQuote(55));
+ _posY += 14;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 17) && (_messageNum == 3)) {
+ _messageNum++;
+ _scene->_kernelMessages.add(Common::Point(63, _posY), 0x1110, 0, 0, 240, _game.getQuote(56));
+ _posY += 14;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 20) && (_messageNum == 4)) {
+ _messageNum++;
+ _scene->_kernelMessages.add(Common::Point(63, _posY), 0x1110, 0, 0, 240, _game.getQuote(50));
+ _posY += 14;
+ }
+ }
+}
+
+void Scene101::preActions() {
+ if (_action.isAction(VERB_LOOK, NOUN_VIEW_SCREEN))
+ _game._player._needToWalk = true;
+
+ if (_sittingFl) {
+ if (_action.isAction(VERB_LOOK) || _action.isObject(NOUN_CHAIR) || _action.isAction(VERB_TALKTO) || _action.isAction(VERB_PEER_THROUGH) || _action.isAction(VERB_EXAMINE))
+ _game._player._needToWalk = false;
+
+ if (_game._player._needToWalk) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._readyToWalk = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _globals._sequenceIndexes[11] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 1, 17);
+ _vm->_sound->command(16);
+ break;
+
+ case 1:
+ _sittingFl = false;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _game._player._readyToWalk = true;
+ _scene->_hotspots.activate(71, true);
+ _scene->_dynamicHotspots.remove(_chairHotspotId);
+ _globals._sequenceIndexes[12] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[12], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 4);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_panelOpened && !(_action.isObject(NOUN_SHIELD_ACCESS_PANEL) || _action.isObject(NOUN_SHIELD_MODULATOR))) {
+ switch (_game._trigger) {
+ case 0:
+ if (_game._player._needToWalk) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _shieldSpriteIdx = _game._objects.isInRoom(OBJ_SHIELD_MODULATOR) ? 13 : 14;
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[_shieldSpriteIdx], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(20);
+ }
+ break;
+
+ case 1:
+ _game._player._stepEnabled = true;
+ _panelOpened = false;
+ _scene->_hotspots.activate(NOUN_SHIELD_MODULATOR, false);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene101::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(10125);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALKTO, NOUN_LIFE_SUPPORT_SECTION)) {
+ _scene->_nextSceneId = 102;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_SIT_IN, NOUN_CHAIR) || (_action.isAction(VERB_LOOK, NOUN_VIEW_SCREEN) && !_sittingFl)) {
+ if (!_sittingFl) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->_sequences.remove(_globals._sequenceIndexes[12]);
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 3, 1);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 1, 17);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_SPRITE, 10, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _action._inProgress = false;
+ return;
+
+ case 1:
+ _vm->_sound->command(16);
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 3, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 17);
+ _game._player._stepEnabled = true;
+ _sittingFl = true;
+ _scene->_hotspots.activate(71, false);
+ _chairHotspotId = _scene->_dynamicHotspots.add(NOUN_CHAIR, VERB_SIT_IN, -1, Common::Rect(159, 84, 159 + 33, 84 + 36));
+ if (!_action.isAction(VERB_LOOK, NOUN_VIEW_SCREEN)) {
+ _action._inProgress = false;
+ return;
+ }
+ _game._trigger = 0;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ _vm->_dialogs->show(10131);
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if ((_action.isAction(VERB_WALKTO, NOUN_SHIELD_ACCESS_PANEL) || _action.isAction(VERB_OPEN, NOUN_SHIELD_ACCESS_PANEL)) && !_panelOpened) {
+ switch (_game._trigger) {
+ case 0:
+ _shieldSpriteIdx = _game._objects.isInRoom(OBJ_SHIELD_MODULATOR) ? 13 : 14;
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[_shieldSpriteIdx], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(20);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[_shieldSpriteIdx], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], -2, -2);
+ _game._player._stepEnabled = true;
+ _panelOpened = true;
+ if (_game._objects.isInRoom(OBJ_SHIELD_MODULATOR))
+ _scene->_hotspots.activate(NOUN_SHIELD_MODULATOR, true);
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_action.isAction(VERB_TAKE, NOUN_SHIELD_MODULATOR) || _action.isAction(VERB_PULL, NOUN_SHIELD_MODULATOR)) && _game._objects.isInRoom(OBJ_SHIELD_MODULATOR)) {
+ _game._objects.addToInventory(OBJ_SHIELD_MODULATOR);
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[14], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], -2, -2);
+ _scene->_hotspots.activate(NOUN_SHIELD_MODULATOR, false);
+ _vm->_dialogs->showItem(OBJ_SHIELD_MODULATOR, 10120);
+ _vm->_sound->command(22);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_SHIELD_ACCESS_PANEL) || (_action.isAction(VERB_LOOK, NOUN_SHIELD_MODULATOR) && !_game._objects.isInInventory(OBJ_SHIELD_MODULATOR)) ) {
+ if (_panelOpened) {
+ if (_game._objects.isInRoom(OBJ_SHIELD_MODULATOR))
+ _vm->_dialogs->show(10128);
+ else
+ _vm->_dialogs->show(10129);
+ } else
+ _vm->_dialogs->show(10127);
+
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_SHIELD_ACCESS_PANEL) && _panelOpened) {
+ _vm->_dialogs->show(10130);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_VIEW_SCREEN) && _sittingFl) {
+ if (_globals[kWatchedViewScreen])
+ sayDang();
+ else {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 21);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _vm->_sound->command(17);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[11] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 21);
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 3, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 17);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 3, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _globals[kWatchedViewScreen] = true;
+ _sittingFl = true;
+ _scene->_nextSceneId = 112;
+ break;
+
+ default:
+ break;
+ }
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_CHAIR)) {
+ _vm->_dialogs->show(10101);
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_action.isAction(VERB_LOOK) || _action.isAction(VERB_PEER_THROUGH)) && (_action.isObject(NOUN_FRONT_WINDOW) || _action.isObject(NOUN_OUTSIDE))) {
+ _vm->_dialogs->show(10102);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_HULL) || _action.isAction(VERB_LOOK, NOUN_OUTER_HULL) || _action.isAction(VERB_EXAMINE, NOUN_HULL) || _action.isAction(VERB_EXAMINE, NOUN_OUTER_HULL)) {
+ _vm->_dialogs->show(10103);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_FUZZY_DICE)) {
+ _vm->_dialogs->show(10104);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_MIRROR) || _action.isAction(VERB_LOOK_IN, NOUN_MIRROR)) {
+ _vm->_dialogs->show(10105);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_CURTAINS)) {
+ _vm->_dialogs->show(10106);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_PLASTIC_JESUS)) {
+ _vm->_dialogs->show(10107);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_ESCAPE_HATCH) || (_action.isAction(VERB_OPEN, NOUN_ESCAPE_HATCH) && !_game._objects.isInInventory(OBJ_REBREATHER))) {
+ _vm->_dialogs->show(10109);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_ESCAPE_HATCH)) {
+ _vm->_dialogs->show(10110);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_TARGET_COMPUTER)) {
+ _vm->_dialogs->show(10111);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_LIBRARY_COMPUTER)) {
+ _vm->_dialogs->show(10126);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_DAMAGE_CONTROL_PANEL)) {
+ _vm->_dialogs->show(10112);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_NAVIGATION_CONTROLS)) {
+ _vm->_dialogs->show(10113);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_ENGINEERING_CONTROLS)) {
+ _vm->_dialogs->show(10114);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_WEAPONS_DISPLAY)) {
+ _vm->_dialogs->show(10115);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_SHIELD_STATUS_PANEL)) {
+ _vm->_dialogs->show(10116);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_PLASTIC_JESUS)) {
+ _vm->_dialogs->show(10118);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_FUZZY_DICE)) {
+ _vm->_dialogs->show(10119);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_DAMAGE_CONTROL_PANEL)) {
+ _vm->_dialogs->show(10121);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_CURTAINS)) {
+ _vm->_dialogs->show(10122);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_CLOSE, NOUN_CURTAINS)) {
+ _vm->_dialogs->show(10123);
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_action.isAction(VERB_LOOK) || _action.isAction(VERB_PLAY)) && _action.isObject(NOUN_VIDEO_GAME)) {
+ _vm->_dialogs->show(10124);
+ _action._inProgress = false;
+ return;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene102::Scene102(MADSEngine *vm) : Scene1xx(vm) {
+ _fridgeOpenedFl = false;
+ _fridgeOpenedDescr = false;
+ _fridgeFirstOpenFl = false;
+ _chairDescrFl = false;
+ _drawerDescrFl = false;
+ _activeMsgFl = false;
+ _fridgeCommentCount = 0;
+}
+
+void Scene102::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_fridgeOpenedFl);
+ s.syncAsByte(_fridgeOpenedDescr);
+ s.syncAsByte(_fridgeFirstOpenFl);
+ s.syncAsByte(_chairDescrFl);
+ s.syncAsByte(_drawerDescrFl);
+ s.syncAsByte(_activeMsgFl);
+
+ s.syncAsSint16LE(_fridgeCommentCount);
+}
+
+void Scene102::setup() {
+ _scene->_animationData->preLoad(formAnimName('A', -1), 3);
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene102::addRandomMessage() {
+ _scene->_kernelMessages.reset();
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ int quoteId = _vm->getRandomNumber(65, 69);
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 73, 120, _game.getQuote(quoteId));
+ _activeMsgFl = true;
+}
+
+void Scene102::enter() {
+ sceneEntrySound();
+
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 3));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 4));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('x', 5));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', -1));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('e', -1));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('n', -1));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('g', -1));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMRC_8");
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('x', 0));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 170, 0, 1, 6);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 11, 0, 2, 3);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 4, 0, 1, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 3, 0, 0, 5);
+
+ if (_game._objects.isInRoom(OBJ_BINOCULARS))
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 24, 0, 0, 24);
+ else
+ _scene->_hotspots.activate(NOUN_BINOCULARS, false);
+
+ _scene->_hotspots.activate(NOUN_BURGER, false);
+
+ if (_globals[kMedicineCabinetOpen]) {
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 6, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], -2, -2);
+ }
+
+ if (_scene->_priorSceneId == 101) {
+ _game._player._playerPos = Common::Point(229, 109);
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[6] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[6], false, 6, 1, 2, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ } else if (_scene->_priorSceneId == 103)
+ _game._player._playerPos = Common::Point(47, 152);
+ else if (_scene->_priorSceneId != -2) {
+ _game._player._facing = FACING_NORTHWEST;
+ _game._player._playerPos = Common::Point(32, 129);
+ }
+
+ if (_scene->_priorSceneId != 106) {
+ if (_globals[kWaterInAPuddle]) {
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 5);
+ }
+ } else {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 5);
+ _vm->_sound->command(24);
+ _vm->_sound->command(28);
+ }
+
+ _fridgeOpenedFl = false;
+ _fridgeOpenedDescr = false;
+ _fridgeCommentCount = 0;
+ _fridgeFirstOpenFl = true;
+ _chairDescrFl = false;
+ _activeMsgFl = false;
+
+ _game.loadQuoteSet(0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x45, 0x43, 0);
+
+ if (_scene->_priorSceneId == 101)
+ _vm->_sound->command(20);
+}
+
+void Scene102::step() {
+ if (_game._trigger == 70)
+ _game._player._stepEnabled = true;
+
+ if (_game._trigger == 72) {
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 5);
+ _scene->_sequences.addTimer(48, 90);
+ }
+
+ if (_game._trigger >= 90) {
+ if (_game._trigger >= 94) {
+ _scene->loadAnimation(formAnimName('B', -1), 71);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+
+ _globals[kWaterInAPuddle] = true;
+ _vm->_sound->command(24);
+ } else {
+ _vm->_sound->command(23);
+ _scene->_sequences.addTimer(48, _game._trigger + 1);
+ }
+ }
+
+ if (_game._trigger == 71) {
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ }
+
+ if (_fridgeOpenedFl && !_fridgeOpenedDescr) {
+ _fridgeCommentCount++;
+ if (_fridgeCommentCount > 16384) {
+ _fridgeOpenedDescr = true;
+ _vm->_dialogs->show(10213);
+ }
+ }
+
+ if (!_activeMsgFl && (_game._player._playerPos == Common::Point(177, 114)) && (_game._player._facing == FACING_NORTH)
+ && (_vm->getRandomNumber(1, 5000) == 1)) {
+ _scene->_kernelMessages.reset();
+ _activeMsgFl = false;
+ addRandomMessage();
+ }
+
+ if (_game._trigger == 73)
+ _activeMsgFl = false;
+}
+
+void Scene102::preActions() {
+ if (_action.isObject(NOUN_REFRIGERATOR) || _action.isObject(NOUN_POSTER))
+ _game._player._needToWalk = _game._player._readyToWalk;
+
+ if (_fridgeOpenedFl && !_action.isObject(NOUN_REFRIGERATOR)) {
+ switch (_game._trigger) {
+ case 0:
+ if (_game._player._needToWalk) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[7], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 15);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(20);
+ }
+ break;
+
+ case 1:
+ if (_game._objects.isInRoom(OBJ_BURGER)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _scene->_hotspots.activate(NOUN_BURGER, false);
+ }
+ _fridgeOpenedFl = false;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_game._player._needToWalk)
+ _scene->_kernelMessages.reset();
+}
+
+void Scene102::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(10234);
+ _action._inProgress = false;
+ return;
+ }
+
+ bool justOpenedFl = false;
+ if (_action.isObject(NOUN_REFRIGERATOR) && !_fridgeOpenedFl) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 15);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ if (_game._objects.isInRoom(OBJ_BURGER)) {
+ _globals._sequenceIndexes[10] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[10], false, 7, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 14);
+ }
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(20);
+ _action._inProgress = false;
+ return;
+
+ case 1:
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 15);
+ int delay;
+ if (_action.isAction(VERB_WALKTO) && !_fridgeFirstOpenFl)
+ delay = 0;
+ else
+ delay = 48;
+ _scene->_sequences.addTimer(delay, 2);
+ _action._inProgress = false;
+ return;
+
+ case 2:
+ _fridgeOpenedFl = true;
+ _fridgeOpenedDescr = false;
+ _fridgeCommentCount = 0;
+ _game._player._stepEnabled = true;
+ justOpenedFl = true;
+ if (_game._objects.isInRoom(OBJ_BURGER))
+ _scene->_hotspots.activate(NOUN_BURGER, true);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_REFRIGERATOR) || _action.isAction(VERB_OPEN, NOUN_REFRIGERATOR)) {
+ if (_game._objects.isInRoom(OBJ_BURGER))
+ _vm->_dialogs->show(10230);
+ else
+ _vm->_dialogs->show(10229);
+
+ _fridgeFirstOpenFl = false;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALKTO, NOUN_REFRIGERATOR) && justOpenedFl) {
+ _fridgeFirstOpenFl = false;
+ int quoteId = _vm->getRandomNumber(59, 63);
+ Common::String curQuote = _game.getQuote(quoteId);
+ int width = _vm->_font->getWidth(curQuote, -1);
+ _scene->_kernelMessages.reset();
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_kernelMessages.add(Common::Point(210, 60), 0x1110, 0, 73, 120, curQuote);
+ _scene->_kernelMessages.add(Common::Point(214 + width, 60), 0x1110, 0, 73, 120, _game.getQuote(64));
+ _activeMsgFl = true;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_CLOSE, NOUN_REFRIGERATOR)) {
+ _vm->_dialogs->show(10213);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_REFRIGERATOR)) {
+ _vm->_dialogs->show(8);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR)) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(20);
+ break;
+
+ case 1:
+ _scene->_nextSceneId = 101;
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALKTO, NOUN_ENGINEERING_SECTION)) {
+ _scene->_nextSceneId = 103;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALKTO, NOUN_POSTER) || _action.isAction(VERB_LOOK, NOUN_POSTER) || _action.isAction(VERB_WALKTO, NOUN_BINOCULARS)) {
+ addRandomMessage();
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_WEIGHT_MACHINE)) {
+ _vm->_dialogs->show(10212);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_ENGINEERING_SECTION)) {
+ _vm->_dialogs->show(10205);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_DOOR)) {
+ _vm->_dialogs->show(10204);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_STARE_AT, NOUN_CEILING) || _action.isAction(VERB_LOOK, NOUN_CEILING)) {
+ _vm->_dialogs->show(10203);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_STARE_AT, NOUN_OVERHEAD_LAMP) || _action.isAction(VERB_LOOK, NOUN_OVERHEAD_LAMP)) {
+ _vm->_dialogs->show(10202);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_ROBO_KITCHEN)) {
+ _vm->_dialogs->show(10215);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_BURGER, NOUN_ROBO_KITCHEN) && _game._objects.isInInventory(OBJ_BURGER)) {
+ _vm->_dialogs->show(10216);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_REFRIGERATOR) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))) {
+ _vm->_dialogs->show(10217);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_DEAD_FISH, NOUN_ROBO_KITCHEN) || _action.isAction(VERB_PUT, NOUN_STUFFED_FISH, NOUN_ROBO_KITCHEN)) {
+ _vm->_dialogs->show(10230);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_ROBO_KITCHEN)) {
+ _vm->_dialogs->show(10218);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_CLOSET)) {
+ _vm->_dialogs->show(10219);
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_action.isObject(NOUN_LADDER) || _action.isObject(NOUN_HATCHWAY)) && (_action.isAction(VERB_LOOK) || _action.isAction(VERB_CLIMB_UP) || _action.isAction(VERB_CLIMB_THROUGH))) {
+ if (_game._objects.isInInventory(OBJ_REBREATHER)) {
+ if (!_action.isAction(VERB_CLIMB_UP) && !_action.isAction(VERB_CLIMB_THROUGH)) {
+ _vm->_dialogs->show(10231);
+ _action._inProgress = false;
+ return;
+ }
+ } else if (_action.isAction(VERB_LOOK) || (_game._difficulty != DIFFICULTY_EASY)) {
+ _vm->_dialogs->show(10222);
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if ((_action.isObject(NOUN_LADDER) || _action.isObject(NOUN_HATCHWAY)) && (_action.isAction(VERB_CLIMB_UP) || _action.isAction(VERB_CLIMB_THROUGH)) ) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->loadAnimation(formAnimName('A', -1), 1);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ break;
+
+ case 1:
+ _vm->_sound->command(24);
+ _scene->_sequences.addTimer(48, 2);
+ break;
+
+ case 2:
+ case 3:
+ case 4:
+ _vm->_sound->command(23);
+ _scene->_sequences.addTimer(48, _game._trigger + 1);
+ break;
+
+ case 5:
+ _vm->_sound->command(24);
+ _scene->_sequences.addTimer(48, _game._trigger + 1);
+ break;
+
+ case 6:
+ if (_game._objects.isInInventory(OBJ_REBREATHER) && !_game._visitedScenes.exists(106))
+ _vm->_dialogs->show(10237);
+ _scene->_nextSceneId = 106;
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_POWER_STATUS_PANEL)) {
+ _vm->_dialogs->show(10226);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_WINDOW) || _action.isAction(VERB_LOOK_THROUGH, NOUN_WINDOW)) {
+ _vm->_dialogs->show(10227);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_DOORWAY) || _action.isAction(VERB_WALKTO, NOUN_DOORWAY)) {
+ _vm->_dialogs->show(10228);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_DRAWER) || ((_action.isAction(VERB_CLOSE, NOUN_DRAWER) || _action.isAction(VERB_PUSH, NOUN_DRAWER)) && !_drawerDescrFl)) {
+ _vm->_dialogs->show(10220);
+ _drawerDescrFl = true;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_CLOSE, NOUN_DRAWER) || _action.isAction(VERB_PUSH, NOUN_DRAWER)) {
+ _vm->_dialogs->show(10221);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_DRAWER)) {
+ _vm->_dialogs->show(10236);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_CHAIR) || (_action.isAction(VERB_SIT_IN, NOUN_CHAIR) && !_chairDescrFl)) {
+ _chairDescrFl = true;
+ _vm->_dialogs->show(10210);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_SIT_IN, NOUN_CHAIR)) {
+ _vm->_dialogs->show(10211);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_MEDICINE_CABINET)) {
+ if (_globals[kMedicineCabinetOpen])
+ _vm->_dialogs->show(10207);
+ else
+ _vm->_dialogs->show(10206);
+
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_CLOSE, NOUN_MEDICINE_CABINET) && _globals[kMedicineCabinetOpen]) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[8], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(21);
+ break;
+
+ case 1:
+ _scene->_sequences.addTimer(48, 2);
+ break;
+
+ case 2:
+ _game._player._stepEnabled = true;
+ _globals[kMedicineCabinetOpen] = false;
+ _vm->_dialogs->show(10209);
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_MEDICINE_CABINET) && !_globals[kMedicineCabinetOpen]) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(21);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], -2, -2);
+ _scene->_sequences.addTimer(48, 2);
+ break;
+
+ case 2:
+ _game._player._stepEnabled = true;
+ _globals[kMedicineCabinetOpen] = true;
+ if (_globals[kMedicineCabinetVirgin]) {
+ _vm->_dialogs->show(10208);
+ } else {
+ _vm->_dialogs->show(10207);
+ }
+ _globals[kMedicineCabinetVirgin] = false;
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_BINOCULARS) && _game._objects.isInRoom(OBJ_BINOCULARS)) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[11]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ break;
+
+ case 1:
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _scene->_hotspots.activate(NOUN_BINOCULARS, false);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _vm->_sound->command(22);
+ _vm->_dialogs->showItem(OBJ_BINOCULARS, 10201);
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_BURGER) && _game._objects.isInRoom(OBJ_BURGER)) {
+ if (_game._trigger == 0) {
+ _vm->_dialogs->showItem(OBJ_BURGER, 10235);
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _game._objects.addToInventory(OBJ_BURGER);
+ _scene->_hotspots.activate(NOUN_BURGER, false);
+ _vm->_sound->command(22);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_POSTER)) {
+ _vm->_dialogs->show(10224);
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_action.isAction(VERB_PUSH) || _action.isAction(VERB_PULL)) && _action.isObject(NOUN_WEIGHT_MACHINE)) {
+ _vm->_dialogs->show(10225);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_FLOOR)) {
+ _vm->_dialogs->show(10232);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS) && !_game._objects.isInInventory(OBJ_BINOCULARS)) {
+ _vm->_dialogs->show(10233);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_BURGER) && (_action._mainObjectSource == 4)) {
+ _vm->_dialogs->show(801);
+ _action._inProgress = false;
+ }
+}
+
+void Scene102::postActions() {
+ if (_action.isAction(VERB_PUT, NOUN_ROBO_KITCHEN) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))) {
+ _vm->_dialogs->show(10217);
+ _action._inProgress = false;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene103::Scene103(MADSEngine *vm) : Scene1xx(vm) {
+ _updateClock = 0;
+}
+
+void Scene103::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ byte dummy = 0;
+ s.syncAsByte(dummy); // In order to avoid to break savegame compatibility
+ s.syncAsUint32LE(_updateClock);
+}
+
+void Scene103::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene103::enter() {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 3));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 4));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('x', 5));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', -1));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('h', -1));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('m', -1));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('t', -1));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('r', -1));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites("*RXMBD_2");
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites("*RXMRD_3");
+ _globals._spriteIndexes[15] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 7, 0, 1, 0);
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 0, 2, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 0);
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 0, 25);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 72);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 1, 37);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 2, 73);
+
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 6);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6);
+
+ if (_game._objects.isInRoom(OBJ_TIMER_MODULE))
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 6);
+ else
+ _vm->_game->_scene._hotspots.activate(371, false);
+
+ if (_game._objects.isInRoom(OBJ_REBREATHER))
+ _globals._sequenceIndexes[10] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[10], false, 6);
+ else
+ _vm->_game->_scene._hotspots.activate(289, false);
+
+ if (_globals[kTurkeyExploded]) {
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 6);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], -2, -2);
+ _scene->_hotspots.activate(362, false);
+ }
+
+ if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(237, 74);
+
+ if (_scene->_priorSceneId == 102) {
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[6] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[6], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ }
+
+ sceneEntrySound();
+ _vm->_game->loadQuoteSet(70, 51, 71, 7, 73, 0);
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(70));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+
+ if (_scene->_priorSceneId == 102)
+ _vm->_sound->command(20);
+
+ _vm->_palette->setEntry(252, 63, 63, 10);
+ _vm->_palette->setEntry(253, 45, 45, 10);
+ _updateClock = _scene->_frameStartTime;
+}
+
+void Scene103::step() {
+ switch (_vm->_game->_trigger) {
+ case 70:
+ _vm->_game->_player._stepEnabled = true;
+ break;
+
+ case 72: {
+ Common::Point pt = _vm->_game->_player._playerPos;
+ int dist = _vm->hypotenuse(pt.x - 58, pt.y - 93);
+ _vm->_sound->command(27, (dist * -128 / 378) + 127);
+ }
+ break;
+
+ case 73: {
+ Common::Point pt = _vm->_game->_player._playerPos;
+ int dist = _vm->hypotenuse(pt.x - 266, pt.y - 81);
+ _vm->_sound->command(27, (dist * -127 / 378) + 127);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (_scene->_frameStartTime >= _updateClock) {
+ Common::Point pt = _vm->_game->_player._playerPos;
+ int dist = _vm->hypotenuse(pt.x - 79, pt.y - 137);
+ _vm->_sound->command(29, (dist * -127 / 378) + 127);
+
+ pt = _vm->_game->_player._playerPos;
+ dist = _vm->hypotenuse(pt.x - 69, pt.y - 80);
+ _vm->_sound->command(30, (dist * -127 / 378) + 127);
+
+ pt = _vm->_game->_player._playerPos;
+ dist = _vm->hypotenuse(pt.x - 266, pt.y - 138);
+ _vm->_sound->command(32, (dist * -127 / 378) + 127);
+
+ _updateClock = _scene->_frameStartTime + _vm->_game->_player._ticksAmount;
+ }
+}
+
+void Scene103::actions() {
+ if (_action._savedFields._lookFlag)
+ _vm->_dialogs->show(10322);
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR)) {
+ switch (_vm->_game->_trigger) {
+ case 0:
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(20);
+ break;
+
+ case 1:
+ _vm->_sound->command(1);
+ _scene->_nextSceneId = 102;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_TIMER_MODULE) && _game._objects.isInRoom(OBJ_TIMER_MODULE)) {
+ switch (_vm->_game->_trigger) {
+ case 0:
+ _scene->changeVariant(1);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 3, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[13]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_SPRITE, 7, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _vm->_game->_player._visible = false;
+ _vm->_game->_player._stepEnabled = false;
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ break;
+
+ case 2:
+ _vm->_sound->command(22);
+ _game._objects.addToInventory(OBJ_TIMER_MODULE);
+ _scene->changeVariant(0);
+ _scene->drawElements(kTransitionNone, false);
+ _scene->_hotspots.activate(371, false);
+ _vm->_game->_player._visible = true;
+ _vm->_game->_player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_REBREATHER, 805);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, 289, 0) && _game._objects.isInRoom(OBJ_REBREATHER)) {
+ switch (_vm->_game->_trigger) {
+ case 0:
+ _scene->changeVariant(1);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 3, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _vm->_game->_player._visible = false;
+ _vm->_game->_player._stepEnabled = false;
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ break;
+
+ case 2:
+ _vm->_sound->command(22);
+ _game._objects.addToInventory(OBJ_REBREATHER);
+ _scene->_hotspots.activate(289, false);
+ _vm->_game->_player._visible = true;
+ _vm->_game->_player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_REBREATHER, 804);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, 362))
+ _vm->_dialogs->show(10301);
+ else if (_action.isAction(VERB_TAKE, 362)) {
+ // Take Turkey
+ if (!_vm->_game->_trigger)
+ _vm->_sound->command(31);
+
+ if (_vm->_game->_trigger < 2) {
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 6, _vm->_game->_trigger < 1 ? 1 : 0);
+ if (_vm->_game->_trigger) {
+ // Lock the turkey into a permanent "exploded" frame
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], -2, -2);
+
+ // Rex says "Gads.."
+ Common::String msg = _game.getQuote(51);
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 18, 0, 60, msg);
+ _scene->_sequences.addTimer(120, _vm->_game->_trigger + 1);
+ } else {
+ // Initial turky explosion
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ }
+ }
+
+ // Re-enable player if sequence is ended, and set global flag
+ _game._player._stepEnabled = _game._trigger == 2;
+ _globals[kTurkeyExploded] = -1;
+
+ if (_game._trigger == 2) {
+ // Show exposition dialog at end of sequence
+ _vm->_dialogs->show(10302);
+ _scene->_hotspots.activate(362, false);
+ }
+ } else if (_action.isAction(VERB_LOOK, 250))
+ _vm->_dialogs->show(!_globals[kTurkeyExploded] ? 10323 : 10303);
+ else if (_action.isAction(VERB_TALKTO, 27)) {
+ switch (_vm->_game->_trigger) {
+ case 0: {
+ _game._player._stepEnabled = false;
+ Common::String msg = _game.getQuote(71);
+ _scene->_kernelMessages.add(Common::Point(), 0x1110, 18, 1, 120, msg);
+ break;
+ }
+
+ case 1: {
+ Common::String msg = _game.getQuote(72);
+ _scene->_kernelMessages.add(Common::Point(310, 132), 0xFDFC, 16, 2, 120, msg);
+ break;
+ }
+
+ case 2:
+ _scene->_kernelMessages.reset();
+ _scene->_sequences.addTimer(1, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->show(10306);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, 27))
+ _vm->_dialogs->show(10304);
+ else if (_action.isAction(VERB_LOOK, 36))
+ _vm->_dialogs->show(10307);
+ else if (_action.isAction(VERB_LOOK, 55))
+ _vm->_dialogs->show(10308);
+ else if (_action.isAction(VERB_TAKE, 315))
+ _vm->_dialogs->show(10309);
+ else if (_action.isAction(VERB_TAKE, 85))
+ _vm->_dialogs->show(10310);
+ else if (_action.isAction(VERB_LOOK, 144))
+ _vm->_dialogs->show(10312);
+ else if (_action.isAction(VERB_OPEN, 144))
+ _vm->_dialogs->show(10313);
+ else if (_action.isAction(VERB_CLOSE, 27))
+ _vm->_dialogs->show(10314);
+ else if (_action.isAction(VERB_LOOK, 310))
+ _vm->_dialogs->show(10315);
+ else if (_action.isAction(VERB_LOOK, 178))
+ _vm->_dialogs->show(10316);
+ else if (_action.isAction(VERB_LOOK, 283))
+ _vm->_dialogs->show(10317);
+ else if (_action.isAction(VERB_LOOK, 120))
+ _vm->_dialogs->show(10318);
+ else if (_action.isAction(VERB_LOOK, 289) && _game._objects.isInInventory(OBJ_REBREATHER))
+ _vm->_dialogs->show(10319);
+ else if (_action.isAction(VERB_LOOK, 371) && _game._objects.isInInventory(OBJ_TIMER_MODULE))
+ _vm->_dialogs->show(10320);
+ else if (_action.isAction(VERB_LOOK, 137))
+ _vm->_dialogs->show(10321);
+ else if (_action.isAction(VERB_LOOK, 409))
+ _vm->_dialogs->show(_game._objects.isInInventory(OBJ_TIMER_MODULE) ? 10324 : 10325);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+void Scene103::postActions() {
+ if (_action.isObject(NOUN_AUXILIARY_POWER) && !_action.isAction(VERB_WALKTO)) {
+ _vm->_dialogs->show(10305);
+ _action._inProgress = false;
+ } else if (_action.isAction(VERB_PUT, NOUN_COAL, NOUN_FURNACE)) {
+ Common::String msg = _game.getQuote(73);
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, msg);
+ _action._inProgress = false;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene104::Scene104(MADSEngine *vm) : Scene1xx(vm) {
+ _kargShootingFl = false;
+ _loseFl = false;
+}
+
+void Scene104::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_kargShootingFl);
+ s.syncAsByte(_loseFl);
+}
+
+void Scene104::setup() {
+ // Preloading has been skipped
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene104::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('h', -1));
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 14, 0, 0, 1);
+
+ if (_scene->_priorSceneId == 105)
+ _game._player._playerPos = Common::Point(302, 107);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(160, 134);
+
+ _loseFl = false;
+ _game.loadQuoteSet(0x35, 0x34, 0);
+ _kargShootingFl = false;
+
+ if (_vm->getRandomNumber(1, 3) == 1) {
+ _scene->loadAnimation(Resources::formatName(104, 'B', -1, EXT_AA, ""), 0);
+ _kargShootingFl = true;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene104::step() {
+ if ((_game._player._playerPos == Common::Point(189, 70)) && (_game._trigger || !_loseFl)) {
+ if (_game._player._facing == FACING_SOUTHWEST || _game._player._facing == FACING_SOUTHEAST)
+ _game._player._facing = FACING_SOUTH;
+
+ if (_game._player._facing == FACING_NORTHWEST || _game._player._facing == FACING_NORTHEAST)
+ _game._player._facing = FACING_NORTH;
+
+ bool mirrorFl = false;
+ if (_game._player._facing == FACING_WEST) {
+ _game._player._facing = FACING_EAST;
+ mirrorFl = true;
+ }
+
+ _loseFl = true;
+
+ switch (_game._player._facing) {
+ case FACING_EAST:
+ switch (_game._trigger) {
+ case 0:
+ _scene->_kernelMessages.reset();
+ _scene->freeAnimation();
+ _scene->resetScene();
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _vm->_palette->refreshSceneColors();
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], mirrorFl, 7, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(198, 143));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], mirrorFl, 7, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(198, 143));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -2, -2);
+ _scene->_sequences.addTimer(90, 2);
+ break;
+
+ case 2:
+ _vm->_dialogs->show(10406);
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case FACING_SOUTH:
+ switch (_game._trigger) {
+ case 0:
+ _scene->_kernelMessages.reset();
+ _scene->freeAnimation();
+ _scene->resetScene();
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _vm->_palette->refreshSceneColors();
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(198, 143));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 4);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(198, 143));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 4);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 15, 32);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 3, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(198, 143));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], -2, -2);
+ _scene->_sequences.addTimer(90, 3);
+ break;
+
+ case 3:
+ _vm->_dialogs->show(10406);
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case FACING_NORTH:
+ switch (_game._trigger) {
+ case 0:
+ _scene->_kernelMessages.reset();
+ _scene->freeAnimation();
+ _scene->resetScene();
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('a', 2));
+ _vm->_palette->refreshSceneColors();
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(198, 143));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ if (_game._storyMode >= STORYMODE_NICE)
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 15, 2);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 8, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(198, 143));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -2, -2);
+ _scene->_sequences.addTimer(90, 2);
+ break;
+
+ case 2:
+ _vm->_dialogs->show(10406);
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!_game._trigger)
+ _vm->_sound->command(34);
+ }
+
+ if (_game._player._moving && (_scene->_rails.getNext() > 0)) {
+ _game._player.cancelCommand();
+ _game._player.startWalking(Common::Point(189, 70), FACING_NONE);
+ _scene->_rails.resetNext();
+ }
+
+ if ((_game._player._special > 0) && _game._player._stepEnabled)
+ _game._player._stepEnabled = false;
+
+ if (_kargShootingFl && (_scene->_activeAnimation->getCurrentFrame() >= 19)) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(52));
+ _kargShootingFl = false;
+ }
+}
+
+void Scene104::preActions() {
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_EASTERN_CLIFF_FACE))
+ _game._player._walkOffScreenSceneId = 105;
+
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_OPEN_AREA_TO_SOUTH))
+ _game._player._walkOffScreenSceneId = 106;
+}
+
+void Scene104::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(10405);
+ else if (_action.isAction(VERB_LOOK, NOUN_CURIOUS_WEED_PATCH))
+ _vm->_dialogs->show(10404);
+ else if (_action.isAction(VERB_LOOK, NOUN_SURFACE))
+ _vm->_dialogs->show(10403);
+ else if (_action.isAction(VERB_LOOK, NOUN_CLIFF_FACE))
+ _vm->_dialogs->show(10401);
+ else if (_action.isAction(VERB_LOOK, NOUN_OCEAN_FLOOR))
+ _vm->_dialogs->show(10402);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene105::Scene105(MADSEngine *vm) : Scene1xx(vm) {
+ _explosionFl = false;
+}
+
+void Scene105::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_explosionFl);
+}
+
+void Scene105::setup() {
+ // Preloading has been skipped
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene105::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('m', 1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('f', 4));
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 0);
+
+ if (_globals[kFishIn105]) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(48, 144));
+
+ int idx = _scene->_dynamicHotspots.add(101, 348, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(56, 141), FACING_NORTHWEST);
+ }
+
+ if (_scene->_priorSceneId == 104)
+ _game._player._playerPos = Common::Point(13, 97);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(116, 147);
+
+ _game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0);
+ _explosionFl = false;
+
+ sceneEntrySound();
+}
+
+void Scene105::step() {
+ if ((_game._player._playerPos == Common::Point(170, 87)) && (_game._trigger || !_explosionFl)) {
+ _explosionFl = true;
+ switch (_game._trigger) {
+ case 0:
+ _scene->_kernelMessages.reset();
+ _scene->resetScene();
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('m', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('m', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('m', 3));
+ _vm->_sound->command(33);
+ _scene->clearSequenceList();
+ _vm->_palette->refreshSceneColors();
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+
+ if (_game._storyMode >= STORYMODE_NICE)
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_SPRITE, 8, 3);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], -2, -2);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 9, 1, 0, 0);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], _globals._sequenceIndexes[0]);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 8);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 5, 7);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 9, 0, 0, 0);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 8);
+ _scene->_sequences.addTimer(90, 3);
+ }
+ break;
+
+ case 3:
+ _vm->_dialogs->show(10507);
+ _scene->_reloadSceneFlag = true;
+ _scene->_sequences.addTimer(90, 4);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_game._player._moving && (_scene->_rails.getNext() > 0)) {
+ _game._player.cancelCommand();
+ _game._player.startWalking(Common::Point(170, 87), FACING_NONE);
+ _scene->_rails.resetNext();
+ }
+
+ if ((_game._player._special > 0) && _game._player._stepEnabled)
+ _game._player._stepEnabled = false;
+}
+
+void Scene105::preActions() {
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_WESTERN_CLIFF_FACE))
+ _game._player._walkOffScreenSceneId = 104;
+
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_OPEN_AREA_TO_SOUTH))
+ _game._player._walkOffScreenSceneId = 107;
+
+ if (_action.isObject(NOUN_MINE) && (_action.isAction(VERB_TALKTO) || _action.isAction(VERB_LOOK)))
+ _game._player._needToWalk = false;
+}
+
+void Scene105::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(10512);
+ else if (_action.isAction(VERB_TAKE, NOUN_DEAD_FISH) && _globals[kFishIn105]) {
+ if (_game._objects.isInInventory(OBJ_DEAD_FISH)) {
+ int randVal = _vm->getRandomNumber(74, 76);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(randVal));
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _game._objects.addToInventory(OBJ_DEAD_FISH);
+ _globals[kFishIn105] = false;
+ _vm->_dialogs->showItem(OBJ_DEAD_FISH, 802, 0);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_WESTERN_CLIFF_FACE))
+ _vm->_dialogs->show(10501);
+ else if (_action.isAction(VERB_LOOK, NOUN_CLIFF_FACE))
+ _vm->_dialogs->show(10502);
+ else if (_action.isAction(VERB_LOOK, NOUN_OCEAN_FLOOR))
+ _vm->_dialogs->show(10503);
+ else if (_action.isAction(VERB_LOOK, NOUN_MEDICAL_WASTE))
+ _vm->_dialogs->show(10504);
+ else if (_action.isAction(VERB_TAKE, NOUN_MEDICAL_WASTE))
+ _vm->_dialogs->show(10505);
+ else if (_action.isAction(VERB_LOOK, NOUN_MINE))
+ _vm->_dialogs->show(10506);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEAD_FISH))
+ _vm->_dialogs->show(10508);
+ else if (_action.isAction(VERB_LOOK, NOUN_SURFACE))
+ _vm->_dialogs->show(10509);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_AREA_TO_SOUTH))
+ _vm->_dialogs->show(10510);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(10511);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene106::Scene106(MADSEngine *vm) : Scene1xx(vm) {
+ _backToShipFl = false;
+ _shadowFl = false;
+ _firstEmergingFl = false;
+ _positionY = 0;
+}
+
+void Scene106::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_backToShipFl);
+ s.syncAsByte(_shadowFl);
+ s.syncAsByte(_firstEmergingFl);
+ s.syncAsSint32LE(_positionY);
+}
+
+void Scene106::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ if ((_scene->_priorSceneId == 102) && !_game._objects.isInInventory(OBJ_REBREATHER) && !_scene->_roomChanged)
+ _game._player._spritesPrefix = "";
+
+ _vm->_dialogs->_defaultPosition.y = 100;
+}
+
+void Scene106::enter() {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('H', -1));
+
+ if (_game._objects.isInInventory(OBJ_REBREATHER) || (_scene->_priorSceneId != 102) || _scene->_roomChanged) {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('A', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('A', 1));
+ }
+
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('G', -1));
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 21, 0, 0, 0);
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('I', -1));
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 32, 47);
+
+ if (_scene->_priorSceneId == 102) {
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 6, 1, 4, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _game._player._facing = FACING_EAST;
+ _game._player._playerPos = Common::Point(106, 69);
+ } else if (_scene->_priorSceneId != -2) {
+ if (_scene->_priorSceneId == 107) {
+ _game._player._playerPos = Common::Point(319, 84);
+ _game._player._facing = _game._player._prepareWalkFacing = FACING_WEST;
+ } else {
+ _game._player._playerPos = Common::Point(319, 44);
+ _game._player._facing = _game._player._prepareWalkFacing = FACING_SOUTHWEST;
+ _scene->_sprites[_game._player._spritesStart + 3]->_charInfo->_velocity = 24;
+ }
+
+ _game._player._prepareWalkPos = Common::Point(246, 69);
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ }
+
+ if (_scene->_priorSceneId != 102) {
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[0], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 14);
+ }
+
+ _backToShipFl = false;
+ _shadowFl = false;
+ _firstEmergingFl = false;
+
+ _game.loadQuoteSet(0x31, 0x32, 0x34, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0);
+ sceneEntrySound();
+}
+
+void Scene106::step() {
+ if (_game._trigger == 70) {
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[0], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 14);
+
+ if (!_game._objects.isInInventory(OBJ_REBREATHER) && !_scene->_roomChanged) {
+ _scene->loadAnimation(Resources::formatName(106, 'A', -1, EXT_AA, ""), 75);
+ } else {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 28, 71);
+ }
+ }
+
+ if (_game._trigger == 71) {
+ _game._player._prepareWalkPos = Common::Point(246, 69);
+ _game._player._prepareWalkFacing = FACING_EAST;
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ _game._player._visible = true;
+
+ if (_game._visitedScenes._sceneRevisited) {
+ _game._player._stepEnabled = true;
+ } else {
+ _game._player._prepareWalkFacing = FACING_SOUTHWEST;
+ _firstEmergingFl = true;
+ _scene->loadAnimation(Resources::formatName(106, 'B', -1, EXT_AA, ""), 80);
+ }
+ }
+
+ if (_firstEmergingFl && (_scene->_activeAnimation->getCurrentFrame() >= 19)) {
+ _firstEmergingFl = false;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(52));
+ }
+
+ if ((_game._trigger >= 80) && (_game._trigger <= 87)) {
+ int tmpVal = _game._trigger - 80;
+ int msgId = -1;
+ switch (tmpVal) {
+ case 0:
+ _positionY = 26;
+ msgId = 49;
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ msgId = 76 + tmpVal;
+ break;
+
+ case 6:
+ msgId = 50;
+ break;
+
+ default:
+ msgId = -1;
+ _game._player._stepEnabled = true;
+ break;
+ }
+
+ if (msgId >= 0) {
+ int nextAbortVal = _game._trigger + 1;
+ _scene->_kernelMessages.add(Common::Point(15, _positionY), 0x1110, 0, 0, 360, _game.getQuote(msgId));
+ _scene->_sequences.addTimer(150, nextAbortVal);
+ _positionY += 14;
+ }
+ }
+
+ if (_backToShipFl) {
+ if (!_shadowFl) {
+ if (_game._player._playerPos.x < 204) {
+ _shadowFl = true;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 4, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 44, 73);
+ }
+ } else if (_game._trigger == 73)
+ _game._player._visible = false;
+ else if (_game._trigger == 72)
+ _scene->_sequences.addTimer(24, 74);
+ else if (_game._trigger == 74)
+ _scene->_nextSceneId = 102;
+ }
+
+ if (_game._trigger == 75) {
+ _game._visitedScenes.pop_back();
+ _scene->_nextSceneId = 102;
+ }
+}
+
+void Scene106::preActions() {
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_SEA_CLIFF) || _action.isAction(VERB_SWIM_TOWARDS, NOUN_SEAWEED_BANK)) {
+ _game._player._stepEnabled = false;
+ _scene->_sprites[_game._player._spritesStart + 1]->_charInfo->_velocity = 24;
+ _game._player._walkOffScreenSceneId = 104;
+ }
+
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_OPEN_AREA_TO_EAST))
+ _game._player._walkOffScreenSceneId = 107;
+}
+
+void Scene106::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(10614);
+ else if (_action.isAction(VERB_SWIM_TO, NOUN_MAIN_AIRLOCK)) {
+ _game._player._stepEnabled = false;
+ _game._player._prepareWalkPos = Common::Point(95, 72);
+ _game._player._prepareWalkFacing = FACING_WEST;
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ _game._player._frameNumber = 9;
+ _backToShipFl = true;
+ } else if (_action.isAction(VERB_LOOK, NOUN_ANEMONE) || _action.isAction(VERB_LOOK_AT, NOUN_ANEMONE))
+ _vm->_dialogs->show(10601);
+ else if (_action.isAction(VERB_TAKE, NOUN_ANEMONE))
+ _vm->_dialogs->show(10602);
+ else if (_action.isAction(VERB_LOOK, NOUN_SEAWEED) || _action.isAction(VERB_LOOK, NOUN_SEAWEED_BANK))
+ _vm->_dialogs->show(10603);
+ else if (_action.isAction(VERB_TAKE, NOUN_SEAWEED) || _action.isAction(VERB_TAKE, NOUN_SEAWEED_BANK))
+ _vm->_dialogs->show(10604);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_AREA_TO_EAST))
+ _vm->_dialogs->show(10605);
+ else if (_action.isAction(VERB_LOOK, NOUN_PILE_OF_ROCKS) || _action.isAction(VERB_LOOK_AT, NOUN_PILE_OF_ROCKS))
+ _vm->_dialogs->show(10606);
+ else if (_action.isObject(NOUN_PILE_OF_ROCKS) && (_action.isAction(VERB_PUSH) || _action.isAction(VERB_PULL) || _action.isAction(VERB_TAKE)))
+ _vm->_dialogs->show(10607);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHIP) || _action.isAction(VERB_LOOK_AT, NOUN_SHIP))
+ _vm->_dialogs->show(10608);
+ else if (_action.isAction(VERB_LOOK, NOUN_MAIN_AIRLOCK))
+ _vm->_dialogs->show(10609);
+ else if (_action.isAction(VERB_OPEN, NOUN_MAIN_AIRLOCK))
+ _vm->_dialogs->show(10610);
+ else if (_action.isAction(VERB_CLOSE, NOUN_MAIN_AIRLOCK))
+ _vm->_dialogs->show(10611);
+ else if (_action.isAction(VERB_LOOK, NOUN_SEA_CLIFF))
+ _vm->_dialogs->show(10612);
+ else if (_action.isAction(VERB_LOOK, NOUN_OCEAN_FLOOR))
+ _vm->_dialogs->show(10613);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene107::Scene107(MADSEngine *vm) : Scene1xx(vm) {
+ _shootingFl = false;
+}
+
+void Scene107::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_shootingFl);
+}
+
+void Scene107::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_MANTA_RAY);
+}
+
+void Scene107::enter() {
+ for (int i = 0; i < 3; i++)
+ _globals._spriteIndexes[i + 1] = _scene->_sprites.addSprites(formAnimName('G', i));
+
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(Resources::formatName(105, 'f', 4, EXT_SS, ""));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 14, 0, 0, 7);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 13);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 19, 0, 0, 9);
+
+ for (int i = 1; i < 4; i++)
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[i], 0);
+
+ if (_globals[kFishIn107]) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(68, 151));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ int idx = _scene->_dynamicHotspots.add(101, 348, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(78, 135), FACING_SOUTHWEST);
+ }
+
+ if (_scene->_priorSceneId == 105)
+ _game._player._playerPos = Common::Point(132, 47);
+ else if (_scene->_priorSceneId == 106)
+ _game._player._playerPos = Common::Point(20, 91);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(223, 151);
+
+ if (((_scene->_priorSceneId == 105) || (_scene->_priorSceneId == 106)) && (_vm->getRandomNumber(1, 3) == 1)) {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(Resources::formatName(105, 'R', 1, EXT_SS, ""));
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], true, 4, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[0], Common::Point(270, 150));
+ _scene->_sequences.setMotion(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_SPRITE, -200, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 2);
+ _scene->_dynamicHotspots.add(218, 348, _globals._sequenceIndexes[0], Common::Rect(0, 0, 0, 0));
+ }
+
+ _game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0);
+ _shootingFl = false;
+
+ if (_vm->getRandomNumber(1, 3) == 1) {
+ _scene->loadAnimation(Resources::formatName(107, 'B', -1, EXT_AA, ""), 0);
+ _shootingFl = true;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene107::step() {
+ if (_shootingFl && (_scene->_activeAnimation->getCurrentFrame() >= 19)) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(52));
+ _shootingFl = false;
+ }
+}
+
+void Scene107::preActions() {
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_OPEN_AREA_TO_WEST))
+ _game._player._walkOffScreenSceneId = 106;
+
+ if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_OPEN_AREA_TO_SOUTH))
+ _game._player._walkOffScreenSceneId = 108;
+}
+
+void Scene107::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(10708);
+ else if (_action.isAction(VERB_TAKE, NOUN_DEAD_FISH) && _globals[kFishIn107]) {
+ if (_game._objects.isInInventory(OBJ_DEAD_FISH)) {
+ int randVal = _vm->getRandomNumber(74, 76);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(randVal));
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _game._objects.addToInventory(OBJ_DEAD_FISH);
+ _globals[kFishIn107] = false;
+ _vm->_dialogs->showItem(OBJ_DEAD_FISH, 802);
+ }
+ } else if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_NORTHERN_SEA_CLIFF))
+ _scene->_nextSceneId = 105;
+ else if (_action.isAction(VERB_LOOK, NOUN_NORTHERN_SEA_CLIFF))
+ _vm->_dialogs->show(10701);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEAD_FISH) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(10702);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUSH_LIKE_FORMATION))
+ _vm->_dialogs->show(10703);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCK))
+ _vm->_dialogs->show(10704);
+ else if (_action.isAction(VERB_LOOK, NOUN_SEAWEED))
+ _vm->_dialogs->show(10705);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_AREA_TO_SOUTH))
+ _vm->_dialogs->show(10706);
+ else if (_action.isAction(VERB_LOOK, NOUN_CLIFF_FACE))
+ _vm->_dialogs->show(10707);
+ else if (_action.isAction(VERB_LOOK, NOUN_MANTA_RAY))
+ _vm->_dialogs->show(10709);
+ else if (_action.isAction(VERB_TAKE, NOUN_MANTA_RAY))
+ _vm->_dialogs->show(10710);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene108::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene108::enter() {
+ if (_globals[kHoovicSated] == 2)
+ _globals[kHoovicSated] = 0;
+
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('X', 0));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('X', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('X', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('X', 3));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(Resources::formatName(105, 'f', 4, EXT_SS, ""));
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 13, 0, 0, 7);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 16, 0, 0, 9);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 3);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 14, 0, 0, 13);
+
+ for (int i = 0; i <= 3; i++)
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[i], 0);
+
+ if (_globals[kFishIn108]) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(41, 109));
+ int idx = _scene->_dynamicHotspots.add(101, 348, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(41, 109), FACING_NORTHWEST);
+ }
+
+ if (_scene->_priorSceneId == 107)
+ _game._player._playerPos = Common::Point(138, 58);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(305, 98);
+
+ _game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0);
+ sceneEntrySound();
+}
+
+void Scene108::preActions() {
+ if (_action.isAction(VERB_SWIM_UNDER, NOUN_OVERHANG_TO_EAST))
+ _game._player._walkOffScreenSceneId = 109;
+}
+
+void Scene108::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(10812);
+ else if (_action.isAction(VERB_TAKE, NOUN_DEAD_FISH) && _globals[kFishIn108]) {
+ if (_game._objects.isInInventory(OBJ_DEAD_FISH)) {
+ int randVal = _vm->getRandomNumber(74, 76);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(randVal));
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _game._objects.addToInventory(OBJ_DEAD_FISH);
+ _globals[kFishIn108] = false;
+ _vm->_dialogs->showItem(OBJ_DEAD_FISH, 10808);
+ }
+ } else if (_action.isAction(VERB_SWIM_TOWARDS, NOUN_OPEN_AREA_TO_NORTH))
+ _scene->_nextSceneId = 107;
+ else if (_action.isAction(VERB_LOOK, NOUN_CLIFF_FACE))
+ _vm->_dialogs->show(10801);
+ else if (_action.isAction(VERB_LOOK, NOUN_OCEAN_FLOOR))
+ _vm->_dialogs->show(10802);
+ else if (_action.isAction(VERB_LOOK, NOUN_ODD_ROCK_FORMATION))
+ _vm->_dialogs->show(10803);
+ else if (_action.isAction(VERB_TAKE, NOUN_ODD_ROCK_FORMATION))
+ _vm->_dialogs->show(10804);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(10805);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCKS))
+ _vm->_dialogs->show(10806);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEAD_FISH))
+ _vm->_dialogs->show(10807);
+ else if (_action.isAction(VERB_LOOK, NOUN_OVERHANG_TO_EAST))
+ _vm->_dialogs->show(10809);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_AREA_TO_NORTH))
+ _vm->_dialogs->show(10810);
+ else if (_action.isAction(VERB_LOOK, NOUN_SURFACE))
+ _vm->_dialogs->show(10811);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene109::Scene109(MADSEngine *vm) : Scene1xx(vm) {
+ _rexThrowingObject = false;
+ _hoovicDifficultFl = false;
+ _beforeEatingRex = false;
+ _eatingRex = false;
+ _hungryFl = false;
+ _eatingFirstFish = false;
+
+ _throwingObjectId = -1;
+ _hoovicTrigger = 0;
+}
+
+void Scene109::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_rexThrowingObject);
+ s.syncAsByte(_hoovicDifficultFl);
+ s.syncAsByte(_beforeEatingRex);
+ s.syncAsByte(_eatingRex);
+ s.syncAsByte(_hungryFl);
+ s.syncAsByte(_eatingFirstFish);
+ s.syncAsSint32LE(_throwingObjectId);
+ s.syncAsSint32LE(_hoovicTrigger);
+}
+
+void Scene109::setup() {
+ _scene->addActiveVocab(NOUN_DEAD_PURPLE_MONSTER);
+ _scene->addActiveVocab(NOUN_MONSTER_SLUDGE);
+
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene109::enter() {
+ _globals[kFishIn105] = true;
+
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites("*RXSWRC_6");
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('O', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('O', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('O', 0));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('H', 4));
+
+ _rexThrowingObject = false;
+ _throwingObjectId = 0;
+ _beforeEatingRex = false;
+ _eatingRex = false;
+ _hungryFl = false;
+
+ if (_scene->_priorSceneId == 110) {
+ _game._player._playerPos = Common::Point(248, 38);
+ _globals[kHoovicSated] = 2;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(20, 68);
+ _game._player._facing = FACING_EAST;
+ }
+
+ if (!_globals[kHoovicAlive]) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 4);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], -2, -2);
+
+ int idx = _scene->_dynamicHotspots.add(102, 348, -1, Common::Rect(256, 57, 267, 87));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(241, 91), FACING_NORTHEAST);
+ idx = _scene->_dynamicHotspots.add(102, 348, -1, Common::Rect(242, 79, 265, 90));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(241, 91), FACING_NORTHEAST);
+ idx = _scene->_dynamicHotspots.add(229, 348, -1, Common::Rect(231, 88, 253, 94));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(241, 91), FACING_NORTHEAST);
+ }
+
+ if (!_globals[kHoovicAlive] || _globals[kHoovicSated])
+ _scene->changeVariant(1);
+
+ if (_game._objects.isInRoom(OBJ_BURGER)) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], -2, -2);
+ int idx = _scene->_dynamicHotspots.add(53, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-3, 0), FACING_NORTHEAST);
+ } else if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_BURGER);
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_DEAD_FISH);
+ _game._objects.addToInventory(OBJ_STUFFED_FISH);
+ }
+
+ _vm->_palette->setEntry(252, 50, 50, 63);
+ _vm->_palette->setEntry(253, 30, 30, 50);
+
+ _game.loadQuoteSet(0x53, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0);
+ _eatingFirstFish = (!_game._visitedScenes._sceneRevisited) && (_scene->_priorSceneId < 110);
+
+ if (_eatingFirstFish) {
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(Resources::formatName(105, 'F', 1, EXT_SS, ""));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('H', 1));
+
+ _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], true, 4, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 5);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(126, 39));
+ _scene->_sequences.setMotion(_globals._sequenceIndexes[10], 0, 200, 0);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[10], 80);
+ _game._player._stepEnabled = false;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene109::step() {
+ if (_beforeEatingRex) {
+ if (!_eatingRex) {
+ if (_game._player._playerPos.x > 205) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 70);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+
+ _eatingRex = true;
+ _vm->_sound->command(34);
+ }
+ } else {
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = false;
+ break;
+
+ case 71:
+ _scene->_reloadSceneFlag = true;
+ break;
+ }
+ }
+ }
+
+ if (_hungryFl && (_game._player._playerPos == Common::Point(160, 32)) && (_game._player._facing == FACING_EAST)) {
+ _game._player.walk(Common::Point(226, 24), FACING_EAST);
+ _game._player._stepEnabled = false;
+ _hungryFl = false;
+ _beforeEatingRex = true;
+ _scene->_sprites.remove(_globals._spriteIndexes[6]);
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('H', 0));
+ _vm->_palette->refreshSceneColors();
+ }
+
+ if (_game._player._moving && (_scene->_rails.getNext() > 0) && _globals[kHoovicAlive] && !_globals[kHoovicSated] && !_hungryFl && !_beforeEatingRex) {
+ _game._player.cancelCommand();
+ _game._player.startWalking(Common::Point(160, 32), FACING_EAST);
+ _scene->_rails.resetNext();
+ _hungryFl = true;
+ }
+
+ if (_eatingFirstFish && (_scene->_sequences[_globals._sequenceIndexes[10]]._position.x >= 178)) {
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 4, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_SPRITE, 29, 72);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 29, 73);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[10], _globals._sequenceIndexes[9]);
+ _eatingFirstFish = false;
+ _game._player._stepEnabled = true;
+ _vm->_sound->command(34);
+ }
+
+ if (_game._trigger == 72)
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+
+ if (_game._trigger == 73) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _scene->_sprites.remove(_globals._spriteIndexes[9]);
+ _scene->_sprites.remove(_globals._spriteIndexes[10]);
+
+ _scene->_spriteSlots.clear();
+ _scene->_spriteSlots.fullRefresh();
+
+ int randVal = _vm->getRandomNumber(85, 88);
+ int idx = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(randVal));
+ _scene->_kernelMessages.setQuoted(idx, 4, true);
+ _scene->_kernelMessages._entries[idx]._frameTimer = _scene->_frameStartTime + 4;
+ }
+}
+
+void Scene109::preActions() {
+ if (_action.isAction(VERB_SWIM_UNDER, NOUN_OVERHANG_TO_WEST))
+ _game._player._walkOffScreenSceneId = 108;
+
+ if ((_action.isAction(VERB_THROW) || _action.isAction(VERB_GIVE) || _action.isAction(VERB_PUT))
+ && (_action.isObject(NOUN_SMALL_HOLE) || _action.isObject(NOUN_TUNNEL))
+ && (_action.isObject(NOUN_DEAD_FISH) || _action.isObject(NOUN_STUFFED_FISH) || _action.isObject(NOUN_BURGER))) {
+ int idx = _game._objects.getIdFromDesc(_action._activeAction._objectNameId);
+ if ((idx >= 0) && _game._objects.isInInventory(idx)) {
+ _game._player._prepareWalkPos = Common::Point(106, 38);
+ _game._player._prepareWalkFacing = FACING_EAST;
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ }
+ }
+
+ if ((_action.isAction(VERB_SWIM_INTO, NOUN_TUNNEL) || _action.isAction(VERB_SWIM_TO, NOUN_SMALL_HOLE))
+ && (!_globals[kHoovicAlive] || _globals[kHoovicSated]) && (_action.isObject(NOUN_TUNNEL)))
+ _game._player._walkOffScreenSceneId = 110;
+
+ _hungryFl = false;
+}
+
+void Scene109::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(10912);
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_action.isAction(VERB_THROW) || _action.isAction(VERB_GIVE)) && (_action.isTarget(NOUN_SMALL_HOLE) || _action.isTarget(NOUN_TUNNEL))) {
+ if (_action.isObject(NOUN_DEAD_FISH) || _action.isObject(NOUN_STUFFED_FISH) || _action.isObject(NOUN_BURGER)) {
+ _throwingObjectId = _game._objects.getIdFromDesc(_action._activeAction._objectNameId);
+ if (_throwingObjectId >= 0) {
+ if ((_game._objects.isInInventory(_throwingObjectId) && _globals[kHoovicAlive]) || _rexThrowingObject) {
+ switch (_game._trigger) {
+ case 0:
+ _rexThrowingObject = true;
+ _hoovicDifficultFl = false;
+ _game._objects.setRoom(_throwingObjectId, NOWHERE);
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 4, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[0]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+
+ switch (_throwingObjectId) {
+ case OBJ_DEAD_FISH:
+ case OBJ_STUFFED_FISH:
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('H', 1));
+ break;
+
+ case OBJ_BURGER:
+ _hoovicDifficultFl = (_game._difficulty == DIFFICULTY_EASY);
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('H', (_hoovicDifficultFl ? 3 : 1)));
+ break;
+ }
+
+ _vm->_palette->refreshSceneColors();
+ break;
+
+ case 1:
+ _game._player._visible = true;
+ _hoovicTrigger = 4;
+ switch (_throwingObjectId) {
+ case OBJ_BURGER:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, (_hoovicDifficultFl ? 4 : 6), 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 2, 2);
+ if (_hoovicDifficultFl) {
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 30);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ } else {
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 8);
+ _hoovicTrigger = 3;
+ }
+ break;
+ case OBJ_DEAD_FISH:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 2);
+ break;
+ case OBJ_STUFFED_FISH:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 2);
+ _hoovicTrigger = 3;
+ break;
+ }
+ break;
+
+ case 2:
+ if (_hoovicDifficultFl)
+ _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 4, 2, 0, 0);
+ else
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 4, 1, 0, 0);
+
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, _hoovicTrigger);
+ _vm->_sound->command(34);
+ break;
+
+ case 3:
+ _scene->loadAnimation(Resources::formatName(109, 'H', 2, EXT_AA, ""), 4);
+ _vm->_sound->command(35);
+ _globals[kHoovicAlive] = false;
+ break;
+
+ case 4:
+ if (!_globals[kHoovicAlive]) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 4);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], -2, -2);
+ int idx = _scene->_dynamicHotspots.add(102, 348, -1, Common::Rect(256, 57, 256 + 12, 57 + 31));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(241, 91), FACING_NORTHEAST);
+ idx = _scene->_dynamicHotspots.add(102, 348, -1, Common::Rect(242, 79, 242 + 24, 79 + 12));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(241, 91), FACING_NORTHEAST);
+ idx = _scene->_dynamicHotspots.add(229, 348, -1, Common::Rect(231, 88, 231 + 23, 88 + 7));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(241, 91), FACING_NORTHEAST);
+ _scene->changeVariant(1);
+ } else {
+ if (_throwingObjectId == OBJ_DEAD_FISH) {
+ ++_globals[kHoovicFishEaten];
+ int threshold;
+ switch (_game._difficulty) {
+ case DIFFICULTY_HARD:
+ threshold = 1;
+ break;
+ case DIFFICULTY_MEDIUM:
+ threshold = 3;
+ break;
+ default:
+ threshold = 50;
+ break;
+ }
+
+ if (_globals[kHoovicFishEaten] >= threshold) {
+ int randVal = _vm->getRandomNumber(83, 84);
+ _scene->_kernelMessages.add(Common::Point(230, 24), 0xFDFC, 0, 0, 120, _game.getQuote(randVal));
+ _globals[kHoovicFishEaten] = 0;
+ _globals[kHoovicSated] = 1;
+ _scene->changeVariant(1);
+ }
+ }
+ }
+ _scene->freeAnimation();
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _scene->_sprites.remove(_globals._spriteIndexes[8]);
+ _scene->_spriteSlots.clear();
+ _scene->_spriteSlots.fullRefresh();
+ _scene->_sequences.scan();
+ if (_game._player._visible) {
+ _game._player._forceRefresh = true;
+ _game._player.update();
+ }
+
+ _game._player._stepEnabled = true;
+ _rexThrowingObject = false;
+ break;
+
+ case 5: {
+ _game._objects.setRoom(OBJ_BURGER, _scene->_currentSceneId);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 30, 30);
+ int idx = _scene->_dynamicHotspots.add(53, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-3, 0), FACING_NORTHEAST);
+ _scene->_sequences.addTimer(65, 6);
+ }
+ break;
+
+ case 6: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 31, 46);
+ int idx = _scene->_dynamicHotspots.add(53, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-3, 0), FACING_NORTHEAST);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 7);
+ }
+ break;
+
+ case 7: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ int idx = _scene->_dynamicHotspots.add(53, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-3, 0), FACING_NORTHEAST);
+ _vm->_dialogs->show(10915);
+ }
+ break;
+
+ case 8:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 5, 16);
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ } else if (_game._objects.isInInventory(_throwingObjectId)) {
+ // Nothing.
+ }
+ }
+ }
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_BURGER) && _game._objects.isInRoom(OBJ_BURGER)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _game._objects.addToInventory(OBJ_BURGER);
+ } else if (_action.isAction(VERB_LOOK, NOUN_OCEAN_FLOOR))
+ _vm->_dialogs->show(10901);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORAL))
+ _vm->_dialogs->show(10902);
+ else if ((_action.isAction(VERB_TAKE) || _action.isAction(VERB_PULL)) && _action.isObject(NOUN_CORAL))
+ _vm->_dialogs->show(10903);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(10904);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCKS))
+ _vm->_dialogs->show(10905);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAVE_WALL))
+ _vm->_dialogs->show(10906);
+ else if (_action.isAction(VERB_LOOK, NOUN_TUNNEL)) {
+ if (_globals[kHoovicAlive])
+ _vm->_dialogs->show(10907);
+ else
+ _vm->_dialogs->show(10913);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SMALL_HOLE))
+ _vm->_dialogs->show(10908);
+ else if (_action.isAction(VERB_LOOK, NOUN_OVERHANG_TO_WEST))
+ _vm->_dialogs->show(10911);
+ else if (_action.isAction(VERB_PUT, NOUN_SMALL_HOLE))
+ _vm->_dialogs->show(10910);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEAD_PURPLE_MONSTER))
+ _vm->_dialogs->show(10914);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene110::Scene110(MADSEngine *vm) : Scene1xx(vm) {
+ _crabsFl = false;
+}
+
+void Scene110::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_crabsFl);
+}
+
+void Scene110::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_CRAB);
+}
+
+void Scene110::enter() {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('X', 0));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('X', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('X', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('X', 3));
+
+ _crabsFl = false;
+
+ if (_scene->_priorSceneId == 109) {
+ _game._player._playerPos = Common::Point(59, 71);
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.startCycle(_globals._spriteIndexes[0], false, 1);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+
+ _crabsFl = true;
+
+ int idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[0], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(194, 23);
+ _game._player._facing = FACING_SOUTH;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(Resources::formatName(110, 'T', 1,EXT_AA, ""), 70);
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x59, 0);
+
+ if (!_game._visitedScenes._sceneRevisited && (_scene->_priorSceneId == 109))
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(109));
+}
+
+void Scene110::step() {
+ if (_game._trigger == 70) {
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+}
+
+void Scene110::preActions() {
+ if (_action.isAction(VERB_SWIM_THROUGH, NOUN_CAVE_ENTRANCE))
+ _game._player._walkOffScreenSceneId = 109;
+
+ if (_crabsFl) {
+ _crabsFl = false;
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[0]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 16, 1, 0, 0);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 16, 1, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 16, 1, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 16, 1, 0, 0);
+
+ int idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[0], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE);
+ }
+}
+
+void Scene110::actions() {
+ if (_action.isAction(VERB_SWIM_THROUGH, NOUN_TUNNEL)) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->loadAnimation(Resources::formatName(110, 'T', 0, EXT_AA, ""), 1);
+ _scene->_activeAnimation->setNextFrameTimer(_game._player._ticksAmount + _game._player._priorTimer);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ break;
+ case 1:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _scene->_nextSceneId = 111;
+ break;
+ }
+ } else if ((_action._lookFlag) || _action.isAction(VERB_LOOK, NOUN_CAVE))
+ _vm->_dialogs->show(11001);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAVE_CEILING) || _action.isAction(VERB_LOOK_AT, NOUN_CAVE_CEILING))
+ _vm->_dialogs->show(11002);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(11003);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCKS))
+ _vm->_dialogs->show(11004);
+ else if (_action.isAction(VERB_LOOK, NOUN_TUNNEL))
+ _vm->_dialogs->show(11005);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAVE_ENTRANCE))
+ _vm->_dialogs->show(11006);
+ else if (_action.isAction(VERB_LOOK, NOUN_FUNGOIDS))
+ _vm->_dialogs->show(11007);
+ else if (_action.isAction(VERB_TAKE, NOUN_FUNGOIDS))
+ _vm->_dialogs->show(11008);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene111::Scene111(MADSEngine *vm) : Scene1xx(vm) {
+ _stampedFl = false;
+ _launch1Fl = false;
+ _launched2Fl = false;
+ _rexDivingFl = false;
+}
+
+void Scene111::synchronize(Common::Serializer &s) {
+ Scene1xx::synchronize(s);
+
+ s.syncAsByte(_stampedFl);
+ s.syncAsByte(_launch1Fl);
+ s.syncAsByte(_launched2Fl);
+ s.syncAsByte(_rexDivingFl);
+}
+
+void Scene111::setup() {
+ _scene->addActiveVocab(NOUN_BATS);
+
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene111::enter() {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('X', 0));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('X', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('X', 2));
+
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('B', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('B', 1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('B', 2));
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 8, 0, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_SPRITE, 9, 73);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_SPRITE, 13, 73);
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 0, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 71, 71);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 0, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+
+ int idx = _scene->_dynamicHotspots.add(NOUN_BATS, VERB_LOOK_AT, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(NOUN_BATS, VERB_LOOK_AT, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+ idx = _scene->_dynamicHotspots.add(NOUN_BATS, VERB_LOOK_AT, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+
+ _launch1Fl = false;
+ _launched2Fl = false;
+ _stampedFl = false;
+
+ if ((_scene->_priorSceneId < 201) && (_scene->_priorSceneId != -2)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->loadAnimation(Resources::formatName(111, 'A', 0, EXT_AA, ""), 70);
+ _game._player._playerPos = Common::Point(234, 116);
+ _game._player._facing = FACING_EAST;
+
+ _launch1Fl = true;
+ _launched2Fl = true;
+
+ _vm->_sound->command(36);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(300, 130);
+ _game._player._facing = FACING_WEST;
+ }
+
+ _rexDivingFl = false;
+
+ sceneEntrySound();
+}
+
+void Scene111::step() {
+ if (_game._trigger == 70) {
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _launch1Fl = false;
+ _launched2Fl = false;
+ }
+
+ if ((_game._trigger == 71) && !_stampedFl) {
+ _stampedFl = true;
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 18, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ }
+
+ if (_game._trigger == 72) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 20);
+ }
+
+ if (!_launch1Fl && (_vm->getRandomNumber(1, 5000) == 1)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 5, 1, 0, 0);
+ _launch1Fl = true;
+ int idx = _scene->_dynamicHotspots.add(NOUN_BATS, VERB_LOOK_AT, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+ }
+
+ if (!_launched2Fl && (_vm->getRandomNumber(1, 30000) == 1)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 5, 1, 0, 0);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BATS, VERB_LOOK_AT, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+ _launched2Fl = true;
+ }
+
+ if (_game._trigger == 73)
+ _vm->_sound->command(37);
+
+ if (_rexDivingFl && (_scene->_activeAnimation->getCurrentFrame() >= 9)) {
+ _vm->_sound->command(36);
+ _rexDivingFl = false;
+ }
+}
+
+void Scene111::preActions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_CAVE_ENTRANCE))
+ _game._player._walkOffScreenSceneId = 212;
+}
+
+void Scene111::actions() {
+ if (_action.isAction(VERB_DIVE_INTO, NOUN_POOL) && _game._objects.isInInventory(OBJ_REBREATHER)) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->loadAnimation(Resources::formatName(111, 'A', 1, EXT_AA, ""), 1);
+ _rexDivingFl = true;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ break;
+
+ case 1:
+ _scene->_nextSceneId = 110;
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_CAVE_FLOOR))
+ _vm->_dialogs->show(11101);
+ else if (_action.isAction(VERB_LOOK, NOUN_POOL))
+ _vm->_dialogs->show(11102);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAVE_ENTRANCE))
+ _vm->_dialogs->show(11103);
+ else if (_action.isAction(VERB_LOOK, NOUN_STALAGMITES))
+ _vm->_dialogs->show(11104);
+ else if (_action.isAction(VERB_LOOK, NOUN_LARGE_STALAGMITE))
+ _vm->_dialogs->show(11105);
+ else if ((_action.isAction(VERB_PULL) || _action.isAction(VERB_TAKE)) && (_action.isObject(NOUN_STALAGMITES) || _action.isObject(NOUN_LARGE_STALAGMITE)))
+ _vm->_dialogs->show(11106);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene112::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene112::enter() {
+ sceneEntrySound();
+
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('X', 0));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('X', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('X', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('X', 5));
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 10, 0, 17, 20);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 4, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 3, 0);
+
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+
+ _scene->_userInterface.emptyConversationList();
+ _scene->_userInterface.setup(kInputConversation);
+
+ _scene->loadAnimation(Resources::formatName(112, 'X', -1, EXT_AA, ""), 70);
+}
+
+void Scene112::step() {
+ if ((_scene->_activeAnimation != nullptr) && (_game._storyMode == STORYMODE_NICE)) {
+ if (_scene->_activeAnimation->getCurrentFrame() >= 54) {
+ _scene->freeAnimation();
+ _game._trigger = 70;
+ }
+ }
+
+ if (_game._trigger == 70) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 3, 0, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ }
+
+ if (_game._trigger == 71) {
+ _scene->_nextSceneId = 101;
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes1.h b/engines/mads/nebular/nebular_scenes1.h
new file mode 100644
index 0000000000..1afa7fccc1
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes1.h
@@ -0,0 +1,264 @@
+/* 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 MADS_NEBULAR_SCENES1_H
+#define MADS_NEBULAR_SCENES1_H
+
+#include "common/scummsys.h"
+#include "common/serializer.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene1xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void sceneEntrySound();
+
+ /**
+ *Sets the AA file to use for the scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+public:
+ Scene1xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene101 : public Scene1xx {
+private:
+ bool _sittingFl;
+ bool _panelOpened;
+
+ int _messageNum;
+ int _posY;
+ int _shieldSpriteIdx;
+ int _chairHotspotId;
+ int _oldSpecial;
+
+ void sayDang();
+
+public:
+ Scene101(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene102 : public Scene1xx {
+private:
+ bool _fridgeOpenedFl;
+ bool _fridgeOpenedDescr;
+ bool _fridgeFirstOpenFl;
+ bool _chairDescrFl;
+ bool _drawerDescrFl;
+ bool _activeMsgFl;
+
+ int _fridgeCommentCount;
+
+ void addRandomMessage();
+
+public:
+ Scene102(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+ virtual void postActions();
+};
+
+class Scene103 : public Scene1xx {
+private:
+ uint32 _updateClock;
+
+public:
+ Scene103(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+ virtual void postActions();
+};
+
+class Scene104 : public Scene1xx {
+private:
+ bool _kargShootingFl;
+ bool _loseFl;
+
+public:
+ Scene104(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene105 : public Scene1xx {
+private:
+ bool _explosionFl;
+
+public:
+ Scene105(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene106 : public Scene1xx {
+private:
+ bool _backToShipFl;
+ bool _shadowFl;
+ bool _firstEmergingFl;
+
+ int _positionY;
+
+public:
+ Scene106(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene107 : public Scene1xx {
+private:
+ bool _shootingFl;
+
+public:
+ Scene107(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene108 : public Scene1xx {
+public:
+ Scene108(MADSEngine *vm) : Scene1xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene109 : public Scene1xx {
+private:
+ bool _rexThrowingObject;
+ bool _hoovicDifficultFl;
+ bool _beforeEatingRex;
+ bool _eatingRex;
+ bool _hungryFl;
+ bool _eatingFirstFish;
+
+ int _throwingObjectId;
+ int _hoovicTrigger;
+
+public:
+ Scene109(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene110 : public Scene1xx {
+private:
+ bool _crabsFl;
+
+public:
+ Scene110(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene111 : public Scene1xx {
+private:
+ bool _stampedFl;
+ bool _launch1Fl;
+ bool _launched2Fl;
+ bool _rexDivingFl;
+
+public:
+ Scene111(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene112 : public Scene1xx {
+public:
+ Scene112(MADSEngine *vm) : Scene1xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions() {};
+};
+
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES1_H */
diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp
new file mode 100644
index 0000000000..36e7107609
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes2.cpp
@@ -0,0 +1,5380 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes2.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene2xx::setAAName() {
+ int idx = (_scene->_nextSceneId == 216) ? 4 : 2;
+ _game._aaName = Resources::formatAAName(idx);
+}
+
+void Scene2xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+ Common::String oldName = _game._player._spritesPrefix;
+
+ switch(_scene->_nextSceneId) {
+ case 213:
+ case 216:
+ _game._player._spritesPrefix = "";
+ break;
+ default:
+ if (_globals[kSexOfRex] != SEX_MALE) {
+ _game._player._spritesPrefix = "ROX";
+ } else {
+ _game._player._spritesPrefix = "RXM";
+ }
+ break;
+ }
+
+ _game._player._scalingVelocity = (_scene->_nextSceneId <= 212);
+
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ if ((_scene->_nextSceneId == 203 || _scene->_nextSceneId == 204) && _globals[kRhotundaStatus])
+ _game._player._loadsFirst = false;
+
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+void Scene2xx::sceneEntrySound() {
+ if (_vm->_musicFlag) {
+ switch (_scene->_nextSceneId) {
+ case 201:
+ if ((_globals[kTeleporterCommand] == 2) || (_globals[kTeleporterCommand] == 4) || (_globals[kMeteorologistStatus] != 1))
+ _vm->_sound->command(9);
+ else
+ _vm->_sound->command(17);
+ break;
+ case 202:
+ case 203:
+ case 204:
+ case 205:
+ case 208:
+ case 209:
+ case 212:
+ _vm->_sound->command(9);
+ break;
+ case 206:
+ case 211:
+ case 215:
+ _vm->_sound->command(10);
+ break;
+ case 207:
+ case 214:
+ _vm->_sound->command(11);
+ break;
+ case 210:
+ if (_globals[kTwinklesStatus] == 0)
+ _vm->_sound->command(15);
+ else
+ _vm->_sound->command(10);
+ break;
+ case 213:
+ if (_globals[kMeteorologistWatch] == METEOROLOGIST_NORMAL)
+ _vm->_sound->command(1);
+ else
+ _vm->_sound->command(9);
+ break;
+ case 216:
+ _vm->_sound->command(16);
+ break;
+ default:
+ _vm->_sound->command(10);
+ break;
+ }
+ } else
+ _vm->_sound->command(2);
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene201::Scene201(MADSEngine *vm) : Scene2xx(vm) {
+ _pterodactylFlag = false;
+}
+
+void Scene201::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_pterodactylFlag);
+}
+
+void Scene201::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_SWOOPING_CREATURE);
+ _scene->addActiveVocab(NOUN_BIRDS);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene201::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('m', -1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('b', -1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*SC002Z1");
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 0, 1, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 50);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 4, 0, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 8);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(185, 46));
+
+ int idx = _scene->_dynamicHotspots.add(NOUN_BIRDS, 209, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(186, 81), FACING_NORTH);
+
+ if ((_scene->_priorSceneId == 202) || (_scene->_priorSceneId == -1)) {
+ _game._player._playerPos = Common::Point(165, 152);
+ } else {
+ _game._player._playerPos = Common::Point(223, 149);
+ _game._player._facing = FACING_SOUTH;
+ }
+
+ if (_globals[kTeleporterCommand]) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ int sepChar = (_globals[kSexOfRex] == SEX_MALE) ? 't' : 'u';
+ // Guess values. What is the default value used by the compiler?
+ int suffixNum = -1;
+ int abortTimers = -1;
+ switch(_globals[kTeleporterCommand]) {
+ case 1:
+ suffixNum = 3;
+ abortTimers = 76;
+ _globals[kTeleporterUnderstood] = true;
+ break;
+ case 2:
+ suffixNum = 1;
+ abortTimers = 77;
+ break;
+ case 3:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ suffixNum = -1;
+ break;
+ case 4:
+ suffixNum = 2;
+ abortTimers = 78;
+ break;
+ }
+ _globals[kTeleporterCommand] = 0;
+ if (suffixNum >= 0)
+ _scene->loadAnimation(formAnimName(sepChar, suffixNum), abortTimers);
+ }
+
+ if ((_scene->_priorSceneId == 202) && (_globals[kMeteorologistStatus] == METEOROLOGIST_PRESENT) && !_scene->_roomChanged) {
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _game.loadQuoteSet(90, 91, 0);
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], -1, 12);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 12, 70);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 1);
+ _pterodactylFlag = false;
+ _game._player.walk(Common::Point(157, 143), FACING_NORTH);
+ _vm->_palette->setEntry(252, 45, 63, 45);
+ _vm->_palette->setEntry(253, 20, 45, 20);
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 2, 0, 120, _game.getQuote(90));
+ } else
+ _pterodactylFlag = true;
+
+ if (_globals[kTeleporterUnderstood])
+ _scene->_hotspots.activate(NOUN_STRANGE_DEVICE, false);
+
+ sceneEntrySound();
+}
+
+void Scene201::step() {
+ if (_pterodactylFlag && (_vm->getRandomNumber(5000) == 9)) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 5, 1, 6, 0);
+ int idx = _scene->_dynamicHotspots.add(351, 13, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(270, 80), FACING_EAST);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 8);
+ _vm->_sound->command(14);
+ _pterodactylFlag = false;
+ }
+
+ if (_game._trigger == 70) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0);
+ _game._player._visible = false;
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 12, 16);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 9, 1, 0, 0);
+ _vm->_sound->command(42);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 3, 81);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ }
+
+ if (_game._trigger == 81) {
+ _scene->_kernelMessages.reset();
+ }
+
+ if (_game._trigger == 71) {
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 9, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 1);
+ }
+
+ if (_game._trigger == 73) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 17, -2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 1);
+ }
+
+ if (_game._trigger == 74) {
+ _vm->_sound->command(40);
+
+ _scene->_kernelMessages.add(Common::Point(125, 56), 0xFDFC, 32, 82, 180, _game.getQuote(91));
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 9, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 1);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], -2, -2);
+ _scene->_sequences.addTimer(180, 75);
+ }
+
+ if (_game._trigger == 75) {
+ _globals[kMeteorologistEverSeen] = 0;
+ _scene->_nextSceneId = 202;
+ }
+
+ if (_game._trigger == 76) {
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ }
+
+ if (_game._trigger == 77) {
+ _globals[kTeleporterCommand] = 1;
+ _scene->_nextSceneId = _globals[kTeleporterDestination];
+ _scene->_reloadSceneFlag = true;
+ }
+
+ if (_game._trigger == 78) {
+ _vm->_sound->command(40);
+ _vm->_dialogs->show(20114);
+ _scene->_reloadSceneFlag = true;
+ }
+}
+
+void Scene201::actions() {
+ if (_action._lookFlag == false) {
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_SOUTH))
+ _scene->_nextSceneId = 202;
+ else if (_action.isAction(VERB_CLIMB_UP, NOUN_STEPS) || (_action.isAction(VERB_WALK_INSIDE, NOUN_TELEPORTER)) || (_action.isAction(VERB_WALK_INSIDE, NOUN_STRANGE_DEVICE))) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ int sepChar = (_globals[kSexOfRex] == SEX_MALE) ? 't' : 'u';
+ _scene->loadAnimation(formAnimName(sepChar, 0), 1);
+ } else if (_game._trigger == 1) {
+ _scene->_nextSceneId = 213;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_GRASSY_FIELD)) {
+ _vm->_dialogs->show(20101);
+ } else if (_action.isAction(VERB_LOOK, NOUN_ROCKS)) {
+ _vm->_dialogs->show(20102);
+ } else if (_action.isAction(VERB_LOOK, NOUN_THORNY_BUSH)) {
+ _vm->_dialogs->show(20103);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SKY)) {
+ _vm->_dialogs->show(20104);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WATER)) {
+ _vm->_dialogs->show(20105);
+ } else if (_action.isAction(VERB_LOOK, NOUN_ISLAND_IN_DISTANCE)) {
+ _vm->_dialogs->show(20106);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WEATHER_STATION)) {
+ _vm->_dialogs->show(20107);
+ } else if (_action.isAction(VERB_LOOK, NOUN_PATH)) {
+ _vm->_dialogs->show(20108);
+ } else if (_action.isAction(VERB_LOOK, NOUN_FIELD_TO_SOUTH)) {
+ _vm->_dialogs->show(20110);
+ } else if (_action.isAction(VERB_LOOK, NOUN_STRANGE_DEVICE)) {
+ if (_globals[kMeteorologistEverSeen])
+ _vm->_dialogs->show(20112);
+ else
+ _vm->_dialogs->show(20109);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER)) {
+ _vm->_dialogs->show(20113);
+ } else
+ return;
+ } else {
+ _vm->_dialogs->show(20111);
+ }
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene202::Scene202(MADSEngine *vm) : Scene2xx(vm) {
+ _activeMsgFl = false;
+ _ladderTopFl = false;
+ _waitingMeteoFl = false;
+ _ladderHotspotId = -1;
+ _meteoClock1 = 0;
+ _meteoClock2 = 0;
+ _toStationFl = false;
+ _toTeleportFl = false;
+ _lastRoute = 0;
+ _stationCounter = 0;
+ _meteoFrame = 0;
+ _startTime = 0;
+ _meteorologistSpecial = false;
+}
+
+void Scene202::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_activeMsgFl);
+ s.syncAsByte(_ladderTopFl);
+ s.syncAsByte(_waitingMeteoFl);
+ s.syncAsByte(_toStationFl);
+ s.syncAsByte(_toTeleportFl);
+
+ s.syncAsSint32LE(_ladderHotspotId);
+ s.syncAsSint32LE(_lastRoute);
+ s.syncAsSint32LE(_stationCounter);
+ s.syncAsSint32LE(_meteoFrame);
+
+ s.syncAsUint32LE(_meteoClock1);
+ s.syncAsUint32LE(_meteoClock2);
+ s.syncAsUint32LE(_startTime);
+
+ s.syncAsByte(_meteorologistSpecial);
+}
+
+void Scene202::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_LADDER);
+ _scene->addActiveVocab(VERB_CLIMB_DOWN);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_BONE);
+ _scene->addActiveVocab(NOUN_SKULL);
+ _scene->addActiveVocab(NOUN_BROKEN_LADDER);
+}
+
+void Scene202::enter() {
+ _game._player._beenVisible = true;
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('l', -1));
+ if (_globals[kSexOfRex] != SEX_MALE) {
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites("*ROXBD_2");
+ } else {
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites("*RXMBD_2");
+ }
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('a', 2));
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(149, 113));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 10);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SKULL, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(153, 97), FACING_SOUTH);
+
+ if (!(_globals[kBone202Status] & 1)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(130, 108));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ idx = _scene->_dynamicHotspots.add(NOUN_BONE, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(132, 97), FACING_SOUTH);
+ }
+
+ if (!(_globals[kBone202Status] & 2)) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[6], Common::Point(166, 110));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 10);
+ idx = _scene->_dynamicHotspots.add(NOUN_BONE, VERB_WALKTO, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(165, 99), FACING_SOUTH);
+ }
+
+ if (_globals[kBone202Status])
+ _scene->changeVariant(_globals[kBone202Status]);
+
+ if (_scene->_priorSceneId == 201) {
+ _game._player._playerPos = Common::Point(190, 91);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(178, 152);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ if (_globals[kLadderBroken]) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 6);
+ _scene->_hotspots.activate(NOUN_LADDER, false);
+ idx = _scene->_dynamicHotspots.add(NOUN_BROKEN_LADDER, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(246, 124), FACING_NORTH);
+ }
+
+ _game.loadQuoteSet(0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x61, 0);
+ _activeMsgFl = false;
+
+ if (_scene->_priorSceneId == -2) {
+ if (_waitingMeteoFl) {
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ _game._player._visible = false;
+ }
+ } else {
+ _waitingMeteoFl = false;
+ _ladderTopFl = false;
+ }
+
+ _meteoClock1 = _meteoClock2 = _scene->_frameStartTime;
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+
+ if (_globals[kMeteorologistWatch] != METEOROLOGIST_NORMAL) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _ladderTopFl = (_globals[kMeteorologistWatch] == METEOROLOGIST_TOWER);
+
+ if (_ladderTopFl) {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], true, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 1);
+
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(247, 82));
+ _game._player._playerPos = Common::Point(246, 124);
+ _game._player._facing = FACING_NORTH;
+ _globals[kTeleporterUnderstood] = true;
+ } else {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 1);
+
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(172, 123));
+ _game._player._playerPos = Common::Point(171, 122);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ _scene->loadAnimation(formAnimName('M', -1), 71);
+ _scene->_activeAnimation->setCurrentFrame(200);
+ } else {
+ if (_ladderTopFl) {
+ _game._player._visible = false;
+ _scene->_sequences.startCycle(_globals._sequenceIndexes[9], true, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _game._player._playerPos = Common::Point(246, 124);
+ _game._player._facing = FACING_NORTH;
+ }
+ }
+
+ _meteorologistSpecial = false;
+}
+
+void Scene202::setRandomKernelMessage() {
+ int vocabId = _vm->getRandomNumber(92, 96);
+ _scene->_kernelMessages.reset();
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 70, 120, _game.getQuote(vocabId));
+ _activeMsgFl = true;
+}
+
+void Scene202::step() {
+ if (!_activeMsgFl && (_game._player._playerPos == Common::Point(77, 105)) && (_game._player._facing == FACING_NORTH) && (_vm->getRandomNumber(999) == 0)) {
+ _scene->_kernelMessages.reset();
+ _activeMsgFl = false;
+ if (_vm->getRandomNumber(4) == 0)
+ setRandomKernelMessage();
+ }
+
+ if (_game._trigger == 70)
+ _activeMsgFl = false;
+
+ if (_game._trigger == 71) {
+ _vm->_sound->command(3);
+ _vm->_sound->command(9);
+
+ _meteoClock1 = _scene->_frameStartTime + 15 * 60;
+
+ if (_globals[kMeteorologistWatch] != METEOROLOGIST_NORMAL) {
+ Common::Point msgPos;
+ int msgFlag;
+ if (!_ladderTopFl) {
+ msgPos = Common::Point(0, 0);
+ msgFlag = 2;
+ } else {
+ msgPos = Common::Point(248, 15);
+ msgFlag = 0;
+ }
+ int msgIndex = _scene->_kernelMessages.add(msgPos, 0x1110, msgFlag | 32, 0, 120, _game.getQuote(102));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+
+ if (_globals[kMeteorologistWatch] == METEOROLOGIST_GROUND) {
+ _action._activeAction._verbId = VERB_LOOK;
+ _action._activeAction._objectNameId = NOUN_BINOCULARS;
+ _action._activeAction._indirectObjectId = NOUN_STRANGE_DEVICE;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_PARSER;
+ _scene->_sequences.addTimer(2 * 60, 2);
+ _meteorologistSpecial = true;
+ } else if (_globals[kMeteorologistWatch] == METEOROLOGIST_TOWER) {
+ _scene->_sequences.addTimer(2 * 60, 90);
+ }
+ }
+
+ _globals[kMeteorologistWatch] = METEOROLOGIST_NORMAL;
+ }
+
+ switch (_game._trigger) {
+ case 90:
+ _vm->_sound->command(41);
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 91);
+ break;
+ case 91:
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], true, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _scene->_sequences.addTimer(60, 92);
+ break;
+ case 92: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[11], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 93);
+ _scene->_kernelMessages.reset();
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(0, -65), 0x1110, 32, 0, 60, _game.getQuote(98));
+ _scene->_kernelMessages.setSeqIndex(msgIndex, _globals._sequenceIndexes[11]);
+ }
+ break;
+ case 93: {
+ _globals[kLadderBroken] = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 0, 0, 0);
+ _scene->_hotspots.activate(NOUN_LADDER, false);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BROKEN_LADDER, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(246, 124), FACING_NORTH);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[11], _globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[11]);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _ladderTopFl = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(99));
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!_scene->_activeAnimation && (_globals[kMeteorologistStatus] != METEOROLOGIST_GONE) && (_meteoClock2 <= _scene->_frameStartTime) && (_meteoClock1 <= _scene->_frameStartTime)) {
+ int randVal = _vm->getRandomNumber(1, 500);
+ int threshold = 1;
+ if (_ladderTopFl)
+ threshold += 25;
+ if (!_globals[kMeteorologistEverSeen])
+ threshold += 25;
+ if (threshold >= randVal) {
+ _vm->_sound->command(17);
+ _scene->loadAnimation(formAnimName('M', -1), 71);
+ _toStationFl = true;
+ _toTeleportFl = false;
+ _globals[kMeteorologistEverSeen] = true;
+ _lastRoute = 0;
+ _stationCounter = 0;
+ _meteoClock2 = _scene->_frameStartTime + 2;
+ }
+ }
+
+ if (!_scene->_activeAnimation)
+ return;
+
+ if (_waitingMeteoFl) {
+ if (_scene->_activeAnimation->getCurrentFrame() >= 200) {
+ if ((_globals[kMeteorologistWatch] == METEOROLOGIST_TOWER) || _globals[kLadderBroken]) {
+ _scene->_nextSceneId = 213;
+ } else {
+ _vm->_dialogs->show(20201);
+ _scene->_reloadSceneFlag = true;
+ }
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 160) && (_meteoFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ Common::Point msgPos;
+ int msgFlag;
+ if (!_ladderTopFl) {
+ msgPos = Common::Point(0, 0);
+ msgFlag = 2;
+ } else {
+ msgPos = Common::Point(248, 15);
+ msgFlag = 0;
+ }
+ int msgIndex = _scene->_kernelMessages.add(msgPos, 0x1110, msgFlag | 32, 0, 120, _game.getQuote(101));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ }
+
+ if (_meteoClock2 + 120 * 60 <= _scene->_frameStartTime) {
+ _toTeleportFl = true;
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == _meteoFrame) {
+ return;
+ }
+
+ _meteoFrame = _scene->_activeAnimation->getCurrentFrame();
+ int randVal = _vm->getRandomNumber(1, 1000);
+ int frameStep = -1;
+
+ switch (_scene->_activeAnimation->getCurrentFrame()) {
+ case 42:
+ case 77:
+ case 96:
+ _stationCounter = 0;
+ frameStep = subStep1(randVal);
+ break;
+ case 51:
+ case 74:
+ _toStationFl = false;
+ frameStep = subStep2(randVal);
+ break;
+ case 27:
+ case 119:
+ case 159:
+ frameStep = subStep3(randVal);
+ break;
+ case 176:
+ frameStep = subStep4(randVal);
+ break;
+ case 59:
+ _lastRoute = 3;
+ ++_stationCounter;
+ if (randVal <= 800)
+ frameStep = 55;
+ break;
+ case 89:
+ _lastRoute = 1;
+ if (randVal <= 700)
+ frameStep = 83;
+ break;
+ case 137:
+ _lastRoute = 2;
+ if (randVal <= 700)
+ frameStep = 126;
+ break;
+ }
+
+ if (frameStep >= 0 && frameStep != _scene->_activeAnimation->getCurrentFrame() + 1) {
+ _scene->_activeAnimation->setCurrentFrame(frameStep);
+ _meteoFrame = frameStep;
+ }
+}
+
+int Scene202::subStep1(int randVal) {
+ if ((randVal <= 100) || _toStationFl)
+ return 42;
+
+ if ((randVal <= 200) || _toTeleportFl)
+ return 96;
+
+ if ((randVal <= 300) && (_lastRoute != 1))
+ return 77;
+
+ return 76;
+}
+
+int Scene202::subStep2(int randVal) {
+ if ((randVal <= 150) && (_stationCounter < 5))
+ return 51;
+
+ if ((randVal <= 300) || _toTeleportFl)
+ return 74;
+
+ if (randVal <= 400)
+ return 64;
+
+ return 44;
+}
+
+int Scene202::subStep3(int randVal) {
+ if ((randVal <= 100) || _toStationFl)
+ return 27;
+
+ if ((randVal <= 200) || _toTeleportFl)
+ return 159;
+
+ if ((randVal <= 300) && (_lastRoute != 2))
+ return 119;
+
+ return 110;
+}
+
+int Scene202::subStep4(int randVal) {
+ if ((randVal <= 100) || _toTeleportFl)
+ return 176;
+
+ if (randVal <= 200)
+ return 19;
+
+ return 166;
+}
+
+void Scene202::preActions() {
+ Player &player = _vm->_game->_player;
+
+ if (player._needToWalk)
+ _scene->_kernelMessages.reset();
+
+ if (_ladderTopFl && (_action.isAction(VERB_CLIMB_DOWN, NOUN_LADDER) || player._needToWalk)) {
+ if (_game._trigger == 0) {
+ _vm->_sound->command(29);
+ player._readyToWalk = false;
+ player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[8], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ } else if (_game._trigger == 1) {
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[8]);
+ _scene->_dynamicHotspots.remove(_ladderHotspotId);
+ player._visible = true;
+ player._readyToWalk = true;
+ player._stepEnabled = true;
+ _ladderTopFl = false;
+ }
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS) && (_action._activeAction._indirectObjectId > 0)) {
+ if (!player._readyToWalk || _ladderTopFl)
+ player._needToWalk = false;
+ else
+ player._needToWalk = true;
+
+ if (!_ladderTopFl)
+ player.walk(Common::Point(171, 122), FACING_NORTH);
+ }
+}
+
+void Scene202::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(20219);
+ return;
+ }
+
+ if (_action.isAction(VERB_CLIMB_DOWN, NOUN_LADDER)) {
+ _action._inProgress = false;
+ return;
+ } else if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_SOUTH)) {
+ _scene->_nextSceneId = 203;
+ } else if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_NORTH)) {
+ if (_globals[kMeteorologistStatus] != METEOROLOGIST_GONE) {
+ if (_scene->_activeAnimation)
+ _globals[kMeteorologistStatus] = METEOROLOGIST_PRESENT;
+ else
+ _globals[kMeteorologistStatus] = METEOROLOGIST_ABSENT;
+ }
+ _scene->_nextSceneId = 201;
+ } else if (_action.isAction(VERB_TAKE, NOUN_BONE) && (_action._savedFields._mainObjectSource == 4)) {
+ switch (_game._trigger) {
+ case 0:
+ if (_game._objects.isInInventory(OBJ_BONES)) {
+ _vm->_dialogs->show(20221);
+ } else {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], false, 3, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[7]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+ case 1:
+ if (_game._player._playerPos == Common::Point(132, 97)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals[kBone202Status] |= BONE_202_LEFT_GONE;
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _globals[kBone202Status] |= BONE_202_RIGHT_GONE;
+ }
+ break;
+ case 2:
+ if (_game._objects.isInInventory(OBJ_BONE)) {
+ _game._objects.removeFromInventory(OBJ_BONE, NOWHERE);
+ _game._objects.addToInventory(OBJ_BONES);
+ _vm->_dialogs->showItem(OBJ_BONES, 20218);
+ } else {
+ _game._objects.addToInventory(OBJ_BONE);
+ _vm->_dialogs->showItem(OBJ_BONE, 20218);
+ }
+ _scene->changeVariant(_globals[kBone202Status]);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ break;
+ default:
+ break;
+ }
+
+ _action._inProgress = false;
+ } else if (_action.isAction(VERB_CLIMB_UP, NOUN_LADDER) && !_globals[kLadderBroken]) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(29);
+ _meteoClock1 = _scene->_frameStartTime;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+
+ _ladderHotspotId = _scene->_dynamicHotspots.add(NOUN_LADDER, 78, -1, Common::Rect(241, 68, 241 + 12, 68 + 54));
+ _scene->_dynamicHotspots.setPosition(_ladderHotspotId, Common::Point(246, 124), FACING_NORTH);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+ case 1: {
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], true, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[8], _globals._sequenceIndexes[9]);
+ _ladderTopFl = true;
+ _game._player._stepEnabled = true;
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(248, 15), 0x1110, 32, 0, 60, _game.getQuote(97));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ break;
+ default:
+ _action._inProgress = false;
+ return;
+ }
+ } else if ((_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_FIELD_TO_NORTH) || (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_STRANGE_DEVICE))) && (_globals[kSexOfRex] == SEX_MALE)) {
+ if (!_ladderTopFl) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible= false;
+ _globals._sequenceIndexes[10] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 1, 6);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(172, 123));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 1);
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[10]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+ case 1:
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(172, 123));
+ if (_scene->_activeAnimation) {
+ _waitingMeteoFl = true;
+ _globals[kMeteorologistWatch] = METEOROLOGIST_GROUND;
+ } else {
+ _scene->_sequences.addTimer(120, 2);
+ }
+ break;
+ case 2:
+ if (!_scene->_activeAnimation && !_meteorologistSpecial) {
+ _vm->_dialogs->show(20222);
+ }
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _globals._sequenceIndexes[10] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[9], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 1);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 1, 6);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(172, 123));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[10]);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ break;
+ default:
+ _action._inProgress = false;
+ return;
+ }
+ } else {
+ switch (_game._trigger) {
+ case 0:
+ _toTeleportFl = true;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+ case 1:
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], true, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 1);
+ if (_scene->_activeAnimation) {
+ if (_scene->_activeAnimation->getCurrentFrame() > 200) {
+ _scene->_sequences.addTimer(120, 2);
+ } else {
+ _waitingMeteoFl = true;
+ _globals[kMeteorologistWatch] = METEOROLOGIST_GONE;
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 44) && (_scene->_activeAnimation->getCurrentFrame() <= 75)) {
+ _scene->_kernelMessages.reset();
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(248, 15), 0x1110, 32, 0, 60, _game.getQuote(100));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, false);
+ } else {
+ _action._inProgress = false;
+ return;
+ }
+ }
+ } else {
+ _scene->_sequences.addTimer(120, 2);
+ }
+ break;
+ case 2:
+ if (!_scene->_activeAnimation)
+ _vm->_dialogs->show(20222);
+ _meteorologistSpecial = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[9], false, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+ case 3:
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], true, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1);
+ _game._player._stepEnabled = true;
+ break;
+ default:
+ _action._inProgress = false;
+ return;
+ }
+ }
+ } else if (_action.isAction(VERB_WALK_INSIDE, NOUN_HUT)) {
+ setRandomKernelMessage();
+ } else if (_action.isAction(VERB_LOOK, NOUN_ROCKS)) {
+ _vm->_dialogs->show(20202);
+ } else if (_action.isAction(VERB_LOOK, NOUN_FIRE_PIT)) {
+ _vm->_dialogs->show(20203);
+ } else if (_action.isAction(VERB_LOOK, NOUN_GRASS)) {
+ _vm->_dialogs->show(20204);
+ } else if (_action.isAction(VERB_LOOK, NOUN_FIELD_TO_NORTH)) {
+ if ((_globals[kMeteorologistStatus] == METEOROLOGIST_ABSENT) || (_globals[kMeteorologistStatus] == METEOROLOGIST_GONE))
+ _vm->_dialogs->show(20205);
+ else if (_globals[kMeteorologistStatus] == METEOROLOGIST_PRESENT)
+ _vm->_dialogs->show(20220);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WATCH_TOWER)) {
+ _vm->_dialogs->show(20206);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TALL_GRASS)) {
+ _vm->_dialogs->show(20207);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TREES)) {
+ _vm->_dialogs->show(20208);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TREE)) {
+ _vm->_dialogs->show(20209);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SKY)) {
+ _vm->_dialogs->show(20210);
+ } else if (_action.isAction(VERB_LOOK, NOUN_HUT)) {
+ if ((_game._player._playerPos == Common::Point(77, 105)) && (_game._player._facing == FACING_NORTH))
+ _vm->_dialogs->show(20212);
+ else
+ _vm->_dialogs->show(20211);
+ } else if (_action.isAction(VERB_LOOK, NOUN_STRANGE_DEVICE)) {
+ _vm->_dialogs->show(20213);
+ } else if (_action.isAction(VERB_LOOK, NOUN_OCEAN_IN_DISTANCE)) {
+ _vm->_dialogs->show(20214);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SKULL)) {
+ _vm->_dialogs->show(20215);
+ } else if (_action.isAction(VERB_TAKE, NOUN_SKULL)) {
+ _vm->_dialogs->show(20216);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BONES) && _action._commandSource == 4) {
+ _vm->_dialogs->show(20217);
+ } else {
+ return;
+ }
+
+ _action._inProgress = false;
+}
+
+/*****************************************************************************/
+
+Scene203::Scene203(MADSEngine *vm) : Scene2xx(vm) {
+ _rhotundaEat2Fl = false;
+ _rhotundaEatFl = false;
+}
+
+void Scene203::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_rhotundaEat2Fl);
+ s.syncAsByte(_rhotundaEatFl);
+}
+
+void Scene203::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(477);
+}
+
+void Scene203::enter() {
+ if (_scene->_priorSceneId == 202) {
+ _game._player._playerPos = Common::Point(187, 99);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId == 209) {
+ _game._player._playerPos = Common::Point(308, 117);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(155, 152);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ _rhotundaEatFl = false;
+ _rhotundaEat2Fl = false;
+
+ if ((_globals[kRhotundaStatus] == 0) && (!_scene->_roomChanged)) {
+ _rhotundaEatFl = true;
+ _game._player.walk(Common::Point(158, 135), FACING_SOUTH);
+ int idx = _scene->_dynamicHotspots.add(131, 396, 0, Common::Rect(0, 0, 320, 156));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(155, 152), FACING_SOUTH);
+ _scene->_dynamicHotspots.setCursor(idx, CURSOR_GO_DOWN);
+ }
+
+ if (!_rhotundaEatFl) {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('b', -1));
+ if (_vm->getRandomNumber(1, 3) == 2) {
+ _globals._spriteIndexes[15] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 9, 1, 0, 0);
+ int idx = _scene->_dynamicHotspots.add(477, 209, _globals._spriteIndexes[15], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+ _vm->_sound->command(14);
+ }
+ }
+
+ _game.loadQuoteSet(0x67, 0x68, 0x69, 0x6A, 0x5A, 0);
+
+ if (_rhotundaEatFl) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(_vm->getRandomNumber(103, 106)));
+ }
+
+ sceneEntrySound();
+}
+
+void Scene203::step() {
+ if (!_rhotundaEatFl)
+ return;
+
+ if ((_game._trigger == 0) && _rhotundaEat2Fl)
+ return;
+
+ if ((_game._player._playerPos != Common::Point(158, 136)) || (_game._player._facing != FACING_SOUTH))
+ return;
+
+ _rhotundaEat2Fl = true;
+
+ if (_game._trigger == 0) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _vm->_palette->lock();
+ _scene->_kernelMessages.reset();
+ _scene->resetScene();
+ _vm->_events->setCursor2(CURSOR_WAIT);
+ _scene->loadAnimation(Resources::formatName(203, 'a', -1, EXT_AA, ""), 81);
+ } else if (_game._trigger == 81) {
+ _scene->_nextSceneId = 208;
+ _scene->_reloadSceneFlag = true;
+ }
+}
+
+void Scene203::preActions() {
+ if (_rhotundaEatFl && !_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_SOUTH)) {
+ _game._player.walk(Common::Point(158, 136), FACING_SOUTH);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALKTO, NOUN_OPEN_AREA_TO_EAST))
+ _game._player._walkOffScreenSceneId = 209;
+}
+
+void Scene203::actions() {
+ if (_action._savedFields._lookFlag) {
+ _vm->_dialogs->show(20307);
+ } else if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_SOUTH)) {
+ _scene->_nextSceneId = 208;
+ } else if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_NORTH)) {
+ _scene->_nextSceneId = 202;
+ } else if (_action.isAction(VERB_LOOK, NOUN_SKY)) {
+ _vm->_dialogs->show(20301);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CLIFF_FACE)) {
+ _vm->_dialogs->show(20302);
+ } else if (_action.isAction(VERB_LOOK, NOUN_PALM_TREE)) {
+ _vm->_dialogs->show(20303);
+ } else if (_action.isAction(VERB_LOOK, NOUN_FIELD_TO_NORTH)) {
+ _vm->_dialogs->show(20304);
+ } else if (_action.isAction(VERB_LOOK, NOUN_GRASSY_FIELD)) {
+ _vm->_dialogs->show(20305);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BOULDERS)) {
+ _vm->_dialogs->show(20305);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*****************************************************************************/
+
+void Scene205::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_CHICKEN);
+ _scene->addActiveVocab(NOUN_PIRANHA);
+}
+
+Scene205::Scene205(MADSEngine *vm) : Scene2xx(vm) {
+ _lastFishTime = 0;
+ _chickenTime = 0;
+ _beingKicked = false;
+ _kernelMessage = -1;
+}
+
+void Scene205::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsUint32LE(_lastFishTime);
+ s.syncAsUint32LE(_chickenTime);
+ s.syncAsByte(_beingKicked);
+ s.syncAsSint16LE(_kernelMessage);
+}
+
+void Scene205::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('f', -1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('p', -1));
+
+ if (_globals[kSexOfRex] == SEX_MALE)
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('a', 1));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 10, 0, 0, 3);
+ int idx = _scene->_dynamicHotspots.add(73, 13, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(162, 120), FACING_NORTHEAST);
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
+ idx = _scene->_dynamicHotspots.add(73, 13, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(162, 120), FACING_NORTHEAST);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 0, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 11);
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _lastFishTime = _scene->_frameStartTime;
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 7, 1, 0, 0);
+ idx = _scene->_dynamicHotspots.add(269, 13, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(49, 86), FACING_NORTH);
+ }
+
+ if (_game._objects[12]._roomNumber == 205) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 7, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 11);
+ } else {
+ _scene->_hotspots.activate(450, false);
+ }
+
+ _beingKicked = false;
+ _game.loadQuoteSet(0x6B, 0x70, 0x71, 0x72, 0x5A, 0x74, 0x75, 0x76, 0x77, 0x78, 0x73, 0x79, 0x7A, 0x7B, 0x7C,
+ 0x7D, 0x7E, 0x7F, 0x80, 0xAC, 0xAD, 0xAE, 0x6C, 0x6D, 0x6E, 0x6F, 0x2, 0);
+ _dialog1.setup(0x2A, 0x5A, 0x78, 0x74, 0x75, 0x76, 0x77, 0);
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _dialog1.set(0x5A, 0x74, 0x75, 0x77, 0);
+
+ _vm->_palette->setEntry(250, 63, 50, 20);
+ _vm->_palette->setEntry(251, 50, 40, 15);
+ _vm->_palette->setEntry(252, 63, 63, 40);
+ _vm->_palette->setEntry(253, 50, 50, 30);
+
+ _chickenTime = _vm->_game->_scene._frameStartTime;
+
+ if (_globals[kSexOfRex] == SEX_FEMALE)
+ _scene->_kernelMessages.initRandomMessages(3,
+ Common::Rect(195, 99, 264, 134), 13, 2, 0xFDFC, 60,
+ 108, 108, 109, 109, 110, 110, 111, 108, 0);
+
+ if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(99, 152);
+
+ if (_globals[kSexOfRex] != SEX_MALE) {
+ _scene->loadAnimation(formAnimName('a', -1));
+ _scene->_activeAnimation->_resetFlag = false;
+ } else {
+ _beingKicked = true;
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 6, 73);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 11, 74);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ }
+ sceneEntrySound();
+}
+
+void Scene205::step() {
+ if (_globals[kSexOfRex] == SEX_FEMALE) {
+ _scene->_kernelMessages.randomServer();
+
+ if (_vm->_game->_scene._frameStartTime >= _chickenTime) {
+ int chanceMinor = _scene->_kernelMessages.checkRandom() + 1;
+ if (_scene->_kernelMessages.generateRandom(100, chanceMinor))
+ _vm->_sound->command(28);
+
+ _chickenTime = _vm->_game->_scene._frameStartTime + 2;
+ }
+ }
+
+ if (_vm->_game->_scene._frameStartTime - _lastFishTime > 1300) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(
+ _globals._spriteIndexes[6], false, 5, 1, 0, 0);
+ int idx = _scene->_dynamicHotspots.add(269, 13, _globals._sequenceIndexes[6],
+ Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(49, 86), FACING_NORTH);
+ _lastFishTime = _vm->_game->_scene._frameStartTime;
+ }
+
+ if (_game._trigger == 73)
+ _scene->_kernelMessages.add(Common::Point(160, 68), 0xFBFA, 32, 0, 60, _game.getQuote(112));
+
+ if (_game._trigger == 74) {
+ _vm->_sound->command(26);
+ _scene->_kernelMessages.add(Common::Point(106, 90), 0x1110, 32, 0, 60, _game.getQuote(113));
+ }
+
+ if (_game._trigger == 71) {
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 2);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], -2, -2);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(160, 68), 0xFBFA, 32, 72, 180, _game.getQuote(114));
+ }
+
+ if (_game._trigger == 72)
+ _scene->_nextSceneId = 211;
+}
+
+void Scene205::handleWomanSpeech(int quote) {
+ _kernelMessage = _scene->_kernelMessages.add(Common::Point(186, 27), 0xFBFA, 0, 0, 9999999, _game.getQuote(quote));
+}
+
+void Scene205::actions() {
+ if (_game._screenObjects._inputMode == 1) {
+ if (_kernelMessage >= 0)
+ _scene->_kernelMessages.remove(_kernelMessage);
+ _kernelMessage = -1;
+
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 18, 1, 120, _game.getQuote(_action._activeAction._verbId));
+ } else {
+ if ((_game._trigger > 1) || (_action._activeAction._verbId != 0x76))
+ _game._player._stepEnabled = true;
+
+ switch (_action._activeAction._verbId) {
+ case 0x5A:
+ handleWomanSpeech(0x7A);
+ _dialog1.write(0x78, true);
+ _dialog1.write(0x5A, false);
+ break;
+
+ case 0x74:
+ handleWomanSpeech(0x7C);
+ _dialog1.write(0x74, false);
+ _dialog1.write(0x76, true);
+ break;
+
+ case 0x75:
+ case 0x78:
+ handleWomanSpeech(0x7B);
+ _dialog1.write(_action._activeAction._verbId, false);
+ _vm->_dialogs->show(20501);
+ break;
+
+ case 0x76:
+ if (_game._trigger == 1) {
+ handleWomanSpeech(0x7D);
+ _scene->_sequences.addTimer(120, 2);
+ } else if (_game._trigger == 2) {
+ handleWomanSpeech(0x7E);
+ _dialog1.write(0x76, false);
+ _globals[kChickenPermitted] = true;
+ }
+ break;
+
+ case 0x77:
+ _scene->_kernelMessages.add(Common::Point(186, 27), 0xFBFA, 0, 0, 120, _game.getQuote(0x7F));
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ default:
+ break;
+ }
+
+ if (_action._activeAction._verbId != 0x77)
+ _dialog1.start();
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(20502);
+ else if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_OPPOSITE_BANK))
+ _vm->_dialogs->show(20518);
+ else if (_action.isAction(VERB_TALKTO, NOUN_NATIVE_WOMAN)) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 18, 1, 120, _game.getQuote(0x73));
+ } else if (_game._trigger == 1) {
+ _game._player._stepEnabled = true;
+ handleWomanSpeech (0x79);
+ _dialog1.write(0x5A, true);
+ _dialog1.write(0x75, true);
+ _dialog1.start();
+ }
+ } else if (_action.isAction(VERB_GIVE, NOUN_NATIVE_WOMAN) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ int rndVal = _vm->getRandomNumber(0xAC, 0xAE);
+ _scene->_kernelMessages.add(Common::Point(186, 27), 0xFBFA, 32, 1, 120, _game.getQuote(rndVal));
+ } else if (_game._trigger == 1)
+ _game._player._stepEnabled = true;
+ } else if (_action.isAction(VERB_WALKTO, NOUN_OPPOSITE_BANK)) {
+ if (_game._trigger == 0) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _vm->_palette->lock();
+ _scene->_kernelMessages.reset();
+ _game._player.removePlayerSprites();
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _vm->_palette->refreshSceneColors();
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], -1);
+ _vm->_sound->command(27);
+ } else if (_game._trigger == 1) {
+ if (_scene->_activeAnimation != nullptr)
+ _scene->_activeAnimation->resetSpriteSetsCount();
+
+ _vm->_dialogs->show(20516);
+ _scene->_reloadSceneFlag = true;
+ }
+ } else {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_SOUTH))
+ _scene->_nextSceneId = 210;
+
+ if (_action.isAction(VERB_WALKTO, NOUN_FIRE_PIT) || _action.isAction(VERB_WALKTO, NOUN_CHICKEN_ON_SPIT)) {
+ if (_game._objects.isInRoom(OBJ_CHICKEN)) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x6B));
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_CHICKEN_ON_SPIT) && _globals[kChickenPermitted] && _game._objects.isInRoom(OBJ_CHICKEN)) {
+ _game._objects.addToInventory(OBJ_CHICKEN);
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _scene->_hotspots.activate(NOUN_CHICKEN_ON_SPIT, false);
+ _vm->_dialogs->showItem(OBJ_CHICKEN, 812);
+ } else if (_action.isAction(VERB_TAKE, NOUN_CHICKEN_ON_SPIT) && (!_globals[kChickenPermitted]))
+ _scene->_kernelMessages.add(Common::Point(186, 27), 0xFBFA, 32, 0, 120, _game.getQuote(0x80));
+ else if (_action.isAction(VERB_LOOK, NOUN_NATIVE_WOMAN))
+ _vm->_dialogs->show(20503);
+ else if (_action.isAction(VERB_LOOK, NOUN_HUT))
+ _vm->_dialogs->show(20504);
+ else if (_action.isAction(VERB_LOOK, NOUN_CHICKEN) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(20505);
+ else if (_action.isAction(VERB_TAKE, NOUN_CHICKEN) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(20506);
+ else if (_action.isAction(VERB_LOOK, NOUN_CHICKEN_ON_SPIT))
+ _vm->_dialogs->show(20507);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIRE_PIT))
+ _vm->_dialogs->show(20508);
+ else if (_action.isAction(VERB_TAKE, NOUN_FIRE_PIT))
+ _vm->_dialogs->show(20509);
+ else if (_action.isAction(VERB_LOOK, NOUN_STREAM))
+ _vm->_dialogs->show(20510);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPPOSITE_BANK))
+ _vm->_dialogs->show(20511);
+ else if (_game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))
+ && ( _action.isAction(VERB_GIVE, NOUN_STREAM) || _action.isAction(VERB_THROW, NOUN_STREAM)
+ || _action.isAction(VERB_GIVE, NOUN_PIRANHA) || _action.isAction(VERB_THROW, NOUN_PIRANHA)))
+ _vm->_dialogs->show(20512);
+ else if (_action.isAction(VERB_LOOK, NOUN_PIRANHA))
+ _vm->_dialogs->show(20513);
+ else if (_action.isAction(VERB_LOOK, NOUN_TWINKIFRUIT_BUSH))
+ _vm->_dialogs->show(20514);
+ else if (_action.isAction(VERB_TAKE, NOUN_TWINKIFRUIT_BUSH))
+ _vm->_dialogs->show(20515);
+ else if (_action.isAction(VERB_TAKE, NOUN_NATIVE_WOMAN))
+ _vm->_dialogs->show(20517);
+ else
+ return;
+ }
+
+ _action._inProgress = false;
+}
+
+/*****************************************************************************/
+
+Scene207::Scene207(MADSEngine *vm) : Scene2xx(vm) {
+ _vultureFl = false;
+ _spiderFl = false;
+ _eyeFl = false;
+ _spiderHotspotId = -1;
+ _vultureHotspotId = -1;
+ _spiderTime = 0;
+ _vultureTime = 0;
+}
+
+void Scene207::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_vultureFl);
+ s.syncAsByte(_spiderFl);
+ s.syncAsByte(_eyeFl);
+
+ s.syncAsSint32LE(_spiderHotspotId);
+ s.syncAsSint32LE(_vultureHotspotId);
+ s.syncAsSint32LE(_spiderTime);
+ s.syncAsSint32LE(_vultureTime);
+}
+
+void Scene207::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_VULTURE);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_SPIDER);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene207::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('h', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('h', 1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('e', 0));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('e', 1));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('g', 1));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('g', 0));
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 7, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 7);
+
+ int var2;
+ if (!_game._visitedScenes._sceneRevisited) {
+ var2 = 1;
+ } else {
+ var2 = _vm->getRandomNumber(4) + 1;
+ }
+
+ if (var2 > 2)
+ _vultureFl = false;
+ else
+ _vultureFl = true;
+
+ _spiderFl = (var2 & 1);
+
+ if (_vultureFl) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 30, 0, 0, 400);
+ _vultureTime = _game._player._priorTimer;
+ _vultureHotspotId = _scene->_dynamicHotspots.add(389, 13, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_vultureHotspotId, Common::Point(254, 94), FACING_WEST);
+ }
+
+ if (_spiderFl) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -1, -1);
+ _spiderTime = _game._player._priorTimer;
+ _spiderHotspotId = _scene->_dynamicHotspots.add(333, 13, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_spiderHotspotId, Common::Point(59, 132), FACING_SOUTH);
+ }
+
+ _eyeFl = false;
+ if (_scene->_priorSceneId == 211) {
+ _game._player._playerPos = Common::Point(13, 105);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId == 214) {
+ _game._player._playerPos = Common::Point(164, 117);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(305, 131);
+ }
+
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 22);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 6);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+}
+
+void Scene207::moveVulture() {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _vm->_sound->command(43);
+ _vultureFl = false;
+ _vultureTime = _game._player._priorTimer;
+ _scene->_dynamicHotspots.remove(_vultureHotspotId);
+}
+
+void Scene207::moveSpider() {
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 5, 1, 0, 0);
+ _spiderFl = false;
+ _spiderTime = _game._player._priorTimer;
+ _scene->_dynamicHotspots.remove(_spiderHotspotId);
+}
+
+void Scene207::step() {
+ if (!_vultureFl)
+ moveVulture();
+
+ if (_spiderFl)
+ moveSpider();
+
+ if (_game._trigger == 70) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 10, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 23, 34);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 6);
+ }
+
+ if (_game._trigger == 71)
+ _eyeFl = false;
+
+ if (_eyeFl)
+ return;
+
+ if ((_game._player._playerPos.x >= 124) && (_game._player._playerPos.x <= 201)) {
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 10, 1, 0, 0);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 6);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _eyeFl = true;
+ }
+}
+
+void Scene207::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_WEST))
+ _game._player._walkOffScreenSceneId = 211;
+
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_OPEN_FIELD_TO_EAST))
+ _game._player._walkOffScreenSceneId = 208;
+
+ if (_action.isAction(VERB_WALKTO) || _action.isAction(VERB_LOOK)) {
+ if (_action.isObject(NOUN_VULTURE)) {
+ _vultureTime = -9999;
+ } else if (_action.isObject(NOUN_SPIDER)) {
+ _spiderTime = -9999;
+ }
+ }
+}
+
+void Scene207::actions() {
+ if (_action._savedFields._lookFlag)
+ _vm->_dialogs->show(20711);
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY))
+ _scene->_nextSceneId = 214;
+ else {
+ if ((_game._player._playerPos.x > 150) && (_game._player._playerPos.x < 189) &&
+ (_game._player._playerPos.y > 111) && (_game._player._playerPos.y < 130)) {
+ if ((_game._player._playerPos.x <= 162) || (_game._player._playerPos.x >= 181) ||
+ (_game._player._playerPos.y <= 115) || (_game._player._playerPos.y >= 126)) {
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 10, 2, 0, 0);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 2, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 6);
+ }
+ } else if (_eyeFl) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _eyeFl = false;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_DENSE_FOREST))
+ _vm->_dialogs->show(20701);
+ else if (_action.isAction(VERB_LOOK, NOUN_HEDGE))
+ _vm->_dialogs->show(20702);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKULL_AND_CROSSBONES))
+ _vm->_dialogs->show(20703);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAULDRON))
+ _vm->_dialogs->show(20704);
+ else if (_action.isAction(VERB_LOOK, NOUN_WITCHDOCTOR_HUT))
+ _vm->_dialogs->show(20705);
+ else if (_action.isAction(VERB_LOOK, NOUN_PATH_TO_WEST))
+ _vm->_dialogs->show(20706);
+ else if (_action.isAction(VERB_LOOK, NOUN_MOUNTAINS))
+ _vm->_dialogs->show(20707);
+ else if (_action.isAction(VERB_LOOK, NOUN_ALOE_PLANT))
+ _vm->_dialogs->show(20708);
+ else if (_action.isAction(VERB_LOOK, NOUN_LAWN))
+ _vm->_dialogs->show(20709);
+ else if (_action.isAction(VERB_LOOK, NOUN_VULTURE))
+ _vm->_dialogs->show(20710);
+ else if (_action.isAction(VERB_TAKE, NOUN_SKULL_AND_CROSSBONES))
+ _vm->_dialogs->show(20712);
+ else if (_action.isAction(VERB_TAKE, NOUN_ALOE_PLANT))
+ _vm->_dialogs->show(20713);
+ else if (_action.isAction(VERB_LOOK, NOUN_SPIDER))
+ _vm->_dialogs->show(20714);
+ else if (_action.isAction(VERB_TAKE, NOUN_SPIDER))
+ _vm->_dialogs->show(20715);
+ else
+ return;
+ }
+
+ _action._inProgress = false;
+}
+
+/*****************************************************************************/
+
+Scene208::Scene208(MADSEngine *vm) : Scene2xx(vm) {
+ _rhotundaTurnFl = false;
+ _boundingFl = false;
+ _rhotundaTime = 0;
+}
+
+void Scene208::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_rhotundaTurnFl);
+ s.syncAsByte(_boundingFl);
+ s.syncAsSint32LE(_rhotundaTime);
+}
+
+void Scene208::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_HUGE_LEGS);
+ _scene->addActiveVocab(NOUN_LEAF_COVERED_PIT);
+ _scene->addActiveVocab(NOUN_PILE_OF_LEAVES);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene208::updateTrap() {
+ if (_globals[kRhotundaStatus] == 1) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 24);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ int idx = _scene->_dynamicHotspots.add(NOUN_HUGE_LEGS, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(100, 146), FACING_NORTH);
+ _scene->_hotspots.activate(414, false);
+ return;
+ }
+
+ switch (_globals[kLeavesStatus]) {
+ case 0: {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 15);
+ int idx = _scene->_dynamicHotspots.add(NOUN_PILE_OF_LEAVES, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(60, 152), FACING_NORTH);
+ }
+ break;
+ case 2: {
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 15);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_hotspots.activate(NOUN_DEEP_PIT, false);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LEAF_COVERED_PIT, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(100, 146), FACING_NORTH);
+ _scene->_dynamicHotspots[idx]._articleNumber = PREP_ON;
+ }
+ break;
+ }
+}
+
+void Scene208::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXMBD_8");
+
+ updateTrap();
+
+ _rhotundaTurnFl = false;
+ _boundingFl = false;
+ _scene->_kernelMessages._talkFont = _vm->_font->getFont(FONT_INTERFACE);
+ _scene->_textSpacing = 0;
+
+ if (_scene->_priorSceneId == 207) {
+ _game._player._playerPos = Common::Point(8, 122);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId == 203) {
+ _game._player._playerPos = Common::Point(142, 108);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId == 209) {
+ _game._player._playerPos = Common::Point(307, 123);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(162, 149);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ _game.loadQuoteSet(0x81, 0x46, 0);
+
+ if ((_scene->_priorSceneId == 207) && (_globals[kMonkeyStatus] == MONKEY_HAS_BINOCULARS)) {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(129));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+
+ _vm->_palette->setEntry(16, 0, 0, 63);
+ _vm->_palette->setEntry(17, 0, 0, 45);
+ sceneEntrySound();
+}
+
+void Scene208::step() {
+ if (_boundingFl && (_rhotundaTime <= _scene->_activeAnimation->getCurrentFrame())) {
+ _rhotundaTime = _scene->_activeAnimation->getCurrentFrame();
+
+ if (_rhotundaTime == 125)
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ }
+
+ if (!_rhotundaTurnFl)
+ return;
+
+ if ((_game._player._playerPos != Common::Point(20, 148)) || (_game._player._facing != FACING_EAST))
+ return;
+
+ if ((_game._trigger == 0) && _boundingFl)
+ return;
+
+ _boundingFl = true;
+
+ switch (_game._trigger) {
+ case 0:
+ _scene->loadAnimation(formAnimName('A', -1), 81);
+ _rhotundaTime = 0;
+ break;
+ case 81:
+ _scene->_sequences.remove(_globals._spriteIndexes[15]);
+ _globals[kRhotundaStatus] = 1;
+ updateTrap();
+ _scene->_sequences.addTimer(90, 82);
+ break;
+ case 82:
+ _game._player._stepEnabled = true;
+ break;
+ }
+}
+
+void Scene208::preActions() {
+ Player &player = _vm->_game->_player;
+
+ if (_action.isAction(VERB_LOOK) && player._readyToWalk)
+ player._needToWalk = true;
+
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_GRASSLAND_TO_EAST))
+ player._walkOffScreenSceneId = 209;
+
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_OPEN_AREA_TO_WEST))
+ player._walkOffScreenSceneId = 207;
+}
+
+void Scene208::subAction(int mode) {
+
+ switch (_game._trigger) {
+ case 0: {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+
+ int abortVal;
+ if ((mode == 1) || (mode == 2))
+ abortVal = 1;
+ else
+ abortVal = 2;
+
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, abortVal);
+ }
+ break;
+ case 1: {
+ int oldVal = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 12, 3, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 3, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldVal);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _vm->_sound->command(20);
+ }
+ break;
+
+ case 2: {
+ switch (mode) {
+ case 1:
+ _game._objects.addToInventory(OBJ_BIG_LEAVES);
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals[kLeavesStatus] = 1;
+ break;
+
+ case 2:
+ _game._objects.setRoom(OBJ_BIG_LEAVES, 1);
+ _globals[kLeavesStatus] = 2;
+ updateTrap();
+ break;
+
+ case 3:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _game._objects.removeFromInventory(OBJ_TWINKIFRUIT, 1);
+ _vm->_sound->command(34);
+ break;
+
+ case 4:
+ _game._objects.removeFromInventory(OBJ_BURGER, 1);
+ _vm->_sound->command(33);
+ break;
+
+ case 5:
+ _game._objects.removeFromInventory(OBJ_DEAD_FISH, 1);
+ _vm->_sound->command(33);
+ break;
+
+ default:
+ break;
+ }
+
+ int oldVal = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldVal);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 3:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene208::actions() {
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_LOWLANDS_TO_NORTH)) {
+ if (_globals[kRhotundaStatus])
+ _scene->_nextSceneId = 203;
+ else if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 1, 120, _game.getQuote(70));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ } else if (_game._trigger == 1)
+ _scene->_nextSceneId = 203;
+ } else if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_SOUTH))
+ _scene->_nextSceneId = 212;
+ else if (_action.isAction(VERB_TAKE, NOUN_PILE_OF_LEAVES) && (!_globals[kLeavesStatus] || _game._trigger)) {
+ subAction(1);
+ if (_game._player._stepEnabled)
+ _vm->_dialogs->showItem(OBJ_BIG_LEAVES, 0x326, 0);
+ } else if (_action.isAction(VERB_PUT, NOUN_BIG_LEAVES, NOUN_DEEP_PIT) && (_globals[kLeavesStatus] == 1 || _game._trigger))
+ subAction(2);
+ else if (_action.isAction(VERB_PUT, NOUN_TWINKIFRUIT, NOUN_LEAF_COVERED_PIT)) {
+ subAction(3);
+ if (_game._player._stepEnabled) {
+ _game._player._stepEnabled = false;
+ _rhotundaTurnFl = true;
+ _game._player.walk(Common::Point(20, 148), FACING_EAST);
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_BURGER, NOUN_LEAF_COVERED_PIT)) {
+ subAction(4);
+ if (_game._player._stepEnabled)
+ _vm->_dialogs->show(20812);
+ } else if (_action.isAction(VERB_PUT, NOUN_DEAD_FISH, NOUN_LEAF_COVERED_PIT)) {
+ subAction(5);
+ if (_game._player._stepEnabled)
+ _vm->_dialogs->show(20812);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CUMULOUS_CLOUD))
+ _vm->_dialogs->show(20801);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_AREA_TO_WEST))
+ _vm->_dialogs->show(20802);
+ else if (_action.isAction(VERB_LOOK, NOUN_THORNY_BUSH))
+ _vm->_dialogs->show(20803);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(20804);
+ else if (_action.isAction(VERB_LOOK, NOUN_SMALL_CACTUS))
+ _vm->_dialogs->show(20805);
+ else if (_action.isAction(VERB_TAKE, NOUN_SMALL_CACTUS))
+ _vm->_dialogs->show(20806);
+ else if (_action.isAction(VERB_LOOK, NOUN_GRASSLAND_TO_EAST))
+ _vm->_dialogs->show(20807);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEEP_PIT))
+ _vm->_dialogs->show(20808);
+ else if (_action.isAction(VERB_LOOK, NOUN_PILE_OF_LEAVES))
+ _vm->_dialogs->show(20809);
+ else if (_action.isAction(VERB_LOOK, NOUN_LEAF_COVERED_PIT)) {
+ if (_game._difficulty == DIFFICULTY_EASY)
+ _vm->_dialogs->show(20810);
+ else
+ _vm->_dialogs->show(20811);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TREE) || _action.isAction(VERB_LOOK, NOUN_TREES))
+ _vm->_dialogs->show(20813);
+ else if (_action.isAction(VERB_TAKE, NOUN_LEAF_COVERED_PIT))
+ _vm->_dialogs->show(20814);
+ else if (_action.isAction(VERB_LOOK, NOUN_HUGE_LEGS))
+ _vm->_dialogs->show(20815);
+ else if (_action.isAction(VERB_TAKE, NOUN_HUGE_LEGS) || _action.isAction(VERB_PULL, NOUN_HUGE_LEGS))
+ _vm->_dialogs->show(20816);
+ else if (_action._savedFields._lookFlag && (_globals[kRhotundaStatus] == 1))
+ _vm->_dialogs->show(20819);
+ else if (_action._savedFields._lookFlag && (_globals[kLeavesStatus] == 2))
+ _vm->_dialogs->show(20818);
+ else if (_action._savedFields._lookFlag)
+ _vm->_dialogs->show(20817);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*****************************************************************************/
+
+Scene209::Scene209(MADSEngine *vm) : Scene2xx(vm) {
+ _dodgeFl = false;
+ _forceDodgeFl = false;
+ _pitchFl = false;
+ _fallFl = false;
+ _forceFallFl = false;
+ _playingAnimFl = false;
+ _shouldFallFl = false;
+ _shouldDodgeFl = false;
+ _monkeyPosition = 0;
+ _counter = 0;
+ _pauseMode = 0;
+ _binocularsDroppedFl = false;
+ _startShootingInTimerFl = false;
+ _dialogAbortVal = 0;
+ _playingDialogFl = false;
+ _shootMissedLastFl = false;
+ _removeMonkeyFl = false;
+ _shootReadyFl = false;
+ _pauseCounterThreshold = 0;
+ _pauseCounter = 0;
+}
+
+void Scene209::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_dodgeFl);
+ s.syncAsByte(_forceDodgeFl);
+ s.syncAsByte(_shouldDodgeFl);
+ s.syncAsByte(_pitchFl);
+ s.syncAsByte(_fallFl);
+ s.syncAsByte(_forceFallFl);
+ s.syncAsByte(_shouldFallFl);
+ s.syncAsByte(_playingAnimFl);
+ s.syncAsByte(_playingDialogFl);
+
+ s.syncAsSint32LE(_pauseMode);
+ s.syncAsSint32LE(_pauseCounterThreshold);
+ s.syncAsSint32LE(_pauseCounter);
+
+ s.syncAsByte(_removeMonkeyFl);
+
+ s.syncAsSint32LE(_monkeyPosition);
+
+ s.syncAsByte(_shootReadyFl);
+ s.syncAsByte(_startShootingInTimerFl);
+ s.syncAsByte(_shootMissedLastFl);
+ s.syncAsByte(_binocularsDroppedFl);
+
+ s.syncAsSint32LE(_dialogAbortVal);
+ s.syncAsSint32LE(_counter);
+}
+
+void Scene209::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_PLANT_STALK);
+}
+
+void Scene209::handlePause() {
+ switch (_game._trigger) {
+ case 124:
+ if (++_pauseCounter <= _pauseCounterThreshold)
+ _scene->_sequences.addTimer(60, 124);
+ else
+ _pauseMode = 0;
+ break;
+ }
+}
+
+void Scene209::initPauseCounterThreshold() {
+ switch (_game._trigger) {
+ case 226:
+ _scene->_sequences.addTimer(1, 124);
+ _pauseCounterThreshold = _vm->getRandomNumber(7,12);
+ _pauseMode = 2;
+ _pauseCounter = 0;
+ break;
+ }
+}
+
+void Scene209::handlePeek() {
+ switch (_game._trigger) {
+ case 133:
+ _vm->_sound->command(18);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 51, 52);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 134);
+ break;
+
+ case 134: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(60, 135);
+ }
+ break;
+
+ case 135:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 7);
+ _scene->_sequences.addTimer(10, 136);
+ break;
+
+ case 136:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.addTimer(50, 137);
+ break;
+
+ case 137:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 51, 52);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 138);
+ break;
+
+ case 138:
+ _pauseMode = 1;
+ _scene->_hotspots.activate(227, false);
+ _playingAnimFl = false;
+ break;
+ }
+}
+
+void Scene209::handleVerticalMove() {
+ switch (_game._trigger) {
+ case 140:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 8, 0, 1);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 141);
+ break;
+
+ case 141: {
+ _vm->_sound->command(18);
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(60, 142);
+ }
+ break;
+
+ case 142:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 143);
+ break;
+
+ case 143:
+ _pauseMode = 1;
+ _playingAnimFl = false;
+ _scene->_hotspots.activate(227, false);
+ break;
+ }
+}
+
+void Scene209::handleLookStay() {
+ switch (_game._trigger) {
+ case 145:
+ _vm->_sound->command(18);
+ _monkeyPosition = 2;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 51, 52);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 146);
+ break;
+
+ case 146: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(15, 147);
+ }
+ break;
+
+ case 147:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 7);
+ _scene->_sequences.addTimer(8, 148);
+ break;
+
+ case 148:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+
+ if (!_dodgeFl) {
+ _scene->_sequences.addTimer(90, 149);
+ } else {
+ _scene->_sequences.addTimer(1, 149);
+ _shouldDodgeFl = true;
+ }
+ break;
+
+ case 149:
+ _playingAnimFl = false;
+ break;
+ }
+}
+
+void Scene209::handleLookRight() {
+ switch (_game._trigger) {
+ case 151:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 152);
+ break;
+
+ case 152: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(60, 153);
+ }
+ break;
+
+ case 153:
+ _playingAnimFl = false;
+ if (_dodgeFl)
+ _shouldDodgeFl = true;
+ break;
+ }
+}
+
+void Scene209::handleBlink() {
+ switch (_game._trigger) {
+ case 155:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.addTimer(50, 156);
+ break;
+
+ case 156:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 7);
+ _scene->_sequences.addTimer(10, 157);
+ break;
+
+ case 157:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.addTimer(50, 158);
+ break;
+
+ case 158:
+ _playingAnimFl = false;
+ if (_dodgeFl)
+ _shouldDodgeFl = true;
+ break;
+ }
+}
+
+void Scene209::handleGetBinoculars() {
+ switch (_game._trigger) {
+ case 161:
+ _vm->_sound->command(18);
+ _monkeyPosition = 3;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 24);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 20, 165);
+ if (!_fallFl && !_dodgeFl) {
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 162);
+ } else {
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 163);
+ }
+ break;
+
+ case 162: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 6, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 163);
+ }
+ break;
+
+ case 163: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(8, 164);
+ }
+ break;
+
+ case 164:
+ _playingAnimFl = false;
+ if (_fallFl)
+ _shouldFallFl = true;
+ break;
+
+ case 165:
+ _vm->_sound->command(18);
+ break;
+ }
+}
+
+void Scene209::handleBinocularBlink() {
+ switch (_game._trigger) {
+ case 167: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 168);
+ }
+ break;
+
+ case 168: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(30, 169);
+ }
+ break;
+
+ case 169:
+ _playingAnimFl = false;
+ if (_fallFl)
+ _shouldFallFl = true;
+ break;
+ }
+}
+
+void Scene209::handleBinocularScan() {
+ switch (_game._trigger) {
+ case 171: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 43, 45);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 172);
+ }
+ break;
+
+ case 172: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ int randAction = _vm->getRandomNumber(1,2);
+ switch (randAction) {
+ case 1:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ break;
+ case 2:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 4, 0, 0);
+ break;
+ }
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 173);
+ }
+ break;
+
+ case 173: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 26, 30);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 174);
+ }
+ break;
+
+ case 174: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(60, 175);
+ }
+ break;
+
+ case 175:
+ _playingAnimFl = false;
+ if (_fallFl)
+ _shouldFallFl = true;
+ break;
+ }
+}
+
+void Scene209::handleJumpInTree() {
+ switch (_game._trigger) {
+ case 178: {
+ int oldIdx = 0;
+ _monkeyPosition = 1;
+ if (_removeMonkeyFl)
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ else
+ oldIdx = _globals._sequenceIndexes[3];
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 46, 49);
+ if (!_removeMonkeyFl)
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 179);
+ }
+ break;
+
+ case 179: {
+ _vm->_sound->command(18);
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 53, 61);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 180);
+ }
+ break;
+
+ case 180:
+ _removeMonkeyFl = true;
+ _pauseMode = 1;
+ _playingAnimFl = false;
+ _scene->_hotspots.activate(227, false);
+ break;
+ }
+}
+
+void Scene209::handleTongue() {
+ switch (_game._trigger) {
+ case 182: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 26, 30);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 183);
+ }
+ break;
+
+ case 183: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 31, 33);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 184);
+ }
+ break;
+
+ case 184: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 36, 37);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 185);
+ }
+ break;
+
+ case 185: {
+ _vm->_sound->command(18);
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 20, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 38, 39);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 186);
+ }
+ break;
+
+ case 186: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 40, 41);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 178);
+ _removeMonkeyFl = false;
+ }
+ break;
+ }
+}
+
+void Scene209::handleStandFromPeek() {
+ switch (_game._trigger) {
+ case 189:
+ _monkeyPosition = 4;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 50);
+ _scene->_sequences.addTimer(8, 190);
+ break;
+
+ case 190:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.addTimer(8, 191);
+ break;
+
+ case 191:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 192);
+ break;
+
+ case 192: {
+ _vm->_sound->command(18);
+ int oldIdx = _globals._sequenceIndexes[6];
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldIdx);
+ _scene->_sequences.addTimer(8, 193);
+ }
+ break;
+
+ case 193:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 22);
+ _scene->_sequences.addTimer(5, 194);
+ break;
+
+ case 194:
+ _playingAnimFl = false;
+ _counter = 0;
+ break;
+ }
+}
+
+void Scene209::handleStandBlink() {
+ switch (_game._trigger) {
+ case 246:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 22);
+ _scene->_sequences.addTimer(10, 247);
+ break;
+
+ case 247:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 23);
+ _scene->_sequences.addTimer(8, 248);
+ break;
+
+ case 248:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 22);
+ _scene->_sequences.addTimer(10, 249);
+ break;
+
+ case 249:
+ _playingAnimFl = false;
+ break;
+ }
+}
+
+void Scene209::handleJumpAndHide() {
+ switch (_game._trigger) {
+ case 196:
+ _vm->_sound->command(18);
+ _monkeyPosition = 1;
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 16);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 197);
+ break;
+
+ case 197:
+ _pauseMode = 1;
+ _scene->_hotspots.activate(227, false);
+ _playingAnimFl = false;
+ break;
+ }
+}
+
+void Scene209::handleMonkeyEating() {
+ switch (_game._trigger) {
+ case 199:
+ _vm->_sound->command(18);
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 200);
+ break;
+
+ case 200: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 10, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 15, 16);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 201);
+ }
+ break;
+
+ case 201: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 12);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addTimer(20, 202);
+ }
+ break;
+
+ case 202:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 19);
+ _scene->_sequences.addTimer(20, 203);
+ break;
+
+ case 203:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 17);
+ _scene->_sequences.addTimer(20, 204);
+ break;
+
+ case 204:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 18, 19);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 205);
+ break;
+
+ case 205: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 20, 21);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 206);
+ }
+ break;
+
+ case 206: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 22, 25);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ if (!_dodgeFl && !_fallFl)
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 207);
+ else
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 209);
+ }
+ break;
+
+ case 207: {
+ _vm->_sound->command(18);
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(180, 25), 0xFDFC, 0, 0, 90, _game.getQuote(130));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 4, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 26, 27);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 208);
+ }
+ break;
+
+ case 208: {
+ _scene->_kernelMessages.add(Common::Point(180, 39), 0xFDFC, 0, 0, 90, _game.getQuote(131));
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 4, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 28, 29);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 209);
+ }
+ break;
+
+ case 209: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 22);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addTimer(1, 210);
+ }
+ break;
+
+ case 210:
+ _playingAnimFl = false;
+ break;
+ }
+}
+
+void Scene209::handleMonkeyFall() {
+ switch (_game._trigger) {
+ case 219: {
+ _vm->_sound->command(25);
+ _scene->_sprites.remove(_globals._spriteIndexes[7]);
+ _scene->_sprites.remove(_globals._spriteIndexes[6]);
+ _scene->_sprites.remove(_globals._spriteIndexes[5]);
+ _scene->_sprites.remove(_globals._spriteIndexes[4]);
+
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('m', 4));
+ _scene->_kernelMessages.add(Common::Point(180, 26), 0xFDFC, 0, 0, 90, _game.getQuote(151));
+ _scene->_sequences.addTimer(40, 100);
+ _scene->_hotspots.activate(227, false);
+ int oldIdx = _globals._sequenceIndexes[3];
+ _monkeyPosition = 1;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 35);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 220);
+ }
+ break;
+
+ case 220: {
+ _vm->_sound->command(18);
+ _scene->_kernelMessages.add(Common::Point(182, 109), 0xFDFC, 0, 0, 90, _game.getQuote(159));
+ _scene->_hotspots.activate(227, false);
+ int oldIdx = _globals._sequenceIndexes[3];
+ _monkeyPosition = 1;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 36, 42);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 221);
+ }
+ break;
+
+ case 221: {
+ _game._objects.setRoom(OBJ_BINOCULARS, 209);
+ _binocularsDroppedFl = true;
+ int oldIdx = _globals._sequenceIndexes[8];
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], oldIdx);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(201, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[8], oldIdx);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 43, 72);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 222);
+ int idx = _scene->_dynamicHotspots.add(39, 13, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(200, 133), FACING_NORTH);
+ }
+ break;
+
+ case 222: {
+ _scene->_kernelMessages.add(Common::Point(182, 109), 0xFDFC, 0, 0, 70, _game.getQuote(160));
+ int oldIdx = _globals._sequenceIndexes[8];
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 73, 78);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[8], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 223);
+ }
+ break;
+
+ case 223:
+ _scene->loadAnimation(Resources::formatName(209, 'e', -1, EXT_AA, ""), 224);
+ _vm->_sound->command(38);
+ break;
+
+ case 224:
+ _playingAnimFl = false;
+ _fallFl = false;
+ _counter = 0;
+ _pauseMode = 0;
+ _vm->_dialogs->show(20910);
+ _game._player._stepEnabled = true;
+ break;
+ }
+}
+
+void Scene209::handleMonkey1() {
+ switch (_game._trigger) {
+ case 212:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 13);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 213);
+ break;
+
+ case 213: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 1, 22);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[7], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 214);
+ }
+ break;
+
+ case 214: {
+ int oldIdx = _globals._sequenceIndexes[7];
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 23, 26);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[7], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 215);
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(170, 21), 0xFDFC, 0, 0, 90, _game.getQuote(156));
+ _scene->_kernelMessages.setQuoted(msgIndex, 3, true);
+ }
+ break;
+
+ case 215: {
+ _vm->_sound->command(18);
+ _scene->loadAnimation(Resources::formatName(209, 'a', -1, EXT_AA, ""), 251);
+ int oldIdx = _globals._sequenceIndexes[7];
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 27, 35);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[7], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 216);
+ }
+ break;
+
+ case 216: {
+ int oldIdx = _globals._sequenceIndexes[7];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 22);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addTimer(25, 217);
+ }
+ break;
+
+ case 217:
+ _pitchFl = false;
+ _counter = 0;
+ _pauseMode = 0;
+ _scene->_sequences.addTimer(1, 196);
+ break;
+ }
+}
+
+void Scene209::handleMonkey2() {
+ switch (_game._trigger) {
+ case 251:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(137));
+ _vm->_sound->command(22);
+ _globals._sequenceIndexes[12] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[12], false, 11, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[12], Common::Point(111, 133));
+ _scene->_sequences.setScale(_globals._sequenceIndexes[12], 79);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[12], 1, 6);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 252);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = false;
+ break;
+
+ case 252: {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(132));
+ int oldIdx = _globals._sequenceIndexes[12];
+ _globals._sequenceIndexes[12] = _scene->_sequences.startCycle(_globals._spriteIndexes[12], false, 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[12], Common::Point(111, 133));
+ _scene->_sequences.setScale(_globals._sequenceIndexes[12], 79);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[12], oldIdx);
+ _scene->_sequences.addTimer(120, 253);
+ }
+ break;
+
+ case 253:
+ _scene->_sequences.remove(_globals._sequenceIndexes[12]);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ }
+}
+
+void Scene209::handleDodge() {
+ switch (_game._trigger) {
+ case 241:
+ _scene->_hotspots.activate(227, true);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 7);
+ _scene->_sequences.addTimer(6, 242);
+ break;
+
+ case 242:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 5);
+ _scene->_sequences.addTimer(25, 243);
+ _vm->_sound->command(24);
+ break;
+
+ case 243:
+ _vm->_sound->command(18);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _playingAnimFl = false;
+ _pauseMode = 0;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(180, 21), 0xFDFC, 0, 0, 90, _game.getQuote(155));
+ if (!_shootMissedLastFl) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(135));
+ _shootMissedLastFl = true;
+ } else {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(136));
+ }
+ break;
+ }
+}
+
+void Scene209::enter() {
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('e', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('m', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('m', 1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('m', 3));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('m', 6));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('m', 8));
+
+ _game.loadQuoteSet(0x82, 0x83, 0x84, 0x9C, 0x97, 0x95, 0x99, 0x9E, 0x98, 0x9B, 0xA0, 0x96, 0x9F,
+ 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91, 0x92, 0x93, 0x94, 0x89, 0x85, 0x8A, 0x86, 0x87, 0x88, 0);
+
+ _vm->_palette->setEntry(252, 63, 44, 30);
+ _vm->_palette->setEntry(253, 63, 20, 22);
+
+ if (_game._objects.isInRoom(OBJ_PLANT_STALK)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ int idx = _scene->_dynamicHotspots.add(271, 13, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(263, 129), FACING_SOUTH);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 13);
+ }
+
+ if (_scene->_priorSceneId == 208) {
+ _game._player._playerPos = Common::Point(11, 121);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(28, 121);
+ _game._player._facing = FACING_SOUTH;
+ }
+
+ if (_game._objects.isInRoom(OBJ_BINOCULARS)) {
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(201, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ int idx = _scene->_dynamicHotspots.add(39, 13, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(200, 133), FACING_NORTH);
+ }
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_POISON_DARTS);
+ _game._objects.addToInventory(OBJ_BLOWGUN);
+ _globals[kMonkeyStatus] = MONKEY_HAS_BINOCULARS;
+ }
+
+ _pitchFl = false;
+ _fallFl = false;
+ _dodgeFl = false;
+ _playingAnimFl = false;
+ _monkeyPosition = 1;
+ _counter = 0;
+ _pauseMode = 0;
+ _forceFallFl = false;
+ _shouldFallFl = false;
+ _forceDodgeFl = false;
+ _binocularsDroppedFl = false;
+ _shouldDodgeFl = false;
+ _startShootingInTimerFl = false;
+ _dialogAbortVal = 5;
+ _playingDialogFl = false;
+ _shootMissedLastFl = false;
+ _removeMonkeyFl = true;
+ _shootReadyFl = false;
+
+ _scene->_hotspots.activate(227, false);
+
+ sceneEntrySound();
+}
+
+void Scene209::step() {
+ if (!_playingAnimFl && !_pitchFl && !_fallFl && !_dodgeFl && (_pauseMode == 0) && (_globals[kMonkeyStatus] == MONKEY_HAS_BINOCULARS)) {
+ int randAction = _vm->getRandomNumber(1,50);
+ switch (randAction) {
+ case 1:
+ if ((_monkeyPosition == 1) && (_counter < 2)) {
+ _scene->_sequences.addTimer(1, 133);
+ _playingAnimFl = true;
+ _scene->_hotspots.activate(227, true);
+ ++_counter;
+ }
+ break;
+
+ case 2:
+ if ((_monkeyPosition == 1) && (_counter < 2)) {
+ _scene->_sequences.addTimer(1, 140);
+ _scene->_hotspots.activate(227, true);
+ _playingAnimFl = true;
+ ++_counter;
+ }
+ break;
+
+ case 3:
+ if (_monkeyPosition == 1) {
+ _scene->_sequences.addTimer(1, 145);
+ _scene->_hotspots.activate(227, true);
+ _playingAnimFl = true;
+ _counter = 0;
+ }
+ break;
+
+ case 4:
+ if ((_monkeyPosition == 2) && (_counter < 2)) {
+ _scene->_sequences.addTimer(1, 151);
+ _scene->_hotspots.activate(227, true);
+ ++_counter;
+ _playingAnimFl = true;
+ }
+ break;
+
+ case 5:
+ if (_monkeyPosition == 2) {
+ _scene->_sequences.addTimer(1, 161);
+ _scene->_hotspots.activate(227, true);
+ _counter = 0;
+ _playingAnimFl = true;
+ }
+ break;
+
+ case 6:
+ if (_monkeyPosition == 2) {
+ _scene->_sequences.addTimer(1, 189);
+ _scene->_hotspots.activate(227, true);
+ _counter = 0;
+ _playingAnimFl = true;
+ }
+ break;
+ case 7:
+ if (_monkeyPosition == 3) {
+ _scene->_hotspots.activate(227, true);
+ _scene->_sequences.addTimer(1, 167);
+ _playingAnimFl = true;
+ }
+ break;
+
+ case 8:
+ if (_monkeyPosition == 3) {
+ _scene->_sequences.addTimer(1, 178);
+ _playingAnimFl = true;
+ _scene->_hotspots.activate(227, true);
+ _counter = 0;
+ }
+ break;
+
+ case 9:
+ if ((_monkeyPosition == 3) && (_game._player._playerPos.x<120)) {
+ _scene->_sequences.addTimer(1, 182);
+ _scene->_hotspots.activate(227, true);
+ _counter = 0;
+ _playingAnimFl = true;
+ }
+ break;
+
+ case 10:
+ if (_monkeyPosition == 4) {
+ _scene->_sequences.addTimer(1, 196);
+ _scene->_hotspots.activate(227, true);
+ _playingAnimFl = true;
+ _counter = 0;
+ }
+ break;
+
+ case 11:
+ if ((_monkeyPosition == 4) && (_counter < 3)) {
+ _scene->_sequences.addTimer(1, 199);
+ _scene->_hotspots.activate(227, true);
+ ++_counter;
+ _playingAnimFl = true;
+ }
+ break;
+
+ case 30:
+ if (_monkeyPosition == 4) {
+ _scene->_sequences.addTimer(1, 246);
+ _scene->_hotspots.activate(227, true);
+ _counter = 0;
+ _playingAnimFl = true;
+ }
+ break;
+
+ default:
+ if ((randAction >= 12) && (randAction <= 20) && (_monkeyPosition == 2) && (_counter < 5)) {
+ _scene->_sequences.addTimer(1, 155);
+ ++_counter;
+ _playingAnimFl = true;
+ }
+
+ if ((randAction >= 21) && (randAction <= 29) && (_monkeyPosition == 3) && (_counter < 3)) {
+ _scene->_sequences.addTimer(1, 171);
+ _playingAnimFl = true;
+ ++_counter;
+ }
+ break;
+ }
+ }
+
+ if (!_dodgeFl && !_pitchFl && !_fallFl && (_pauseMode == 1))
+ _scene->_sequences.addTimer(1, 226);
+
+ if (!_dodgeFl && !_pitchFl && !_fallFl && (_pauseMode == 2))
+ handlePause();
+
+ if (!_dodgeFl && !_pitchFl && !_fallFl && (_pauseMode == 1))
+ initPauseCounterThreshold();
+
+ handlePeek();
+ handleVerticalMove();
+ handleLookStay();
+ handleLookRight();
+ handleBlink();
+ handleGetBinoculars();
+ handleStandFromPeek();
+ handleDodge();
+ handleBinocularBlink();
+ handleBinocularScan();
+ handleJumpInTree();
+ handleTongue();
+ handleMonkeyFall();
+ handleJumpAndHide();
+ handleMonkeyEating();
+ handleMonkey1();
+ handleStandBlink();
+ handleMonkey2();
+
+ if ((_monkeyPosition == 1) && !_playingAnimFl && _fallFl) {
+ _scene->_sequences.addTimer(1, 145);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 2) && !_playingAnimFl && _fallFl) {
+ _scene->_sequences.addTimer(1, 161);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 4) && !_playingAnimFl && _fallFl) {
+ _scene->_sequences.addTimer(1, 196);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 3) && !_playingAnimFl && _fallFl && _forceFallFl) {
+ _scene->_sequences.addTimer(1, 219);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 1) && !_playingAnimFl && _pitchFl) {
+ _scene->_sequences.addTimer(1, 145);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 2) && !_playingAnimFl && _pitchFl) {
+ _scene->_sequences.addTimer(1, 189);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 4) && !_playingAnimFl && _pitchFl) {
+ _scene->_sequences.addTimer(1, 212);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 3) && !_playingAnimFl && _pitchFl) {
+ _scene->_sequences.addTimer(1, 178);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 1) && !_playingAnimFl && _dodgeFl) {
+ _scene->_sequences.addTimer(1, 145);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 4) && !_playingAnimFl && _dodgeFl) {
+ _scene->_sequences.addTimer(1, 196);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 3) && !_playingAnimFl && _dodgeFl) {
+ _scene->_sequences.addTimer(1, 178);
+ _playingAnimFl = true;
+ }
+
+ if ((_monkeyPosition == 2) && !_playingAnimFl && _dodgeFl && _forceDodgeFl) {
+ _scene->_sequences.addTimer(1, 241);
+ _playingAnimFl = true;
+ }
+
+ if (_dodgeFl || _fallFl) { /* if want to dodge or fall */
+ if (!_playingAnimFl && (_monkeyPosition == 2))
+ _shouldDodgeFl = true;
+
+ if (!_playingAnimFl && (_monkeyPosition == 3))
+ _shouldFallFl = true;
+
+ switch (_game._trigger) {
+ case 228:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 229);
+ break;
+
+ case 229: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addTimer(35, 230);
+ }
+ break;
+
+ case 230:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 231);
+ break;
+
+ case 231: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 8, 10);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 232);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], -1);
+ _game._player._visible = false;
+ }
+ break;
+
+ case 232: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 10);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addTimer(2, 233);
+ _scene->_kernelMessages.reset();
+ if (_dodgeFl && (_monkeyPosition != 1) && (_monkeyPosition != 2))
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 34463, _game.getQuote(138));
+ if (_fallFl && (_monkeyPosition != 3))
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 34463, _game.getQuote(138));
+ }
+ break;
+
+ case 233:
+ _shootReadyFl = true;
+ break;
+
+ case 234:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _scene->_kernelMessages.reset();
+ if (_action.isAction(VERB_HOSE_DOWN, NOUN_BLOWGUN, NOUN_MONKEY)) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 16, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 11, 12);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 12, 239);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 235);
+ } else if (_action.isAction(VERB_SHOOT, NOUN_BLOWGUN, NOUN_MONKEY)) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 11, 12);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 235);
+ _vm->_sound->command(23);
+ }
+ break;
+
+ case 235: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 13);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addTimer(12, 236);
+ _forceFallFl = true;
+ _forceDodgeFl = true;
+ }
+ break;
+
+ case 236:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 14, 16);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(116, 131));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 237);
+ break;
+
+ case 237:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(1, 238);
+ break;
+
+ case 238:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ if (_dodgeFl)
+ _game._player._stepEnabled = true;
+
+ _startShootingInTimerFl = false;
+
+ if (_fallFl) {
+ _globals[kMonkeyStatus] = MONKEY_IS_GONE;
+ _game._objects.setRoom(OBJ_POISON_DARTS, NOWHERE);
+ }
+ _dodgeFl = false;
+ _fallFl = false;
+ _forceFallFl = false;
+ _forceDodgeFl = false;
+ _shouldFallFl = false;
+ _shouldDodgeFl = false;
+ break;
+
+ case 239:
+ _vm->_sound->command(23);
+ break;
+ }
+ }
+
+ if (_game._trigger == 100)
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(134));
+
+ if (_shootReadyFl && (_shouldFallFl || _shouldDodgeFl)) {
+ _scene->_sequences.addTimer(4, 234);
+ _shootReadyFl = false;
+ }
+}
+
+void Scene209::preActions() {
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_FIELD_TO_WEST))
+ _game._player._walkOffScreenSceneId = 208;
+
+ if (_globals[kMonkeyStatus] == MONKEY_HAS_BINOCULARS) {
+ if ((_action.isAction(VERB_SHOOT) || _action.isAction(VERB_HOSE_DOWN)) && _action.isTarget(NOUN_MONKEY)
+ && _action.isObject(NOUN_BLOWGUN) && _game._objects.isInInventory(OBJ_BLOWGUN) && _game._objects.isInInventory(OBJ_POISON_DARTS)) {
+ _game._player._prepareWalkPos = Common::Point(111, 129);
+ _game._player._prepareWalkFacing = FACING_NORTHEAST;
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_MONKEY) || _action.isAction(VERB_TALKTO, NOUN_MONKEY)) {
+ _game._player._prepareWalkPos = Common::Point(111, 129);
+ _game._player._prepareWalkFacing = FACING_NORTHEAST;
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ }
+ }
+}
+
+void Scene209::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(20912);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_ROCKY_AREA_TO_NORTH)) {
+ _scene->_nextSceneId = 203;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TALKTO, NOUN_MONKEY) && !_pitchFl && !_playingDialogFl) {
+ _scene->_sequences.addTimer(1, _dialogAbortVal);
+ _playingDialogFl = true;
+ _game._player._stepEnabled = false;
+ _action._inProgress = false;
+ return;
+ }
+
+ switch (_game._trigger) {
+ case 130:
+ _game._player._stepEnabled = true;
+ _playingDialogFl = false;
+ _action._inProgress = false;
+ return;
+
+ case 5:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 6, 180, _game.getQuote(139));
+ _action._inProgress = false;
+ return;
+
+ case 6:
+ _scene->_kernelMessages.add(Common::Point(180, 21), 0xFDFC, 0, 0, 60, _game.getQuote(151));
+ _scene->_sequences.addTimer(60, 130);
+ _dialogAbortVal = 7;
+ _action._inProgress = false;
+ return;
+
+ case 7:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 8, 180, _game.getQuote(140));
+ _action._inProgress = false;
+ return;
+
+ case 8:
+ _scene->_kernelMessages.add(Common::Point(180, 21), 0xFDFC, 0, 0, 60, _game.getQuote(149));
+ _scene->_sequences.addTimer(60, 130);
+ _dialogAbortVal = 9;
+ _action._inProgress = false;
+ return;
+
+ case 9:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 180, _game.getQuote(141));
+ _scene->_sequences.addTimer(200, 10);
+ _action._inProgress = false;
+ return;
+
+ case 10:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 11, 180, _game.getQuote(142));
+ _action._inProgress = false;
+ return;
+
+ case 11:
+ _scene->_kernelMessages.add(Common::Point(180, 21), 0xFDFC, 0, 0, 60, _game.getQuote(152));
+ _scene->_sequences.addTimer(60, 130);
+ _dialogAbortVal = 12;
+ _action._inProgress = false;
+ return;
+
+ case 12:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 130, _game.getQuote(143));
+ _scene->_sequences.addTimer(150, 13);
+ _action._inProgress = false;
+ return;
+
+ case 13:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 14, 180, _game.getQuote(145));
+ _action._inProgress = false;
+ return;
+
+ case 14:
+ _scene->_kernelMessages.add(Common::Point(180, 21), 0xFDFC, 0, 0, 60, _game.getQuote(151));
+ _scene->_sequences.addTimer(60, 130);
+ _dialogAbortVal = 15;
+ _action._inProgress = false;
+ return;
+
+ case 15:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 16, 180, _game.getQuote(146));
+ _action._inProgress = false;
+ return;
+
+ case 16:
+ _scene->_kernelMessages.add(Common::Point(180, 21), 0xFDFC, 0, 17, 60, _game.getQuote(154));
+ _action._inProgress = false;
+ return;
+
+ case 17:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 130, 60, _game.getQuote(147));
+ _dialogAbortVal = 18;
+ _action._inProgress = false;
+ return;
+
+ case 18:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 180, _game.getQuote(148));
+ _pitchFl = true;
+ _playingDialogFl = false;
+ _dialogAbortVal = 5;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_globals[kMonkeyStatus] == MONKEY_HAS_BINOCULARS) {
+ if ((_action.isAction(VERB_SHOOT) || _action.isAction(VERB_HOSE_DOWN)) && _action.isTarget(NOUN_MONKEY)
+ && _action.isObject(NOUN_BLOWGUN) && _game._objects.isInInventory(OBJ_BLOWGUN) && _game._objects.isInInventory(OBJ_POISON_DARTS)) {
+ if (_action.isAction(VERB_SHOOT, NOUN_BLOWGUN, NOUN_MONKEY) && !_startShootingInTimerFl) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 231);
+ _startShootingInTimerFl = true;
+ _game._player._stepEnabled = false;
+ _dodgeFl = true;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_HOSE_DOWN, NOUN_BLOWGUN, NOUN_MONKEY) && !_startShootingInTimerFl) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 228);
+ _game._player._stepEnabled = false;
+ _fallFl = true;
+ _startShootingInTimerFl = true;
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_MONKEY)) {
+ _pitchFl = true;
+ _game._player._stepEnabled = false;
+ _vm->_dialogs->show(20914);
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_PLANT_STALK) && (_game._trigger || _game._objects.isInRoom(OBJ_PLANT_STALK))) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMBD_2");
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[11]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._objects.addToInventory(OBJ_PLANT_STALK);
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _scene->_sequences.addTimer(4, 3);
+ _vm->_dialogs->showItem(OBJ_PLANT_STALK, 0x328);
+ break;
+
+ case 3:
+ _scene->_sprites.remove(_globals._spriteIndexes[11]);
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_BINOCULARS) && (_game._trigger || _game._objects.isInRoom(OBJ_BINOCULARS))) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites("*RXMBD_8");
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 3, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[10]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _binocularsDroppedFl = false;
+ _scene->_sequences.addTimer(4, 3);
+ break;
+
+ case 3:
+ _vm->_dialogs->showItem (OBJ_BINOCULARS, 0x51AF);
+ _scene->_sprites.remove(_globals._spriteIndexes[10]);
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_SKY)) {
+ _vm->_dialogs->show(20901);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_BAMBOO_LIKE_PLANT)) {
+ _vm->_dialogs->show(20902);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_MOUNTAINSIDE)) {
+ _vm->_dialogs->show(20903);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_GRASSY_FIELD)) {
+ _vm->_dialogs->show(20904);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_FIELD_TO_WEST)) {
+ _vm->_dialogs->show(20905);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_ROCKY_AREA_TO_NORTH)) {
+ _vm->_dialogs->show(20906);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_PLANT_STALK) && (_action._savedFields._mainObjectSource == 4)) {
+ _vm->_dialogs->show(20907);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_GIVE, NOUN_TWINKIFRUIT, NOUN_MONKEY) || _action.isAction(VERB_THROW, NOUN_TWINKIFRUIT, NOUN_MONKEY)) {
+ _vm->_dialogs->show(20909);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_TREES)) {
+ _vm->_dialogs->show(20913);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_THROW, NOUN_MONKEY) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))) {
+ if (!_action.isObject(NOUN_POISON_DARTS)) {
+ _vm->_dialogs->show(20915);
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_THROW, NOUN_POISON_DARTS, NOUN_MONKEY)) {
+ _vm->_dialogs->show(20916);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_PALM_TREE)) {
+ if (_globals[kMonkeyStatus] == MONKEY_HAS_BINOCULARS) {
+ if (_monkeyPosition == 1)
+ _vm->_dialogs->show(20917);
+ else
+ _vm->_dialogs->show(20918);
+ } else {
+ if (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY)
+ _vm->_dialogs->show(20917);
+ else
+ _vm->_dialogs->show(20919);
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_MELON_MUSH)) {
+ _vm->_dialogs->show(20920);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_MELON_MUSH)) {
+ _vm->_dialogs->show(20921);
+ _action._inProgress = false;
+ return;
+ }
+}
+
+/*****************************************************************************/
+
+Scene210::Scene210(MADSEngine *vm) : Scene2xx(vm) {
+ _curDialogNode = -1;
+ _nextHandsPlace = 0;
+ _twinkleAnimationType = 0;
+ _twinklesCurrentFrame = 0;
+ _shouldTalk = false;
+ _shouldFaceRex = false;
+ _shouldMoveHead = false;
+ _stopWalking = false;
+ _twinklesTalking = false;
+ _twinklesTalk2 = false;
+ _doorway = 0;
+ _subQuote2 = "";
+}
+
+void Scene210::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsSint32LE(_curDialogNode);
+ s.syncAsSint32LE(_nextHandsPlace);
+ s.syncAsSint32LE(_twinkleAnimationType);
+ s.syncAsSint32LE(_twinklesCurrentFrame);
+
+ s.syncAsByte(_shouldTalk);
+ s.syncAsByte(_shouldFaceRex);
+ s.syncAsByte(_shouldMoveHead);
+ s.syncAsByte(_stopWalking);
+ s.syncAsByte(_twinklesTalking);
+ s.syncAsByte(_twinklesTalk2);
+
+ s.syncAsSint32LE(_doorway);
+
+ s.syncString(_subQuote2);
+}
+
+void Scene210::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_DOORWAY);
+ _scene->addActiveVocab(VERB_WALK_THROUGH);
+}
+
+void Scene210::handleConversations() {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _game._player._stepEnabled = false;
+ Common::String curQuote = _game.getQuote(_action._activeAction._verbId);
+ if (_scene->_kernelMessages._talkFont->getWidth(curQuote, _scene->_textSpacing) > 200) {
+ Common::String subQuote1;
+ _game.splitQuote(curQuote, subQuote1, _subQuote2);
+ _scene->_kernelMessages.add(Common::Point(0, -14), 0x1110, 34, 0, 240, subQuote1);
+ _scene->_sequences.addTimer(60, 50);
+ } else {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 1, 120, curQuote);
+ }
+ } else if (_game._trigger == 50) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 240, _subQuote2);
+ _scene->_sequences.addTimer(180, 1);
+ } else {
+ if (_game._trigger == 1)
+ _scene->_kernelMessages.reset();
+
+ switch (_curDialogNode) {
+ case 1:
+ handleConversation1();
+ break;
+
+ case 2:
+ handleConversation2();
+ break;
+
+ case 3:
+ handleConversation3();
+ break;
+
+ case 5:
+ handleConversation5();
+ break;
+
+ case 6:
+ handleConversation6();
+ break;
+
+ case 7:
+ handleConversation7();
+ break;
+
+ case 8:
+ handleConversation8();
+ break;
+ }
+ }
+}
+
+void Scene210::handleConversation1() {
+ switch (_action._activeAction._verbId) {
+ case 180:
+ setDialogNode(2);
+ break;
+
+ case 181:
+ setDialogNode(6);
+ break;
+
+ case 182:
+ setDialogNode(4);
+ break;
+
+ case 183:
+ setDialogNode(9);
+ break;
+
+ case 184:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::handleConversation2() {
+ switch (_action._activeAction._verbId) {
+ case 187:
+ setDialogNode(3);
+ break;
+
+ case 188:
+ setDialogNode(4);
+ break;
+
+ case 189:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::handleConversation3() {
+ switch (_action._activeAction._verbId) {
+ case 193:
+ setDialogNode(6);
+ break;
+
+ case 194:
+ setDialogNode(5);
+ break;
+
+ case 195:
+ setDialogNode(4);
+ break;
+
+ case 196:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::handleConversation5() {
+ switch (_action._activeAction._verbId) {
+ case 204:
+ setDialogNode(6);
+ break;
+
+ case 205:
+ case 206:
+ setDialogNode(4);
+ break;
+
+ case 207:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::handleConversation6() {
+ switch (_action._activeAction._verbId) {
+ case 211:
+ setDialogNode(7);
+ break;
+
+ case 212:
+ setDialogNode(4);
+ break;
+
+ case 213:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::handleConversation7() {
+ switch (_action._activeAction._verbId) {
+ case 216:
+ case 217:
+ case 219:
+ setDialogNode(4);
+ break;
+
+ case 218:
+ setDialogNode(8);
+ break;
+
+ case 220:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::handleConversation8() {
+ switch (_action._activeAction._verbId) {
+ case 223:
+ case 224:
+ setDialogNode(4);
+ break;
+
+ case 225:
+ case 226:
+ setDialogNode(9);
+ break;
+
+ case 227:
+ setDialogNode(0);
+ break;
+ }
+}
+
+void Scene210::setDialogNode(int node) {
+ switch (node) {
+ case 0:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _shouldFaceRex = false;
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ _curDialogNode = 0;
+ break;
+
+ case 2:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 1;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(0xB9, -1, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+
+ case 2:
+ _nextHandsPlace = 0;
+ handleTwinklesSpeech(186, 0, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+
+ default:
+ _nextHandsPlace = 0;
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ newNode(2);
+ break;
+ }
+ break;
+
+ case 3:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 0;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(0xBE, -2, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+ case 2:
+ _nextHandsPlace = 2;
+ handleTwinklesSpeech(191, -1, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+ case 3:
+ _nextHandsPlace = 0;
+ handleTwinklesSpeech(192, 0, 0);
+ _scene->_sequences.addTimer(180, 4);
+ break;
+ default:
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ newNode(3);
+ break;
+ }
+ break;
+
+ case 4:
+ if (_game._trigger == 1) {
+ _nextHandsPlace = 1;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+
+ int quote;
+ if (_game._storyMode == STORYMODE_NAUGHTY)
+ quote = _vm->getRandomNumber(199, 201);
+ else
+ quote = _vm->getRandomNumber(197, 198);
+
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(quote, 0, 360);
+ _scene->_sequences.addTimer(120, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ } else {
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _shouldFaceRex = false;
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ case 5:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 2;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(0xCA, -1, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+
+ case 2:
+ _nextHandsPlace = 1;
+ handleTwinklesSpeech(0xCB, 0, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+
+ default:
+ _nextHandsPlace = 2;
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ newNode(5);
+ break;
+ }
+ break;
+
+ case 6:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 1;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(0xD0, -2, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+
+ case 2:
+ handleTwinklesSpeech(0xD1, -1, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+
+ case 3:
+ _nextHandsPlace = 1;
+ handleTwinklesSpeech(0xD2, 0, 0);
+ _scene->_sequences.addTimer(180, 4);
+ break;
+
+ default:
+ _nextHandsPlace = 0;
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ newNode(6);
+ break;
+ }
+ break;
+
+ case 7:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 2;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(0xD6, -1, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+
+ case 2:
+ handleTwinklesSpeech(0xD7, 0, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+
+ default:
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ newNode(7);
+ break;
+ }
+ break;
+
+ case 8:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 2;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ handleTwinklesSpeech(0xDD, -1, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+
+ case 2:
+ handleTwinklesSpeech(0xDE, 0, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+
+ default:
+ _shouldTalk = false;
+ _game._player._stepEnabled = true;
+ newNode(8);
+ break;
+ }
+ break;
+
+
+ case 9:
+ switch (_game._trigger) {
+ case 1:
+ _nextHandsPlace = 0;
+ _shouldTalk = true;
+ _game._player._stepEnabled = false;
+ if (_twinklesTalking) {
+ _scene->_userInterface.emptyConversationList();
+ _scene->_userInterface.setup(kInputConversation);
+ handleTwinklesSpeech(0xE4, -1, 0);
+ _scene->_sequences.addTimer(180, 2);
+ } else {
+ _scene->_sequences.addTimer(6, 1);
+ }
+ break;
+
+ case 2:
+ handleTwinklesSpeech(0xE5, 0, 0);
+ _scene->_sequences.addTimer(180, 3);
+ break;
+
+ case 3:
+ _twinkleAnimationType = 2;
+ _globals[kCurtainOpen] = true;
+ _game._player._visible = false;
+ _vm->_palette->lock();
+ _scene->_kernelMessages.reset();
+ _scene->freeAnimation();
+ _scene->_activeAnimation = nullptr;
+ _scene->resetScene();
+
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _game.loadQuoteSet(0xE6, 0xE9, 0xEA, 0xE7, 0xE8, 0);
+ _scene->loadAnimation(formAnimName('B', -1), 4);
+ break;
+
+ case 4: {
+ _globals._spriteIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 5);
+ _scene->_sequences.setDepth(_globals._spriteIndexes[8], 1);
+
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(160, 20), 0x1110, 32, 5, 180, _game.getQuote(231));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ break;
+
+ case 5: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(160, 40), 0xFDFC, 32, 6, 180, _game.getQuote(233));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ break;
+
+ case 6: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(160, 60), 0x1110, 32, 7, 180, _game.getQuote(232));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ break;
+
+ case 7: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(160, 80), 0xFDFC, 32, 8, 180, _game.getQuote(234));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ break;
+
+ case 8:
+ _globals[kTwinklesStatus] = TWINKLES_GONE;
+ _scene->_nextSceneId = 216;
+ break;
+ }
+ break;
+ }
+}
+
+void Scene210::handleTwinklesSpeech(int quoteId, int shiftX, uint32 delay) {
+ _scene->_kernelMessages.add(Common::Point(10, 70 + (shiftX * 14)), 0xFDFC, 0, 0, (delay == 0) ? 9999999 : delay, _game.getQuote(quoteId));
+}
+
+void Scene210::newNode(int node) {
+ _curDialogNode = node;
+
+ switch (_curDialogNode) {
+ case 1:
+ _conv1.start();
+ break;
+
+ case 2:
+ _conv2.start();
+ break;
+
+ case 3:
+ _conv3.start();
+ break;
+
+ case 5:
+ _conv5.start();
+ break;
+
+ case 6:
+ _conv6.start();
+ break;
+
+ case 7:
+ _conv7.start();
+ break;
+
+ case 8:
+ _conv8.start();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene210::restoreDialogNode(int node, int msgId, int posY) {
+ int curQuoteId = msgId;
+ int curY = 1 - posY;
+ for (int count = 0; count < posY; count++) {
+ handleTwinklesSpeech(curQuoteId, curY, 0);
+ curY++;
+ curQuoteId++;
+ }
+
+ newNode(node);
+}
+
+void Scene210::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', -1));
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _globals[kCurtainOpen] = 0;
+
+ if (_scene->_priorSceneId == 205)
+ _game._player._playerPos = Common::Point(277, 56);
+ else if (_scene->_priorSceneId == 215) {
+ _game._player._playerPos = Common::Point(168, 128);
+ _game._player._facing = FACING_SOUTH;
+ _globals[kCurtainOpen] = true;
+ } else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(308, 132);
+
+ if (!_globals[kCurtainOpen]) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ } else {
+ int idx = _scene->_dynamicHotspots.add(112, 395, -1, Common::Rect(163, 87, 163 + 19, 87 + 36));
+ _doorway = _scene->_dynamicHotspots.setPosition(idx, Common::Point(168, 127), FACING_NORTH);
+ _scene->_dynamicHotspots.setCursor(_doorway, CURSOR_GO_UP);
+ }
+
+ _game.loadQuoteSet(0x5A, 0x73, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB8, 0xB7,
+ 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
+ 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC,
+ 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0);
+
+ _conv1.setup(0x2E, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0);
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _conv1.set(0x2E, 0xB4, 0xB5, 0xB6, 0xB8, 0);
+
+ if (_game._widepipeCtr >= 2)
+ _conv1.write(0xB7, true);
+ }
+
+ bool sceneRevisited = _game._visitedScenes._sceneRevisited;
+ _conv2.setup(0x2F, 0xBC, 0xBB, 0xBD, sceneRevisited ? 0 : -1);
+ _conv3.setup(0x30, 0xC3, 0xC2, 0xC1, 0xC4, sceneRevisited ? 0 : -1);
+ _conv5.setup(0x31, 0xCD, 0xCC, 0xCE, 0xCF, sceneRevisited ? 0 : -1);
+ _conv6.setup(0x32, 0xD3, 0xD4, 0xD5, sceneRevisited ? 0 : -1);
+ _conv7.setup(0x33, 0xD8, 0xDA, 0xD9, 0xDB, 0xDC, sceneRevisited ? 0 : -1);
+ _conv8.setup(0x34, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, sceneRevisited ? 0 : -1);
+
+ _twinkleAnimationType = 0;
+ _twinklesCurrentFrame = 0;
+
+ if (_scene->_priorSceneId != -2) {
+ _shouldMoveHead = false;
+ _shouldFaceRex = false;
+ _shouldTalk = false;
+ _nextHandsPlace = 0;
+ _twinklesTalking = false;
+ _curDialogNode = 0;
+ _stopWalking = false;
+ _twinklesTalk2 = (_globals[kTwinklesApproached] > 0);
+ }
+
+ if (_globals[kTwinklesStatus] == 0) {
+ _scene->loadAnimation(formAnimName('A', -1));
+ _twinkleAnimationType = 1;
+ } else
+ _scene->_hotspots.activate(476, false);
+
+ if (_curDialogNode) {
+ int quote = 0;
+ int number = 0;
+
+ switch (_curDialogNode) {
+ case 1:
+ quote = 0xB3;
+ number = 1;
+ break;
+ case 2:
+ quote = 0xB9;
+ number = 2;
+ break;
+ case 3:
+ quote = 0xBE;
+ number = 3;
+ break;
+ case 5:
+ quote = 0xCA;
+ number = 2;
+ break;
+ case 6:
+ quote = 0xD0;
+ number = 3;
+ break;
+ case 7:
+ quote = 0xD6;
+ number = 2;
+ break;
+ case 8:
+ quote = 0xDD;
+ number = 2;
+ break;
+ }
+
+ restoreDialogNode(_curDialogNode, quote, number);
+ if (_scene->_activeAnimation)
+ _scene->_activeAnimation->setCurrentFrame(131);
+ }
+
+ _vm->_palette->setEntry(252, 63, 63, 10);
+ _vm->_palette->setEntry(253, 45, 45, 5);
+
+ sceneEntrySound();
+}
+
+void Scene210::step() {
+ if ((_twinkleAnimationType == 1) && _scene->_activeAnimation) {
+ if (_twinklesCurrentFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _twinklesCurrentFrame = _scene->_activeAnimation->getCurrentFrame();
+ int reset_frame = -1;
+ int random = _vm->getRandomNumber(1, 1000);
+
+ switch (_twinklesCurrentFrame) {
+ case 31:
+ case 58:
+ case 74:
+ case 108:
+ case 190:
+ if (_shouldFaceRex)
+ reset_frame = 108;
+ else if ((random <= 100) || _shouldMoveHead)
+ reset_frame = 74;
+ else if (random <= 300)
+ reset_frame = 58;
+ else if (random <= 500)
+ reset_frame = 31;
+ else
+ reset_frame = 0;
+ break;
+
+ case 80:
+ case 90:
+ _twinklesTalking = false;
+ if (_shouldMoveHead) {
+ reset_frame = 90;
+ } else if (_twinklesCurrentFrame == 90) {
+ if ((random <= 400) || _shouldFaceRex)
+ reset_frame = 99;
+ else
+ reset_frame = 79;
+ }
+ break;
+
+ case 98:
+ if (_shouldMoveHead)
+ reset_frame = 91;
+ break;
+
+ case 99:
+ if ((random <= 400) && !_shouldFaceRex)
+ reset_frame = 79;
+ break;
+
+ case 124:
+ case 136:
+ case 174:
+ case 143:
+ case 152:
+ if (_nextHandsPlace == 3)
+ reset_frame = 174;
+ else if (!_shouldFaceRex)
+ reset_frame = 174;
+ else if (_nextHandsPlace == 1)
+ reset_frame = 136;
+ else if (_nextHandsPlace == 2)
+ reset_frame = 152;
+ else if (_shouldTalk)
+ reset_frame = 124;
+ else
+ reset_frame = (random <= 200) ? 131 : 143;
+ break;
+
+ case 131:
+ if (_shouldTalk) {
+ switch (_nextHandsPlace) {
+ case 1:
+ reset_frame = 136;
+ break;
+ case 2:
+ reset_frame = 152;
+ break;
+ default:
+ reset_frame = 124;
+ break;
+ }
+ }
+ break;
+
+ case 138:
+ case 141:
+ if ((_nextHandsPlace == 0) || !_shouldFaceRex)
+ reset_frame = 141;
+ else if (_nextHandsPlace == 2)
+ reset_frame = 152;
+ else if (!_shouldTalk || (_twinklesCurrentFrame == 141))
+ reset_frame = 137;
+ break;
+
+ case 153:
+ case 169:
+ if ((_nextHandsPlace == 0) || !_shouldFaceRex)
+ reset_frame = 169;
+ else if (_nextHandsPlace == 1)
+ reset_frame = 136;
+ else if (_shouldTalk)
+ reset_frame = 153;
+ else
+ reset_frame = 162;
+ break;
+
+ case 162:
+ if (_shouldTalk) {
+ switch (_nextHandsPlace) {
+ case 0:
+ reset_frame = 124;
+ break;
+ case 1:
+ reset_frame = 136;
+ break;
+ default:
+ reset_frame = 153;
+ break;
+ }
+ }
+ break;
+ }
+
+ if (reset_frame >= 0) {
+ if (reset_frame != _scene->_activeAnimation->getCurrentFrame()) {
+ _scene->_activeAnimation->setCurrentFrame(reset_frame);
+ _twinklesCurrentFrame = reset_frame;
+ }
+
+ if ((reset_frame == 90) || (reset_frame == 91) || (reset_frame == 124) || (reset_frame == 153)
+ || ((reset_frame == 137) && _shouldTalk)) {
+ _twinklesTalking = true;
+ } else {
+ _twinklesTalking = false;
+ }
+ }
+ }
+ }
+
+ if ((_twinkleAnimationType == 2) && _scene->_activeAnimation) {
+ if (_twinklesCurrentFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _twinklesCurrentFrame = _scene->_activeAnimation->getCurrentFrame();
+ int reset_frame = -1;
+
+ if (_twinklesCurrentFrame == 53) {
+ _scene->_kernelMessages.add(Common::Point(151, 61), 0xFDFC, 32, 70, 180, _game.getQuote(230));
+ _shouldTalk = true;
+ } else if ((_twinklesCurrentFrame == 75) && _shouldTalk)
+ reset_frame = 60;
+
+ if ((reset_frame >= 0) && (reset_frame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(reset_frame);
+ _twinklesCurrentFrame = reset_frame;
+ }
+ }
+
+ if (_game._trigger == 70)
+ _shouldTalk = false;
+ }
+
+ if ((_twinkleAnimationType == 1) && (_scene->_rails.getNext() > 0)) {
+ _game._player.walk(Common::Point(214, 150), FACING_NORTHWEST);
+ _scene->_rails.resetNext();
+ _stopWalking = true;
+ }
+}
+
+void Scene210::preActions() {
+ _stopWalking = false;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_EAST))
+ _game._player._walkOffScreenSceneId = 211;
+}
+
+void Scene210::actions() {
+ if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_HUT_TO_NORTH)) {
+ _vm->_dialogs->show(21017);
+ } else if (_game._screenObjects._inputMode == 1) {
+ handleConversations();
+ } else if (_action.isAction(VERB_TALKTO, NOUN_NATIVE_WOMAN) ||
+ ((_game._player._playerPos == Common::Point(214, 150)) && (_game._player._facing == FACING_NORTHWEST) && (_twinkleAnimationType == 1) && _stopWalking)) {
+ switch (_game._trigger) {
+ case 0: {
+ _game._player._stepEnabled = false;
+ int quote;
+ if (_globals[kTwinklesApproached] == 0)
+ quote = 90;
+ else if (_globals[kTwinklesApproached] == 1)
+ quote = 115;
+ else
+ quote = 171;
+
+ _shouldFaceRex = true;
+ _nextHandsPlace = 0;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.addQuote(quote, 1, 120);
+ }
+ break;
+
+ case 1:
+ _shouldTalk = true;
+ if (!_twinklesTalking) {
+ _scene->_sequences.addTimer(6, 1);
+ } else {
+ if (_globals[kTwinklesApproached] == 0) {
+ handleTwinklesSpeech(0xAF, -1, 0);
+ handleTwinklesSpeech(0xB0, 0, 0);
+ } else if (_globals[kTwinklesApproached] == 1) {
+ handleTwinklesSpeech(0xB1, 0, 0);
+ } else {
+ int quote = _twinklesTalk2 ? 0xB3 : 0xB2;
+ _twinklesTalk2 = true;
+ handleTwinklesSpeech(quote, 0, 0);
+ }
+ _scene->_sequences.addTimer(60, 3);
+ }
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _shouldMoveHead = false;
+ _shouldTalk = false;
+
+ if (_globals[kTwinklesApproached] < 2)
+ _globals[kTwinklesApproached]++;
+
+ _conv1.start();
+ _curDialogNode = 1;
+ break;
+ }
+ } else if (_action.isAction(VERB_GIVE, NOUN_NATIVE_WOMAN) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))) {
+ switch (_game._trigger) {
+ case 0: {
+ int quote = _vm->getRandomNumber(172, 174);
+ _shouldMoveHead = true;
+ _game._player._stepEnabled = false;
+ handleTwinklesSpeech(quote, 0, 120);
+ _scene->_sequences.addTimer(120, 1);
+ }
+ break;
+
+ case 1:
+ _game._player._stepEnabled = true;
+ _shouldMoveHead = false;
+ break;
+ }
+ } else if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_NORTH) || _action.isAction(VERB_WALK_TOWARDS, NOUN_HUT_TO_NORTH)) {
+ _scene->_nextSceneId = 205;
+ } else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY)) {
+ _scene->_nextSceneId = 215;
+ } else if ((_action.isAction(VERB_PULL, NOUN_CURTAIN) || _action.isAction(VERB_OPEN, NOUN_CURTAIN)) && !_globals[kCurtainOpen]) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _game._player._stepEnabled = true;
+ _globals[kCurtainOpen] = true;
+ _doorway = _scene->_dynamicHotspots.add(112, 395, -1, Common::Rect(163, 87, 163 + 19, 87 + 36));
+ _scene->_dynamicHotspots.setPosition(_doorway, Common::Point(168, 127), FACING_NORTH);
+ _scene->_dynamicHotspots.setCursor(_doorway, CURSOR_GO_UP);
+ break;
+ }
+ } else if ((_action.isAction(VERB_PULL, NOUN_CURTAIN) || _action.isAction(VERB_CLOSE, NOUN_CURTAIN)) && _globals[kCurtainOpen]) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._player._stepEnabled = false;
+ _game._player._facing = FACING_NORTH;
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 12, 0, 0, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _game._player._stepEnabled = false;
+ break;
+ case 1:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->_sequences.addTimer(48, 2);
+ break;
+ case 2:
+ _scene->_dynamicHotspots.remove(_doorway);
+ _game._player._stepEnabled = true;
+ _globals[kCurtainOpen] = false;
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_HUT)) {
+ if (_globals[kTwinklesStatus] == TWINKLES_GONE) {
+ if (_game._storyMode == STORYMODE_NAUGHTY)
+ _vm->_dialogs->show(21003);
+ else
+ _vm->_dialogs->show(21002);
+ } else {
+ _vm->_dialogs->show(21001);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_BRA)) {
+ _vm->_dialogs->show(21004);
+ } else if (_action.isAction(VERB_LOOK, NOUN_HOTPANTS)) {
+ _vm->_dialogs->show(21005);
+ } else if (_action.isAction(VERB_TAKE, NOUN_HOTPANTS) || _action.isAction(VERB_TAKE, NOUN_BRA)) {
+ _vm->_dialogs->show(21006);
+ } else if (_action.isAction(VERB_LOOK, NOUN_STREAM)) {
+ _vm->_dialogs->show(21007);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BUSHY_FERN)) {
+ _vm->_dialogs->show(21008);
+ } else if (_action.isAction(VERB_LOOK, NOUN_VILLAGE_PATH)) {
+ _vm->_dialogs->show(21009);
+ } else if (_action.isAction(VERB_LOOK, NOUN_NATIVE_WOMAN)) {
+ _vm->_dialogs->show(21010);
+ } else if (_action.isAction(VERB_SHOOT, NOUN_NATIVE_WOMAN) || _action.isAction(VERB_HOSE_DOWN, NOUN_NATIVE_WOMAN)) {
+ _vm->_dialogs->show(21011);
+ } else if (_action.isAction(VERB_LOOK, NOUN_PATH_TO_NORTH)) {
+ _vm->_dialogs->show(21012);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CURTAIN)) {
+ _vm->_dialogs->show(21013);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CLOTHESLINE)) {
+ _vm->_dialogs->show(21014);
+ } else if (_action.isAction(VERB_TAKE, NOUN_CLOTHESLINE)) {
+ _vm->_dialogs->show(21015);
+ } else if (_action.isAction(VERB_LOOK, NOUN_HUT_TO_NORTH)) {
+ _vm->_dialogs->show(21016);
+ } else {
+ // Not handled
+ return;
+ }
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene211::Scene211(MADSEngine *vm) : Scene2xx(vm) {
+ _ambushFl = false;
+ _wakeFl = false;
+ _monkeyFrame = 0;
+ _scrollY = 0;
+ _monkeyTime = 0;
+}
+
+void Scene211::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsByte(_ambushFl);
+ s.syncAsByte(_wakeFl);
+
+ s.syncAsSint32LE(_monkeyFrame);
+ s.syncAsSint32LE(_scrollY);
+ s.syncAsUint32LE(_monkeyTime);
+}
+
+void Scene211::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_SLITHERING_SNAKE);
+}
+
+void Scene211::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*SC002Z2");
+ _wakeFl = false;
+
+ if (_scene->_priorSceneId == 210)
+ _game._player._playerPos = Common::Point(25, 148);
+ else if (_scene->_priorSceneId == 205) {
+ _game._player._playerPos = Common::Point(49, 133);
+ _game._player._facing = FACING_WEST;
+ _wakeFl = true;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->loadAnimation(formAnimName('A', -1), 100);
+ _scene->_activeAnimation->setCurrentFrame(169);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(310, 31);
+ _game._player._facing = FACING_SOUTHWEST;
+ }
+
+ if (_vm->getRandomNumber(1, 8) == 1) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(202, 126));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 8);
+ _scene->_sequences.setMotion(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, -200, 0);
+ _scene->_dynamicHotspots.add(324, 13, _globals._sequenceIndexes[2], Common::Rect(1, 1, 1 + 41, 1 + 10));
+ }
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+
+ _vm->_palette->setEntry(252, 63, 44, 30);
+ _vm->_palette->setEntry(253, 63, 20, 22);
+ _game.loadQuoteSet(0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 1, 0);
+
+ if (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY)
+ _scene->_kernelMessages.initRandomMessages(2,
+ Common::Rect(0, 0, 54, 30), 13, 2, 0xFDFC, 60,
+ 151, 152, 153, 154, 0);
+
+ _monkeyTime = _vm->_game->_scene._frameStartTime;
+ _scrollY = 30;
+
+ _ambushFl = false;
+ _monkeyFrame = 0;
+
+ sceneEntrySound();
+}
+
+void Scene211::step() {
+ if (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY) {
+ _scene->_kernelMessages.randomServer();
+
+ if (!_ambushFl && !_wakeFl && (_vm->_game->_scene._frameStartTime >= _monkeyTime)) {
+ int chanceMinor = _scene->_kernelMessages.checkRandom() * 4 + 1;
+ if (_scene->_kernelMessages.generateRandom(80, chanceMinor))
+ _vm->_sound->command(18);
+
+ _monkeyTime = _vm->_game->_scene._frameStartTime + 2;
+ }
+
+ if ((_game._player._playerPos == Common::Point(52, 132)) && (_game._player._facing == FACING_WEST) && !_game._player._moving &&
+ (_game._trigger || !_ambushFl)) {
+ switch (_game._trigger) {
+ case 0:
+ if (_game._objects.isInInventory(OBJ_BINOCULARS)) {
+ _ambushFl = true;
+ _monkeyFrame = 0;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_kernelMessages.reset();
+ _scene->loadAnimation(formAnimName('A', -1), 90);
+ _vm->_sound->command(19);
+ int count = (int)_game._objects._inventoryList.size();
+ for (int idx = 0; idx < count; idx++) {
+ if ((_game._objects._inventoryList[idx] == OBJ_BINOCULARS) && (_scene->_userInterface._selectedInvIndex != idx))
+ _scene->_userInterface.selectObject(idx);
+ }
+ }
+ break;
+
+ case 90:
+ _vm->_sound->command(10);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._playerPos = Common::Point(49, 133);
+ _ambushFl = false;
+ _globals[kMonkeyStatus] = MONKEY_HAS_BINOCULARS;
+ break;
+ }
+ }
+ }
+
+ if (_ambushFl && (_scene->_activeAnimation->getCurrentFrame() > _monkeyFrame)) {
+ _monkeyFrame = _scene->_activeAnimation->getCurrentFrame();
+ switch (_monkeyFrame) {
+ case 2: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(12, 4), 0xFDFC, 0, 0, 60, _game.getQuote(157));
+ _scene->_kernelMessages.setQuoted(msgIndex, 2, true);
+ }
+ break;
+
+ case 12: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(35, 20), 0xFDFC, 0, 0, 60, _game.getQuote(155));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ }
+ break;
+
+ case 42: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(60, 45), 0xFDFC, 0, 0, 60, _game.getQuote(156));
+ _scene->_kernelMessages.setQuoted(msgIndex, 6, true);
+ }
+ break;
+
+ case 73:
+ _scene->_kernelMessages.add(Common::Point(102, 95), 0xFDFC, 32, 0, 75, _game.getQuote(157));
+ break;
+
+ case 90: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(102, 95), 0xFDFC, 32, 0, 60, _game.getQuote(158));
+ _scene->_kernelMessages.setQuoted(msgIndex, 6, true);
+ }
+ break;
+
+ case 97:
+ _scene->_userInterface.selectObject(-1);
+ _game._objects.removeFromInventory(OBJ_BINOCULARS, 1);
+ break;
+
+ case 177: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(161));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+
+ case 181: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(162));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+
+ case 188: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(163));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+
+ case 200: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(164));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+ }
+ }
+
+ if (_wakeFl) {
+ if (_game._trigger == 100) {
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _wakeFl = false;
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() > _monkeyFrame) {
+ _monkeyFrame = _scene->_activeAnimation->getCurrentFrame();
+ switch (_scene->_activeAnimation->getCurrentFrame()) {
+ case 177: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(165));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+
+ case 181: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(166));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+
+ case 188: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(167));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+
+ case 200: {
+ int msgIndex = _scene->_kernelMessages.add(Common::Point(63, _scrollY), 0x1110, 0, 0, 180, _game.getQuote(168));
+ _scene->_kernelMessages.setQuoted(msgIndex, 4, true);
+ _scrollY += 14;
+ }
+ break;
+ }
+ }
+ }
+}
+
+void Scene211::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_JUNGLE_PATH) && _game._objects.isInInventory(OBJ_BINOCULARS) && (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY)
+ && (_scene->_customDest.x <= 52) && (_scene->_customDest.y >= 132))
+ _game._player.walk(Common::Point(52, 132), FACING_WEST);
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_WEST)) {
+ if (_game._objects.isInInventory(OBJ_BINOCULARS) && (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY))
+ _game._player.walk(Common::Point(52, 132), FACING_WEST);
+ else
+ _game._player._walkOffScreenSceneId = 210;
+ }
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_NORTHEAST))
+ _game._player._walkOffScreenSceneId = 207;
+}
+
+void Scene211::actions() {
+ if (_action._lookFlag && (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY))
+ _vm->_dialogs->show(21111);
+ else if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_PALM_TREE))
+ _vm->_dialogs->show(21116);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUSHY_FERN))
+ _vm->_dialogs->show(21101);
+ else if (_action.isAction(VERB_LOOK, NOUN_JUNGLE_PATH))
+ _vm->_dialogs->show(21102);
+ else if (_action.isAction(VERB_LOOK, NOUN_PALM_TREE)) {
+ if (_globals[kMonkeyStatus] == MONKEY_AMBUSH_READY) {
+ if (_game._storyMode == STORYMODE_NAUGHTY)
+ _vm->_dialogs->show(21103);
+ else
+ _vm->_dialogs->show(21104);
+ } else {
+ _vm->_dialogs->show(21105);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_THICK_UNDERGROWTH)) {
+ if (_game._storyMode == STORYMODE_NAUGHTY)
+ _vm->_dialogs->show(21106);
+ else
+ _vm->_dialogs->show(21107);
+ } else if (_action.isAction(VERB_LOOK, NOUN_JUNGLE))
+ _vm->_dialogs->show(21108);
+ else if (_action.isAction(VERB_LOOK, NOUN_PATH_TO_NORTHEAST))
+ _vm->_dialogs->show(21109);
+ else if (_action.isAction(VERB_LOOK, NOUN_PATH_TO_WEST))
+ _vm->_dialogs->show(21110);
+ else if (_action.isAction(VERB_LOOK, NOUN_SLITHERING_SNAKE))
+ _vm->_dialogs->show(21113);
+ else if (_action.isAction(VERB_TAKE, NOUN_SLITHERING_SNAKE))
+ _vm->_dialogs->show(21114);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(21115);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene212::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_BOUNCING_REPTILE);
+}
+
+void Scene212::enter() {
+ // CHECKME: Some useless variables have been remove here
+
+ if (_scene->_priorSceneId == 208) {
+ _game._player._playerPos = Common::Point(195, 85);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(67, 117);
+ _game._player._facing = FACING_NORTHEAST;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene212::step() {
+// CHECKME: Could we move the dino?
+}
+
+void Scene212::preActions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_CAVE_ENTRANCE))
+ _game._player._walkOffScreenSceneId = 111;
+}
+
+void Scene212::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(21209);
+ else if (_action.isAction(VERB_WALK_TOWARDS) && (_action.isObject(NOUN_FIELD_TO_NORTH) || _action.isObject(NOUN_MOUNTAINS)))
+ _scene->_nextSceneId = 208;
+ else if (_action.isAction(VERB_WALK_TOWARDS, NOUN_CAVE))
+ _scene->_nextSceneId = 111;
+ else if (_action.isAction(VERB_LOOK, NOUN_GRASS))
+ _vm->_dialogs->show(21201);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCKS))
+ _vm->_dialogs->show(21202);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAVE_ENTRANCE))
+ _vm->_dialogs->show(21203);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKY))
+ _vm->_dialogs->show(21204);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIELD_TO_NORTH))
+ _vm->_dialogs->show(21205);
+ else if (_action.isAction(VERB_LOOK, NOUN_TREES))
+ _vm->_dialogs->show(21206);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLANTS))
+ _vm->_dialogs->show(21207);
+ else if (_action.isAction(VERB_LOOK, NOUN_MOUNTAINS))
+ _vm->_dialogs->show(21208);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene213::setup() {
+ _game._player._spritesPrefix = "";
+
+ // The original is calling Scene2xx::setAAName()
+ _game._aaName = Resources::formatAAName(2);
+}
+
+void Scene213::enter() {
+ if (_globals[kMeteorologistWatch] != METEOROLOGIST_NORMAL)
+ _handSpriteId = _scene->_sprites.addSprites("*METHAND");
+ else if (_globals[kSexOfRex] == REX_MALE)
+ _handSpriteId = _scene->_sprites.addSprites("*REXHAND");
+ else
+ _handSpriteId = _scene->_sprites.addSprites("*ROXHAND");
+
+ teleporterEnter();
+
+ // The original is calling Scene2xx::sceneEntrySound()
+ if (_vm->_musicFlag) {
+ if (_globals[kMeteorologistWatch] == METEOROLOGIST_NORMAL)
+ _vm->_sound->command(1);
+ else
+ _vm->_sound->command(9);
+ } else {
+ _vm->_sound->command(2);
+ }
+}
+
+void Scene213::step() {
+ teleporterStep();
+}
+
+void Scene213::actions() {
+ if (teleporterActions()) {
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_CONTROL_PANEL))
+ _vm->_dialogs->show(21301);
+ else if (_action.isAction(VERB_LOOK, NOUN_KEYPAD) || _action.isAction (VERB_INSPECT, NOUN_KEYPAD))
+ _vm->_dialogs->show(21302);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(21303);
+ else if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT) || _action.isAction(VERB_PEER_THROUGH, NOUN_VIEWPORT))
+ _vm->_dialogs->show(21304);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEVICE))
+ _vm->_dialogs->show(21305);
+ else if (_action.isAction(VERB_LOOK, NOUN_0_KEY) || _action.isAction(VERB_LOOK, NOUN_1_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_2_KEY) || _action.isAction(VERB_LOOK, NOUN_3_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_4_KEY) || _action.isAction(VERB_LOOK, NOUN_5_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_6_KEY) || _action.isAction(VERB_LOOK, NOUN_7_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_8_KEY) || _action.isAction(VERB_LOOK, NOUN_9_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_SMILE_KEY) || _action.isAction(VERB_LOOK, NOUN_FROWN_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_ENTER_KEY))
+ _vm->_dialogs->show(21306);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene214::Scene214(MADSEngine *vm) : Scene2xx(vm) {
+ _devilTime = 0;
+ _devilRunningFl = false;
+}
+
+void Scene214::synchronize(Common::Serializer &s) {
+ Scene2xx::synchronize(s);
+
+ s.syncAsUint32LE(_devilTime);
+ s.syncAsByte(_devilRunningFl);
+}
+
+void Scene214::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_CAPTIVE_CREATURE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene214::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('e', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('e', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('t', -1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXMRD_7");
+
+ _devilTime = _game._player._priorTimer;
+ _devilRunningFl = false;
+
+ if (_game._objects.isInRoom(OBJ_POISON_DARTS)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(103, 86));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 11);
+ } else {
+ _scene->_hotspots.activate(NOUN_POISON_DARTS, false);
+ }
+
+ if (_game._objects.isInRoom(OBJ_BLOWGUN)) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(90, 87));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 13);
+ } else {
+ _scene->_hotspots.activate(NOUN_BLOWGUN, false);
+ }
+
+ if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(191, 152);
+
+ sceneEntrySound();
+}
+
+void Scene214::step() {
+ if ((_game._player._priorTimer - _devilTime > 800) && !_devilRunningFl) {
+ _devilRunningFl = true;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 6, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 2);
+ _scene->_dynamicHotspots.add(451, 13, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ }
+
+ if (_devilRunningFl) {
+ switch (_game._trigger) {
+ case 71: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 5, 0, 0);
+ _scene->_sequences.updateTimeout(oldIdx, _globals._sequenceIndexes[3]);
+ _scene->_dynamicHotspots.add(451, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 5, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ }
+ break;
+
+ case 72: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.updateTimeout(oldIdx, _globals._sequenceIndexes[3]);
+ _scene->_dynamicHotspots.add(451, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 9, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 2);
+ _devilTime = _game._player._priorTimer;
+ _devilRunningFl = false;
+ }
+ break;
+ }
+ }
+}
+
+void Scene214::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(21427);
+ else if (_action.isAction(VERB_WALK_OUTSIDE, NOUN_HUT))
+ _scene->_nextSceneId = 207;
+ else if (_action.isAction(VERB_TAKE, NOUN_POISON_DARTS) && (_game._trigger || _game._objects.isInRoom(OBJ_POISON_DARTS))) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], true, 6, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], true, 6, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._objects.addToInventory(OBJ_POISON_DARTS);
+ _scene->_hotspots.activate(NOUN_POISON_DARTS, false);
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(48, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_POISON_DARTS, 0x53A5);
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_BLOWGUN) && (_game._trigger || _game._objects.isInRoom(OBJ_BLOWGUN))) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _game._objects.addToInventory(OBJ_BLOWGUN);
+ _scene->_hotspots.activate(NOUN_BLOWGUN, false);
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(48, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_BLOWGUN, 0x329);
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_WINDOW))
+ _vm->_dialogs->show(21401);
+ else if (_action.isAction(VERB_LOOK, NOUN_EXPERIMENT_CAGE))
+ _vm->_dialogs->show(21402);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAPTIVE_CREATURE))
+ _vm->_dialogs->show(21403);
+ else if (_action.isAction(VERB_LOOK, NOUN_BEAR_RUG))
+ _vm->_dialogs->show(21404);
+ else if (_action.isAction(VERB_LOOK, NOUN_TROPHY))
+ _vm->_dialogs->show(21405);
+ else if (_action.isAction(VERB_LOOK, NOUN_LARGE_BOWL)) {
+ if (_game._storyMode == STORYMODE_NAUGHTY) {
+ _vm->_dialogs->show(21406);
+ } else {
+ _vm->_dialogs->show(21407);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_SPECIMEN_JARS))
+ _vm->_dialogs->show(21408);
+ else if (_action.isAction(VERB_TAKE, NOUN_LARGE_BOWL) || _action.isAction(VERB_TAKE, NOUN_SPECIMEN_JARS))
+ _vm->_dialogs->show(21409);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHRUNKEN_HEADS))
+ _vm->_dialogs->show(21410);
+ else if (_action.isAction(VERB_TAKE, NOUN_SHRUNKEN_HEADS) || _action.isAction(VERB_TAKE, NOUN_LARGE_HEADS))
+ _vm->_dialogs->show(21411);
+ else if (_action.isAction(VERB_LOOK, NOUN_LARGE_HEADS))
+ _vm->_dialogs->show(21428);
+ else if (_action.isAction(VERB_LOOK, NOUN_POISON_DARTS) && (_action._savedFields._mainObjectSource == 4))
+ _vm->_dialogs->show(21412);
+ else if (_action.isAction(VERB_OPEN, NOUN_EXPERIMENT_CAGE))
+ _vm->_dialogs->show(21414);
+ else if (_action.isAction(VERB_TALKTO, NOUN_CAPTIVE_CREATURE))
+ _vm->_dialogs->show(21415);
+ else if (_action.isAction(VERB_GIVE, NOUN_TWINKIFRUIT, NOUN_CAPTIVE_CREATURE))
+ _vm->_dialogs->show(21416);
+ else if (_action.isAction(VERB_SHOOT, NOUN_BLOWGUN, NOUN_CAPTIVE_CREATURE) || _action.isAction(VERB_HOSE_DOWN, NOUN_BLOWGUN, NOUN_CAPTIVE_CREATURE))
+ _vm->_dialogs->show(21417);
+ else if (_action.isAction(VERB_LOOK, NOUN_BIG_HEADS))
+ _vm->_dialogs->show(21418);
+ else if (_action.isAction(VERB_TAKE, NOUN_BIG_HEADS))
+ _vm->_dialogs->show(21419);
+ else if (_action.isAction(VERB_TAKE, NOUN_BEAR_RUG))
+ _vm->_dialogs->show(21420);
+ else if (_action.isAction(VERB_LOOK, NOUN_FLOOR_OF_HUT))
+ _vm->_dialogs->show(21421);
+ else if (_action.isAction(VERB_LOOK, NOUN_BLOWGUN))
+ _vm->_dialogs->show(21422);
+ else if (_action.isAction(VERB_LOOK, NOUN_TABLE)) {
+ if (_game._objects.isInRoom(OBJ_POISON_DARTS) && _game._objects.isInRoom(OBJ_BLOWGUN)) {
+ _vm->_dialogs->show(21423);
+ } else if (_game._objects.isInRoom(OBJ_POISON_DARTS) && !_game._objects.isInRoom(OBJ_BLOWGUN)) {
+ _vm->_dialogs->show(21424);
+ } else if (!_game._objects.isInRoom(OBJ_POISON_DARTS) && _game._objects.isInRoom(OBJ_BLOWGUN)) {
+ _vm->_dialogs->show(21425);
+ } else {
+ _vm->_dialogs->show(21426);
+ }
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene215::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene215::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('e', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 0));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle (_globals._spriteIndexes[1], false, 7, 0, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(235, 83));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ if (_globals[kSexOfRex] == REX_MALE)
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMRC_9");
+ else
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*ROXRC_9");
+
+ if (_scene->_priorSceneId == 216) {
+ _game._player._playerPos = Common::Point(140, 119);
+ _game._player._facing = FACING_SOUTHWEST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.addTimer(120, 70);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(204, 152);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ _game.loadQuoteSet(0xA9, 0xAA, 0);
+ sceneEntrySound();
+}
+
+void Scene215::step() {
+ if (_game._trigger == 70) {
+ _scene->_sequences.remove (_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ }
+
+ if (_game._trigger == 71) {
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+}
+
+void Scene215::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(21509);
+ else if (_action.isAction(VERB_TAKE, NOUN_TWINKIFRUIT)) {
+ if (!_game._objects.isInInventory(OBJ_TWINKIFRUIT) || _game._trigger) {
+ switch (_game._trigger) {
+ case 0:
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_LOOP, 0, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _game._objects.addToInventory(OBJ_TWINKIFRUIT);
+ _vm->_dialogs->showItem(OBJ_TWINKIFRUIT, 0x5404);
+ }
+ break;
+
+ case 1:
+ if (!_game._objects.isInInventory(OBJ_TWINKIFRUIT)) {
+ _game._objects.addToInventory(OBJ_TWINKIFRUIT);
+ _vm->_dialogs->showItem(OBJ_TWINKIFRUIT, 0x5404);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ break;
+ }
+ } else {
+ int idx = _vm->getRandomNumber(169, 170);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(idx));
+ }
+ } else if (_action.isAction(VERB_WALK_OUTSIDE, NOUN_HUT))
+ _scene->_nextSceneId = 210;
+ else if (_action.isAction(VERB_LOOK, NOUN_BEAR_RUG))
+ _vm->_dialogs->show(21501);
+ else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(21502);
+ else if (_action.isAction(VERB_LOOK, NOUN_WELCOME_MAT))
+ _vm->_dialogs->show(21503);
+ else if (_action.isAction(VERB_LOOK, NOUN_LOVE_ALTAR))
+ _vm->_dialogs->show(21504);
+ else if (_action.isAction(VERB_LOOK, NOUN_WINDOW))
+ _vm->_dialogs->show(21505);
+ else if (_action.isAction(VERB_LOOK, NOUN_PICTURE))
+ _vm->_dialogs->show(21506);
+ else if (_action.isAction(VERB_LOOK, NOUN_TWINKIFRUIT) && (_action._savedFields._mainObjectSource == 4))
+ _vm->_dialogs->show(21507);
+ else if (_action.isAction(VERB_TAKE, NOUN_BEAR_RUG))
+ _vm->_dialogs->show(21510);
+ else if (_action.isAction(VERB_TAKE, NOUN_LOVE_ALTAR))
+ _vm->_dialogs->show(21511);
+ else if (_action.isAction(VERB_LOOK, NOUN_BAG_OF_TWINKIFRUITS))
+ _vm->_dialogs->show(21512);
+ else if (_action.isAction(VERB_TAKE, NOUN_BAG_OF_TWINKIFRUITS))
+ _vm->_dialogs->show(21513);
+ else if (_action.isAction(VERB_TAKE, NOUN_WELCOME_MAT))
+ _vm->_dialogs->show(21514);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene216::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene216::enter() {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+
+ _scene->_userInterface.emptyConversationList();
+ _scene->_userInterface.setup(kInputConversation);
+ _scene->loadAnimation(formAnimName('A', -1), 60);
+
+ sceneEntrySound();
+}
+
+void Scene216::step() {
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 215;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes2.h b/engines/mads/nebular/nebular_scenes2.h
new file mode 100644
index 0000000000..c860db9470
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes2.h
@@ -0,0 +1,325 @@
+/* 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 MADS_NEBULAR_SCENES2_H
+#define MADS_NEBULAR_SCENES2_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene2xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+
+ void sceneEntrySound();
+public:
+ Scene2xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene201 : public Scene2xx {
+private:
+ bool _pterodactylFlag;
+
+public:
+ Scene201(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene202 : public Scene2xx {
+private:
+ bool _activeMsgFl, _ladderTopFl, _waitingMeteoFl, _toStationFl, _toTeleportFl;
+ int _ladderHotspotId, _lastRoute, _stationCounter, _meteoFrame;
+ uint32 _meteoClock1, _meteoClock2, _startTime;
+ bool _meteorologistSpecial;
+
+ int subStep1(int randVal);
+ int subStep2(int randVal);
+ int subStep3(int randVal);
+ int subStep4(int randVal);
+
+public:
+ Scene202(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+
+ void setRandomKernelMessage();
+};
+
+class Scene203 : public Scene2xx {
+private:
+ bool _rhotundaEat2Fl, _rhotundaEatFl;
+
+public:
+ Scene203(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene205 : public Scene2xx {
+private:
+ uint32 _lastFishTime, _chickenTime;
+ bool _beingKicked;
+ int _kernelMessage;
+ Conversation _dialog1;
+
+ void handleWomanSpeech(int quoteId);
+
+public:
+ Scene205(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene207 : public Scene2xx {
+private:
+ bool _vultureFl, _spiderFl, _eyeFl;
+ int _spiderHotspotId, _vultureHotspotId;
+ int32 _spiderTime, _vultureTime;
+
+ void moveVulture();
+ void moveSpider();
+
+public:
+ Scene207(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene208 : public Scene2xx {
+private:
+ bool _rhotundaTurnFl, _boundingFl;
+ int32 _rhotundaTime;
+
+ void updateTrap();
+ void subAction(int mode);
+
+public:
+ Scene208(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene209 : public Scene2xx {
+private:
+ bool _dodgeFl, _forceDodgeFl, _shouldDodgeFl;
+ bool _pitchFl;
+ bool _fallFl, _forceFallFl, _shouldFallFl;
+ bool _playingAnimFl, _playingDialogFl;
+ int _pauseMode, _pauseCounterThreshold, _pauseCounter;
+ bool _removeMonkeyFl;
+ int _monkeyPosition;
+ bool _shootReadyFl, _startShootingInTimerFl, _shootMissedLastFl;
+ bool _binocularsDroppedFl;
+ int _dialogAbortVal;
+ int _counter;
+
+ void handlePause();
+ void initPauseCounterThreshold();
+ void handlePeek();
+ void handleVerticalMove();
+ void handleLookStay();
+ void handleLookRight();
+ void handleBlink();
+ void handleGetBinoculars();
+ void handleStandFromPeek();
+ void handleDodge();
+ void handleBinocularBlink();
+ void handleBinocularScan();
+ void handleJumpInTree();
+ void handleTongue();
+ void handleMonkeyFall();
+ void handleJumpAndHide();
+ void handleMonkeyEating();
+ void handleMonkey1();
+ void handleStandBlink();
+ void handleMonkey2();
+
+public:
+ Scene209(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene210 : public Scene2xx {
+private:
+ int _curDialogNode;
+ int _nextHandsPlace;
+ int _twinkleAnimationType;
+ int _twinklesCurrentFrame;
+ bool _shouldTalk, _shouldFaceRex, _shouldMoveHead;
+ bool _stopWalking;
+ bool _twinklesTalking;
+ bool _twinklesTalk2;
+ int _doorway;
+ Common::String _subQuote2;
+ Conversation _conv1, _conv2, _conv3;
+ Conversation _conv5, _conv6, _conv7, _conv8;
+
+ void handleConversations();
+ void handleConversation1();
+ void handleConversation2();
+ void handleConversation3();
+ void handleConversation5();
+ void handleConversation6();
+ void handleConversation7();
+ void handleConversation8();
+ void setDialogNode(int node);
+ void handleTwinklesSpeech(int quoteId, int shiftX, uint32 delay);
+ void newNode(int node);
+ void restoreDialogNode(int node, int msgId, int posY);
+
+public:
+ Scene210(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene211 : public Scene2xx {
+private:
+ bool _ambushFl, _wakeFl;
+ int _monkeyFrame, _scrollY;
+ uint32 _monkeyTime;
+
+public:
+ Scene211(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene212 : public Scene2xx {
+public:
+ Scene212(MADSEngine *vm) : Scene2xx(vm) {}
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene213 : public SceneTeleporter {
+public:
+ Scene213(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene214 : public Scene2xx {
+private:
+ uint32 _devilTime;
+ bool _devilRunningFl;
+
+public:
+ Scene214(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene215 : public Scene2xx {
+public:
+ Scene215(MADSEngine *vm) : Scene2xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene216 : public Scene2xx {
+public:
+ Scene216(MADSEngine *vm) : Scene2xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions() {};
+};
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES2_H */
diff --git a/engines/mads/nebular/nebular_scenes3.cpp b/engines/mads/nebular/nebular_scenes3.cpp
new file mode 100644
index 0000000000..a963484bd0
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes3.cpp
@@ -0,0 +1,5818 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes3.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene3xx::setAAName() {
+ _game._aaName = Resources::formatAAName(4);
+}
+
+void Scene3xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+
+ Common::String oldName = _game._player._spritesPrefix;
+
+ if (_globals[kSexOfRex] == REX_MALE)
+ _game._player._spritesPrefix = "RXM";
+ else
+ _game._player._spritesPrefix = "ROX";
+
+ if ((_scene->_nextSceneId == 313) || (_scene->_nextSceneId == 366)
+ || ((_scene->_nextSceneId >= 301) && (_scene->_nextSceneId <= 303))
+ || ((_scene->_nextSceneId == 304) && (_scene->_currentSceneId == 303))
+ || ((_scene->_nextSceneId == 311) && (_scene->_currentSceneId == 304))
+ || ((_scene->_nextSceneId >= 308) && (_scene->_nextSceneId <= 310))
+ || ((_scene->_nextSceneId >= 319) && (_scene->_nextSceneId <= 322))
+ || ((_scene->_nextSceneId >= 387) && (_scene->_nextSceneId <= 391))) {
+ _game._player._spritesPrefix = "";
+ _game._player._spritesChanged = true;
+ }
+
+ _game._player._scalingVelocity = true;
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+void Scene3xx::sceneEntrySound() {
+ if (!_vm->_musicFlag) {
+ _vm->_sound->command(2);
+ return;
+ }
+
+ switch (_scene->_nextSceneId) {
+ case 301:
+ case 302:
+ case 303:
+ case 304:
+ case 308:
+ case 309:
+ case 310:
+ _vm->_sound->command(11);
+ break;
+
+ case 311:
+ if (_scene->_priorSceneId == 304)
+ _vm->_sound->command(11);
+ else
+ _vm->_sound->command(10);
+ break;
+
+ case 313:
+ case 316:
+ case 320:
+ case 322:
+ case 357:
+ case 358:
+ case 359:
+ case 360:
+ case 361:
+ case 387:
+ case 388:
+ case 389:
+ case 390:
+ case 391:
+ case 399:
+ _vm->_sound->command(10);
+ break;
+
+ case 318:
+ if ((_scene->_priorSceneId == 357) || (_scene->_priorSceneId == 407))
+ _vm->_sound->command(10);
+ else if (_scene->_priorSceneId == 319)
+ _vm->_sound->command(16);
+ else
+ _vm->_sound->command(3);
+
+ _vm->_sound->command(50);
+ break;
+
+ case 319:
+ _vm->_sound->command(16);
+ break;
+
+ case 321:
+ _vm->_sound->command(18);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene3xx::initForceField(ForceField *force, bool flag) {
+ force->_flag = flag;
+ force->_vertical = 0;
+ force->_horizontal = 0;
+ force->_timer = 0;
+
+ for (int count = 0; count < 40; count++)
+ force->_seqId[count] = -1;
+
+ if (force->_flag)
+ _vm->_sound->command(24);
+}
+
+int Scene3xx::computeScale(int low, int high, int id) {
+ int diff = high - (low + 2);
+ int quotient = diff / 20;
+ int remainder = diff % 20;
+ int value = low + 2 + (quotient * id) + (remainder / (id + 1));
+
+ return (value);
+}
+
+void Scene3xx::handleForceField(ForceField *force, int *sprites) {
+ if (_game._trigger >= 150) {
+ int id = _game._trigger - 150;
+ if (id < 40) {
+ if (id < 20)
+ force->_vertical--;
+ else
+ force->_horizontal--;
+
+ force->_seqId[id] = -1;
+ }
+ return;
+ }
+
+ if (!force->_flag || (_scene->_frameStartTime < force->_timer) || (force->_vertical + force->_horizontal >= 5))
+ return;
+
+ if (_vm->getRandomNumber(1, 1000) <= (200 + ((40 - (force->_vertical + force->_horizontal)) << 5))) {
+ int id = -1;
+ for (int i = 0; i < 100; i++) {
+ int randIdx = _vm->getRandomNumber(0, 39);
+ if (force->_seqId[randIdx] < 0) {
+ id = randIdx;
+ break;
+ }
+ }
+
+ if (id < 0) {
+ for (int i = 0; i < 40; i++) {
+ if (force->_seqId[i] < 0) {
+ id = i;
+ break;
+ }
+ }
+ }
+
+ int speedX, speedY;
+ int posX, posY;
+ int randVal = _vm->getRandomNumber(1, 100);
+ int spriteId;
+ bool mirror;
+
+ if (id >= 20) {
+ spriteId = 2;
+ mirror = (randVal <= 50);
+ posX = mirror ? 315 : 5;
+ posY = computeScale(15, 119, id - 20);
+ speedX = 1000 * (mirror ? -1 : 1);
+ speedY = 0;
+ } else if (randVal <= 50) {
+ spriteId = 1;
+ mirror = false;
+ posX = computeScale(21, 258, id);
+ posY = 0;
+ speedX = 0;
+ speedY = 600;
+ } else {
+ spriteId = 0;
+ mirror = false;
+ posX = computeScale(21, 258, id);
+ posY = 155;
+ speedX = 0;
+ speedY = -600;
+ }
+
+ if (id >= 0) {
+ force->_seqId[id] = _scene->_sequences.addSpriteCycle(sprites[spriteId], mirror, 2, 0, 0, 0);
+ _scene->_sequences.setDepth(force->_seqId[id], 8);
+ _scene->_sequences.setPosition(force->_seqId[id], Common::Point(posX, posY));
+ _scene->_sequences.setMotion(force->_seqId[id], 2, speedX, speedY);
+ _scene->_sequences.addSubEntry(force->_seqId[id], SEQUENCE_TRIGGER_EXPIRE, 0, 150 + id);
+ if (spriteId == 2)
+ force->_horizontal++;
+ else
+ force->_vertical++;
+ }
+ }
+
+ force->_timer = _scene->_frameStartTime + 4;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene300s::preActions() {
+ _game._player._needToWalk = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene301::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene301::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+
+ _globals[kMeteorologistStatus] = METEOROLOGIST_GONE;
+ _globals[kTeleporterCommand] = TELEPORTER_NONE;
+
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+
+ sceneEntrySound();
+}
+
+void Scene301::step() {
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 302;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene302::Scene302(MADSEngine *vm) : Scene3xx(vm) {
+ _oldFrame = 0;
+}
+
+void Scene302::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsSint32LE(_oldFrame);
+}
+
+void Scene302::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene302::enter() {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+
+ _scene->loadAnimation(formAnimName('a', -1), 71);
+ sceneEntrySound();
+}
+
+void Scene302::step() {
+ if (_game._trigger == 71)
+ _scene->_nextSceneId = 303;
+
+ if ((_scene->_activeAnimation != nullptr) && (_scene->_activeAnimation->getCurrentFrame() != _oldFrame)) {
+ _oldFrame = _scene->_activeAnimation->getCurrentFrame();
+ if (_oldFrame == 147) {
+ _game._objects.setRoom(OBJ_POISON_DARTS, 1);
+ _game._objects.setRoom(OBJ_BLOWGUN, 1);
+ _game._objects.setRoom(OBJ_REBREATHER, 1);
+ _game._objects.setRoom(OBJ_STUFFED_FISH, 1);
+ _game._objects.setRoom(OBJ_DEAD_FISH, 1);
+ _game._objects.setRoom(OBJ_BURGER, 1);
+
+ int count = (int)_game._objects._inventoryList.size();
+ for (int idx = 0; idx < count; idx++) {
+ if (_game._objects.isInInventory(idx))
+ _game._objects.setRoom(idx, 50);
+ }
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene303::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene303::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 1));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 10, 0, 50, 120);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 10, 0, 0, 0);
+
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+
+ sceneEntrySound();
+}
+
+void Scene303::step() {
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 304;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene304::Scene304(MADSEngine *vm) : Scene3xx(vm) {
+ _explosionSpriteId = -1;
+}
+
+void Scene304::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsSint32LE(_explosionSpriteId);
+}
+
+void Scene304::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene304::enter() {
+ if (_scene->_priorSceneId == 303) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+ } else {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ else
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('a', 2));
+
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 0));
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 150, 0, 3, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 2);
+ _vm->_palette->setEntry(252, 45, 63, 45);
+ _vm->_palette->setEntry(253, 20, 45, 20);
+
+ if (_globals[kSexOfRex] == REX_MALE)
+ _game._player._playerPos = Common::Point(111, 117);
+ else
+ _game._player._playerPos = Common::Point(113, 116);
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 11, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, -1);
+ _scene->_sequences.addTimer(48, 70);
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0xEB, 0xEC, 0);
+}
+
+void Scene304::step() {
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 311;
+
+ if (_game._trigger >= 70) {
+ switch (_game._trigger) {
+ case 70: {
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ if (_globals[kSexOfRex] == REX_MALE)
+ _explosionSpriteId = _globals._spriteIndexes[1];
+ else
+ _explosionSpriteId = _globals._spriteIndexes[4];
+
+ int sprIdx = _scene->_sequences.addSpriteCycle(_explosionSpriteId, false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(sprIdx, -1, 4);
+ _scene->_sequences.setDepth(sprIdx, 1);
+ _scene->_sequences.addSubEntry(sprIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+ }
+ break;
+
+ case 71:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(0xEB));
+ _scene->_sequences.addTimer(1, 72);
+ break;
+
+ case 72: {
+ _vm->_sound->command(43);
+ int sprIdx = _scene->_sequences.addSpriteCycle(_explosionSpriteId, false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(sprIdx, 5, -2);
+ _scene->_sequences.setDepth(sprIdx, 1);
+ _scene->_sequences.addSubEntry(sprIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ if (_game._storyMode == STORYMODE_NICE)
+ _scene->_sequences.addSubEntry(sprIdx, SEQUENCE_TRIGGER_SPRITE, 8, 78);
+ }
+ break;
+
+ case 73: {
+ int sprIdx = _scene->_sequences.addSpriteCycle(_explosionSpriteId, false, 8, 0, 0, 0);
+ _scene->_sequences.setAnimRange(sprIdx, -2, -2);
+ _scene->_sequences.setDepth(sprIdx, 1);
+ }
+ break;
+
+ case 74:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 5, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ break;
+
+ case 75:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 76);
+ break;
+
+ case 76:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 2);
+ _scene->_sequences.addTimer(48, 77);
+ break;
+
+ case 77:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(211, 45), 0xFDFC, 32, 0, 180, _game.getQuote(0xEC));
+ _scene->_sequences.addTimer(120, 78);
+ break;
+
+ case 78:
+ _scene->_nextSceneId = 316;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene307::Scene307(MADSEngine *vm) : Scene3xx(vm) {
+ _afterPeeingFl = false;
+ _duringPeeingFl = false;
+ _grateOpenedFl = false;
+ _activePrisonerFl = false;
+
+ _animationMode = -1;
+ _prisonerMessageId = -1;
+ _fieldCollisionCounter = -1;
+
+ _lastFrameTime = 0;
+ _guardTime = 0;
+ _prisonerTimer = 0;
+
+ _subQuote2 = "";
+
+ _forceField.init();
+}
+
+void Scene307::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ _forceField.synchronize(s);
+
+ s.syncAsByte(_afterPeeingFl);
+ s.syncAsByte(_duringPeeingFl);
+ s.syncAsByte(_grateOpenedFl);
+ s.syncAsByte(_activePrisonerFl);
+
+ s.syncAsSint32LE(_animationMode);
+ s.syncAsSint32LE(_prisonerMessageId);
+ s.syncAsSint32LE(_fieldCollisionCounter);
+
+ s.syncAsUint32LE(_lastFrameTime);
+ s.syncAsUint32LE(_guardTime);
+ s.syncAsUint32LE(_prisonerTimer);
+
+ s.syncString(_subQuote2);
+}
+
+void Scene307::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_AIR_VENT);
+ _scene->addActiveVocab(NOUN_CLIMB_INTO);
+}
+
+void Scene307::handleRexDialog(int quote) {
+ Common::String curQuote = _game.getQuote(_action._activeAction._verbId);
+ if (_vm->_font->getWidth(curQuote, _scene->_textSpacing) > 200) {
+ Common::String subQuote1;
+ _game.splitQuote(curQuote, subQuote1, _subQuote2);
+ _scene->_kernelMessages.add(Common::Point(0, -14), 0x1110, 34, 0, 240, subQuote1);
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 1, 180, _subQuote2);
+ } else
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 1, 120, curQuote);
+}
+
+void Scene307::handlePrisonerEncounter() {
+ switch (_action._activeAction._verbId) {
+ case 275:
+ setDialogNode(5);
+ break;
+
+ case 277:
+ setDialogNode(4);
+ break;
+
+ case 276:
+ setDialogNode(6);
+ break;
+ }
+}
+
+void Scene307::handlePrisonerSpeech(int firstQuoteId, int number, long timeout) {
+ int height = number * 14;
+ int posY;
+
+ if (height < 60)
+ posY = 65 - height;
+ else
+ posY = 78 - (height / 2);
+
+ _scene->_kernelMessages.reset();
+ _activePrisonerFl = true;
+
+ int quoteId = firstQuoteId;
+ for (int count = 0; count < number; count++) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_kernelMessages.add(Common::Point(5, posY), 0xFDFC, 0, 81, timeout, _game.getQuote(quoteId));
+ posY += 14;
+ quoteId++;
+ }
+}
+
+void Scene307::setDialogNode(int node) {
+ switch (node) {
+ case 0:
+ handlePrisonerSpeech(0x153, 2, 120);
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ case 1:
+ _globals[kMetBuddyBeast] = true;
+ handlePrisonerSpeech(0x10F, 2, 9999999);
+ _dialog1.start();
+ break;
+
+ case 2:
+ _globals[kMetBuddyBeast] = true;
+ handlePrisonerSpeech(0x111, 2, 9999999);
+ _dialog1.start();
+ break;
+
+ case 4:
+ handlePrisonerSpeech(0x116, 1, 120);
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ case 5:
+ _globals[kKnowsBuddyBeast] = true;
+ handlePrisonerSpeech(0x117, 2, 9999999);
+ _dialog2.start();
+ break;
+
+ case 6:
+ handlePrisonerSpeech(0x123, 1, 120);
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ case 7:
+ _globals[kKnowsBuddyBeast] = true;
+ handlePrisonerSpeech(0x124, 10, 9999999);
+ _dialog2.write(0x11A, false);
+ _dialog2.write(0x11B, true);
+ _dialog2.write(0x120, true);
+ _dialog2.start();
+ break;
+
+ case 8:
+ handlePrisonerSpeech(0x12E, 6, 9999999);
+ _dialog2.write(0x11A, false);
+ _dialog2.write(0x11B, false);
+ _dialog2.write(0x11C, true);
+ _dialog2.write(0x11D, true);
+ _dialog2.write(0x11F, true);
+ _dialog2.start();
+ break;
+
+ case 9:
+ handlePrisonerSpeech(0x134, 4, 9999999);
+ _dialog2.write(0x11D, false);
+ _dialog2.start();
+ break;
+
+ case 10:
+ handlePrisonerSpeech(0x138, 6, 9999999);
+ _dialog2.write(0x11E, false);
+ _dialog2.start();
+ break;
+
+ case 11:
+ handlePrisonerSpeech(0x13E, 6, 9999999);
+ _dialog2.write(0x11F, false);
+ _dialog2.write(0x121, true);
+ _dialog2.start();
+ break;
+
+ case 12:
+ handlePrisonerSpeech(0x144, 4, 9999999);
+ _dialog2.write(0x11C, false);
+ _dialog2.start();
+ break;
+
+ case 13:
+ handlePrisonerSpeech(0x148, 7, 9999999);
+ _dialog2.write(0x120, false);
+ _dialog2.start();
+ break;
+
+ case 14:
+ handlePrisonerSpeech(0x14F, 3, 9999999);
+ _dialog2.write(0x121, false);
+ _dialog2.start();
+ break;
+
+ case 15:
+ handlePrisonerSpeech(0x152, 1, 120);
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ case 16:
+ _globals[kKnowsBuddyBeast] = true;
+ handlePrisonerSpeech(0x10C, 1, 9999999);
+ _dialog2.start();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene307::handlePrisonerDialog() {
+ switch (_action._activeAction._verbId) {
+ case 0x11A:
+ setDialogNode(7);
+ break;
+
+ case 0x11B:
+ setDialogNode(8);
+ break;
+
+ case 0x11C:
+ setDialogNode(12);
+ break;
+
+ case 0x11D:
+ setDialogNode(9);
+ break;
+
+ case 0x11E:
+ setDialogNode(10);
+ break;
+
+ case 0x11F:
+ setDialogNode(11);
+ break;
+
+ case 0x120:
+ setDialogNode(13);
+ break;
+
+ case 0x121:
+ setDialogNode(14);
+ break;
+
+ case 0x122:
+ setDialogNode(15);
+ break;
+ }
+}
+
+void Scene307::handleDialog() {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _game._player._stepEnabled = false;
+ handleRexDialog(_action._activeAction._verbId);
+ } else {
+ _game._player._stepEnabled = true;
+
+ if (!_globals[kKnowsBuddyBeast]) {
+ handlePrisonerEncounter();
+ } else {
+ handlePrisonerDialog();
+ }
+ }
+}
+
+void Scene307::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*SC003x0");
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites("*SC003x1");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*SC003x2");
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 0));
+
+ initForceField(&_forceField, true);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+
+ _animationMode = 0;
+ _fieldCollisionCounter = 0;
+
+ _scene->changeVariant(1);
+
+ _game.loadQuoteSet(0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0x10C, 0x104, 0x106, 0x107, 0x108, 0x105,
+ 0x109, 0x10A, 0x10B, 0x10D, 0x10E, 0x10F, 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117,
+ 0x118, 0x119, 0x11A, 0x11B, 0x11C, 0x11D, 0x11E, 0x11F, 0x120, 0x121, 0x122, 0x123, 0x124, 0x125,
+ 0x126, 0x127, 0x128, 0x129, 0x12A, 0x12B, 0x12C, 0x12D, 0x12E, 0x12F, 0x130, 0x131, 0x132, 0x133,
+ 0x134, 0x135, 0x136, 0x137, 0x138, 0x139, 0x13A, 0x13B, 0x13C, 0x13D, 0x13E, 0x13F, 0x140, 0x141,
+ 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, 0x148, 0x149, 0x14A, 0x14B, 0x14C, 0x14D, 0x14E, 0x14F,
+ 0x150, 0x151, 0x152, 0x153, 0);
+
+ _dialog1.setup(0x3F, 0x113, 0x114, 0x115, -1);
+ _dialog2.setup(0x40, 0x11A, 0x11B, 0x11C, 0x11D, 0x11E, 0x11F, 0x120, 0x121, 0x122, 0);
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _dialog2.set(0x11A, 0x122, 0);
+ else if (_scene->_priorSceneId == 318)
+ _dialog2.write(0x11E, true);
+
+
+ if (_scene->_priorSceneId == -2) {
+ if (_grateOpenedFl)
+ _vm->_sound->command(10);
+ else
+ _vm->_sound->command(3);
+ } else {
+ _afterPeeingFl = false;
+ _duringPeeingFl = false;
+ _guardTime = 0;
+ _grateOpenedFl = false;
+ _activePrisonerFl = false;
+ _prisonerTimer = 0;
+ _prisonerMessageId = 0x104;
+
+ if (_scene->_priorSceneId == 308) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _game._player._playerPos = Common::Point(156, 113);
+ _game._player._facing = FACING_NORTH;
+ _animationMode = 1;
+ _vm->_sound->command(11);
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+ } else if (_scene->_priorSceneId == 387) {
+ _game._player._playerPos = Common::Point(129, 108);
+ _game._player._facing = FACING_NORTH;
+ _vm->_sound->command(3);
+ _grateOpenedFl = true;
+ } else {
+ _game._player._playerPos = Common::Point(159, 109);
+ _game._player._facing = FACING_SOUTH;
+ _vm->_sound->command(3);
+ }
+ }
+
+ if (_grateOpenedFl) {
+ _scene->_hotspots.activate(17, false);
+
+ int idx = _scene->_dynamicHotspots.add(17, VERB_CLIMB_INTO, -1, Common::Rect(117, 67, 117 + 19, 67 + 13));
+ int hotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(129, 104), FACING_NORTH);
+ _scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_UP);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+ }
+
+ _vm->_palette->setEntry(252, 63, 30, 20);
+ _vm->_palette->setEntry(253, 45, 15, 12);
+
+ sceneEntrySound();
+
+ if ((_scene->_priorSceneId == 318) || (_scene->_priorSceneId == 387))
+ _scene->_kernelMessages.addQuote(0xF3, 120, 0);
+}
+
+void Scene307::step() {
+ handleForceField(&_forceField, &_globals._spriteIndexes[0]);
+
+ if ((_animationMode == 1) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() == 126) {
+ _forceField._flag = false;
+ _vm->_sound->command(5);
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 194) {
+ _forceField._flag = true;
+ _vm->_sound->command(24);
+ }
+ }
+
+ if ((_animationMode == 2) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() == 54)
+ _forceField._flag = false;
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 150) {
+ _game._player._visible = false;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ }
+ }
+
+ if (_game._trigger == 60) {
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _animationMode = 0;
+ _vm->_sound->command(9);
+ }
+
+ if ((_lastFrameTime != _scene->_frameStartTime) && !_duringPeeingFl) {
+ int32 elapsedTime = _lastFrameTime - _scene->_frameStartTime;
+ if ((elapsedTime > 0) && (elapsedTime <= 4)) {
+ _guardTime += elapsedTime;
+ _prisonerTimer += elapsedTime;
+ } else {
+ _guardTime++;
+ _prisonerTimer++;
+ }
+ _lastFrameTime = _scene->_frameStartTime;
+
+ if ((_guardTime > 3000) && !_duringPeeingFl && (_scene->_activeAnimation == nullptr)
+ && (_game._screenObjects._inputMode != 1) && _globals[kMetBuddyBeast] && !_activePrisonerFl) {
+ if (!_game._objects.isInInventory(OBJ_SCALPEL) && !_grateOpenedFl) {
+ _game._player._stepEnabled = false;
+ _game._player.walk(Common::Point(151, 119), FACING_SOUTHEAST);
+ _animationMode = 2;
+ _vm->_sound->command(11);
+ _scene->loadAnimation(formAnimName('b', -1), 70);
+ }
+ _guardTime = 0;
+ } else if ((_prisonerTimer > 300) && (_game._screenObjects._inputMode != 1) && (_scene->_activeAnimation == nullptr) && !_activePrisonerFl) {
+ if (!_globals[kMetBuddyBeast]) {
+ int idx = _scene->_kernelMessages.add(Common::Point(5, 51), 0xFDFC, 0, 81, 120, _game.getQuote(_prisonerMessageId));
+ _scene->_kernelMessages.setQuoted(idx, 4, true);
+ _prisonerMessageId++;
+ if (_prisonerMessageId > 0x10A)
+ _prisonerMessageId = 0x104;
+ } else if (_globals[kKnowsBuddyBeast] && (_dialog2.read(0) > 1) && (_vm->getRandomNumber(1, 3) == 1)) {
+ int idx = _scene->_kernelMessages.add(Common::Point(5, 51), 0xFDFC, 0, 81, 120, _game.getQuote(267));
+ _scene->_kernelMessages.setQuoted(idx, 4, true);
+ }
+ _prisonerTimer = 0;
+ }
+ }
+
+ if (_game._trigger == 70)
+ _scene->_nextSceneId = 318;
+
+ if (_game._trigger == 81) {
+ _prisonerTimer = 0;
+ if (_activePrisonerFl && (_guardTime > 2600))
+ _guardTime = 3000 - _vm->getRandomNumber(1, 800);
+
+ _activePrisonerFl = false;
+ }
+}
+
+void Scene307::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(30715);
+ else if (_game._screenObjects._inputMode == 1)
+ handleDialog();
+ else if (_action.isAction(VERB_TALKTO, NOUN_CELL_WALL) || _action.isAction(VERB_TALKTO, NOUN_WALL) || _action.isAction(VERB_TALKTO, NOUN_TOILET)) {
+ int node, say;
+ if (_globals[kKnowsBuddyBeast]) {
+ say = 0x10E;
+ node = 16;
+ } else if (_globals[kMetBuddyBeast]) {
+ say = 0x10E;
+ node = 2;
+ } else {
+ say = 0x10D;
+ node = 1;
+ }
+
+ switch (_game._trigger) {
+ case 0:
+ handleRexDialog(say);
+ break;
+
+ case 1:
+ setDialogNode(node);
+ break;
+ }
+ } else if (_action.isAction(VERB_PRY, NOUN_SCALPEL, NOUN_AIR_VENT)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(239));
+ _scene->_sequences.addTimer(120, 1);
+ break;
+
+ case 1:
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXCL_8");
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], -1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 12, 6, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 2, 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 3: {
+ int oldIdx = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldIdx);
+ _scene->_sequences.addTimer(48, 4);
+ }
+ break;
+
+ case 4:
+ _vm->_sound->command(26);
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+ _scene->_sequences.addTimer(90, 5);
+ break;
+
+ case 5:
+ _vm->_sound->command(10);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(241));
+ _scene->_sequences.addTimer(120, 6);
+ break;
+
+ case 6: {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _grateOpenedFl = true;
+ _scene->_hotspots.activate(17, false);
+ int idx = _scene->_dynamicHotspots.add(17, NOUN_CLIMB_INTO, -1, Common::Rect(117, 67, 117 + 19, 67 + 13));
+ int hotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(129, 104), FACING_NORTH);
+ _scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_UP);
+ _game._objects.removeFromInventory(OBJ_SCALPEL, NOWHERE);
+ _scene->_kernelMessages.addQuote(0xF2, 120, 7);
+ }
+ break;
+
+ case 7:
+ _scene->_sprites.remove(_globals._spriteIndexes[5]);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) {
+ if (_grateOpenedFl) {
+ switch (_game._trigger) {
+ case 0:
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXCL_8");
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 60, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 3, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 18, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], -1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 4, 10);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 3:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 3);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 11);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(129, 102));
+ _scene->_sequences.addTimer(48, 4);
+ break;
+
+ case 4:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 12, 14);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(129, 102));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ break;
+
+ case 5:
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 15);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(129, 102));
+ _scene->_sequences.addTimer(48, 6);
+ break;
+
+ case 6:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _scene->_sequences.addTimer(48, 7);
+ break;
+
+ case 7:
+ _scene->_nextSceneId = 313;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_USE, NOUN_TOILET) && (_game._storyMode != STORYMODE_NAUGHTY))
+ _vm->_dialogs->show(30723);
+ else if (_action.isAction(VERB_USE, NOUN_TOILET)) {
+ if (!_afterPeeingFl) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(25);
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _duringPeeingFl = true;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], -1, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 5, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 3, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(48, 3);
+ break;
+
+ case 3: {
+ _scene->_sprites.remove(_globals._spriteIndexes[3]);
+ _scene->_kernelMessages.reset();
+ int idx = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 4, 120, _game.getQuote(237));
+ _scene->_kernelMessages.setQuoted(idx, 4, true);
+ }
+ break;
+
+ case 4:
+ _game._player._stepEnabled = true;
+ _duringPeeingFl = false;
+ _afterPeeingFl = true;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ _scene->_kernelMessages.reset();
+ int idx = _scene->_kernelMessages.add(Common::Point(85, 39), 0x1110, 0, 0, 180, _game.getQuote(238));
+ _scene->_kernelMessages.setQuoted(idx, 4, true);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT)) {
+ if (!_grateOpenedFl)
+ _vm->_dialogs->show(30710);
+ else
+ _vm->_dialogs->show(30711);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(30712);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(30713);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOILET))
+ _vm->_dialogs->show(30714);
+ else if (_action.isAction(VERB_SHARPEN, NOUN_SCALPEL))
+ _vm->_dialogs->show(30716);
+ else if (_action.isAction(VERB_LOOK, NOUN_CELL_WALL))
+ _vm->_dialogs->show(30717);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHT))
+ _vm->_dialogs->show(30718);
+ else if (_action.isAction(VERB_WALK_INTO, NOUN_CORRIDOR)) {
+ switch (_fieldCollisionCounter) {
+ case 0:
+ _vm->_dialogs->show(30719);
+ _fieldCollisionCounter = 1;
+ break;
+
+ case 1:
+ _vm->_dialogs->show(30720);
+ _fieldCollisionCounter = 2;
+ break;
+
+ case 2:
+ _vm->_dialogs->show(30721);
+ _fieldCollisionCounter = 3;
+ break;
+
+ case 3:
+ _vm->_dialogs->show(30722);
+ break;
+ }
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene308::Scene308(MADSEngine *vm) : Scene3xx(vm) {
+ _forceField.init();
+}
+
+void Scene308::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ _forceField.synchronize(s);
+}
+
+
+void Scene308::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene308::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*SC003x0");
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites("*SC003x1");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*SC003x2");
+
+ initForceField(&_forceField, true);
+
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+
+ _vm->_palette->setEntry(252, 63, 30, 20);
+ _vm->_palette->setEntry(253, 45, 15, 12);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_sequences.addTimer(48, 70);
+
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0xF4, 0xF5, 0xF6, 0);
+}
+
+void Scene308::step() {
+ handleForceField(&_forceField, &_globals._spriteIndexes[0]);
+
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 307;
+
+ if (_game._trigger < 70)
+ return;
+
+ switch (_game._trigger) {
+ case 70: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 18, 9, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_kernelMessages.reset();
+ int idx = _scene->_kernelMessages.add(Common::Point(171, 21), 0xFDFC, 0, 0, 120, _game.getQuote(244));
+ _scene->_kernelMessages.setQuoted(idx, 2, true);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ }
+ break;
+
+ case 71: {
+ int seqIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], seqIdx);
+ _scene->_sequences.addTimer(48, 72);
+ }
+ break;
+
+ case 72:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 20, 5, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 3, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_kernelMessages.reset();
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ break;
+
+ case 73: {
+ int seqIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], seqIdx);
+ _scene->_sequences.addTimer(48, 74);
+ }
+ break;
+
+ case 74: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 20, 8, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 6, 7);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_kernelMessages.reset();
+ int idx = _scene->_kernelMessages.add(Common::Point(171, 21), 0xFDFC, 0, 0, 120, _game.getQuote(245));
+ _scene->_kernelMessages.setQuoted(idx, 2, true);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ }
+ break;
+
+ case 75: {
+ int seqIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 23, 5, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 10);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 76);
+ }
+ break;
+
+ case 76: {
+ int seqIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+ _scene->_kernelMessages.reset();
+ int idx = _scene->_kernelMessages.add(Common::Point(171, 21), 0xFDFC, 0, 0, 120, _game.getQuote(246));
+ _scene->_kernelMessages.setQuoted(idx, 2, true);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], seqIdx);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene309::Scene309(MADSEngine *vm) : Scene3xx(vm) {
+ for (int i = 0; i < 3; i++) {
+ _characterSpriteIndexes[i] = -1;
+ _messagesIndexes[i] = -1;
+ }
+
+ _lastFrame = -1;
+ _forceField.init();
+}
+
+void Scene309::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ _forceField.synchronize(s);
+
+ for (int i = 0; i < 3; ++i)
+ s.syncAsSint32LE(_characterSpriteIndexes[i]);
+ for (int i = 0; i < 3; ++i)
+ s.syncAsSint32LE(_messagesIndexes[i]);
+ s.syncAsSint32LE(_lastFrame);
+}
+
+void Scene309::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene309::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*SC003x0");
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites("*SC003x1");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*SC003x2");
+
+ initForceField(&_forceField, true);
+
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 15);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], -1, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 3, 70);
+
+ _vm->_palette->setEntry(252, 63, 37, 26);
+ _vm->_palette->setEntry(253, 45, 24, 17);
+ _vm->_palette->setEntry(16, 63, 63, 63);
+ _vm->_palette->setEntry(17, 45, 45, 45);
+ _vm->_palette->setEntry(250, 63, 20, 20);
+ _vm->_palette->setEntry(251, 45, 10, 10);
+
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+
+ _characterSpriteIndexes[0] = _scene->_activeAnimation->_spriteListIndexes[2];
+ _characterSpriteIndexes[1] = _scene->_activeAnimation->_spriteListIndexes[2];
+ _characterSpriteIndexes[2] = _scene->_activeAnimation->_spriteListIndexes[1];
+
+ _messagesIndexes[0] = -1;
+ _messagesIndexes[1] = -1;
+ _messagesIndexes[2] = -1;
+
+ sceneEntrySound();
+
+ _game.loadQuoteSet(0xF7, 0xF8, 0xF9, 0x15C, 0x15D, 0x15E, 0);
+}
+
+void Scene309::step() {
+ handleForceField(&_forceField, &_globals._spriteIndexes[0]);
+
+ if (_game._trigger == 61) {
+ _messagesIndexes[0] = -1;
+ _messagesIndexes[1] = -1;
+ }
+
+ if (_game._trigger == 62)
+ _messagesIndexes[2] = -1;
+
+ if (_scene->_activeAnimation != nullptr) {
+ if (_lastFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _lastFrame = _scene->_activeAnimation->getCurrentFrame();
+ if (_lastFrame == 39) {
+ _messagesIndexes[0] = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 32, 61, 210, _game.getQuote(348));
+ _messagesIndexes[1] = _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 32, 0, 210, _game.getQuote(349));
+ }
+
+ if (_lastFrame == 97)
+ _messagesIndexes[2] = _scene->_kernelMessages.add(Common::Point(0, 0), 0xFBFA, 32, 62, 180, _game.getQuote(350));
+
+ for (int charIdx = 0; charIdx < 3; charIdx++) {
+ if (_messagesIndexes[charIdx] >= 0) {
+ bool match = false;
+ int j = -1;
+ for (j = _scene->_activeAnimation->_oldFrameEntry; j < _scene->_activeAnimation->_header._frameEntriesCount; j++) {
+ if (_scene->_activeAnimation->_frameEntries[j]._spriteSlot._spritesIndex == _characterSpriteIndexes[charIdx]) {
+ match = true;
+ break;
+ }
+ }
+
+ if (match) {
+ SpriteSlotSubset *curSpriteSlot = &_scene->_activeAnimation->_frameEntries[j]._spriteSlot;
+ _scene->_kernelMessages._entries[_messagesIndexes[charIdx]]._position.x = curSpriteSlot->_position.x;
+ _scene->_kernelMessages._entries[_messagesIndexes[charIdx]]._position.y = curSpriteSlot->_position.y - (50 + (14 * ((charIdx == 0) ? 2 : 1)));
+ }
+ }
+ }
+ }
+ }
+
+ if (_game._trigger >= 70) {
+ switch (_game._trigger) {
+ case 70: {
+ int idx = _scene->_dynamicHotspots.add(689, 690, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(142, 146), FACING_NORTHEAST);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 4, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ }
+ break;
+
+ case 71: {
+ int _oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 7);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
+ int idx = _scene->_kernelMessages.add(Common::Point(85, 37), 0xFDFC, 0, 0, 120, _game.getQuote(248));
+ _scene->_kernelMessages.setQuoted(idx, 2, true);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ }
+ break;
+
+ case 72: {
+ int _oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 8, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ }
+ break;
+
+ case 73: {
+ int _oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 12, 20);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
+ int idx = _scene->_kernelMessages.add(Common::Point(170, 49), 0xFDFC, 0, 0, 120, _game.getQuote(249));
+ _scene->_kernelMessages.setQuoted(idx, 2, true);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+ }
+ break;
+
+ case 74: {
+ int _oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 6, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 21, 23);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ }
+ break;
+
+ case 75: {
+ int _oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 6, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 24, 25);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 76);
+ }
+ break;
+
+ case 76: {
+ int _oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 26, 28);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 77);
+ }
+ break;
+
+ case 77: {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 90, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 29, 30);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11);
+ int idx = _scene->_kernelMessages.add(Common::Point(15, 46), 0xFDFC, 0, 0, 120, _game.getQuote(247));
+ _scene->_kernelMessages.setQuoted(idx, 2, true);
+ _scene->_sequences.addTimer(120, 78);
+ }
+ break;
+ }
+ }
+
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 308;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene310::Scene310(MADSEngine *vm) : Scene3xx(vm) {
+ _forceField.init();
+}
+
+void Scene310::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ _forceField.synchronize(s);
+}
+
+void Scene310::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene310::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*SC003x0");
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites("*SC003x1");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*SC003x2");
+
+ initForceField(&_forceField, true);
+
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 15);
+
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 70);
+
+ sceneEntrySound();
+}
+
+void Scene310::step() {
+ handleForceField(&_forceField, &_globals._spriteIndexes[0]);
+
+ if (_game._trigger == 70)
+ _scene->_nextSceneId = 309;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene311::Scene311(MADSEngine *vm) : Scene3xx(vm) {
+ _checkGuardFl = false;
+}
+
+void Scene311::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsByte(_checkGuardFl);
+}
+
+void Scene311::setup() {
+ if (_scene->_currentSceneId == 391)
+ _globals[kSexOfRex] = REX_MALE;
+
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ if (_scene->_currentSceneId == 304)
+ _game._player._spritesPrefix = "";
+}
+
+void Scene311::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXCL_8");
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXCL_2");
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ _checkGuardFl = false;
+ _game.loadQuoteSet(0xFA, 0);
+
+ if (_scene->_priorSceneId == 391) {
+ _globals[kSexOfRex] = REX_MALE;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _game._player._facing = FACING_SOUTH;
+ _game._player._playerPos = Common::Point(166, 101);
+ _scene->_sequences.addTimer(120, 71);
+ } else if (_scene->_priorSceneId == 310)
+ _game._player._playerPos = Common::Point(302, 145);
+ else if (_scene->_priorSceneId == 320) {
+ _game._player._playerPos = Common::Point(129, 113);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 70);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene311::step() {
+ if (_game._trigger == 70)
+ _scene->_nextSceneId = 310;
+
+ if (_game._trigger >= 71) {
+ switch (_game._trigger) {
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 72);
+ break;
+
+ case 72:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 73);
+ break;
+
+ case 73:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 3);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 74);
+ break;
+
+ case 74:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 5);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ break;
+
+ case 75: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(15, 76);
+ }
+ break;
+
+ case 76:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 7);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 77);
+ break;
+
+ case 77:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 8);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 78);
+ break;
+
+ case 78:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 9);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 79);
+ break;
+
+ case 79:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 10, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ break;
+
+ case 80:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_game._player._moving && (_scene->_rails.getNext() > 0)) {
+ int x = _game._player._prepareWalkPos.x;
+ if (x < 75)
+ x = 75;
+ if (x > 207)
+ x = 207;
+
+ _checkGuardFl = true;
+ _game._player.startWalking(Common::Point(x, 122), FACING_SOUTH);
+ _scene->_rails.resetNext();
+ }
+}
+
+void Scene311::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(31119);
+ else if (_checkGuardFl) {
+ _checkGuardFl = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.addQuote(0xFA, 120, 0);
+ } else if (_action.isAction(VERB_SIT_AT, NOUN_DESK))
+ _scene->_nextSceneId = 320;
+ else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 50, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 3, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 15, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1: {
+ int oldIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], oldIdx);
+ }
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 4, 10);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 3: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 3);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 11);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addTimer(15, 4);
+ }
+ break;
+
+ case 4:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 12, 14);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(167, 100));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ break;
+
+ case 5: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 15);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addTimer(15, 6);
+ }
+ break;
+
+ case 6:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addTimer(15, 7);
+ break;
+
+ case 7:
+ _scene->_nextSceneId = 313;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_DESK))
+ _vm->_dialogs->show(31110);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(31111);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHTING_FIXTURE) || _action.isAction(VERB_STARE_AT, NOUN_LIGHTING_FIXTURE))
+ _vm->_dialogs->show(31112);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHTS) || _action.isAction(VERB_STARE_AT, NOUN_LIGHTS))
+ _vm->_dialogs->show(31113);
+ else if (_action.isAction(VERB_TAKE, NOUN_LIGHTS))
+ _vm->_dialogs->show(31114);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHT) || _action.isAction(VERB_STARE_AT, NOUN_LIGHT))
+ _vm->_dialogs->show(31115);
+ else if (_action.isAction(VERB_TAKE, NOUN_LIGHT))
+ _vm->_dialogs->show(31116);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(31117);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(31118);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(31120);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene313::setup() {
+ setPlayerSpritesPrefix();
+ _game._player._spritesPrefix = "RM313A";
+ setAAName();
+}
+
+void Scene313::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+
+ if ((_scene->_priorSceneId == 366) || (_scene->_priorSceneId == 316)) {
+ _game._player._playerPos = Common::Point(30, 80);
+ _game._player._facing = FACING_NORTH;
+ } else if ((_scene->_priorSceneId == 311) || (_scene->_priorSceneId == 361) || (_scene->_priorSceneId == 391)) {
+ _game._player._playerPos = Common::Point(90, 70);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId == 390) {
+ _game._player._playerPos = Common::Point(126, 70);
+ _game._player._facing = FACING_EAST;
+ } else if ((_scene->_priorSceneId == 389) || (_scene->_priorSceneId == 399)) {
+ _game._player._playerPos = Common::Point(163, 70);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId == 388) {
+ _game._player._playerPos = Common::Point(199, 70);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(234, 70);
+ _game._player._facing = FACING_WEST;
+ }
+
+ if (_globals[kAfterHavoc]) {
+ for (uint16 i = 0; i < _scene->_paletteCycles.size(); i++) {
+ int palIdx = _scene->_paletteCycles[i]._firstColorIndex;
+ int size = _scene->_paletteCycles[i]._colorCount * 3;
+ memset(&_vm->_palette->_cyclingPalette[palIdx], 0, size);
+ memset(&_vm->_palette->_mainPalette[palIdx], 0, size);
+ }
+ }
+
+ sceneEntrySound();
+}
+
+void Scene313::actions() {
+ if (_action.isAction(VERB_CRAWL_TO, NOUN_FOURTH_CELL))
+ _scene->_nextSceneId = 387;
+ else if (_action.isAction(VERB_CRAWL_TO, NOUN_THIRD_CELL))
+ _scene->_nextSceneId = 388;
+ else if (_action.isAction(VERB_CRAWL_TO, NOUN_SECOND_CELL)) {
+ if (_globals[kAfterHavoc])
+ _scene->_nextSceneId = 399;
+ else
+ _scene->_nextSceneId = 389;
+ } else if (_action.isAction(VERB_CRAWL_TO, NOUN_FIRST_CELL))
+ _scene->_nextSceneId = 390;
+ else if (_action.isAction(VERB_CRAWL_TO, NOUN_SECURITY_STATION)) {
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals[kSexOfRex] = REX_MALE;
+ _vm->_dialogs->show(31301);
+ }
+ _scene->_nextSceneId = 391;
+ } else if (_action.isAction(VERB_CRAWL_TO, NOUN_EQUIPMENT_ROOM)) {
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals[kSexOfRex] = REX_MALE;
+ _vm->_dialogs->show(31301);
+ }
+ _scene->_nextSceneId = 366;
+ } else if (!_action.isAction(VERB_CRAWL_DOWN, NOUN_AIR_SHAFT))
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene316::setup() {
+ if (_scene->_currentSceneId == 366)
+ _globals[kSexOfRex] = REX_MALE;
+
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene316::handleRexInGrate() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addTimer(15, 1);
+ break;
+
+ case 1:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 12, 3, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 2, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 4, 8);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ }
+ break;
+
+ case 3: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ }
+ break;
+
+ case 4: {
+ int oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 10, 11);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 5, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ }
+ break;
+
+ case 5: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+
+ oldIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 12);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx);
+ _scene->_sequences.addTimer(15, 6);
+ }
+ break;
+
+ case 6:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 13, 14);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 7);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 8);
+ break;
+
+ case 7:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 15);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], -1);
+ break;
+
+ case 8: {
+ int oldIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx);
+ _scene->_sequences.addTimer(15, 9);
+ }
+ break;
+
+ case 9:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addTimer(48, 10);
+ break;
+
+ case 10:
+ _scene->_nextSceneId = 313;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene316::handleRoxInGrate() {
+ int temp;
+ int temp1;
+
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addTimer(15, 1);
+ break;
+
+ case 1:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 17, 3, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 2, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 17, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+
+ temp = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 17, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 4, 8);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], temp);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ break;
+
+ case 3:
+ temp1 = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], temp1);
+ break;
+
+ case 4:
+ temp = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 17, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 10, 11);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], temp);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 17, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 5, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ break;
+
+ case 5:
+ temp = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], temp);
+
+ temp = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 12);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], temp);
+ _scene->_sequences.addTimer(20, 6);
+ break;
+
+ case 6:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 17, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 13, 15);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 17, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 7);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 8);
+ break;
+
+ case 7:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 16);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], -1);
+ break;
+
+ case 8:
+ temp = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], temp);
+ _scene->_sequences.addTimer(20, 9);
+ break;
+
+ case 9:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addTimer(48, 10);
+ break;
+
+ case 10:
+ _scene->_nextSceneId = 313;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene316::enter() {
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', -1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCL_8");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites("*RXCL_2");
+ } else {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('g', 0));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*ROXCL_8");
+ }
+
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('v', 0));
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+
+ if (_scene->_priorSceneId == 366) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _game._player._playerPos = Common::Point(78, 87);
+ _game._player._facing = FACING_SOUTH;
+ _scene->_sequences.addTimer(48, 70);
+ } else if (_scene->_priorSceneId == 321) {
+ _game._player._playerPos = Common::Point(153, 102);
+ _game._player._facing = FACING_SOUTH;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _vm->_sound->command(44);
+ int spriteIdx = (_globals[kSexOfRex] == REX_MALE) ? 1 : 2;
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[spriteIdx], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
+ } else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(291, 126);
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0xFD, 0);
+}
+
+void Scene316::step() {
+ if (_game._trigger == 60) {
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[1]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger >= 70) {
+ switch (_game._trigger) {
+ case 70:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 5);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 71: {
+ int synxIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], synxIdx);
+ }
+ break;
+
+ case 72: {
+ int synxIdx = _globals._sequenceIndexes[6];
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 6, 9);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[6], synxIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ }
+ break;
+
+ case 73:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
+
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 10, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ break;
+
+ case 74: {
+ int synxIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 12);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], synxIdx);
+ }
+ break;
+
+ case 75:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[6]);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene316::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST)) {
+ if (_globals[kAfterHavoc])
+ _game._player._walkOffScreenSceneId = 354;
+ else
+ _game._player._walkOffScreenSceneId = 304;
+ }
+}
+
+void Scene316::actions() {
+ if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) {
+ if (_globals[kSexOfRex] == REX_FEMALE)
+ handleRoxInGrate();
+ else
+ handleRexInGrate();
+ } else if (_action.isAction(VERB_WALK_UP, NOUN_RAMP) || _action.isAction(VERB_WALK_ONTO, NOUN_PLATFORM)) {
+ switch (_game._trigger) {
+ case 0:
+ if (_globals[kCityFlooded]) {
+ _vm->_dialogs->show(31623);
+ } else {
+ _vm->_sound->command(45);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], -1, 7);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ } else {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ }
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 8, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_kernelMessages.reset();
+ if (!_game._visitedScenes.exists(321))
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(253));
+
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 7, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_sequences.addTimer(48, 4);
+ break;
+
+ case 3:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -2, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _scene->_sequences.addTimer(48, 4);
+ break;
+
+ case 4:
+ _scene->_nextSceneId = 321;
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM))
+ _vm->_dialogs->show(31610);
+ else if (_action.isAction(VERB_LOOK, NOUN_STRANGE_DEVICE)) {
+ if (_game._visitedScenes.exists(321))
+ _vm->_dialogs->show(31612);
+ else
+ _vm->_dialogs->show(31611);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CONTROLS))
+ _vm->_dialogs->show(31613);
+ else if (_action.isAction(VERB_LOOK, NOUN_EQUIPMENT))
+ _vm->_dialogs->show(31614);
+ else if (_action.isAction(VERB_LOOK, NOUN_PANEL))
+ _vm->_dialogs->show(31615);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(31616);
+ else if (_action.isAction(VERB_LOOK, NOUN_RAMP))
+ _vm->_dialogs->show(31617);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(31618);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST)) {
+ if (!_globals[kAfterHavoc]) {
+ if (_game._difficulty != DIFFICULTY_EASY)
+ _vm->_dialogs->show(31620);
+ else
+ _vm->_dialogs->show(31619);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_FLOOR))
+ _vm->_dialogs->show(31621);
+ else if (_action.isAction(VERB_LOOK, NOUN_SUPPORT))
+ _vm->_dialogs->show(31622);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+
+/*------------------------------------------------------------------------*/
+
+Scene318::Scene318(MADSEngine *vm) : Scene3xx(vm) {
+ _dropTimer = 0;
+
+ _lastFrame = -1;
+ _animMode = -1;
+ _internCounter = -1;
+ _counter = -1;
+
+ _dialogFl = false;
+ _internTalkingFl = false;
+ _internWalkingFl = false;
+ _internVisibleFl = false;
+ _explosionFl = false;
+
+ _lastFrameCounter = 0;
+
+ _subQuote2 = "";
+}
+
+void Scene318::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsUint32LE(_dropTimer);
+
+ s.syncAsSint32LE(_lastFrame);
+ s.syncAsSint32LE(_animMode);
+ s.syncAsSint32LE(_internCounter);
+ s.syncAsSint32LE(_counter);
+
+ s.syncAsByte(_dialogFl);
+ s.syncAsByte(_internTalkingFl);
+ s.syncAsByte(_internWalkingFl);
+ s.syncAsByte(_internVisibleFl);
+ s.syncAsByte(_explosionFl);
+
+ s.syncAsUint32LE(_lastFrameCounter);
+
+ s.syncString(_subQuote2);
+}
+
+void Scene318::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene318::handleDialog() {
+ if (!_game._trigger) {
+ _game._player._stepEnabled = false;
+ handleRexDialogs(_action._activeAction._verbId);
+ } else if (_game._trigger == 2) {
+ int synxIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], synxIdx);
+ _vm->_sound->command(3);
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._stepEnabled = true;
+ } else {
+ if (_action._activeAction._verbId < 0x19C)
+ _dialog1.write(_action._activeAction._verbId, false);
+
+ switch (_action._activeAction._verbId) {
+ case 0x191:
+ handleInternDialog(0x19E, 2, 9999999);
+ _dialog1.write(0x192, true);
+ break;
+
+ case 0x192:
+ handleInternDialog(0x1A0, 5, 9999999);
+ _dialog1.write(0x193, true);
+ break;
+
+ case 0x193:
+ handleInternDialog(0x1A5, 4, 9999999);
+ _dialog1.write(0x194, true);
+ break;
+
+ case 0x194:
+ handleInternDialog(0x1A9, 6, 9999999);
+ _dialog1.write(0x195, true);
+ _dialog1.write(0x196, true);
+ _dialog1.write(0x19D, false);
+ break;
+
+ case 0x195:
+ handleInternDialog(0x1AF, 7, 9999999);
+ if (!_dialog1.read(0x196))
+ _dialog1.write(0x197, true);
+ break;
+
+ case 0x196:
+ handleInternDialog(0x1B6, 5, 9999999);
+ if (!_dialog1.read(0x195))
+ _dialog1.write(0x197, true);
+ break;
+
+ case 0x197:
+ handleInternDialog(0x1BB, 5, 9999999);
+ break;
+
+ case 0x198:
+ handleInternDialog(0x1C0, 5, 9999999);
+ _dialog1.write(0x19A, true);
+ break;
+
+ case 0x199:
+ handleInternDialog(0x1C5, 3, 9999999);
+ break;
+
+ case 0x19A:
+ handleInternDialog(0x1C8, 5, 9999999);
+ _dialog1.write(0x19B, true);
+ break;
+
+ case 0x19B:
+ handleInternDialog(0x1CD, 3, 9999999);
+ break;
+
+ case 0x19C:
+ case 0x19D:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+
+ _dialogFl = false;
+ handleInternDialog(0x1D0, 1, 120);
+ if (_dialog1.read(0) || (_action._activeAction._verbId == 0x19D)) {
+ _explosionFl = true;
+ _internCounter = 3420;
+ }
+ break;
+ }
+
+ if (_action._activeAction._verbId < 0x19C) {
+ _dialog1.start();
+ _game._player._stepEnabled = true;
+ }
+
+ }
+}
+
+void Scene318::handleRexDialogs(int quote) {
+ _scene->_kernelMessages.reset();
+
+ Common::String curQuote = _game.getQuote(quote);
+ if (_vm->_font->getWidth(curQuote, _scene->_textSpacing) > 200) {
+ Common::String subQuote1;
+ _game.splitQuote(curQuote, subQuote1, _subQuote2);
+ _scene->_kernelMessages.add(Common::Point(138, 59), 0x1110, 32, 0, 240, subQuote1);
+ _scene->_kernelMessages.add(Common::Point(138, 73), 0x1110, 32, 1, 180, _subQuote2);
+ } else
+ _scene->_kernelMessages.add(Common::Point(138, 73), 0x1110, 32, 1, 120, curQuote);
+}
+
+void Scene318::handleInternDialog(int quoteId, int quoteNum, uint32 timeout) {
+ int height = quoteNum * 14;
+ int posY;
+ if (height < 85)
+ posY = 87 - height;
+ else
+ posY = 2;
+
+ int curQuoteId= quoteId;
+
+ int maxWidth = 0;
+ for (int i = 0; i < quoteNum; i++) {
+ maxWidth = MAX(maxWidth, _vm->_font->getWidth(_game.getQuote(curQuoteId), -1));
+ curQuoteId++;
+ }
+
+ int posX = MIN(319 - maxWidth, 178 - (maxWidth >> 1));
+ curQuoteId = quoteId;
+
+ _scene->_kernelMessages.reset();
+ _internTalkingFl = true;
+
+ for (int i = 0; i < quoteNum; i++) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(180, 63);
+ _scene->_kernelMessages.add(Common::Point(posX, posY), 0xFDFC, 0, 0, timeout, _game.getQuote(curQuoteId));
+ posY += 14;
+ curQuoteId++;
+ }
+}
+
+void Scene318::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('k', -1));
+
+ if (_globals[kAfterHavoc]) {
+ _scene->loadAnimation(formAnimName('f', -1));
+ _scene->_activeAnimation->_resetFlag = true;
+ } else if (!_globals[kHasSeenProfPyro]) {
+ _scene->_hotspots.activate(NOUN_PROFESSORS_GURNEY, false);
+ _scene->_hotspots.activate(NOUN_PROFESSOR, false);
+ _scene->_hotspots.activate(NOUN_TAPE_PLAYER, false);
+ }
+
+ if (_game._objects.isInRoom(OBJ_SCALPEL)) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 0, 0, 120);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 4);
+ _scene->_dynamicHotspots.add(NOUN_SCALPEL, VERB_TAKE, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ }
+
+ if (_scene->_priorSceneId == 357)
+ _game._player._playerPos = Common::Point(15, 110);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(214, 152);
+
+ _dialog1.setup(0x47, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0);
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _dialog1.set(0x191, 0x198, 0x199, 0x19C, 0);
+ if (_game._widepipeCtr >= 2)
+ _dialog1.write(0x19D, true);
+ }
+
+ if (_scene->_priorSceneId == 307) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('a', -1), 60);
+ _animMode = 1;
+ }
+
+ _lastFrame = 0;
+ _scene->_hotspots.activate(NOUN_INTERN, false);
+
+ if (_scene->_priorSceneId != -2) {
+ _dialogFl = false;
+ _internWalkingFl = false;
+ _counter= 0;
+ _internCounter= 0;
+ _internVisibleFl = true;
+ _explosionFl = false;
+ }
+
+ _game.loadQuoteSet(0x18C, 0x18D, 0x18E, 0x18F, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196,
+ 0x197, 0x198, 0x199, 0x19A, 0x19B, 0x19C, 0x19E, 0x19E, 0x1A0, 0x1A1, 0x1A2, 0x1A3,
+ 0x1A4, 0x1A5, 0x1A6, 0x1A7, 0x1A8, 0x1A9, 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1AE, 0x1AF,
+ 0x1B0, 0x1B1, 0x1B2, 0x1B3, 0x1B4, 0x1B5, 0x1B6, 0x1B7, 0x1B8, 0x1B9, 0x1BA, 0x1BB,
+ 0x1BC, 0x1BD, 0x1BE, 0x1BF, 0x1C0, 0x1C1, 0x1C2, 0x1C3, 0x1C4, 0x1C5, 0x1C6, 0x1C7,
+ 0x1C8, 0x1C9, 0x1CA, 0x1CB, 0x1CC, 0x1CD, 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3,
+ 0x190, 0x19D, 0);
+
+ if ((_scene->_priorSceneId== -2) || (((_scene->_priorSceneId == 318) || (_scene->_priorSceneId == -1)) && (!_globals[kAfterHavoc]))) {
+ if (!_globals[kAfterHavoc]) {
+ _game._player._visible = false;
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('g', -1));
+ _animMode = 2;
+
+ if (_game._visitedScenes.exists(319) || !_internVisibleFl) {
+ _internVisibleFl = false;
+ _dialogFl = false;
+ } else {
+ _scene->loadAnimation(formAnimName('b', -1), 61);
+ _scene->_hotspots.activate(NOUN_INTERN, true);
+ }
+
+ if (_dialogFl) {
+ _dialog1.start();
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 8);
+ } else
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ }
+ }
+
+ if (_scene->_priorSceneId == 319) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _animMode = 4;
+ if (!_globals[kHasSeenProfPyro]) {
+ _scene->loadAnimation(formAnimName('d', -1), 64);
+ _globals[kHasSeenProfPyro] = true;
+ } else {
+ _scene->loadAnimation(formAnimName('e', -1), 64);
+ }
+ }
+
+ _internTalkingFl = false;
+ _vm->_palette->setEntry(252, 63, 63, 10);
+ _vm->_palette->setEntry(253, 45, 45, 05);
+
+ _dropTimer = _vm->_game->_scene._frameStartTime;
+ sceneEntrySound();
+
+ if (_dialogFl)
+ _vm->_sound->command(15);
+}
+
+void Scene318::step() {
+ if ((_scene->_activeAnimation != nullptr) && (_animMode == 2)) {
+ if (_lastFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _lastFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+
+ switch (_lastFrame) {
+ case 20:
+ case 30:
+ case 40:
+ case 50:
+ case 60:
+ case 70:
+ case 80:
+ case 90:
+ case 100:
+ case 110:
+ case 120:
+ case 130:
+ case 140:
+ case 149:
+ if (_internWalkingFl) {
+ nextFrame = 149;
+ } else if (_internTalkingFl) {
+ nextFrame = 149;
+ } else if (_lastFrame == 149) {
+ nextFrame = 4;
+ }
+ break;
+
+ case 151:
+ if (_internWalkingFl)
+ nextFrame = 183;
+ break;
+
+ case 167:
+ case 184:
+ if (_internWalkingFl) {
+ nextFrame = 184;
+ } else if (!_internTalkingFl) {
+ nextFrame = 0;
+ } else if (_vm->getRandomNumber(1, 100) <= 50) {
+ nextFrame = 151;
+ } else {
+ nextFrame = 167;
+ }
+
+ if (nextFrame == 184) {
+ handleInternDialog(0x1D1, 3, 240);
+ _scene->_hotspots.activate(NOUN_INTERN, false);
+ _internVisibleFl = false;
+ }
+ break;
+ }
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _lastFrame = nextFrame;
+ }
+ }
+ }
+
+ switch (_game._trigger) {
+ case 60:
+ _vm->_sound->command(3);
+ _animMode = 2;
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ case 61:
+ _counter = 0;
+ break;
+
+ case 62:
+ _scene->_nextSceneId = 319;
+ break;
+
+ case 63:
+ _internTalkingFl = false;
+ break;
+
+ case 64:
+ _vm->_sound->command(3);
+ _scene->_nextSceneId = 307;
+ break;
+ }
+
+ uint32 tmpFrame = _vm->_events->getFrameCounter();
+ long diffFrame = tmpFrame - _lastFrameCounter;
+ _lastFrameCounter = tmpFrame;
+
+ if ((_animMode == 2) && !_internVisibleFl && _game._player._stepEnabled) {
+ if ((diffFrame >= 0) && (diffFrame <= 4))
+ _counter += diffFrame;
+ else
+ _counter++;
+
+ int extraCounter = _game._objects.isInInventory(OBJ_SCALPEL) ? 900 : 0;
+
+ if (_counter + extraCounter >= 1800) {
+ _scene->freeAnimation();
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('c', -1), 62);
+ _animMode = 3;
+ }
+ } else if ((_animMode == 2) && _explosionFl && _internVisibleFl && !_dialogFl
+ && !_internWalkingFl && (_game._screenObjects._inputMode != 1)) {
+ if ((diffFrame >= 0) && (diffFrame <= 4))
+ _internCounter += diffFrame;
+ else
+ _internCounter++;
+
+ if (_internCounter >= 3600) {
+ _vm->_sound->command(59);
+ _vm->_screen._shakeCountdown = 20;
+ _internWalkingFl = true;
+ }
+ }
+
+ if ((_vm->_game->_scene._frameStartTime - _dropTimer) > 600) {
+ _vm->_sound->command(51);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 14, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _dropTimer = _vm->_game->_scene._frameStartTime;
+ }
+}
+
+void Scene318::preActions() {
+ if (_game._player._needToWalk)
+ _game._player._needToWalk = _game._player._visible;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 357;
+}
+
+void Scene318::actions() {
+ if (_game._screenObjects._inputMode == 1) {
+ handleDialog();
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TALKTO, NOUN_INTERN)) {
+ switch (_game._trigger) {
+ case 0: {
+ _dialogFl = true;
+ _vm->_sound->command(15);
+ _game._player._stepEnabled = false;
+ handleRexDialogs(_vm->getRandomNumber(0x18C, 0x18E));
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 80);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _game._player._stepEnabled = true;
+ handleInternDialog(0x18F, 1, 9999999);
+ _dialog1.start();
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ }
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_SCALPEL) && (_game._objects.isInRoom(OBJ_SCALPEL) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 2, 0, 80);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ if (_internVisibleFl)
+ handleInternDialog(0x190, 1, 120);
+ else {
+ _game._objects.addToInventory(OBJ_SCALPEL);
+ _vm->_dialogs->showItem(OBJ_SCALPEL, 0x7C5D);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ }
+ break;
+
+ case 2: {
+ int oldIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], oldIdx);
+ _scene->_sequences.addTimer(60, 3);
+ }
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_game._player._visible) {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH)) {
+ _scene->_nextSceneId = 407;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_TAPE_PLAYER)) {
+ if (_game._objects.isInRoom(OBJ_AUDIO_TAPE)) {
+ _vm->_dialogs->showItem(OBJ_AUDIO_TAPE, 0x7C5B);
+ _game._objects.addToInventory(OBJ_AUDIO_TAPE);
+ } else
+ _vm->_dialogs->show(31834);
+
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_TAPE_PLAYER)) {
+ if (_game._objects.isInRoom(OBJ_AUDIO_TAPE))
+ _vm->_dialogs->show(31833);
+ else
+ _vm->_dialogs->show(31834);
+
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALK_INTO, NOUN_DOCTORS_OFFICE)) {
+ _vm->_dialogs->show(31831);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_GURNEY)) {
+ _vm->_dialogs->show(31823);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_INSTRUMENT_TABLE)) {
+ _vm->_dialogs->show(31825);
+ _action._inProgress = false;
+ return;
+ }
+ } else { // Not visible
+ if (_action.isAction(VERB_LOOK, NOUN_GURNEY)) {
+ _vm->_dialogs->show(31822);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_INSTRUMENT_TABLE)) {
+ _vm->_dialogs->show(31824);
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(31810);
+ else if (_action.isAction(VERB_LOOK, NOUN_FLOOR))
+ _vm->_dialogs->show(31811);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(31812);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(31813);
+ else if (_action.isAction(VERB_LOOK, NOUN_FAUCET))
+ _vm->_dialogs->show(31814);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(31815);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONVEYOR_BELT))
+ _vm->_dialogs->show(31816);
+ else if (_action.isAction(VERB_LOOK, NOUN_LARGE_BLADE))
+ _vm->_dialogs->show(31817);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(31818);
+ else if (_action.isAction(VERB_LOOK, NOUN_CABINETS))
+ _vm->_dialogs->show(31819);
+ else if (_action.isAction(VERB_LOOK, NOUN_EQUIPMENT))
+ _vm->_dialogs->show(31820);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHELF))
+ _vm->_dialogs->show(31821);
+ else if (_action.isAction(VERB_OPEN, NOUN_CABINETS))
+ _vm->_dialogs->show(31829);
+ else if (_action.isAction(VERB_LOOK, NOUN_INTERN))
+ _vm->_dialogs->show(31830);
+ else if (_action.isAction(VERB_LOOK, NOUN_PROFESSOR))
+ _vm->_dialogs->show(31832);
+ else if (_action.isAction(VERB_LOOK, NOUN_PROFESSORS_GURNEY))
+ _vm->_dialogs->show(31836);
+ else if (_action._lookFlag) {
+ if (_game._player._visible || _game._objects.isInInventory(OBJ_SCALPEL))
+ _vm->_dialogs->show(31828);
+ else if (_internVisibleFl)
+ _vm->_dialogs->show(31826);
+ else
+ _vm->_dialogs->show(31827);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene319::Scene319(MADSEngine *vm) : Scene3xx(vm) {
+ _animMode = -1;
+ _animFrame = -1;
+ _nextAction1 = -1;
+ _nextAction2 = -1;
+ _slacheMode = -1;
+ _slacheTopic = -1;
+ _slachePosY = -1;
+
+ _slacheTalkingFl = false;
+ _slacheReady = false;
+ _slacheInitFl = false;
+
+ _subQuote2 = "";
+}
+
+void Scene319::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsUint32LE(_animMode);
+ s.syncAsUint32LE(_animFrame);
+ s.syncAsUint32LE(_nextAction1);
+ s.syncAsUint32LE(_nextAction2);
+ s.syncAsUint32LE(_slacheMode);
+ s.syncAsUint32LE(_slacheTopic);
+ s.syncAsUint32LE(_slachePosY);
+
+ s.syncAsByte(_slacheTalkingFl);
+ s.syncAsByte(_slacheReady);
+ s.syncAsByte(_slacheInitFl);
+
+ s.syncString(_subQuote2);
+}
+
+void Scene319::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene319::handleRexDialogues(int quote) {
+ _scene->_kernelMessages.reset();
+
+ Common::String curQuote = _game.getQuote(quote);
+ if (_vm->_font->getWidth(curQuote, _scene->_textSpacing) > 200) {
+ Common::String subQuote1;
+ _game.splitQuote(curQuote, subQuote1, _subQuote2);
+ _scene->_kernelMessages.add(Common::Point(160, 106), 0x1110, 32, 0, 120, subQuote1);
+ _scene->_kernelMessages.add(Common::Point(160, 120), 0x1110, 32, 1, 120, _subQuote2);
+ } else
+ _scene->_kernelMessages.add(Common::Point(160, 120), 0x1110, 32, 1, 120, curQuote);
+}
+
+void Scene319::handleSlacheDialogs(int quoteId, int counter, uint32 timer) {
+ int curQuote = quoteId;
+ int posY = 5 + (_slachePosY * 14);
+
+ for (int count = 0; count < counter; count++, curQuote++) {
+ _scene->_kernelMessages.add(Common::Point(8, posY), 0xFDFC, 0, 0, timer, _game.getQuote(curQuote));
+ posY += 14;
+ }
+}
+
+void Scene319::enter() {
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('e', 0));
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 3));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('k', -1));
+
+ if (!_game._objects.isInInventory(OBJ_SCALPEL)) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ }
+
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 18, 0, 0, 300);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 67, 0, 0, 377);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 173, 0, 0, 233);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 14);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 14);
+
+ _globals._sequenceIndexes[0] = _scene->_sequences.startCycle(_globals._spriteIndexes[0], false, 1);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+
+ _dialog1.setup(0x43, 0x165, 0x166, 0x167, 0x168, 0x169, 0x16A, 0);
+ _dialog2.setup(0x44, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0);
+ _dialog3.setup(0x45, 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0);
+
+ if (_scene->_priorSceneId != -2) {
+ _dialog1.set(0x165, 0x166, 0x167, 0x168, 0);
+ _dialog2.set(0x171, 0x172, 0x173, 0x174, 0);
+ _dialog3.set(0x17D, 0x17E, 0x17F, 0x180, 0);
+ }
+
+ _game.loadQuoteSet(0x15F, 0x160, 0x161, 0x162, 0x163, 0x164, 0x16B, 0x16C, 0x16D,
+ 0x16E, 0x16F, 0x170, 0x177, 0x178, 0x178, 0x17A, 0x17B, 0x17C, 0x165, 0x166,
+ 0x167, 0x168, 0x169, 0x16A, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x17D,
+ 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0x184, 0x185, 0x186, 0x187, 0x188,
+ 0x189, 0x18A, 0x18B, 0);
+
+ _vm->_palette->setEntry(252, 63, 30, 2);
+ _vm->_palette->setEntry(253, 45, 15, 1);
+
+ _slachePosY = 0;
+ _slacheInitFl = false;
+ _slacheTalkingFl = false;
+ _slacheReady = false;
+ _animFrame = 0;
+
+ _scene->loadAnimation(formAnimName('b', 0));
+
+ if (_scene->_priorSceneId != -2) {
+ _animMode = 1;
+ _nextAction1 = 2;
+ _nextAction2 = 2;
+ _slacheMode = 1;
+ _slacheTopic = 1;
+ _slacheInitFl = true;
+
+ if (_globals[kRexHasMetSlache]) {
+ handleSlacheDialogs(VERB_WALK_OUTSIDE, 2, 9999999);
+ _slachePosY = 3;
+ } else {
+ handleSlacheDialogs(0x186, 4, 9999999);
+ _slachePosY = 5;
+ }
+ }
+
+ switch (_slacheTopic) {
+ case 1:
+ handleSlacheDialogs(0x15F, 2, 9999999);
+ _dialog1.start();
+ break;
+
+ case 2:
+ handleSlacheDialogs(0x16B, 2, 9999999);
+ _dialog2.start();
+ break;
+
+ case 3:
+ handleSlacheDialogs(0x177, 2, 9999999);
+ _dialog3.start();
+ break;
+
+ default:
+ break;
+ }
+
+ _slachePosY = 0;
+ sceneEntrySound();
+}
+
+void Scene319::step() {
+ if (_scene->_activeAnimation == nullptr)
+ return;
+
+ if (_animFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _animFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+ if (_animMode == 1) {
+ switch (_animFrame) {
+ case 6:
+ _slacheTalkingFl = true;
+ break;
+
+ case 29:
+ _slacheReady = true;
+ break;
+
+ case 39:
+ if (_slacheInitFl) {
+ _slacheInitFl = false;
+ if (_nextAction1 == 2)
+ nextFrame = 0;
+ } else if (_nextAction1 == 2)
+ _nextAction1 = 1;
+ break;
+
+ case 50:
+ case 60:
+ case 70:
+ case 85:
+ if (_nextAction1 == 2)
+ nextFrame = 0;
+ else if (_nextAction1 == 3) {
+ nextFrame = 85;
+ _slacheTalkingFl = true;
+ } else if (_animFrame == 85) {
+ if (!_game._player._stepEnabled)
+ _slacheTalkingFl = true;
+ nextFrame = 40;
+ }
+ break;
+
+ case 115:
+ _slacheReady = true;
+ break;
+
+ case 129:
+ if (_nextAction1 == 3) {
+ nextFrame = 115;
+ if (!_game._player._stepEnabled)
+ _slacheTalkingFl = true;
+ }
+ break;
+
+ case 145:
+ nextFrame = 40;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((_animFrame > 40) && (_animFrame < 85) && (nextFrame < 0)) {
+ switch (_nextAction1) {
+ case 4:
+ _animFrame = 0;
+ _scene->freeAnimation();
+ _animMode = 2;
+ _scene->loadAnimation(formAnimName('b', 3), 70);
+ break;
+
+ case 5:
+ _animFrame = 0;
+ _scene->freeAnimation();
+ _animMode = 3;
+ _scene->loadAnimation(formAnimName('b', 4), 71);
+ break;
+
+ case 6:
+ _animFrame = 0;
+ _scene->freeAnimation();
+ _animMode = 4;
+ _scene->loadAnimation(formAnimName('b', 5), 72);
+ break;
+
+ default:
+ break;
+ }
+
+ if (!_animFrame) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[0]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+
+ for (int i = 0; i <= 1; i++) {
+ _globals._sequenceIndexes[i] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[i], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[i], 1, 7);
+ }
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ }
+ }
+ }
+
+ if (_animMode == 2) {
+ if (_animFrame == 13)
+ _vm->_screen._shakeCountdown = 40;
+
+ if (_animFrame == 16)
+ _vm->_screen._shakeCountdown = 1;
+ }
+
+ if (_animMode == 3) {
+ if (_animFrame == 11)
+ _vm->_screen._shakeCountdown = 60;
+
+ if (_animFrame == 18)
+ _vm->_screen._shakeCountdown = 1;
+ }
+
+ if ((_animMode == 4) && (_animFrame == 16))
+ _vm->_screen._shakeCountdown = 80;
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _animFrame = nextFrame;
+ }
+ }
+
+ switch (_game._trigger) {
+ case 70:
+ case 71:
+ _animMode = 1;
+ _nextAction1 = _nextAction2;
+ _animFrame = 0;
+ _scene->freeAnimation();
+ _scene->loadAnimation(formAnimName('b', 0));
+ if (_nextAction1 == 3)
+ _scene->_activeAnimation->setCurrentFrame(85);
+ else if (_nextAction1 == 1)
+ _scene->_activeAnimation->setCurrentFrame(40);
+
+ _animFrame = _scene->_activeAnimation->getCurrentFrame();
+ _slacheTalkingFl = true;
+ _vm->_screen._shakeCountdown = 1;
+
+ for (int i = 0; i <= 1; i++) {
+ int oldIdx = _globals._sequenceIndexes[i];
+ _scene->_sequences.remove(_globals._sequenceIndexes[i]);
+ _globals._sequenceIndexes[i] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[i], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[i], 8, 13);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[i], oldIdx);
+ }
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+ break;
+
+ case 72:
+ _vm->_palette->setColorFlags(0xFF, 0, 0);
+ _vm->_palette->setColorValues(0, 0, 0);
+ _vm->_palette->fadeOut(_vm->_palette->_mainPalette, nullptr, 18, 228,
+ 248, 0, 1, 16);
+ _vm->_screen._shakeCountdown = 1;
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ case 73:
+ for (int i = 0; i <= 1; i++) {
+ int oldIdx = _globals._sequenceIndexes[i];
+ _scene->_sequences.remove(_globals._sequenceIndexes[i]);
+ _globals._sequenceIndexes[i] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[i], false, 8, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[i], 6, 7);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[i], oldIdx);
+ }
+ break;
+
+ case 74:
+ for (int i = 0; i <= 1; i++) {
+ int oldIdx = _globals._sequenceIndexes[i];
+ _scene->_sequences.remove(_globals._sequenceIndexes[i]);
+ _globals._sequenceIndexes[i] = _scene->_sequences.startCycle(_globals._spriteIndexes[i], false, 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[i], oldIdx);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene319::actions() {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ handleRexDialogues(_action._activeAction._verbId);
+ } else {
+ if ((_action._activeAction._verbId == 0x165) || (_action._activeAction._verbId == 0x166)) {
+ if (_game._trigger == 1) {
+ _nextAction1 = 3;
+ _slacheTalkingFl = false;
+ _slacheMode = 1;
+ _slacheTopic = 2;
+ }
+
+ if (!_slacheTalkingFl) {
+ _scene->_sequences.addTimer(4, 2);
+ } else {
+ handleSlacheDialogs(0x16B, 2, 9999999);
+ _dialog2.start();
+ _game._player._stepEnabled = true;
+ }
+ }
+
+ if ((_action._activeAction._verbId == 0x171) || (_action._activeAction._verbId == 0x172)) {
+ if (_game._trigger == 1) {
+ _nextAction1 = 2;
+ _slacheTalkingFl = false;
+ _slacheMode = 1;
+ _slacheTopic = 3;
+ }
+
+ if (!_slacheTalkingFl) {
+ _scene->_sequences.addTimer(4, 2);
+ } else {
+ handleSlacheDialogs(0x177, 2, 9999999);
+ _dialog3.start();
+ _game._player._stepEnabled = true;
+ }
+ }
+
+ if ((_action._activeAction._verbId == 0x17D) || (_action._activeAction._verbId == 0x17E)) {
+ if (_game._trigger == 1) {
+ _nextAction1 = 3;
+ _slacheTalkingFl = false;
+ _slacheReady = false;
+ _slacheMode = 1;
+ _slacheTopic = 1;
+ }
+
+ if (!_slacheTalkingFl) {
+ _scene->_sequences.addTimer(4, 2);
+ } else {
+ if (_game._trigger == 2)
+ handleSlacheDialogs(0x184, 2, 180);
+
+ if (!_slacheReady) {
+ _scene->_sequences.addTimer(120, 3);
+ } else {
+ _globals[kRexHasMetSlache] = true;
+ _scene->_nextSceneId = 318;
+ }
+ }
+ }
+
+ if ((_action._activeAction._verbId == 0x168) || (_action._activeAction._verbId == 0x174) ||
+ (_action._activeAction._verbId == 0x180) || (_action._activeAction._verbId == 0x169) ||
+ (_action._activeAction._verbId == 0x175) || (_action._activeAction._verbId == 0x181) ||
+ (_action._activeAction._verbId == 0x16A) || (_action._activeAction._verbId == 0x176) ||
+ (_action._activeAction._verbId == 0x182) || (_action._activeAction._verbId == 0x183) ||
+ (_action._activeAction._verbId == 0x167) || (_action._activeAction._verbId == 0x173) ||
+ (_action._activeAction._verbId == 0x17F)) {
+
+ bool addDialogLine = !((_action._activeAction._verbId == 0x167) || (_action._activeAction._verbId == 0x173) ||
+ (_action._activeAction._verbId == 0x17F) || (_action._activeAction._verbId == 0x16A) ||
+ (_action._activeAction._verbId == 0x176) || (_action._activeAction._verbId == 0x182) ||
+ (_action._activeAction._verbId == 0x183));
+
+ int addVerbId = _action._activeAction._verbId + 1;
+ if ((addVerbId == 0x182) && (_game._storyMode != STORYMODE_NAUGHTY))
+ addVerbId = 0x183;
+
+ if (_slacheMode == 1) {
+ if (_game._trigger == 1) {
+ _nextAction2 = _nextAction1;
+ _nextAction1 = 4;
+ }
+
+ if (_nextAction1 != _nextAction2) {
+ _scene->_sequences.addTimer(4, 2);
+ } else {
+ Conversation *curDialog;
+ int nextDocQuote;
+ if ((_action._activeAction._verbId == 0x168) || (_action._activeAction._verbId == 0x167)) {
+ curDialog = &_dialog1;
+ nextDocQuote = 0x161;
+ } else if ((_action._activeAction._verbId == 0x174) || (_action._activeAction._verbId == 0x1753)) {
+ nextDocQuote = 0x16D;
+ curDialog = &_dialog2;
+ } else {
+ nextDocQuote = 0x179;
+ curDialog = &_dialog3;
+ }
+
+ handleSlacheDialogs(nextDocQuote, 2, 9999999);
+ if (addDialogLine) {
+ curDialog->write(_action._activeAction._verbId, false);
+ curDialog->write(addVerbId, true);
+ }
+
+ curDialog->start();
+ _game._player._stepEnabled = true;
+ _slacheMode = 2;
+ }
+ } else if (_slacheMode == 2) {
+ if (_game._trigger == 1) {
+ _nextAction2 = _nextAction1;
+ _nextAction1 = 5;
+ }
+
+ if (_nextAction1 != _nextAction2) {
+ _scene->_sequences.addTimer(4, 2);
+ } else {
+ Conversation *curDialog;
+ int nextDocQuote;
+ if ((_action._activeAction._verbId == 0x168) || (_action._activeAction._verbId == 0x169) || (_action._activeAction._verbId == 0x167)) {
+ curDialog = &_dialog1;
+ nextDocQuote = 0x163;
+ } else if ((_action._activeAction._verbId == 0x174) || (_action._activeAction._verbId == 0x175) || (_action._activeAction._verbId == 0x173)) {
+ nextDocQuote = 0x16F;
+ curDialog = &_dialog2;
+ } else {
+ nextDocQuote = 0x17B;
+ curDialog = &_dialog3;
+ }
+
+ handleSlacheDialogs(nextDocQuote, 2, 9999999);
+ if (addDialogLine) {
+ curDialog->write(_action._activeAction._verbId, false);
+ curDialog->write(addVerbId, true);
+ }
+
+ curDialog->start();
+ _game._player._stepEnabled = true;
+ _slacheMode = 3;
+ }
+ } else {
+ _nextAction2 = _nextAction1;
+ _nextAction1 = 6;
+ }
+ }
+ }
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene320::Scene320(MADSEngine *vm) : Scene300s(vm) {
+ _blinkFl = false;
+ _flippedFl = false;
+
+ _buttonId = -1;
+ _lastFrame = -1;
+ _leftItemId = -1;
+ _posX = -1;
+ _rightItemId = -1;
+}
+
+void Scene320::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsByte(_blinkFl);
+ s.syncAsByte(_flippedFl);
+
+ s.syncAsSint32LE(_buttonId);
+ s.syncAsSint32LE(_lastFrame);
+ s.syncAsSint32LE(_leftItemId);
+ s.syncAsSint32LE(_posX);
+ s.syncAsSint32LE(_rightItemId);
+}
+
+void Scene320::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene320::setRightView(int view) {
+ if (_rightItemId < 8) _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+
+ int spriteNum;
+ switch (view) {
+ case 0:
+ spriteNum = 16;
+ break;
+
+ case 1:
+ spriteNum = 14;
+ break;
+
+ case 2:
+ spriteNum = 17;
+ break;
+
+ case 3:
+ spriteNum = 15;
+ break;
+
+ default:
+ spriteNum = view + 6;
+ break;
+ }
+
+ if (view != 8) {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[spriteNum], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 0);
+ }
+
+ _globals[kRightView320] = _rightItemId = view;
+}
+
+void Scene320::setLeftView(int view) {
+ if (_leftItemId < 10)
+ _scene->_sequences.remove(_globals._sequenceIndexes[0]);
+
+ if (view != 10) {
+ _globals._sequenceIndexes[0] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[view], false, 6, 0, 0, 18);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 0);
+ if (!_blinkFl)
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[0], 2, 2);
+ }
+
+ _leftItemId = view;
+}
+
+void Scene320::handleButtons() {
+ switch(_action._activeAction._objectNameId) {
+ case 0x2DD:
+ _buttonId = 5;
+ break;
+
+ case 0x2DE:
+ _buttonId = 4;
+ break;
+
+ case 0x2E0:
+ _buttonId = 6;
+ break;
+
+ case 0x2E1:
+ _buttonId = 7;
+ break;
+
+ case 0x2E2:
+ _buttonId = 8;
+ break;
+
+ case 0x2E3:
+ _buttonId = 9;
+ break;
+
+ case 0x2E4:
+ _buttonId = 10;
+ break;
+
+ case 0x2E5:
+ _buttonId = 11;
+ break;
+
+ case 0x2E6:
+ _buttonId = 12;
+ break;
+
+ case 0x2E7:
+ _buttonId = 13;
+ break;
+
+ case 0x2E8:
+ _buttonId = 0;
+ break;
+
+ case 0x2E9:
+ _buttonId = 1;
+ break;
+
+ case 0x2EA:
+ _buttonId = 2;
+ break;
+
+ case 0x2EB:
+ _buttonId = 3;
+ break;
+
+ default:
+ break;
+ }
+
+ if (_buttonId <= 3) {
+ _posX = (8 * _buttonId) - 2;
+ _flippedFl = true;
+ } else if (_buttonId <= 5) {
+ _posX = (13 * _buttonId) - 14;
+ _flippedFl = true;
+ } else {
+ _posX = (8 * _buttonId) + 98;
+ _flippedFl = false;
+ }
+}
+
+void Scene320::enter() {
+ _blinkFl = true;
+ _rightItemId = 8;
+ _leftItemId = 10;
+ _lastFrame = 0;
+
+ for (int i = 0; i < 10; i++)
+ _globals._spriteIndexes[i] = _scene->_sprites.addSprites(formAnimName('M', i));
+
+ for (int i = 0; i < 8; i++)
+ _globals._spriteIndexes[10 + i] = _scene->_sprites.addSprites(formAnimName('N', i));
+
+ _globals._spriteIndexes[18] = _scene->_sprites.addSprites("*REXHAND");
+ _game._player._visible = false;
+
+ setRightView(_globals[kRightView320]);
+ setLeftView(0);
+
+ _vm->_palette->setEntry(252, 63, 30, 20);
+ _vm->_palette->setEntry(253, 45, 15, 10);
+
+ sceneEntrySound();
+}
+
+void Scene320::step() {
+ if (_scene->_activeAnimation != nullptr) {
+ if (_lastFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _lastFrame = _scene->_activeAnimation->getCurrentFrame();
+ switch (_lastFrame) {
+ case 95:
+ _blinkFl = true;
+ setLeftView(9);
+ _vm->_sound->command(41);
+ break;
+
+ case 139:
+ _blinkFl = false;
+ setLeftView(9);
+ break;
+
+ case 191:
+ _scene->_kernelMessages.add(Common::Point(1, 1), 0xFDFC, 0, 0, 60, _game.getQuote(0xFE));
+ break;
+
+ case 417:
+ case 457:
+ _vm->_screen._shakeCountdown = 40;
+ _vm->_sound->command(59);
+ break;
+
+ case 430:
+ _blinkFl = true;
+ setLeftView(4);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_game._trigger == 70) {
+ _globals[kAfterHavoc] = true;
+ _globals[kTeleporterRoom + 1] = 351;
+ _scene->_nextSceneId = 361;
+ }
+}
+
+void Scene320::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(32011);
+ else if ((_action.isAction(VERB_PRESS) || _action.isAction(VERB_PUSH)) &&
+ (_action.isObject(NOUN_LEFT_1_KEY) || _action.isObject(NOUN_LEFT_2_KEY) || _action.isObject(NOUN_LEFT_3_KEY) || _action.isObject(NOUN_LEFT_4_KEY) ||
+ _action.isObject(NOUN_GREEN_BUTTON) || _action.isObject(NOUN_RED_BUTTON) || _action.isObject(NOUN_RIGHT_1_KEY) || _action.isObject(NOUN_RIGHT_2_KEY) ||
+ _action.isObject(NOUN_RIGHT_3_KEY) || _action.isObject(NOUN_RIGHT_4_KEY) || _action.isObject(NOUN_RIGHT_5_KEY) || _action.isObject(NOUN_RIGHT_6_KEY) ||
+ _action.isObject(NOUN_RIGHT_7_KEY) || _action.isObject(NOUN_RIGHT_8_KEY)
+ )) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ handleButtons();
+ _globals._sequenceIndexes[18] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[18], _flippedFl, 4, 2, 0, 0);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[18], 60);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[18], Common::Point(_posX, 170));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[18], 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[18], SEQUENCE_TRIGGER_LOOP, 0, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[18], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ if (_buttonId >= 6) {
+ _vm->_sound->command(60);
+ setRightView(_buttonId - 6);
+ }
+ if (_buttonId == 4) {
+ _vm->_sound->command(38);
+ if (_leftItemId == 3)
+ setLeftView(0);
+ else
+ setLeftView(3);
+ }
+ if (_buttonId == 5) {
+ _vm->_sound->command(38);
+ if (_leftItemId == 1)
+ setLeftView(2);
+ else
+ setLeftView(1);
+ }
+ if (_buttonId <= 3) {
+ _vm->_sound->command(60);
+ setLeftView(_buttonId + 5);
+ }
+ break;
+
+ case 2:
+ _game._player._stepEnabled = true;
+ if (_buttonId == 5) {
+ if (_leftItemId == 2) {
+ _game._player._stepEnabled = false;
+ setRightView(8);
+ setLeftView(10);
+ _scene->_kernelMessages.reset();
+ _scene->resetScene();
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('m', 2));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('m', 4));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('m', 9));
+ _blinkFl = false;
+ setLeftView(2);
+ _game.loadQuoteSet(0xFE, 0);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->loadAnimation(formAnimName('a', -1), 70);
+ _vm->_sound->command(17);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LEAVE, NOUN_SECURITY_STATION))
+ _scene->_nextSceneId = 311;
+ else if (_action.isAction(VERB_LOOK, NOUN_RIGHT_MONITOR))
+ _vm->_dialogs->show(32001);
+ else if (_action.isAction(VERB_LOOK, NOUN_LEFT_MONITOR))
+ _vm->_dialogs->show(32002);
+ else if (_action.isAction(VERB_LOOK, NOUN_DESK))
+ _vm->_dialogs->show(32003);
+ else if (_action.isAction(VERB_LOOK, NOUN_SECURITY_STATION))
+ _vm->_dialogs->show(32004);
+ else if (_action.isAction(VERB_LOOK, NOUN_MUG))
+ _vm->_dialogs->show(32005);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOUGHNUT))
+ _vm->_dialogs->show(32006);
+ else if (_action.isAction(VERB_LOOK, NOUN_MAGAZINE))
+ _vm->_dialogs->show(32006);
+ else if (_action.isAction(VERB_LOOK, NOUN_PAPER_FOOTBALL))
+ _vm->_dialogs->show(32008);
+ else if (_action.isAction(VERB_LOOK, NOUN_NEWSPAPER))
+ _vm->_dialogs->show(32009);
+ else if (_action.isAction(VERB_LOOK, NOUN_CLIPBOARD))
+ _vm->_dialogs->show(32010);
+ else if (_action.isAction(VERB_TAKE, NOUN_MUG))
+ _vm->_dialogs->show(32012);
+ else if (_action.isAction(VERB_TAKE, NOUN_CLIPBOARD))
+ _vm->_dialogs->show(32013);
+ else if (_action.isAction(VERB_TAKE, NOUN_DOUGHNUT) || _action.isAction(VERB_EAT, NOUN_DOUGHNUT))
+ _vm->_dialogs->show(32014);
+ else if (_action.isAction(VERB_TAKE, NOUN_PAPER_FOOTBALL))
+ _vm->_dialogs->show(32015);
+ else if (_action.isAction(VERB_TAKE, NOUN_MAGAZINE))
+ _vm->_dialogs->show(32016);
+ else if (_action.isAction(VERB_TAKE, NOUN_NEWSPAPER))
+ _vm->_dialogs->show(32017);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene321::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene321::enter() {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+
+ _scene->_userInterface.emptyConversationList();
+ _scene->_userInterface.setup(kInputConversation);
+
+ int suffixNum;
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals[kSexOfRex] = REX_MALE;
+ suffixNum = 1;
+ } else {
+ _globals[kSexOfRex] = REX_FEMALE;
+ suffixNum = _game._visitedScenes._sceneRevisited ? 2 : 0;
+ }
+
+ _scene->loadAnimation(formAnimName('g', suffixNum), 60);
+ sceneEntrySound();
+}
+
+void Scene321::step() {
+ if (_scene->_activeAnimation != nullptr) {
+ if ((_scene->_activeAnimation->getCurrentFrame() >= 260) && (_globals[kSexOfRex] == REX_MALE) && (_game._storyMode >= STORYMODE_NICE))
+ _scene->_nextSceneId = 316;
+ }
+
+ if (_game._trigger == 60)
+ _scene->_nextSceneId = 316;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene322::setup() {
+ _game._player._spritesPrefix = "";
+ // The original is calling scene3xx_setAAName()
+ _game._aaName = Resources::formatAAName(4);
+}
+
+void Scene322::enter() {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _handSpriteId = _scene->_sprites.addSprites("*REXHAND");
+ else
+ _handSpriteId = _scene->_sprites.addSprites("*ROXHAND");
+
+ teleporterEnter();
+
+ // The original is using scene3xx_sceneEntrySound()
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else
+ _vm->_sound->command(10);
+}
+
+void Scene322::step() {
+ teleporterStep();
+}
+
+void Scene322::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(32214);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (teleporterActions()) {
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT) || _action.isAction(VERB_PEER_THROUGH, NOUN_VIEWPORT))
+ _vm->_dialogs->show(32210);
+ else if (_action.isAction(VERB_LOOK, NOUN_KEYPAD))
+ _vm->_dialogs->show(32211);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(32212);
+ else if (_action.isAction(VERB_LOOK, NOUN_0_KEY) || _action.isAction(VERB_LOOK, NOUN_1_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_2_KEY) || _action.isAction(VERB_LOOK, NOUN_3_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_4_KEY) || _action.isAction(VERB_LOOK, NOUN_5_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_6_KEY) || _action.isAction(VERB_LOOK, NOUN_7_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_8_KEY) || _action.isAction(VERB_LOOK, NOUN_9_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_SMILE_KEY) || _action.isAction(VERB_LOOK, NOUN_ENTER_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_FROWN_KEY))
+ _vm->_dialogs->show(32213);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEVICE))
+ _vm->_dialogs->show(32214);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene351::setup() {
+ if (_scene->_currentSceneId == 391)
+ _globals[kSexOfRex] = REX_MALE;
+
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene351::enter() {
+ _globals[kAfterHavoc] = -1;
+ _globals[kTeleporterRoom + 1] = 351;
+
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*ROXRC_7");
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXRD_7");
+
+ if (_game._objects.isInRoom(OBJ_CREDIT_CHIP)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 4);
+ } else
+ _scene->_hotspots.activate(NOUN_CREDIT_CHIP, false);
+
+ if (_scene->_priorSceneId == 352)
+ _game._player._playerPos = Common::Point(148, 152);
+ else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(207, 81);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ if (_globals[kTeleporterCommand]) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+
+ char sepChar = 'a';
+ if (_globals[kSexOfRex] != REX_MALE)
+ sepChar = 'b';
+
+ int suffixNum = -1;
+ int trigger = 0;
+
+ switch (_globals[kTeleporterCommand]) {
+ case 1:
+ suffixNum = 0;
+ trigger = 60;
+ _globals[kTeleporterCommand] = true;
+ break;
+
+ case 2:
+ suffixNum = 1;
+ trigger = 61;
+ break;
+
+ case 3:
+ case 4:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _game._player._turnToFacing = FACING_SOUTH;
+ suffixNum = -1;
+ break;
+
+ default:
+ break;
+ }
+
+ _globals[kTeleporterCommand] = 0;
+
+ if (suffixNum >= 0)
+ _scene->loadAnimation(formAnimName(sepChar, suffixNum), trigger);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene351::step() {
+ if (_game._trigger == 60) {
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._turnToFacing = FACING_SOUTH;
+ }
+
+ if (_game._trigger == 61) {
+ _globals[kTeleporterCommand] = 1;
+ _scene->_nextSceneId = _globals[kTeleporterDestination];
+ _scene->_reloadSceneFlag = true;
+ }
+}
+
+void Scene351::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(35121);
+ else if (_action.isAction(VERB_STEP_INTO, NOUN_TELEPORTER))
+ _scene->_nextSceneId = 322;
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH))
+ _scene->_nextSceneId = 352;
+ else if (_action.isAction(VERB_TAKE, NOUN_CREDIT_CHIP)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_CREDIT_CHIP)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _scene->_hotspots.activate(NOUN_CREDIT_CHIP, false);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._objects.addToInventory(OBJ_CREDIT_CHIP);
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_CREDIT_CHIP, 0x32F);
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_VIEW_SCREEN))
+ _vm->_dialogs->show(35110);
+ else if (_action.isAction(VERB_LOOK, NOUN_RIP_IN_FLOOR))
+ _vm->_dialogs->show(35111);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIRE_HYDRANT))
+ _vm->_dialogs->show(35112);
+ else if (_action.isAction(VERB_LOOK, NOUN_GUARD)) {
+ if (_game._objects[0xF]._roomNumber == 351)
+ _vm->_dialogs->show(35114);
+ else
+ _vm->_dialogs->show(35113);
+ } else if (_action.isAction(VERB_LOOK, NOUN_EQUIPMENT))
+ _vm->_dialogs->show(35115);
+ else if (_action.isAction(VERB_LOOK, NOUN_DESK))
+ _vm->_dialogs->show(35116);
+ else if (_action.isAction(VERB_LOOK, NOUN_MACHINE))
+ _vm->_dialogs->show(35117);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(35118);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONTROL_PANEL))
+ _vm->_dialogs->show(35119);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(35120);
+ else if (_action.isAction(VERB_LOOK, NOUN_POLE))
+ _vm->_dialogs->show(35122);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene352::Scene352(MADSEngine *vm) : Scene3xx(vm) {
+ _vaultOpenFl = false;
+ _mustPutArmDownFl = false;
+ _leaveRoomFl = false;
+
+ _tapePlayerHotspotIdx = -1;
+ _hotspot1Idx = -1;
+ _hotspot2Idx = -1;
+ _lampHostpotIdx = -1;
+ _commonSequenceIdx = -1;
+ _commonSpriteIndex = -1;
+}
+
+void Scene352::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsByte(_vaultOpenFl);
+ s.syncAsByte(_mustPutArmDownFl);
+ s.syncAsByte(_leaveRoomFl);
+
+ s.syncAsSint32LE(_tapePlayerHotspotIdx);
+ s.syncAsSint32LE(_hotspot1Idx);
+ s.syncAsSint32LE(_hotspot2Idx);
+ s.syncAsSint32LE(_lampHostpotIdx);
+ s.syncAsSint32LE(_commonSequenceIdx);
+ s.syncAsSint32LE(_commonSpriteIndex);
+}
+
+void Scene352::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_YOUR_STUFF);
+ _scene->addActiveVocab(NOUN_OTHER_STUFF);
+ _scene->addActiveVocab(NOUN_LAMP);
+}
+
+void Scene352::putArmDown(bool corridorExit, bool doorwayExit) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(0xFF));
+ _scene->_sequences.addTimer(48, 1);
+ break;
+
+ case 1:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 5, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ } else {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 2: {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 0, 0);
+ int idx = _scene->_dynamicHotspots.add(NOUN_GUARDS_ARM, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(230, 117), FACING_NORTHWEST);
+ _scene->changeVariant(0);
+ }
+ break;
+
+ case 3:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x100));
+ _game._objects.setRoom(OBJ_GUARDS_ARM, _scene->_currentSceneId);
+ _game._player._visible = true;
+ if (corridorExit)
+ _scene->_sequences.addTimer(48, 6);
+ else if (doorwayExit)
+ _scene->_sequences.addTimer(48, 4);
+ else {
+ _mustPutArmDownFl = false;
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ case 4:
+ _game._player.walk(Common::Point(116, 107), FACING_NORTH);
+ _game._player._stepEnabled = true;
+ _mustPutArmDownFl = false;
+ _scene->_sequences.addTimer(180, 5);
+ _leaveRoomFl = true;
+ break;
+
+ case 5:
+ if (_leaveRoomFl)
+ _scene->_nextSceneId = 351;
+
+ break;
+
+ case 6:
+ _game._player.walk(Common::Point(171, 152), FACING_SOUTH);
+ _game._player._stepEnabled = true;
+ _mustPutArmDownFl = false;
+ _scene->_sequences.addTimer(180, 7);
+ _leaveRoomFl = true;
+ break;
+
+ case 7:
+ if (_leaveRoomFl)
+ _scene->_nextSceneId = 353;
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene352::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*RM302x0");
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites("*RM302x2");
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites("*RM302x3");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('g', -1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('b', -1));
+
+
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*ROXRC_7");
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites("*ROXRC_6");
+ _globals._spriteIndexes[15] = _scene->_sprites.addSprites("*ROXRC_9");
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('a', 3));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('a', 2));
+ } else {
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXRD_7");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites("*RXRC_6");
+ _globals._spriteIndexes[14] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ }
+
+ _leaveRoomFl = false;
+
+ if (_game._objects.isInRoom(OBJ_TAPE_PLAYER)) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 5);
+ int idx = _scene->_dynamicHotspots.add(NOUN_TAPE_PLAYER, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _tapePlayerHotspotIdx = _scene->_dynamicHotspots.setPosition(idx, Common::Point(84, 145), FACING_WEST);
+ }
+
+ _vaultOpenFl = false;
+
+ if (_scene->_priorSceneId != -2) {
+ _mustPutArmDownFl = false;
+ if (!_game._visitedScenes._sceneRevisited)
+ _globals[kHaveYourStuff] = false;
+ }
+
+ if (_game._objects.isInRoom(OBJ_GUARDS_ARM)) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 0, 0);
+ int idx = _scene->_dynamicHotspots.add(NOUN_GUARDS_ARM, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(230, 117), FACING_NORTHWEST);
+ } else
+ _mustPutArmDownFl = true;
+
+ if (_scene->_priorSceneId == 353)
+ _game._player._playerPos = Common::Point(171, 155);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(116, 107);
+
+ sceneEntrySound();
+
+ _game.loadQuoteSet(0xFF, 0x100, 0x101, 0x102, 0x103, 0);
+}
+
+void Scene352::preActions() {
+ _leaveRoomFl = false;
+
+ if (_action.isAction(VERB_OPEN, NOUN_VAULT))
+ _game._player.walk(Common::Point(266, 111), FACING_NORTHEAST);
+
+ if (_vaultOpenFl && !_action.isObject(NOUN_VAULT) && !_action.isObject(NOUN_LAMP) && !_action.isObject(NOUN_OTHER_STUFF) && !_action.isObject(NOUN_YOUR_STUFF)) {
+ if (_globals[kHaveYourStuff]) {
+ _commonSpriteIndex = _globals._spriteIndexes[13];
+ _commonSequenceIdx = _globals._sequenceIndexes[13];
+ } else {
+ _commonSpriteIndex = _globals._spriteIndexes[1];
+ _commonSequenceIdx = _globals._sequenceIndexes[1];
+ }
+
+ switch (_game._trigger) {
+ case 0:
+ if (_game._player._needToWalk) {
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_commonSequenceIdx);
+ _vm->_sound->command(20);
+ _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.setDepth(_commonSequenceIdx, 15);
+ }
+ break;
+
+ case 1:
+ if (!_globals[kHaveYourStuff])
+ _scene->_dynamicHotspots.remove(_hotspot2Idx);
+
+ _scene->_dynamicHotspots.remove(_hotspot1Idx);
+ _scene->_dynamicHotspots.remove(_lampHostpotIdx);
+ _vaultOpenFl = false;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_GUARDS_ARM, NOUN_SCANNER)) {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _game._player.walk(Common::Point(269, 111), FACING_NORTHEAST);
+ else
+ _game._player.walk(Common::Point(271, 111), FACING_NORTHEAST);
+ }
+
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY) || _action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH) || _action.isAction(VERB_PUT, NOUN_GUARDS_ARM, NOUN_FLOOR)) {
+ if (_game._objects.isInInventory(OBJ_GUARDS_ARM))
+ _game._player.walk(Common::Point(230, 117), FACING_NORTHWEST);
+ }
+}
+
+void Scene352::actions() {
+ if (_action._lookFlag) {
+ _vm->_dialogs->show(35225);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_OPEN, NOUN_VAULT)) {
+ if (!_vaultOpenFl) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_FEMALE)
+ _commonSpriteIndex = _globals._spriteIndexes[9];
+ else
+ _commonSpriteIndex = _globals._spriteIndexes[8];
+
+ _commonSequenceIdx = _scene->_sequences.addSpriteCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
+ _scene->_sequences.updateTimeout(_commonSequenceIdx, -1);
+ _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ _vm->_sound->command(21);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], FACING_NORTH);
+ int oldIdx = _commonSequenceIdx;
+ _commonSequenceIdx = _scene->_sequences.startCycle(_commonSpriteIndex, false, -2);
+ _scene->_sequences.updateTimeout(_commonSequenceIdx, oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 2:
+ _vm->_sound->command(22);
+ _scene->_sequences.remove(_commonSequenceIdx);
+ _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_commonSequenceIdx, 1, 3);
+ _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _commonSequenceIdx);
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(60, 4);
+ break;
+
+ case 4:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x101));
+ _game._player._stepEnabled = true;
+ break;
+ }
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_game._objects.isInInventory(OBJ_GUARDS_ARM)) {
+ _mustPutArmDownFl = true;
+ }
+
+ bool exit_corridor = false;
+ bool exit_doorway = false;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH)) {
+ exit_corridor = true;
+ }
+
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY)) {
+ exit_doorway = true;
+ }
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH) || _action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY) || _action.isAction(VERB_PUT, NOUN_GUARDS_ARM, NOUN_FLOOR)) {
+ if (_mustPutArmDownFl)
+ putArmDown(exit_corridor, exit_doorway);
+ else if (exit_corridor)
+ _scene->_nextSceneId = 353;
+ else
+ _scene->_nextSceneId = 351;
+
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_GUARDS_ARM)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_GUARDS_ARM)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _game._objects.addToInventory(OBJ_GUARDS_ARM);
+ _scene->changeVariant(1);
+ break;
+
+ case 2:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_GUARDS_ARM, 0x899C);
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_GUARDS_ARM, NOUN_SCANNER)) {
+ if (!_vaultOpenFl) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_FEMALE)
+ _commonSpriteIndex = _globals._spriteIndexes[11];
+ else
+ _commonSpriteIndex = _globals._spriteIndexes[10];
+
+ _commonSequenceIdx = _scene->_sequences.addSpriteCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
+ _scene->_sequences.updateTimeout(_commonSequenceIdx, -1);
+ _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ _vm->_sound->command(21);
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8);
+ int oldIdx = _commonSequenceIdx;
+ _commonSequenceIdx = _scene->_sequences.startCycle(_commonSpriteIndex, false, -2);
+ _scene->_sequences.updateTimeout(_commonSequenceIdx, oldIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 2:
+ _vm->_sound->command(23);
+ _scene->_sequences.remove(_commonSequenceIdx);
+ _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_commonSequenceIdx, 1, 4);
+ _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _commonSequenceIdx);
+ _game._player._visible = true;
+ if (_globals[kHaveYourStuff])
+ _commonSpriteIndex = _globals._spriteIndexes[13];
+ else
+ _commonSpriteIndex = _globals._spriteIndexes[1];
+
+ _vm->_sound->command(20);
+ _commonSequenceIdx = _scene->_sequences.addSpriteCycle(_commonSpriteIndex, false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_commonSequenceIdx, 15);
+ _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ break;
+
+ case 4:
+ _commonSequenceIdx = _scene->_sequences.addSpriteCycle(_commonSpriteIndex, false, 6, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_commonSequenceIdx, -2, -2);
+ _scene->_sequences.setDepth(_commonSequenceIdx, 15);
+ _scene->_sequences.addTimer(60, 5);
+ break;
+
+ case 5: {
+ _vaultOpenFl = true;
+ int idx;
+ if (!_globals[kHaveYourStuff]) {
+ idx = _scene->_dynamicHotspots.add(NOUN_YOUR_STUFF, VERB_WALKTO, -1, Common::Rect(282, 87, 282 + 13, 87 + 7));
+ _hotspot2Idx = _scene->_dynamicHotspots.setPosition(idx, Common::Point(280, 111), FACING_NORTHEAST);
+ _globals._sequenceIndexes[1] = _commonSequenceIdx;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x102));
+ } else {
+ _globals._sequenceIndexes[13] = _commonSequenceIdx;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x103));
+ }
+
+ idx = _scene->_dynamicHotspots.add(NOUN_OTHER_STUFF, VERB_WALKTO, -1, Common::Rect(282, 48, 282 + 36, 48 + 27));
+ _hotspot1Idx = _scene->_dynamicHotspots.setPosition(idx, Common::Point(287, 115), FACING_NORTHEAST);
+ idx = _scene->_dynamicHotspots.add(NOUN_LAMP, VERB_WALKTO, -1, Common::Rect(296, 76, 296 + 11, 76 + 17));
+ _lampHostpotIdx = _scene->_dynamicHotspots.setPosition(idx, Common::Point(287, 115), FACING_NORTHEAST);
+ _game._player._stepEnabled = true;
+ }
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_YOUR_STUFF)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._sequenceIndexes[14] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[14], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[14], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[14]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[14], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[14], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _globals._sequenceIndexes[15] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[15], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[15], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[15]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[15], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[15], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _scene->_dynamicHotspots.remove(_hotspot2Idx);
+ _globals[kHaveYourStuff] = true;
+
+ for (uint16 i = 0; i < _game._objects.size(); i++) {
+ if (_game._objects[i]._roomNumber == 50)
+ _game._objects.addToInventory(i);
+ }
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 15);
+ break;
+
+ case 2:
+ if (_globals[kSexOfRex] == REX_MALE)
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[14]);
+ else
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[15]);
+
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_TAPE_PLAYER) && !_game._objects.isInInventory(OBJ_TAPE_PLAYER)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], true, 6, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], true, 6, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[7]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _scene->_dynamicHotspots.remove(_tapePlayerHotspotIdx);
+ break;
+
+ case 2:
+ _game._objects.addToInventory(OBJ_TAPE_PLAYER);
+ if (_globals[kSexOfRex] == REX_MALE)
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[6]);
+ else
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[7]);
+
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_TAPE_PLAYER, 0x899B);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_SCANNER))
+ _vm->_dialogs->show(35210);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR)) {
+ if (_game._storyMode == STORYMODE_NAUGHTY)
+ _vm->_dialogs->show(35211);
+ else
+ _vm->_dialogs->show(35212);
+ } else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(35213);
+ else if (_action.isAction(VERB_LOOK, NOUN_STATUE))
+ _vm->_dialogs->show(35214);
+ else if (_action.isAction(VERB_LOOK, NOUN_TAPE_PLAYER) && (_action._savedFields._mainObjectSource == 4))
+ _vm->_dialogs->show(35215);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(35216);
+ else if (_action.isAction(VERB_LOOK, NOUN_GUARDS_ARM) && (_action._savedFields._mainObjectSource == 4))
+ _vm->_dialogs->show(35217);
+ else if (_action.isAction(VERB_LOOK, NOUN_IRONING_BOARD))
+ _vm->_dialogs->show(35218);
+ else if (_action.isAction(VERB_LOOK, NOUN_CLOCK))
+ _vm->_dialogs->show(35219);
+ else if (_action.isAction(VERB_LOOK, NOUN_GAUGE))
+ _vm->_dialogs->show(35220);
+ else if (_action.isAction(VERB_LOOK, NOUN_VAULT)) {
+ if (!_vaultOpenFl)
+ _vm->_dialogs->show(35221);
+ } else if (_action.isAction(VERB_LOOK, NOUN_YOUR_STUFF))
+ _vm->_dialogs->show(35222);
+ else if (_action.isAction(VERB_LOOK, NOUN_OTHER_STUFF))
+ _vm->_dialogs->show(35223);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(35224);
+ else if (_action.isAction(VERB_TAKE, NOUN_OTHER_STUFF))
+ _vm->_dialogs->show(35226);
+ else if (_action.isAction(VERB_LOOK, NOUN_DESK))
+ _vm->_dialogs->show(35229);
+ else if (_action.isAction(VERB_LOOK, NOUN_GUARD))
+ _vm->_dialogs->show(35230);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOORWAY))
+ _vm->_dialogs->show(35231);
+ else if (_action.isAction(VERB_LOOK, NOUN_TABLE))
+ _vm->_dialogs->show(35232);
+ else if (_action.isAction(VERB_LOOK, NOUN_PROJECTOR))
+ _vm->_dialogs->show(35233);
+ else if (_action.isAction(VERB_LOOK, NOUN_SUPPORT))
+ _vm->_dialogs->show(35234);
+ else if (_action.isAction(VERB_LOOK, NOUN_SECURITY_MONITOR))
+ _vm->_dialogs->show(35235);
+ else
+ return;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene353::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene353::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(Resources::formatName(303, 'B', 0, EXT_SS, ""));
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 0, 5, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ if (_scene->_priorSceneId == 352)
+ _game._player._playerPos = Common::Point(144, 95);
+ else
+ _game._player._playerPos = Common::Point(139, 155);
+
+ sceneEntrySound();
+}
+
+void Scene353::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(35315);
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY))
+ _scene->_nextSceneId = 352;
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH))
+ _scene->_nextSceneId = 354;
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCK_CHUNK))
+ _vm->_dialogs->show(35310);
+ else if (_action.isAction(VERB_LOOK, NOUN_PIPES) || _action.isAction(VERB_LOOK, NOUN_PIPE))
+ _vm->_dialogs->show(35311);
+ else if (_action.isAction(VERB_LOOK, NOUN_BROKEN_BEAM))
+ _vm->_dialogs->show(35312);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOORWAY))
+ _vm->_dialogs->show(35313);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(35314);
+ else if (_action.isAction(VERB_LOOK, NOUN_FLOOR))
+ _vm->_dialogs->show(35316);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEILING))
+ _vm->_dialogs->show(35317);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(35318);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene354::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene354::enter() {
+ _globals[kAfterHavoc] = true;
+ _globals[kTeleporterRoom + 1] = 351;
+
+ if (_scene->_priorSceneId == 361)
+ _game._player._playerPos = Common::Point(231, 110);
+ else if (_scene->_priorSceneId == 401) {
+ _game._player._playerPos = Common::Point(106, 152);
+ _game._player._facing = FACING_NORTH;
+ } else if (_scene->_priorSceneId == 316)
+ _game._player._playerPos = Common::Point(71, 107);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(167, 57);
+
+ sceneEntrySound();
+}
+
+void Scene354::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH))
+ _game._player._walkOffScreenSceneId = 401;
+}
+
+void Scene354::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(35414);
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_NORTH)) {
+ _game._player.startWalking(Common::Point(208, 0), FACING_NORTHEAST);
+ _game._player._walkOffScreenSceneId = 353;
+ } else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _scene->_nextSceneId = 361;
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _scene->_nextSceneId = 316;
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH))
+ _scene->_nextSceneId = 401;
+ else if (_action.isAction(VERB_LOOK, NOUN_CONTROLS))
+ _vm->_dialogs->show(35410);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGNAL))
+ _vm->_dialogs->show(35411);
+ else if (_action.isAction(VERB_LOOK, NOUN_CATWALK))
+ _vm->_dialogs->show(35412);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_DUCT))
+ _vm->_dialogs->show(35413);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_NORTH))
+ _vm->_dialogs->show(35415);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(35416);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(35417);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(35418);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEBRIS))
+ _vm->_dialogs->show(35419);
+ else if (_action.isAction(VERB_LOOK, NOUN_GUARD))
+ _vm->_dialogs->show(35420);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene357::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene357::enter() {
+ _globals[kAfterHavoc] = true;
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ if (_scene->_priorSceneId == 318)
+ _game._player._playerPos = Common::Point(298, 142);
+ else if (_scene->_priorSceneId == 313)
+ _game._player._playerPos = Common::Point(127, 101);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(15, 148);
+
+ sceneEntrySound();
+}
+
+void Scene357::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 318;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 358;
+}
+
+void Scene357::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(35715);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(35710);
+ else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT))
+ _vm->_dialogs->show(35711);
+ else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(35712);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(35713);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOILET))
+ _vm->_dialogs->show(35714);
+ else if (_action.isAction(VERB_LOOK, NOUN_CELL_WALL))
+ _vm->_dialogs->show(35716);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHT))
+ _vm->_dialogs->show(35717);
+ else if (_action.isAction(VERB_LOOK, NOUN_RIP_IN_FLOOR))
+ _vm->_dialogs->show(35718);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEBRIS))
+ _vm->_dialogs->show(35719);
+ else if (_action.isAction(VERB_TAKE, NOUN_DEBRIS))
+ _vm->_dialogs->show(35720);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(35721);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(35722);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(35723);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene358::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene358::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ if (_scene->_priorSceneId == 357)
+ _game._player._playerPos = Common::Point(305, 142);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(12, 141);
+
+ sceneEntrySound();
+}
+
+void Scene358::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 357;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 359;
+}
+
+void Scene358::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(35815);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(35810);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(35811);
+ else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(35812);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(35813);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOILET))
+ _vm->_dialogs->show(35814);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR) || _action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(35816);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(35817);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene359::Scene359(MADSEngine *vm) : Scene3xx(vm) {
+ _cardHotspotId = -1;
+}
+
+void Scene359::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsSint32LE(_cardHotspotId);
+}
+
+void Scene359::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene359::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', -1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+
+ if (_globals[kSexOfRex] == REX_MALE)
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMBD_2");
+ else
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*ROXBD_2");
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 15);
+
+ if (_game._objects.isInRoom(OBJ_SECURITY_CARD)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+ _cardHotspotId = _scene->_dynamicHotspots.add(NOUN_SECURITY_CARD, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_cardHotspotId, Common::Point(107, 107), FACING_SOUTH);
+ }
+
+ if (_scene->_priorSceneId == 358)
+ _game._player._playerPos = Common::Point(301, 141);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(15, 148);
+
+ sceneEntrySound();
+}
+
+void Scene359::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 358;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 360;
+}
+
+void Scene359::actions() {
+ if (_action._lookFlag) {
+ if ((_game._difficulty != DIFFICULTY_HARD) && (_game._objects[OBJ_SECURITY_CARD]._roomNumber == 359))
+ _vm->_dialogs->show(35914);
+ else
+ _vm->_dialogs->show(35915);
+ } else if (_action.isAction(VERB_TAKE, NOUN_SECURITY_CARD)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_SECURITY_CARD)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _vm->_dialogs->show(35920);
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 4, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], true, 7, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(106, 110));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_cardHotspotId);
+ _vm->_sound->command(57);
+ _game._objects.addToInventory(OBJ_SECURITY_CARD);
+ _vm->_dialogs->showItem(OBJ_SECURITY_CARD, 0x330);
+ _scene->changeVariant(1);
+ break;
+
+ case 2:
+ if (_globals[kSexOfRex] == REX_MALE)
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ else
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]);
+
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_BLOODY_CELL_WALL))
+ _vm->_dialogs->show(35910);
+ else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(35911);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(35912);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOILET))
+ _vm->_dialogs->show(35913);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(35916);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(35917);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIMB))
+ _vm->_dialogs->show(35918);
+ else if (_action.isAction(VERB_TAKE, NOUN_LIMB))
+ _vm->_dialogs->show(35919);
+ else if (_action.isAction(VERB_LOOK, NOUN_SECURITY_CARD) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(35921);
+ else if (_action.isAction(VERB_LOOK, NOUN_BLOOD_STAIN)) {
+ if ((_game._difficulty != DIFFICULTY_HARD) && (_game._objects[OBJ_SECURITY_CARD]._roomNumber == 359))
+ _vm->_dialogs->show(35922);
+ else
+ _vm->_dialogs->show(35923);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WALL_BOARD))
+ _vm->_dialogs->show(35924);
+ else if (_action.isAction(VERB_TAKE, NOUN_WALL_BOARD))
+ _vm->_dialogs->show(35925);
+ else if (_action.isAction(VERB_LOOK, NOUN_RIP_IN_FLOOR))
+ _vm->_dialogs->show(35926);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR))
+ _vm->_dialogs->show(35927);
+ else if (_action.isAction(VERB_LOOK, NOUN_FLOOR)) {
+ if ((_game._difficulty != DIFFICULTY_HARD) && (_game._objects[OBJ_SECURITY_CARD]._roomNumber == 359))
+ _vm->_dialogs->show(35928);
+ else
+ _vm->_dialogs->show(35929);
+ } else if (_action.isAction(VERB_OPEN, NOUN_AIR_VENT) || _action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(36016);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene360::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene360::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(127, 78));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ if (_scene->_priorSceneId == 359)
+ _game._player._playerPos = Common::Point(304, 143);
+ else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(13, 141);
+
+ sceneEntrySound();
+}
+
+void Scene360::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 359;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 361;
+}
+
+void Scene360::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(36015);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(36010);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(36011);
+ else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(36012);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(36013);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOILET))
+ _vm->_dialogs->show(36014);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(36016);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR))
+ _vm->_dialogs->show(36017);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(36018);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene361::setup() {
+ if (_scene->_currentSceneId == 391)
+ _globals[kSexOfRex] = REX_MALE;
+
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene361::handleRexAction() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 50, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 3, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 15, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1: {
+ int seqIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 4);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], seqIdx);
+ }
+ break;
+
+ case 2: {
+ int seqIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 4, 10);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 3: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 3);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ int seqIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 11);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], seqIdx);
+ _scene->_sequences.addTimer(15, 4);
+ }
+ break;
+
+ case 4:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 12, 14);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(167, 100));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ break;
+
+ case 5: {
+ int seqIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 15);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], seqIdx);
+ _scene->_sequences.addTimer(15, 6);
+ }
+ break;
+
+ case 6:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[2]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addTimer(48, 7);
+ break;
+
+ case 7:
+ _scene->_nextSceneId = 313;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene361::handleRoxAction() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 18, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 2, 4);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 18, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1: {
+ int tmpIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 4);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], tmpIdx);
+ }
+ break;
+
+ case 2: {
+ int tmpIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 4, 8);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], tmpIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ }
+ break;
+
+ case 3: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 3);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ int tmpIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 9, 10);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], tmpIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ }
+ break;
+
+ case 4: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ int tmpIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 11, 15);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], tmpIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ }
+ break;
+
+ case 5: {
+ int tmpIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 16);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(167, 100));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], tmpIdx);
+ _scene->_sequences.addTimer(48, 6);
+ }
+ break;
+
+ case 6:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[4]);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addTimer(48, 7);
+ break;
+
+ case 7:
+ _scene->_nextSceneId = 313;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene361::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(Resources::formatName(307, 'X', 0, EXT_SS, ""));
+
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXCL_8");
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXCL_2");
+ } else
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*ROXCL_8");
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ if (_scene->_priorSceneId == 391) {
+ _globals[kSexOfRex] = REX_MALE;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _game._player._facing = FACING_SOUTH;
+ _game._player._playerPos = Common::Point(166, 101);
+ _scene->_sequences.addTimer(120, 70);
+ } else if (_scene->_priorSceneId == 360)
+ _game._player._playerPos = Common::Point(302, 145);
+ else if (_scene->_priorSceneId == 320) {
+ _game._player._playerPos = Common::Point(129, 113);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(13, 145);
+
+ _game.loadQuoteSet(0xFB, 0xFC, 0);
+
+ if (_scene->_priorSceneId == 320)
+ _scene->_kernelMessages.setQuoted(_scene->_kernelMessages.addQuote(0xFB, 0, 0x78), 4, true);
+
+ sceneEntrySound();
+}
+
+void Scene361::step() {
+ if (_game._trigger >= 70) {
+ switch (_game._trigger) {
+ case 70:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 72);
+ break;
+
+ case 72:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 3);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 73);
+ break;
+
+ case 73:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 5);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 74);
+ break;
+
+ case 74: {
+ int seqIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 6);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], seqIdx);
+ _scene->_sequences.addTimer(15, 75);
+ }
+ break;
+
+ case 75:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 7);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 76);
+ break;
+
+ case 76:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 8);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 77);
+ break;
+
+ case 77:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(165, 76));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 15);
+
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 9);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 78);
+ break;
+
+ case 78:
+ _scene->_sequences.setDone(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 10, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 79);
+ break;
+
+ case 79:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene361::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 360;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 354;
+}
+
+void Scene361::actions() {
+ if (_action._lookFlag)
+ _vm->_dialogs->show(36119);
+ else if (_action.isAction(VERB_SIT_AT, NOUN_DESK)) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.addQuote(0xFC, 120, 0);
+ } else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) {
+ if (_globals[kSexOfRex] == REX_FEMALE)
+ handleRoxAction();
+ else
+ handleRexAction();
+ } else if (_action.isAction(VERB_LOOK, NOUN_DESK))
+ _vm->_dialogs->show(36110);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(36111);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHTING_FIXTURE) || _action.isAction(VERB_STARE_AT, NOUN_LIGHTING_FIXTURE))
+ _vm->_dialogs->show(36112);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHTS) || _action.isAction(VERB_STARE_AT, NOUN_LIGHTS))
+ _vm->_dialogs->show(36113);
+ else if (_action.isAction(VERB_TAKE, NOUN_LIGHTS))
+ _vm->_dialogs->show(36114);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHT_BULB) || _action.isAction(VERB_STARE_AT, NOUN_LIGHT_BULB))
+ _vm->_dialogs->show(36115);
+ else if (_action.isAction(VERB_TAKE, NOUN_LIGHT_BULB))
+ _vm->_dialogs->show(36116);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(36117);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(36118);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_VENT))
+ _vm->_dialogs->show(36120);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene366::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene366::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._visible = false;
+ sceneEntrySound();
+}
+
+void Scene366::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 302;
+ else if (_action.isAction(VERB_OPEN, NOUN_GRATE)) {
+ if (_game._visitedScenes.exists(316))
+ _vm->_dialogs->show(36612);
+ else
+ _vm->_dialogs->show(36613);
+ _scene->_nextSceneId = 316;
+ } else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE)) {
+ if (_game._visitedScenes.exists(321))
+ _vm->_dialogs->show(36611);
+ else
+ _vm->_dialogs->show(36610);
+ } else {
+ return;
+ }
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene387::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene387::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._visible = false;
+
+ sceneEntrySound();
+}
+
+void Scene387::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 313;
+ else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE))
+ _vm->_dialogs->show(38710);
+ else if (_action.isAction(VERB_OPEN, NOUN_GRATE))
+ _vm->_dialogs->show(38711);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene388::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene388::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+
+ if (_globals[kAfterHavoc])
+ _scene->_hotspots.activate(NOUN_SAUROPOD, false);
+ else {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._sequenceIndexes[0] = _scene->_sequences.startCycle(_globals._spriteIndexes[0], false, 1);
+ }
+
+ _game._player._visible = false;
+ _vm->_palette->setEntry(252, 63, 30, 20);
+ _vm->_palette->setEntry(253, 45, 15, 12);
+ _game.loadQuoteSet(0x154, 0x155, 0x156, 0x157, 0x158, 0);
+
+ sceneEntrySound();
+}
+
+void Scene388::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 313;
+ else if (_action.isAction(VERB_TALKTO, NOUN_SAUROPOD)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(160, 136), 0x1110, 32, 1, 120, _game.getQuote(0x154));
+ break;
+
+ case 1:
+ _scene->_kernelMessages.add(Common::Point(82, 38), 0xFDFC, 0, 0, 300, _game.getQuote(0x156));
+ _scene->_kernelMessages.add(Common::Point(82, 52), 0xFDFC, 0, 0, 300, _game.getQuote(0x157));
+ _scene->_kernelMessages.add(Common::Point(82, 66), 0xFDFC, 0, 2, 300, _game.getQuote(0x158));
+ break;
+
+ case 2:
+ _game._player._stepEnabled = true;
+ _scene->_kernelMessages.add(Common::Point(160, 136), 0x1110, 32, 0, 120, _game.getQuote(0x155));
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE)) {
+ if (_globals[kAfterHavoc])
+ _vm->_dialogs->show(38811);
+ else
+ _vm->_dialogs->show(38810);
+ } else if (_action.isAction(VERB_OPEN, NOUN_GRATE))
+ _vm->_dialogs->show(38812);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene389::Scene389(MADSEngine *vm) : Scene300s(vm) {
+ _monsterTime = 0;
+ _circularQuoteId = -1;
+}
+
+void Scene389::synchronize(Common::Serializer &s) {
+ Scene3xx::synchronize(s);
+
+ s.syncAsUint32LE(_monsterTime);
+ s.syncAsSint32LE(_circularQuoteId);
+}
+
+void Scene389::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene389::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _monsterTime = 0;
+ _circularQuoteId = 0x159;
+
+ if (_globals[kAfterHavoc])
+ _scene->_hotspots.activate(NOUN_MONSTER, false);
+ else {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('m', -1));
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0], false, 6, 0, 0, 0);
+ _scene->_kernelMessages.initRandomMessages(1,
+ Common::Rect(88, 19, 177, 77), 13, 2, 0xFDFC, 60,
+ 247, 248, 249, 0);
+ }
+
+ _vm->_palette->setEntry(252, 63, 37, 26);
+ _vm->_palette->setEntry(253, 45, 24, 17);
+ _game._player._visible = false;
+ _game.loadQuoteSet(0xF7, 0xF8, 0xF9, 0x159, 0x15A, 0x15B, 0);
+
+ sceneEntrySound();
+}
+
+void Scene389::step() {
+ _scene->_kernelMessages.randomServer();
+ if (_scene->_frameStartTime >= _monsterTime) {
+ int chanceMinor = _scene->_kernelMessages.checkRandom() * 4 + 1;
+ _scene->_kernelMessages.generateRandom(20, chanceMinor);
+ _monsterTime = _scene->_frameStartTime + 2;
+ }
+}
+
+void Scene389::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 313;
+ else if (_action.isAction(VERB_TALKTO, NOUN_MONSTER)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(160, 136), 0x1110, 32, 1, 120, _game.getQuote(_circularQuoteId));
+ _circularQuoteId++;
+ if (_circularQuoteId > 0x15B)
+ _circularQuoteId = 0x159;
+
+ break;
+
+ case 1:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE)) {
+ if (_globals[kAfterHavoc]) {
+ if ((_game._difficulty != DIFFICULTY_HARD) && (_game._objects[OBJ_SECURITY_CARD]._roomNumber == 359))
+ _vm->_dialogs->show(38911);
+ else
+ _vm->_dialogs->show(38912);
+ } else
+ _vm->_dialogs->show(38910);
+ } else if (_action.isAction(VERB_OPEN, NOUN_GRATE)) {
+ if (_globals[kAfterHavoc])
+ _vm->_dialogs->show(38914);
+ else
+ _vm->_dialogs->show(38913);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene390::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene390::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._visible = false;
+
+ sceneEntrySound();
+}
+
+void Scene390::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 313;
+ else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE))
+ _vm->_dialogs->show(39010);
+ else if (_action.isAction(VERB_OPEN, NOUN_GRATE))
+ _vm->_dialogs->show(39011);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene391::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene391::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._visible = false;
+ sceneEntrySound();
+}
+
+void Scene391::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 313;
+ else if (_action.isAction(VERB_OPEN, NOUN_GRATE)) {
+ if (_globals[kKickedIn391Grate])
+ _vm->_dialogs->show(39113);
+ else {
+ _vm->_dialogs->show(39112);
+ _globals[kKickedIn391Grate] = true;
+ }
+
+ if (_globals[kAfterHavoc])
+ _scene->_nextSceneId = 361;
+ else
+ _scene->_nextSceneId = 311;
+ } else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE)) {
+ if (_globals[kAfterHavoc])
+ _vm->_dialogs->show(39111);
+ else
+ _vm->_dialogs->show(39110);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene399::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene399::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._visible = false;
+ sceneEntrySound();
+}
+
+void Scene399::actions() {
+ if (_action.isAction(VERB_RETURN_TO, NOUN_AIR_SHAFT))
+ _scene->_nextSceneId = 313;
+ else if (_action.isAction(VERB_LOOK_THROUGH, NOUN_GRATE)) {
+ if (_globals[kAfterHavoc]) {
+ if ((_game._difficulty != DIFFICULTY_HARD) && (_game._objects[OBJ_SECURITY_CARD]._roomNumber == 359))
+ _vm->_dialogs->show(38911);
+ else
+ _vm->_dialogs->show(38912);
+ } else
+ _vm->_dialogs->show(38910);
+ } else if (_action.isAction(VERB_OPEN, NOUN_GRATE)) {
+ if (_globals[kAfterHavoc])
+ _vm->_dialogs->show(38914);
+ else
+ _vm->_dialogs->show(38913);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes3.h b/engines/mads/nebular/nebular_scenes3.h
new file mode 100644
index 0000000000..9efd38e9a4
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes3.h
@@ -0,0 +1,548 @@
+/* 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 MADS_NEBULAR_SCENES3_H
+#define MADS_NEBULAR_SCENES3_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+typedef struct {
+ bool _flag;
+ int _vertical;
+ int _horizontal;
+ int _seqId[40];
+ uint32 _timer;
+
+ void init() {
+ _flag = false;
+ _vertical = _horizontal = -1;
+ _timer = 0;
+ for (int i = 0; i < 40; ++i)
+ _seqId[i] = -1;
+ }
+
+ void synchronize(Common::Serializer &s) {
+ s.syncAsByte(_flag);
+ s.syncAsSint32LE(_vertical);
+ s.syncAsSint32LE(_horizontal);
+ for (int i = 0; i < 40; ++i)
+ s.syncAsSint32LE(_seqId[i]);
+ s.syncAsUint32LE(_timer);
+ };
+} ForceField;
+
+class Scene3xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+
+ void sceneEntrySound();
+
+ void initForceField(ForceField *force, bool flag);
+ void handleForceField(ForceField *force, int *sprites);
+ int computeScale(int low, int high, int id);
+
+public:
+ Scene3xx(MADSEngine *vm) : NebularScene(vm) {}
+
+ virtual void actions() {}
+};
+
+class Scene300s : public Scene3xx {
+public:
+ Scene300s(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void preActions();
+};
+
+class Scene301 : public Scene3xx {
+public:
+ Scene301(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene302 : public Scene3xx {
+private:
+ int _oldFrame;
+
+public:
+ Scene302(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene303 : public Scene3xx {
+public:
+ Scene303(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene304 : public Scene3xx {
+private:
+ int _explosionSpriteId;
+
+public:
+ Scene304(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene307 : public Scene3xx {
+private:
+ ForceField _forceField;
+
+ bool _afterPeeingFl;
+ bool _duringPeeingFl;
+ bool _grateOpenedFl;
+ bool _activePrisonerFl;
+
+ int _animationMode;
+ int _prisonerMessageId;
+ int _fieldCollisionCounter;
+
+ uint32 _lastFrameTime;
+ uint32 _guardTime;
+ uint32 _prisonerTimer;
+
+ Common::String _subQuote2;
+
+ Conversation _dialog1, _dialog2;
+
+ void handleDialog();
+ void handleRexDialog(int quote);
+ void handlePrisonerDialog();
+ void handlePrisonerEncounter();
+ void setDialogNode(int node);
+ void handlePrisonerSpeech(int firstQuoteId, int number, long timeout);
+
+public:
+ Scene307(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene308 : public Scene3xx {
+private:
+ ForceField _forceField;
+
+public:
+ Scene308(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene309 : public Scene3xx {
+private:
+ ForceField _forceField;
+ int _characterSpriteIndexes[3];
+ int _messagesIndexes[3];
+ int _lastFrame;
+
+public:
+ Scene309(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene310 : public Scene3xx {
+private:
+ ForceField _forceField;
+
+public:
+ Scene310(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene311 : public Scene3xx {
+private:
+ bool _checkGuardFl;
+
+public:
+ Scene311(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene313 : public Scene3xx {
+public:
+ Scene313(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene316 : public Scene3xx {
+private:
+ void handleRexInGrate();
+ void handleRoxInGrate();
+
+public:
+ Scene316(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene318 : public Scene3xx {
+private:
+ uint32 _dropTimer;
+
+ int _lastFrame;
+ int _animMode;
+ int _internCounter;
+ int _counter;
+
+ bool _dialogFl;
+ bool _internTalkingFl;
+ bool _internWalkingFl;
+ bool _internVisibleFl;
+ bool _explosionFl;
+
+ uint32 _lastFrameCounter;
+
+ Common::String _subQuote2;
+
+ Conversation _dialog1;
+
+ void handleDialog();
+ void handleRexDialogs(int quote);
+ void handleInternDialog(int quoteId, int quoteNum, uint32 timeout);
+
+public:
+ Scene318(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene319 : public Scene3xx {
+private:
+ Conversation _dialog1, _dialog2, _dialog3;
+
+ int _animMode, _animFrame;
+ int _nextAction1, _nextAction2;
+ int _slacheMode;
+ int _slacheTopic;
+ int _slachePosY;
+
+ bool _slacheTalkingFl;
+ bool _slacheReady;
+ bool _slacheInitFl;
+
+ Common::String _subQuote2;
+
+ void handleRexDialogues(int quote);
+ void handleSlacheDialogs(int quoteId, int counter, uint32 timer);
+public:
+ Scene319(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene320 : public Scene300s {
+private:
+ void setRightView(int view);
+ void setLeftView(int view);
+ void handleButtons();
+
+ bool _blinkFl;
+ bool _flippedFl;
+
+ int _buttonId;
+ int _lastFrame;
+ int _leftItemId;
+ int _posX;
+ int _rightItemId;
+
+public:
+ Scene320(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene321 : public Scene3xx {
+public:
+ Scene321(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+};
+
+class Scene322 : public SceneTeleporter {
+public:
+ Scene322(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene351 : public Scene3xx {
+public:
+ Scene351(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene352 : public Scene3xx {
+private:
+ bool _vaultOpenFl;
+ bool _mustPutArmDownFl;
+ bool _leaveRoomFl;
+
+ int _tapePlayerHotspotIdx;
+ int _hotspot1Idx;
+ int _hotspot2Idx;
+ int _lampHostpotIdx;
+ int _commonSequenceIdx;
+ int _commonSpriteIndex;
+
+ void putArmDown(bool corridorExit, bool doorwayExit);
+
+public:
+ Scene352(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene353 : public Scene3xx {
+public:
+ Scene353(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene354 : public Scene3xx {
+public:
+ Scene354(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene357 : public Scene3xx {
+public:
+ Scene357(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene358 : public Scene3xx {
+public:
+ Scene358(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene359 : public Scene3xx {
+private:
+ int _cardHotspotId;
+
+public:
+ Scene359(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene360 : public Scene3xx {
+public:
+ Scene360(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene361 : public Scene3xx {
+private:
+ void handleRexAction();
+ void handleRoxAction();
+
+public:
+ Scene361(MADSEngine *vm) : Scene3xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene366 : public Scene300s {
+public:
+ Scene366(MADSEngine *vm) : Scene300s(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene387 : public Scene300s {
+public:
+ Scene387(MADSEngine *vm) : Scene300s(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene388 : public Scene300s {
+public:
+ Scene388(MADSEngine *vm) : Scene300s(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene389 : public Scene300s {
+private:
+ uint32 _monsterTime;
+
+ int _circularQuoteId;
+
+public:
+ Scene389(MADSEngine *vm);
+ virtual void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene390 : public Scene300s {
+public:
+ Scene390(MADSEngine *vm) : Scene300s(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene391 : public Scene300s {
+public:
+ Scene391(MADSEngine *vm) : Scene300s(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene399 : public Scene300s {
+public:
+ Scene399(MADSEngine *vm) : Scene300s(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES3_H */
diff --git a/engines/mads/nebular/nebular_scenes4.cpp b/engines/mads/nebular/nebular_scenes4.cpp
new file mode 100644
index 0000000000..d114232255
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes4.cpp
@@ -0,0 +1,4191 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes4.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene4xx::setAAName() {
+ _game._aaName = Resources::formatAAName(4);
+}
+
+void Scene4xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+ Common::String oldName = _game._player._spritesPrefix;
+
+ if ((_scene->_nextSceneId == 403) || (_scene->_nextSceneId == 409))
+ _game._player._spritesPrefix = "";
+ else if (_globals[kSexOfRex] == REX_FEMALE)
+ _game._player._spritesPrefix = "ROX";
+ else
+ _game._player._spritesPrefix = "RXM";
+
+ _game._player._scalingVelocity = true;
+
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+void Scene4xx::sceneEntrySound() {
+ if (!_vm->_musicFlag) {
+ _vm->_sound->command(2);
+ return;
+ }
+
+ switch (_scene->_nextSceneId) {
+ case 401:
+ _vm->_sound->startQueuedCommands();
+ if (_scene->_priorSceneId == 402)
+ _vm->_sound->command(12, 64);
+ else
+ _vm->_sound->command(12, 1);
+ break;
+
+ case 402:
+ _vm->_sound->startQueuedCommands();
+ _vm->_sound->command(12, 127);
+ break;
+
+ case 405:
+ case 407:
+ case 409:
+ case 410:
+ case 413:
+ _vm->_sound->command(10);
+ break;
+
+ case 408:
+ _vm->_sound->command(52);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene401::Scene401(MADSEngine *vm) : Scene4xx(vm), _destPos(0, 0) {
+ _northFl = false;
+ _timer = 0;
+}
+
+void Scene401::synchronize(Common::Serializer &s) {
+ Scene4xx::synchronize(s);
+
+ s.syncAsByte(_northFl);
+ s.syncAsSint16LE(_destPos.x);
+ s.syncAsSint16LE(_destPos.y);
+ s.syncAsUint32LE(_timer);
+}
+
+void Scene401::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene401::enter() {
+ if (_scene->_priorSceneId != -2)
+ _northFl = false;
+
+ _timer = 0;
+
+ if (_scene->_priorSceneId == 402) {
+ _game._player._playerPos = Common::Point(203, 115);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId == 354) {
+ _game._player._playerPos = Common::Point(149, 90);
+ _game._player._facing = FACING_SOUTH;
+ _northFl = true;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(142, 131);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ _game.loadQuoteSet(0x1D4, 0);
+ sceneEntrySound();
+}
+
+void Scene401::step() {
+ if (_game._trigger == 70) {
+ _scene->_nextSceneId = 354;
+ _scene->_reloadSceneFlag = true;
+ }
+
+ if (_game._trigger == 80) {
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _northFl = false;
+ _game._player.walk(Common::Point(149, 110), FACING_SOUTH);
+ }
+
+ if (_scene->_frameStartTime >= _timer) {
+ int dist = 64 - ((_vm->hypotenuse(_game._player._playerPos.x - 219, _game._player._playerPos.y - 115) * 64) / 120);
+
+ if (dist > 64)
+ dist = 64;
+ else if (dist < 1)
+ dist = 1;
+
+ _vm->_sound->command(12, dist);
+ _timer = _scene->_frameStartTime + _game._player._ticksAmount;
+ }
+
+}
+
+void Scene401::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_NORTH)) {
+ _game._player.walk(Common::Point(149, 89), FACING_NORTH);
+ _northFl = false;
+ }
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH) && !_northFl)
+ _game._player._walkOffScreenSceneId = 405;
+
+ if (_action.isAction(VERB_TAKE))
+ _game._player._needToWalk = false;
+
+ if (_game._player._needToWalk && _northFl) {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _destPos = Common::Point(148, 94);
+ else
+ _destPos = Common::Point(149, 99);
+
+ _game._player.walk(_destPos, FACING_SOUTH);
+ }
+}
+
+void Scene401::actions() {
+ if ((_game._player._playerPos == _destPos) && _northFl) {
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _vm->_sound->command(21);
+ _scene->loadAnimation(formAnimName('s', 1), 70);
+ _globals[kHasBeenScanned] = true;
+ _vm->_sound->command(22);
+ int idx = _scene->_kernelMessages.add(Common::Point(153, 46), 0x1110, 32, 0, 60, _game.getQuote(0x1D4));
+ _scene->_kernelMessages.setQuoted(idx, 4, true);
+ }
+
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _vm->_sound->command(21);
+ _scene->loadAnimation(formAnimName('s', 2), 80);
+ _vm->_sound->command(23);
+ _globals[kHasBeenScanned] = true;
+ }
+ }
+
+ if (_action.isAction(VERB_WALK_INTO, NOUN_BAR)) {
+ if (!_northFl)
+ _scene->_nextSceneId = 402;
+ } else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_NORTH))
+ _scene->_nextSceneId = 354;
+ else if (_action.isAction(VERB_LOOK, NOUN_SCANNER)) {
+ if (_globals[kHasBeenScanned])
+ _vm->_dialogs->show(40111);
+ else
+ _vm->_dialogs->show(40110);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BAR))
+ _vm->_dialogs->show(40112);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN))
+ _vm->_dialogs->show(40113);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(40114);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_NORTH))
+ _vm->_dialogs->show(40115);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(40116);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene402::Scene402(MADSEngine *vm) : Scene4xx(vm) {
+ _lightOn = false;
+ _blowingSmoke = false;
+ _leftWomanMoving = false;
+ _rightWomanMoving = false;
+ _firstTalkToGirlInChair = false;
+ _waitingGinnyMove = false;
+ _ginnyLooking = false;
+ _bigBeatFl = false;
+ _roxOnStool = false;
+ _bartenderSteady = false;
+ _bartenderHandsHips = false;
+ _bartenderLooksLeft = false;
+ _bartenderReady = false;
+ _bartenderTalking = false;
+ _bartenderCalled = false;
+ _conversationFl = false;
+ _activeTeleporter = false;
+ _activeArrows = false;
+ _activeArrow1 = false;
+ _activeArrow2 = false;
+ _activeArrow3 = false;
+ _cutSceneReady = false;
+ _cutSceneNeeded = false;
+ _helgaReady = false;
+ _refuseAlienLiquor = false;
+
+ _drinkTimer = -1;
+ _beatCounter = -1;
+ _bartenderMode = -1;
+ _bartenderDialogNode = -1;
+ _bartenderCurrentQuestion = -1;
+ _helgaTalkMode = -1;
+ _roxMode = -1;
+ _rexMode = -1;
+ _talkTimer = -1;
+}
+
+void Scene402::synchronize(Common::Serializer &s) {
+ Scene4xx::synchronize(s);
+
+ s.syncAsByte(_lightOn);
+ s.syncAsByte(_blowingSmoke);
+ s.syncAsByte(_leftWomanMoving);
+ s.syncAsByte(_rightWomanMoving);
+ s.syncAsByte(_firstTalkToGirlInChair);
+ s.syncAsByte(_waitingGinnyMove);
+ s.syncAsByte(_ginnyLooking);
+ s.syncAsByte(_bigBeatFl);
+ s.syncAsByte(_roxOnStool);
+ s.syncAsByte(_bartenderSteady);
+ s.syncAsByte(_bartenderHandsHips);
+ s.syncAsByte(_bartenderLooksLeft);
+ s.syncAsByte(_bartenderReady);
+ s.syncAsByte(_bartenderTalking);
+ s.syncAsByte(_bartenderCalled);
+ s.syncAsByte(_conversationFl);
+ s.syncAsByte(_activeTeleporter);
+ s.syncAsByte(_activeArrows);
+ s.syncAsByte(_activeArrow1);
+ s.syncAsByte(_activeArrow2);
+ s.syncAsByte(_activeArrow3);
+ s.syncAsByte(_cutSceneReady);
+ s.syncAsByte(_cutSceneNeeded);
+ s.syncAsByte(_helgaReady);
+ s.syncAsByte(_refuseAlienLiquor);
+
+ s.syncAsSint16LE(_drinkTimer);
+ s.syncAsSint16LE(_beatCounter);
+ s.syncAsSint16LE(_bartenderMode);
+ s.syncAsSint16LE(_bartenderDialogNode);
+ s.syncAsSint16LE(_bartenderCurrentQuestion);
+ s.syncAsSint16LE(_helgaTalkMode);
+ s.syncAsSint16LE(_roxMode);
+ s.syncAsSint16LE(_rexMode);
+ s.syncAsSint16LE(_talkTimer);
+}
+
+void Scene402::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_BARTENDER);
+ _scene->addActiveVocab(NOUN_ALIEN_LIQUOR);
+ _scene->addActiveVocab(VERB_DRINK);
+ _scene->addActiveVocab(NOUN_BINOCULARS);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_CREDIT_CHIP);
+ _scene->addActiveVocab(VERB_TAKE);
+ _scene->addActiveVocab(NOUN_REPAIR_LIST);
+ _scene->addActiveVocab(VERB_LOOK_AT);
+}
+
+void Scene402::setDialogNode(int node) {
+ if (node > 0)
+ _bartenderDialogNode = node;
+
+ _game._player._stepEnabled = true;
+
+ switch (node) {
+ case 0:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _conversationFl = false;
+ _bartenderDialogNode = 0;
+ break;
+
+ case 1:
+ _dialog1.start();
+ _bartenderDialogNode = 1;
+ break;
+
+ case 2:
+ _dialog2.start();
+ _bartenderDialogNode = 2;
+ break;
+
+ case 3:
+ _dialog3.start();
+ _bartenderDialogNode = 3;
+ break;
+
+ case 4:
+ _dialog4.start();
+ _bartenderDialogNode = 4;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene402::handleConversation1() {
+ switch (_action._activeAction._verbId) {
+ case 0x214: {
+ int quoteId = 0;
+ int quotePosX = 0;
+ switch (_vm->getRandomNumber(1, 3)) {
+ case 1:
+ quoteId = 0x1E4;
+ _bartenderCurrentQuestion = 4;
+ quotePosX = 205;
+ break;
+
+ case 2:
+ quoteId = 0x1E5;
+ _bartenderCurrentQuestion = 5;
+ quotePosX = 203;
+ break;
+
+ case 3:
+ quoteId = 0x1E6;
+ _bartenderCurrentQuestion = 6;
+ quotePosX = 260;
+ break;
+
+ default:
+ break;
+ }
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(quotePosX, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(quoteId));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ setDialogNode(2);
+ }
+ break;
+
+ case 0x215:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(260, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EC));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ _bartenderCurrentQuestion = 1;
+ setDialogNode(3);
+ break;
+
+ case 0x237:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(208, 41), 0xFDFC, 0, 0, 100, _game.getQuote(0x1FD));
+ setDialogNode(0);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1120;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene402::handleConversation2() {
+ switch (_action._activeAction._verbId) {
+ case 0x216:
+ _dialog2.write(0x216, false);
+ _dialog2.write(0x21D, true);
+ break;
+
+ case 0x219:
+ _dialog2.write(0x219, false);
+ _dialog2.write(0x220, true);
+ break;
+
+ case 0x21A:
+ _dialog2.write(0x21A, false);
+ _dialog2.write(0x223, true);
+ break;
+
+ case 0x21B:
+ _dialog2.write(0x21B, false);
+ _dialog2.write(0x224, true);
+ break;
+
+ case 0x21D:
+ _dialog2.write(0x21D, false);
+ _dialog2.write(0x227, true);
+ break;
+
+ case 0x220:
+ _dialog2.write(0x220, false);
+ _dialog2.write(0x22A, true);
+ break;
+
+ case 0x223:
+ _dialog2.write(0x223, false);
+ _dialog2.write(0x22D, true);
+ break;
+
+ case 0x224:
+ _dialog2.write(0x224, false);
+ _dialog2.write(0x230, true);
+ break;
+
+ case 0x227:
+ _dialog2.write(0x227, false);
+ break;
+
+ case 0x22A:
+ _dialog2.write(0x22A, false);
+ break;
+
+ case 0x22D:
+ _dialog2.write(0x22D, false);
+ break;
+
+ case 0x230:
+ _dialog2.write(0x230, false);
+ break;
+
+ case 0x21C:
+ setDialogNode(0);
+ break;
+
+ default:
+ break;
+
+ }
+
+ if (_action._activeAction._verbId != 0x21C) {
+ switch (_vm->getRandomNumber(1, 3)) {
+ case 1:
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 180;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(198, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E7));
+ _scene->_kernelMessages.add(Common::Point(201, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E8));
+ _bartenderCurrentQuestion = 7;
+ break;
+
+ case 2:
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 180;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(220, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E9));
+ _scene->_kernelMessages.add(Common::Point(190, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EA));
+ _bartenderCurrentQuestion = 8;
+ break;
+
+ case 3:
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 150;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(196, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EB));
+ _bartenderCurrentQuestion = 9;
+ break;
+
+ default:
+ break;
+ }
+ _dialog2.start();
+ } else {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(208, 41), 0xFDFC, 0, 0, 100, _game.getQuote(0x1FD));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1120;
+ }
+}
+
+void Scene402::handleConversation3() {
+ switch (_action._activeAction._verbId) {
+ case 0x233:
+ case 0x234:
+ case 0x235:
+ case 0x236:
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 86);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(188, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1ED));
+ _scene->_kernelMessages.add(Common::Point(199, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EE));
+ setDialogNode(4);
+ _bartenderCurrentQuestion = 2;
+ break;
+
+ case 0x237:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(208, 41), 0xFDFC, 0, 0, 100, _game.getQuote(0x1FD));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1120;
+ setDialogNode(0);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene402::handleConversation4() {
+ switch (_action._activeAction._verbId) {
+ case 0x238:
+ _scene->_kernelMessages.reset();
+ setDialogNode(0);
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(196, 13), 0xFDFC, 0, 0, 180, _game.getQuote(0x1F0));
+ _scene->_kernelMessages.add(Common::Point(184, 27), 0xFDFC, 0, 0, 180, _game.getQuote(0x1F1));
+ _scene->_kernelMessages.add(Common::Point(200, 41), 0xFDFC, 0, 0, 180, _game.getQuote(0x1F2));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1100;
+ _dialog4.write(0x238, false);
+ _bartenderMode = 22;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(100, 95);
+ _refuseAlienLiquor = true;
+ break;
+
+ case 0x239:
+ _game._player._stepEnabled = false;
+ _roxMode = 21;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 92);
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _conversationFl = false;
+ break;
+
+ case 0x23A:
+ setDialogNode(0);
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(193, 27), 0xFDFC, 0, 0, 150, _game.getQuote(0x1F4));
+ _scene->_kernelMessages.add(Common::Point(230, 41), 0xFDFC, 0, 0, 150, _game.getQuote(0x1F5));
+ _dialog4.write(0x23A, false);
+ _globals[kHasSaidTimer] = true;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1100;
+ _bartenderMode = 22;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(100, 95);
+ _refuseAlienLiquor = true;
+ break;
+
+ case 0x23D:
+ setDialogNode(0);
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(153, 27), 0xFDFC, 0, 0, 150, _game.getQuote(0x1F6));
+ _scene->_kernelMessages.add(Common::Point(230, 41), 0xFDFC, 0, 0, 150, _game.getQuote(0x1F7));
+ _dialog4.write(0x23D, false);
+ _globals[kHasSaidBinocs] = true;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1100;
+ _bartenderMode = 22;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(100, 95);
+ _refuseAlienLiquor = true;
+ break;
+
+ case 0x23E:
+ _scene->_kernelMessages.reset();
+ setDialogNode(0);
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.add(Common::Point(205, 41), 0xFDFC, 0, 0, 100, _game.getQuote(0x1F8));
+ _bartenderMode = 22;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1050;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(50, 95);
+ _refuseAlienLiquor = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene402::handleDialogs() {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _game._player._stepEnabled = false;
+ Common::String curQuote = _game.getQuote(_action._activeAction._verbId);
+ if (_vm->_font->getWidth(curQuote, _scene->_textSpacing) > 200) {
+ Common::String subQuote1, subQuote2;
+ _game.splitQuote(curQuote, subQuote1, subQuote2);
+ _scene->_kernelMessages.add(Common::Point(230, 42), 0x1110, 32, 0, 140, subQuote1);
+ _scene->_kernelMessages.add(Common::Point(230, 56), 0x1110, 32, 0, 140, subQuote2);
+ _scene->_sequences.addTimer(160, 120);
+ } else {
+ _scene->_kernelMessages.add(Common::Point(230, 56), 0x1110, 32, 1, 140, curQuote);
+ _scene->_sequences.addTimer(160, 120);
+ }
+ } else if (_game._trigger == 120) {
+ _game._player._stepEnabled = true;
+ switch (_bartenderDialogNode) {
+ case 1:
+ handleConversation1();
+ break;
+
+ case 2:
+ handleConversation2();
+ break;
+
+ case 3:
+ handleConversation3();
+ break;
+
+ case 4:
+ handleConversation4();
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene402::enter() {
+ _globals._spriteIndexes[0] = _scene->_sprites.addSprites(formAnimName('n', -1));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('g', 0));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('g', 1));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[15] = _scene->_sprites.addSprites(formAnimName('x', 5));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('x', 4));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('b', 2));
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('b', 3));
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[14] = _scene->_sprites.addSprites(formAnimName('l', 0));
+ _globals._spriteIndexes[16] = _scene->_sprites.addSprites(formAnimName('h', 0));
+ _globals._spriteIndexes[17] = _scene->_sprites.addSprites(formAnimName('z', 0));
+ _globals._spriteIndexes[18] = _scene->_sprites.addSprites(formAnimName('z', 1));
+ _globals._spriteIndexes[19] = _scene->_sprites.addSprites(formAnimName('z', 2));
+ _globals._spriteIndexes[20] = _scene->_sprites.addSprites(formAnimName('x', 6));
+ _globals._spriteIndexes[21] = _scene->_sprites.addSprites("*ROXRC_9");
+ _globals._spriteIndexes[22] = _scene->_sprites.addSprites("*ROXCL_8");
+
+ if (_scene->_priorSceneId == 401) {
+ _game._player._playerPos = Common::Point(160, 150);
+ _game._player._facing = FACING_NORTH;
+ _roxOnStool = false;
+ _bartenderDialogNode = 1;
+ _conversationFl = false;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(160, 150);
+ _game._player._facing = FACING_NORTH;
+ _game._objects.addToInventory(OBJ_CREDIT_CHIP);
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+ _game._objects.addToInventory(OBJ_TIMER_MODULE);
+ _roxOnStool = false;
+ _bartenderDialogNode = 1;
+ _conversationFl = false;
+ }
+
+ _game.loadQuoteSet(0x1D7, 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, 0x1DD, 0x1DE, 0x1DF, 0x1E2, 0x1E3, 0x1E6, 0x1E5, 0x1E7,
+ 0x1E8, 0x1E9, 0x1EA, 0x1EF, 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, 0x1F5, 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB,
+ 0x1FC, 0x1EB, 0x1EC, 0x1ED, 0x1EE, 0x1E4, 0x1FD, 0x1E0, 0x1E1, 0x1FE, 0x1FF, 0x200, 0x201, 0x202, 0x203, 0x204,
+ 0x205, 0x206, 0x207, 0x208, 0x209, 0x20A, 0x20B, 0x20C, 0x20F, 0x20D, 0x20E, 0x210, 0x211, 0x212, 0x213, 0x214,
+ 0x215, 0x237, 0x216, 0x219, 0x21A, 0x21B, 0x21C, 0x21D, 0x220, 0x223, 0x224, 0x227, 0x22A, 0x22D, 0x230, 0x233,
+ 0x234, 0x235, 0x236, 0x238, 0x239, 0x23A, 0x23D, 0x23E, 0x23F, 0);
+
+ _vm->_palette->setEntry(250, 47, 41, 40);
+ _vm->_palette->setEntry(251, 50, 63, 55);
+ _vm->_palette->setEntry(252, 38, 34, 25);
+ _vm->_palette->setEntry(253, 45, 41, 35);
+
+ _dialog1.setup(0x60, 0x214, 0x215, 0x237, 0);
+ _dialog2.setup(0x61, 0x216, 0x219, 0x21A, 0x21B, 0x21D, 0x220, 0x223, 0x224, 0x227, 0x22A, 0x22D, 0x230, 0x21C, 0);
+ _dialog3.setup(0x62, 0x233, 0x234, 0x235, 0x236, 0x237, -1);
+ _dialog4.setup(0x63, 0x238, 0x239, 0x23A, 0x23D, 0x23E, 0);
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _dialog2.set(0x61, 0x216, 0x219, 0x21A, 0x21B, 0x21C, 0);
+ _dialog4.set(0x63, 0x238, 0x23E, 0);
+ _dialog1.set(0x60, 0x214, 0x215, 0x237, 0);
+ }
+
+ if (_game._objects.isInInventory(OBJ_CREDIT_CHIP))
+ _dialog4.write(0x239, true);
+ else
+ _dialog4.write(0x239, false);
+
+ if (_game._objects.isInInventory(OBJ_BINOCULARS) && !_globals[kHasSaidBinocs])
+ _dialog4.write(0x23D, true);
+ else
+ _dialog4.write(0x23D, false);
+
+ if (_game._objects.isInInventory(OBJ_TIMER_MODULE) && !_globals[kHasSaidTimer])
+ _dialog4.write(0x23A, true);
+ else
+ _dialog4.write(0x23A, false);
+
+ if (_dialog2.read(0) <= 1)
+ _dialog1.write(0x214, false);
+
+ if (_conversationFl) {
+ switch (_bartenderDialogNode) {
+ case 0:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _bartenderDialogNode = 1;
+ break;
+
+ case 1:
+ _dialog1.start();
+ break;
+
+ case 2:
+ _dialog2.start();
+ break;
+
+ case 3:
+ _dialog3.start();
+ break;
+
+ case 4:
+ _dialog4.start();
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_bartenderCurrentQuestion) {
+ case 1:
+ _scene->_kernelMessages.add(Common::Point(260, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EC));
+ break;
+
+ case 2:
+ _scene->_kernelMessages.add(Common::Point(188, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1ED));
+ _scene->_kernelMessages.add(Common::Point(199, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EE));
+ break;
+
+ case 3:
+ _scene->_kernelMessages.add(Common::Point(177, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EF));
+ break;
+
+ case 4:
+ _scene->_kernelMessages.add(Common::Point(205, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E4));
+ break;
+
+ case 5:
+ _scene->_kernelMessages.add(Common::Point(203, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E5));
+ break;
+
+ case 6:
+ _scene->_kernelMessages.add(Common::Point(260, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E6));
+ break;
+
+ case 7:
+ _scene->_kernelMessages.add(Common::Point(198, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E7));
+ _scene->_kernelMessages.add(Common::Point(201, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E8));
+ break;
+
+ case 8:
+ _scene->_kernelMessages.add(Common::Point(220, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E9));
+ _scene->_kernelMessages.add(Common::Point(190, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EA));
+ break;
+
+ case 9:
+ _scene->_kernelMessages.add(Common::Point(196, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EB));
+ break;
+
+ case 10:
+ _scene->_kernelMessages.add(Common::Point(198, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E2));
+ _scene->_kernelMessages.add(Common::Point(199, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E3));
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ _firstTalkToGirlInChair = false;
+ _lightOn = false;
+ _blowingSmoke = false;
+ _leftWomanMoving = false;
+ _rightWomanMoving = false;
+ _ginnyLooking = false;
+ _beatCounter = 0;
+ _waitingGinnyMove = false;
+ _bigBeatFl = true;
+ _bartenderHandsHips = false;
+ _bartenderSteady = true;
+ _bartenderLooksLeft = false;
+ _activeTeleporter = false;
+ _activeArrows = false;
+ _activeArrow1 = false;
+ _activeArrow2 = false;
+ _activeArrow3 = false;
+ _cutSceneReady = false;
+ _cutSceneNeeded = false;
+ _helgaReady = true;
+ _bartenderReady = true;
+ _drinkTimer = 0;
+ _bartenderTalking = false;
+ _bartenderCalled = false;
+ _helgaTalkMode = 0;
+ _rexMode = 0;
+ _refuseAlienLiquor = false;
+
+ _scene->loadAnimation(Resources::formatName(402, 'd', 1, EXT_AA, ""));
+ _scene->_activeAnimation->_resetFlag = true;
+
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+
+ if (!_game._objects.isInInventory(OBJ_REPAIR_LIST)) {
+ _globals._sequenceIndexes[14] = _scene->_sequences.startCycle(_globals._spriteIndexes[14], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[14], 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[14], Common::Point(210, 80));
+ int idx = _scene->_dynamicHotspots.add(NOUN_REPAIR_LIST, VERB_LOOK_AT, _globals._sequenceIndexes[14], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_NONE);
+ }
+
+ {
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ }
+
+ if (!_game._objects.isInRoom(OBJ_ALIEN_LIQUOR) && !_game._objects.isInInventory(OBJ_CREDIT_CHIP)) {
+ _globals._sequenceIndexes[15] = _scene->_sequences.startCycle(_globals._spriteIndexes[15], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[15], 8);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[15], Common::Point(250, 80));
+ int idx = _scene->_dynamicHotspots.add(NOUN_CREDIT_CHIP, VERB_TAKE, _globals._sequenceIndexes[15], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_NONE);
+ }
+
+ _globals._sequenceIndexes[20] = _scene->_sequences.startCycle(_globals._spriteIndexes[20], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[20], 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[20], Common::Point(234, 72));
+
+ if (_globals[kBottleDisplayed]) {
+ _globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 7);
+ }
+
+ if (_roxOnStool) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 5);
+ _game._player._visible = false;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene402::step() {
+ if (_game._trigger == 104) {
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[15]);
+ _game._objects.addToInventory(OBJ_CREDIT_CHIP);
+ _vm->_dialogs->showItem(OBJ_CREDIT_CHIP, 40242);
+ _game._player._stepEnabled = true;
+ }
+
+ if ((_vm->getRandomNumber(1, 1500) == 1) && (!_activeTeleporter) && (_game._player._playerPos.x < 150)) {
+ _vm->_sound->command(30);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 13, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 48);
+ _activeTeleporter = true;
+ _globals[kSomeoneHasExploded] = true;
+ }
+
+ if (_game._trigger == 48)
+ _activeTeleporter = false;
+
+ if (_game._trigger == 100) {
+ _bartenderReady = false;
+ if (_bartenderHandsHips) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _bartenderHandsHips = false;
+ } else if (_bartenderLooksLeft) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _bartenderLooksLeft = false;
+ } else if (_bartenderSteady) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _bartenderSteady = false;
+ }
+
+ if (!_bartenderTalking) {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 7, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 3, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[10], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _bartenderTalking = true;
+ if (_talkTimer > 1000)
+ _scene->_sequences.addTimer(_talkTimer - 1000, 101);
+ else
+ _scene->_sequences.addTimer(_talkTimer, 101);
+ }
+ }
+
+ if ((_game._trigger == 101) && _bartenderTalking) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _bartenderSteady = true;
+ _bartenderTalking = false;
+ if (_talkTimer < 1000)
+ _bartenderReady = true;
+ }
+
+ if (_game._trigger == 28)
+ _game._player._stepEnabled = true;
+
+ switch (_game._trigger) {
+ case 92:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 1, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 93);
+ break;
+
+ case 93: {
+ int seqIdx = _globals._sequenceIndexes[7];
+ switch (_roxMode) {
+ case 20:
+ _vm->_sound->command(57);
+ _scene->_sequences.remove(_globals._sequenceIndexes[15]);
+ _game._objects.addToInventory(OBJ_CREDIT_CHIP);
+ _vm->_dialogs->showItem(OBJ_CREDIT_CHIP, 40242);
+ break;
+
+ case 22:
+ _vm->_sound->command(57);
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _game._objects.addToInventory(OBJ_ALIEN_LIQUOR);
+ _globals[kBottleDisplayed] = false;
+ _vm->_dialogs->showItem(OBJ_ALIEN_LIQUOR, 40241);
+ break;
+
+ case 21:
+ _globals._sequenceIndexes[15] = _scene->_sequences.startCycle(_globals._spriteIndexes[15], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[15], 8);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[15], Common::Point(250, 80));
+ break;
+
+ default:
+ break;
+ }
+ _globals._sequenceIndexes[7] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[7], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 1, 3);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[7], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 94);
+
+ if (_roxMode == 21) {
+ if (_game._objects.isInInventory(OBJ_CREDIT_CHIP))
+ _game._objects.setRoom (OBJ_CREDIT_CHIP, NOWHERE);
+
+ _bartenderMode = 20;
+ _scene->_sequences.addTimer(60, 95);
+ }
+ }
+ break;
+
+ case 94: {
+ int seqIdx = _globals._sequenceIndexes[7];
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[6], seqIdx);
+ if (_roxMode == 22) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(230, 56), 0x1110, 32, 0, 120, _game.getQuote(0x23F));
+ _bartenderMode = 21;
+ _globals[kHasPurchased] = true;
+ _scene->_sequences.addTimer(140, 95);
+ } else if (_roxMode == 20)
+ _game._player._stepEnabled = true;
+
+ }
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 95:
+ _bartenderReady = false;
+ _game._player._stepEnabled = false;
+ if (_bartenderHandsHips || _bartenderTalking) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _bartenderHandsHips = false;
+ _bartenderTalking = false;
+ }
+
+ if (_bartenderLooksLeft) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _bartenderLooksLeft = false;
+ }
+
+ if (_bartenderSteady) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _bartenderSteady = false;
+ }
+ _globals._sequenceIndexes[12] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[12], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[12], 1, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 96);
+ break;
+
+ case 96: {
+ int seqIdx = _globals._sequenceIndexes[12];
+ _globals._sequenceIndexes[12] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[12], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[12], 6, 7);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[12], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 97);
+ }
+ break;
+
+ case 97: {
+ int seqIdx = _globals._sequenceIndexes[12];
+ switch (_bartenderMode) {
+ case 20:
+ _scene->_sequences.remove(_globals._sequenceIndexes[15]);
+ break;
+
+ case 21: {
+ _globals._sequenceIndexes[15] = _scene->_sequences.startCycle(_globals._spriteIndexes[15], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[15], 8);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[15], Common::Point(250, 80));
+ int idx = _scene->_dynamicHotspots.add(NOUN_CREDIT_CHIP, VERB_TAKE, _globals._sequenceIndexes[15], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_NONE);
+ }
+ break;
+
+ case 22:
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _globals[kBottleDisplayed] = false;
+ break;
+
+ default:
+ break;
+ }
+
+ _globals._sequenceIndexes[12] = _scene->_sequences.startCycle(_globals._spriteIndexes[12], false, 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[12], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8);
+ _scene->_sequences.addTimer(10, 98);
+ }
+ break;
+
+ case 98:
+ _scene->_sequences.remove(_globals._sequenceIndexes[12]);
+ _globals._sequenceIndexes[12] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[12], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[12], 1, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 99);
+ break;
+
+ case 99: {
+ int seqIdx = _globals._sequenceIndexes[12];
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ _bartenderSteady = true;
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ if (_bartenderMode == 20) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(210, 41), 0xFDFC, 0, 0, 100, _game.getQuote(0x1F3));
+ _scene->_sequences.addTimer(5, 100);
+ _talkTimer = 180;
+ _roxMode = 22;
+ _scene->_sequences.addTimer(65, 92);
+ } else if ((_bartenderMode == 21) || (_bartenderMode == 22)) {
+ _game._player._stepEnabled = true;
+ _bartenderReady = true;
+ }
+
+ }
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 86:
+ _bartenderReady = false;
+ _game._player._stepEnabled = false;
+ if ((_bartenderHandsHips) || (_bartenderTalking)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _bartenderHandsHips = false;
+ _bartenderTalking = false;
+ } else if (_bartenderLooksLeft) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _bartenderLooksLeft = false;
+ } else if (_bartenderSteady) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _bartenderSteady = false;
+ }
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 1, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 87);
+ break;
+
+ case 87: {
+ int seqIdx = _globals._sequenceIndexes[9];
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], seqIdx);
+ _scene->_sequences.addTimer(10, 89);
+
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 7);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 88);
+ }
+ break;
+
+ case 88:
+ _globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 7);
+ _globals[kBottleDisplayed] = true;
+ break;
+
+ case 89:
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _scene->_sequences.addTimer(10, 90);
+ break;
+
+ case 90:
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _scene->_sequences.addTimer(10, 91);
+ break;
+
+ case 91: {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _bartenderSteady = true;
+ _game._player._stepEnabled = true;
+ _bartenderReady = true;
+ }
+ break;
+ }
+
+ if (!_waitingGinnyMove && !_ginnyLooking) {
+ _waitingGinnyMove = true;
+ ++ _beatCounter;
+ if (_beatCounter >= 20) {
+ _ginnyLooking = true;
+ _beatCounter = 0;
+ _scene->_sequences.addTimer(60, 54);
+ } else {
+ _scene->_sequences.addTimer(30, 75);
+ }
+ }
+
+ switch (_game._trigger) {
+ case 75:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _bigBeatFl = !_bigBeatFl;
+
+ if (_bigBeatFl) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 5);
+ _scene->_sequences.addTimer(8, 130);
+ } else {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 5);
+ _scene->_sequences.addTimer(8, 53);
+ }
+
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ break;
+
+ case 130:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ _scene->_sequences.addTimer(8, 131);
+ break;
+
+ case 131:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ _scene->_sequences.addTimer(8, 53);
+ break;
+
+ case 53:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ _waitingGinnyMove = false;
+ break;
+ }
+
+ if ((_game._trigger == 54) && _ginnyLooking) {
+ ++_beatCounter;
+ if (_beatCounter >= 10) {
+ _ginnyLooking = false;
+ _waitingGinnyMove = false;
+ _beatCounter = 0;
+ _bigBeatFl = true;
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, _vm->getRandomNumber(1, 4));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ _scene->_sequences.addTimer(60, 54);
+ }
+ }
+
+ if (_bartenderReady) {
+ if (_vm->getRandomNumber(1, 250) == 1) {
+ if (_bartenderLooksLeft) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _bartenderLooksLeft = false;
+ } else if (_bartenderHandsHips) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _bartenderHandsHips = false;
+ } else if (_bartenderSteady) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _bartenderSteady = false;
+ }
+
+ switch (_vm->getRandomNumber(1, 3)) {
+ case 1: {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[10], false, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[10], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _bartenderHandsHips = true;
+ }
+ break;
+
+ case 2: {
+ _globals._sequenceIndexes[11] = _scene->_sequences.startCycle(_globals._spriteIndexes[11], false, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[11], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[11], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _bartenderLooksLeft = true;
+ }
+ break;
+
+ case 3: {
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _bartenderSteady = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_game._trigger == 76) {
+ int seqIdx = _globals._sequenceIndexes[6];
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[6], seqIdx);
+ if (!_globals[kBeenThruHelgaScene]) {
+ _game._player._stepEnabled = false;
+ _cutSceneNeeded = true;
+ } else {
+ _game._player._stepEnabled = true;
+ }
+ _roxOnStool = true;
+ }
+
+ switch (_game._trigger) {
+ case 77:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 10, 12);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 78);
+ break;
+
+ case 78: {
+ _vm->_sound->command(57);
+ int seqIdx = _globals._sequenceIndexes[7];
+ _game._objects.addToInventory(OBJ_REPAIR_LIST);
+ _scene->_sequences.remove(_globals._sequenceIndexes[14]);
+ _globals._sequenceIndexes[7] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[7], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 10, 12);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[7], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 79);
+ }
+ break;
+
+ case 79: {
+ int seqIdx = _globals._sequenceIndexes[7];
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[6], seqIdx);
+ _scene->_sequences.addTimer(20, 180);
+ }
+ break;
+
+ case 180:
+ _vm->_dialogs->showItem(OBJ_REPAIR_LIST, 40240);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (_cutSceneNeeded && _cutSceneReady) {
+ _cutSceneNeeded = false;
+ _scene->_sequences.addTimer(20, 55);
+ _helgaReady = false;
+ _bartenderReady = false;
+ }
+
+ if (_vm->getRandomNumber(1, 25) == 1) {
+ if (_lightOn) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[0]);
+ _lightOn = false;
+ } else {
+ _globals._sequenceIndexes[0] = _scene->_sequences.startCycle(_globals._spriteIndexes[0], false, 1);
+ _lightOn = true;
+ }
+ }
+
+ if (!_blowingSmoke && (_vm->getRandomNumber(1, 300) == 1)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 14);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 30);
+ _blowingSmoke = true;
+ }
+
+ switch (_game._trigger) {
+ case 30:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1],SEQUENCE_TRIGGER_EXPIRE, 0, 31);
+ break;
+
+ case 31:
+ _blowingSmoke = false;
+ break;
+ }
+
+ if (!_leftWomanMoving) {
+ if (_vm->getRandomNumber(1, 1000) == 1) {
+ switch (_vm->getRandomNumber(1, 2)) {
+ case 1:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 33);
+ _leftWomanMoving = true;
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.addTimer(12, 35);
+ _leftWomanMoving = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ switch (_game._trigger) {
+ case 33: {
+ int seqIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 9);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], seqIdx);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(60, 250), 34);
+ }
+ break;
+
+ case 34:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 38);
+ break;
+
+ case 35:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 2);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(60, 300), 36);
+ break;
+
+ case 36:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.addTimer(12, 37);
+ break;
+
+ case 37:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _leftWomanMoving = false;
+ break;
+
+ case 38:
+ _leftWomanMoving = false;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!_rightWomanMoving) {
+ if (_vm->getRandomNumber(1, 300) == 1) {
+ switch (_vm->getRandomNumber(1, 4)) {
+ case 1:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 32);
+ _rightWomanMoving = true;
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 32);
+ _rightWomanMoving = true;
+ break;
+
+ case 3:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 32);
+ _rightWomanMoving = true;
+ break;
+
+ case 4:
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 3, 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 32);
+ _rightWomanMoving = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_game._trigger == 32)
+ _rightWomanMoving = false;
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 1) {
+ switch (_vm->getRandomNumber(1, 50)) {
+ case 1:
+ _scene->_activeAnimation->setCurrentFrame(2);
+ break;
+
+ case 2:
+ _scene->_activeAnimation->setCurrentFrame(7);
+ break;
+
+ case 3:
+ _scene->_activeAnimation->setCurrentFrame(11);
+ break;
+
+ default:
+ _scene->_activeAnimation->setCurrentFrame(0);
+ break;
+ }
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 4) && (_drinkTimer < 10)) {
+ ++ _drinkTimer;
+ _scene->_activeAnimation->setCurrentFrame(3);
+ }
+
+ if (_drinkTimer == 10) {
+ _drinkTimer = 0;
+ _scene->_activeAnimation->setCurrentFrame(4);
+ _scene->_activeAnimation->_currentFrame = 5;
+ }
+
+
+ switch (_scene->_activeAnimation->getCurrentFrame()) {
+ case 6:
+ case 10:
+ case 14:
+ _scene->_activeAnimation->setCurrentFrame(0);
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 39:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(89, 67), 0xFDFC, 32, 0, 120, _game.getQuote(0x1D8));
+ _scene->_sequences.addTimer(150, 40);
+ break;
+
+ case 40:
+ _scene->_kernelMessages.add(Common::Point(89, 67), 0xFDFC, 32, 0, 120, _game.getQuote(0x1D9));
+ _scene->_sequences.addTimer(150, 41);
+ break;
+
+ case 41:
+ _scene->_kernelMessages.add(Common::Point(89, 67), 0xFDFC, 32, 0, 120, _game.getQuote(0x1DA));
+ _game._player._stepEnabled = true;
+ break;
+
+ case 42:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(89, 67), 0xFDFC, 32, 0, 120, _game.getQuote(0x1DC));
+ _scene->_sequences.addTimer(150, 43);
+ break;
+
+ case 43:
+ _scene->_kernelMessages.add(Common::Point(89, 67), 0xFDFC, 32, 0, 120, _game.getQuote(0x1DD));
+ _game._player._stepEnabled = true;
+ break;
+
+ case 44:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 55:
+ if (_bartenderHandsHips) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _bartenderHandsHips = false;
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _bartenderSteady = true;
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ } else if (_bartenderLooksLeft) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _bartenderLooksLeft = false;
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[9], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(228, 83), FACING_SOUTH);
+ _bartenderSteady = true;
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ }
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(180, 47), 0xFBFA, 0, 0, 100, _game.getQuote(0x1FE));
+ _scene->_sequences.addTimer(120, 56);
+ break;
+
+ case 56:
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 2, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 57);
+ break;
+
+ case 57: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _scene->_sequences.remove(_globals._sequenceIndexes[20]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 6, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 58);
+ }
+ break;
+
+ case 58: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 5, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 59);
+ }
+ break;
+
+ case 59: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 1, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
+ _globals._sequenceIndexes[20] = _scene->_sequences.startCycle(_globals._spriteIndexes[20], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[20], 8);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[20], Common::Point(234, 72));
+ }
+ break;
+
+ case 60: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addTimer(10, 61);
+ }
+ break;
+
+ case 61:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(181, 33), 0xFBFA, 0, 0, 130, _game.getQuote(0x1FF));
+ _scene->_kernelMessages.add(Common::Point(171, 47), 0xFBFA, 0, 0, 130, _game.getQuote(0x200));
+ _scene->_sequences.addTimer(150, 63);
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 30, 4, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 62);
+ break;
+
+ case 62: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ }
+ break;
+
+ case 63:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(160, 33), 0xFBFA, 0, 0, 130, _game.getQuote(0x201));
+ _scene->_kernelMessages.add(Common::Point(165, 47), 0xFBFA, 0, 0, 130, _game.getQuote(0x202));
+ _scene->_sequences.addTimer(150, 64);
+ break;
+
+ case 64:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(210, 27), 0xFDFC, 0, 0, 130, _game.getQuote(0x1E0));
+ _scene->_kernelMessages.add(Common::Point(198, 41), 0xFDFC, 0, 0, 130, _game.getQuote(0x1E1));
+ _scene->_sequences.addTimer(150, 65);
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 1130;
+ break;
+
+ case 65:
+ _vm->_sound->command(30);
+ _globals._sequenceIndexes[16] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[16], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[16], 1, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[16], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[16], SEQUENCE_TRIGGER_EXPIRE, 0, 66);
+ break;
+
+ case 66: {
+ int seqIdx = _globals._sequenceIndexes[16];
+ _globals._sequenceIndexes[16] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[16], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[16], 7, 37);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[16], 9);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[16], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[16], SEQUENCE_TRIGGER_EXPIRE, 0, 68);
+
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 12, 13);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 67);
+ }
+ break;
+
+ case 67: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 13);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ }
+ break;
+
+ case 68:
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 12, 13);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 69);
+ break;
+
+ case 69: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(179, 33), 0xFBFA, 0, 0, 130, _game.getQuote(0x203));
+ _scene->_kernelMessages.add(Common::Point(167, 47), 0xFBFA, 0, 0, 130, _game.getQuote(0x204));
+ _scene->_sequences.addTimer(150, 71);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ }
+ break;
+
+ case 70:
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 12);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 71:
+ _scene->_sequences.addTimer(210, 73);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(168, 33), 0xFBFA, 0, 0, 180, _game.getQuote(0x205));
+ _scene->_kernelMessages.add(Common::Point(151, 47), 0xFBFA, 0, 0, 180, _game.getQuote(0x206));
+ if (!_game._objects.isInInventory(OBJ_REPAIR_LIST))
+ _activeArrows = true;
+ break;
+
+ case 72: {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ }
+ break;
+
+ case 73:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(177, 33), 0xFBFA, 0, 0, 150, _game.getQuote(0x207));
+ _scene->_kernelMessages.add(Common::Point(172, 47), 0xFBFA, 0, 0, 150, _game.getQuote(0x208));
+ _bartenderSteady = true;
+ _game._player._stepEnabled = true;
+ _helgaReady = true;
+ _bartenderReady = true;
+ _globals[kBeenThruHelgaScene] = true;
+ _activeArrows = false;
+ break;
+
+ default:
+ break;
+ }
+
+ if (_helgaReady) {
+ int rndVal = _vm->getRandomNumber(1, 1000);
+ if (rndVal < 6)
+ switch (rndVal) {
+ case 1:
+ _cutSceneReady = false;
+ _helgaReady = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 2, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 82);
+ break;
+
+ case 2:
+ _cutSceneReady = false;
+ _helgaReady = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 11, 13);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26);
+ break;
+
+ case 3:
+ _cutSceneReady = false;
+ _helgaReady = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26);
+ break;
+
+ case 4:
+ _cutSceneReady = false;
+ _helgaReady = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 14, 15);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26);
+ break;
+
+ case 5:
+ _cutSceneReady = false;
+ _helgaReady = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 16, 19);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_game._trigger == 80) {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 19);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(60, 120), 81);
+ }
+
+ if (_game._trigger == 81) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 16, 19);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26);
+ }
+
+ if (_game._trigger == 26) {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _cutSceneReady = true;
+
+ if (!_cutSceneNeeded)
+ _helgaReady = true;
+ }
+
+ if (_game._trigger == 82) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[20]);
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 6, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 83);
+ }
+
+ if (_game._trigger == 83) {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 5, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 84);
+ }
+
+ if (_game._trigger == 84) {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 1, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 85);
+
+ _globals._sequenceIndexes[20] = _scene->_sequences.startCycle(_globals._spriteIndexes[20], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[20], 8);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[20], Common::Point(234, 72));
+ }
+
+ if (_game._trigger == 85) {
+ int seqIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _cutSceneReady = true;
+ if (!_cutSceneNeeded)
+ _helgaReady = true;
+ }
+
+ if (_game._trigger == 102) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[7], 14, 18);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 103);
+ } else if (_game._trigger == 103) {
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _roxOnStool = false;
+ _game._player._facing = FACING_SOUTH;
+ _game._player.selectSeries();
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _game._player._readyToWalk = true;
+ }
+
+ if (_activeArrows) {
+ if (!_activeArrow1) {
+ _globals._sequenceIndexes[17] = _scene->_sequences.startCycle(_globals._spriteIndexes[17], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[17], 1);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(10, 15), 49);
+ _activeArrow1 = true;
+ }
+
+ if (!_activeArrow2) {
+ _globals._sequenceIndexes[18] = _scene->_sequences.startCycle(_globals._spriteIndexes[18], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[18], 1);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(10, 15), 50);
+ _activeArrow2 = true;
+ }
+
+ if (!_activeArrow3) {
+ _globals._sequenceIndexes[19] = _scene->_sequences.startCycle(_globals._spriteIndexes[19], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[19], 1);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(10, 15), 51);
+ _activeArrow3 = true;
+ }
+ }
+
+ if (_game._trigger == 49) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[17]);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(10, 15), 45);
+ }
+
+ if (_game._trigger == 45)
+ _activeArrow1 = false;
+
+ if (_game._trigger == 50) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[18]);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(10, 15), 46);
+ }
+
+ if (_game._trigger == 46)
+ _activeArrow2 = false;
+
+ if (_game._trigger == 51) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[19]);
+ _scene->_sequences.addTimer(_vm->getRandomNumber(10, 15), 47);
+ }
+
+ if (_game._trigger == 47)
+ _activeArrow3 = false;
+}
+
+void Scene402::preActions() {
+ if (_action.isAction(VERB_SIT_ON, NOUN_BAR_STOOL) && (_game._player._prepareWalkPos.x != 248))
+ _game._player.walk(Common::Point(232, 112), FACING_EAST);
+
+ if (_action.isAction(VERB_WALKTO, NOUN_WOMAN_ON_BALCONY))
+ _game._player._needToWalk = _game._player._readyToWalk;
+
+ if (!_roxOnStool && _action.isAction(VERB_TAKE, NOUN_CREDIT_CHIP) && !_game._objects.isInInventory(OBJ_CREDIT_CHIP))
+ _game._player.walk(Common::Point(246, 108), FACING_NORTH);
+
+ if (_action.isAction(VERB_TAKE))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_TAKE, NOUN_CREDIT_CHIP) && !_roxOnStool)
+ _game._player._needToWalk = true;
+
+ if (_roxOnStool) {
+ if (_action.isAction(VERB_LOOK) || _action.isObject(NOUN_BAR_STOOL) || _action.isAction(VERB_TALKTO))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_TAKE, NOUN_REPAIR_LIST) || _action.isAction(VERB_TAKE, NOUN_CREDIT_CHIP))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_TALKTO, NOUN_WOMAN_IN_CHAIR) || _action.isAction(VERB_TALKTO, NOUN_WOMAN_IN_ALCOVE))
+ _game._player._needToWalk = _game._player._readyToWalk;
+
+ if (_game._player._needToWalk) {
+ _game._player._facing = FACING_SOUTH;
+ _game._player._readyToWalk = false;
+ _game._player._stepEnabled = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 102);
+ }
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_REPAIR_LIST) && !_roxOnStool && !_game._objects.isInInventory(OBJ_REPAIR_LIST))
+ _game._player.walk(Common::Point(191, 99), FACING_NORTHEAST);
+
+ if (_action.isAction(VERB_TALKTO, NOUN_BARTENDER) && !_roxOnStool)
+ _game._player.walk(Common::Point(228, 83), FACING_SOUTH);
+
+ if (_action.isAction(VERB_TALKTO, NOUN_REPAIR_WOMAN) && !_roxOnStool)
+ _game._player.walk(Common::Point(208, 102), FACING_NORTHEAST);
+}
+
+void Scene402::actions() {
+ if (_action.isAction(VERB_TAKE, NOUN_REPAIR_LIST) && _game._objects.isInRoom(OBJ_REPAIR_LIST) && _roxOnStool) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 77);
+ _game._player._needToWalk = false;
+ } else if (_action.isAction(VERB_TAKE, NOUN_REPAIR_LIST) && _game._objects.isInRoom(OBJ_REPAIR_LIST) && !_roxOnStool) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[21] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[21], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[21], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[21]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[21], SEQUENCE_TRIGGER_SPRITE, 2, 165);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[21], SEQUENCE_TRIGGER_EXPIRE, 0, 166);
+ } else if (_game._trigger == 165) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[14]);
+ _game._objects.addToInventory(OBJ_REPAIR_LIST);
+ }
+ } else if (_game._trigger == 166) {
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 167);
+ } else if (_game._trigger == 167) {
+ _vm->_dialogs->showItem(OBJ_REPAIR_LIST, 40240);
+ _game._player._stepEnabled = true;
+ } else if (_game._screenObjects._inputMode == 1)
+ handleDialogs();
+ else if (_action.isAction(VERB_WALK_INTO, NOUN_CORRIDOR_TO_SOUTH))
+ _scene->_nextSceneId = 401;
+ else if (_action.isAction(VERB_WALK_ONTO, NOUN_DANCE_FLOOR))
+ ; // just... nothing
+ else if (_action.isAction(VERB_TALKTO, NOUN_REPAIR_WOMAN)) {
+ switch (_game._trigger) {
+ case 0: {
+ _game._player._stepEnabled = false;
+ int random = _vm->getRandomNumber(1, 3);
+ if (_helgaTalkMode == 0)
+ random = 1;
+
+ int centerFlag;
+ Common::Point centerPos;
+ if (_roxOnStool) {
+ centerFlag = 0;
+ centerPos = Common::Point(230, 56);
+ } else {
+ centerFlag = 2;
+ centerPos = Common::Point(0, 0);
+ }
+
+ switch (random) {
+ case 1:
+ _scene->_kernelMessages.add(centerPos, 0x1110, 32 | centerFlag, 0, 90, _game.getQuote(0x211));
+ _scene->_sequences.addTimer(110, 25);
+ break;
+
+ case 2:
+ _scene->_kernelMessages.add(centerPos, 0x1110, 32 | centerFlag, 0, 90, _game.getQuote(0x212));
+ _scene->_sequences.addTimer(110, 25);
+ break;
+
+ case 3:
+ _scene->_kernelMessages.add(centerPos, 0x1110, 32 | centerFlag, 0, 90, _game.getQuote(0x213));
+ _scene->_sequences.addTimer(110, 25);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case 25:
+ switch (_helgaTalkMode) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _helgaTalkMode = 1;
+ _scene->_kernelMessages.add(Common::Point(177, 33), 0xFBFA, 0, 0, 130, _game.getQuote(0x209));
+ _scene->_kernelMessages.add(Common::Point(182, 47), 0xFBFA, 0, 0, 130, _game.getQuote(0x20A));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(130, 28);
+ break;
+
+ case 1:
+ _game._player._stepEnabled = false;
+ _helgaTalkMode = 2;
+ _scene->_kernelMessages.add(Common::Point(157, 47), 0xFBFA, 0, 0, 100, _game.getQuote(0x20B));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(100, 28);
+ break;
+
+ case 2:
+ _game._player._stepEnabled = false;
+ _helgaTalkMode = 3;
+ _scene->_kernelMessages.add(Common::Point(172, 47), 0xFBFA, 0, 0, 100, _game.getQuote(0x20C));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(100, 28);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+ } else if (_action.isAction(VERB_TALKTO, NOUN_WOMAN_IN_CHAIR) && !_firstTalkToGirlInChair) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x1D7));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(150, 39);
+ _game._player._stepEnabled = false;
+ _firstTalkToGirlInChair = true;
+ } else if (_action.isAction(VERB_TALKTO, NOUN_WOMAN_IN_CHAIR) && _firstTalkToGirlInChair) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x1DB));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(150, 42);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_TALKTO, NOUN_WOMAN_IN_ALCOVE) || _action.isAction(VERB_WALKTO, NOUN_WOMAN_IN_ALCOVE)) {
+ _scene->_kernelMessages.add(Common::Point(102, 48), 0xFBFA, 0, 0, 120, _game.getQuote(0x1DE));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(120, 44);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_WALK_ALONG, NOUN_BAR_STOOL) && (_game._player._targetPos.x == 248)){
+ _scene->_kernelMessages.add(Common::Point(0, -14), 0x1110, 34, 0, 120, _game.getQuote(0x20D));
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x20E));
+ } else if (_action.isAction(VERB_WALK_ALONG, NOUN_BAR_STOOL) && !_roxOnStool && (_game._player._targetPos.x != 248)) {
+ _game._player._visible = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 76);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_TAKE, NOUN_CREDIT_CHIP) && !_game._objects.isInInventory(OBJ_CREDIT_CHIP) && _roxOnStool) {
+ _roxMode = 20;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 92);
+ } else if (_action.isAction(VERB_TAKE, NOUN_CREDIT_CHIP) && !_game._objects.isInInventory(OBJ_CREDIT_CHIP) && !_roxOnStool) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[22] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[22], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[22], 1, 2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[22], Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[22], 5);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[22], 88);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[22], SEQUENCE_TRIGGER_EXPIRE, 0, 104);
+ } else if (_action.isAction(VERB_TALKTO, NOUN_BARTENDER)) {
+ switch (_game._trigger) {
+ case 0: {
+ int centerFlag;
+ Common::Point centerPos;
+ if (_roxOnStool) {
+ centerFlag = 0;
+ centerPos = Common::Point(230, 56);
+ } else {
+ centerFlag = 2;
+ centerPos = Common::Point(0, 0);
+ }
+
+ _game._player._stepEnabled = false;
+ int quoteId;
+ if (_bartenderCalled) {
+ quoteId = 0x210;
+ } else {
+ quoteId = 0x20F;
+ _bartenderCalled = true;
+ }
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(centerPos, 0x1110, 32 | centerFlag, 0, 90, _game.getQuote(quoteId));
+ _scene->_sequences.addTimer(110, 29);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(90, 28);
+ }
+ break;
+
+ case 29:
+ _scene->_kernelMessages.reset();
+ if (!_roxOnStool) {
+ if (_game._objects.isInRoom(OBJ_ALIEN_LIQUOR)) {
+ _scene->_kernelMessages.add(Common::Point(177, 41), 0xFDFC, 0, 0, 120, _game.getQuote(0x1DF));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ } else if (_rexMode == 0) {
+ _scene->_kernelMessages.add(Common::Point(175, 13), 0xFDFC, 0, 0, 180, _game.getQuote(0x1F9));
+ _scene->_kernelMessages.add(Common::Point(184, 27), 0xFDFC, 0, 0, 180, _game.getQuote(0x1FA));
+ _scene->_kernelMessages.add(Common::Point(200, 41), 0xFDFC, 0, 0, 180, _game.getQuote(0x1FB));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 180;
+ _rexMode = 1;
+ } else if (_rexMode == 1) {
+ _scene->_kernelMessages.add(Common::Point(205, 41), 0xFDFC, 0, 0, 120, _game.getQuote(0x1FC));
+ _game._player._stepEnabled = true;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ _rexMode = 3;
+ } else {
+ _game._player._stepEnabled = true;
+ }
+ } else {
+ if (_game._objects.isInRoom(OBJ_ALIEN_LIQUOR)) {
+ if (!_refuseAlienLiquor) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(198, 27), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E2));
+ _scene->_kernelMessages.add(Common::Point(199, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1E3));
+ _bartenderCurrentQuestion = 10;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ _conversationFl = true;
+ _bartenderDialogNode = 1;
+ if (_dialog2.read(0) <= 1)
+ _dialog1.write(0x214, false);
+
+ _dialog1.start();
+ } else {
+ _scene->_kernelMessages.add(Common::Point(177, 41), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x1EF));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ _bartenderCurrentQuestion = 3;
+ _conversationFl = true;
+ _bartenderDialogNode = 1;
+ if (_dialog2.read(0) <= 1)
+ _dialog1.write(0x214, false);
+
+ _dialog1.start();
+ _game._player._stepEnabled = true;
+ }
+ } else {
+ if (_rexMode == 0) {
+ _scene->_kernelMessages.add(Common::Point(175, 13), 0xFDFC, 0, 0, 180, _game.getQuote(0x1F9));
+ _scene->_kernelMessages.add(Common::Point(184, 27), 0xFDFC, 0, 0, 180, _game.getQuote(0x1FA));
+ _scene->_kernelMessages.add(Common::Point(200, 41), 0xFDFC, 0, 0, 180, _game.getQuote(0x1FB));
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 180;
+ _rexMode = 1;
+ } else if (_rexMode == 1) {
+ _scene->_kernelMessages.add(Common::Point(205, 41), 0xFDFC, 0, 0, 120, _game.getQuote(0x1FC));
+ _game._player._stepEnabled = true;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(1, 100);
+ _talkTimer = 120;
+ _rexMode = 3;
+ } else {
+ _game._player._stepEnabled = true;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_DANCE_FLOOR))
+ _vm->_dialogs->show(40210);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER)) {
+ if (_globals[kSomeoneHasExploded])
+ _vm->_dialogs->show(40212);
+ else
+ _vm->_dialogs->show(40211);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BAR))
+ _vm->_dialogs->show(40213);
+ else if (_action.isAction(VERB_LOOK, NOUN_BARTENDER))
+ _vm->_dialogs->show(40214);
+ else if (_action.isAction(VERB_LOOK, NOUN_WOMAN_IN_ALCOVE))
+ _vm->_dialogs->show(40215);
+ else if (_action.isAction(VERB_LOOK, NOUN_WOMAN_ON_BALCONY))
+ _vm->_dialogs->show(40216);
+ else if (_action.isAction(VERB_LOOK, NOUN_WOMAN_IN_CHAIR))
+ _vm->_dialogs->show(40217);
+ else if (_action.isAction(VERB_LOOK, NOUN_REPAIR_WOMAN))
+ _vm->_dialogs->show(40218);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(40219);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(40220);
+ else if (_action.isAction(VERB_LOOK, NOUN_WOMEN))
+ _vm->_dialogs->show(40221);
+ else if (_action.isAction(VERB_PUSH, NOUN_REPAIR_WOMAN) || _action.isAction(VERB_PULL, NOUN_REPAIR_WOMAN))
+ _vm->_dialogs->show(40222);
+ else if (_action.isAction(VERB_TALKTO, NOUN_WOMEN))
+ _vm->_dialogs->show(40223);
+ else if (_action.isAction(VERB_TALKTO, NOUN_WOMAN_ON_BALCONY))
+ _vm->_dialogs->show(40224);
+ else if (_action.isAction(VERB_LOOK, NOUN_RAILING))
+ _vm->_dialogs->show(40225);
+ else if (_action.isAction(VERB_LOOK, NOUN_TABLE))
+ _vm->_dialogs->show(40226);
+ else if (_action.isAction(VERB_TAKE, NOUN_TABLE))
+ _vm->_dialogs->show(40227);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN))
+ _vm->_dialogs->show(40228);
+ else if (_action.isAction(VERB_TAKE, NOUN_SIGN))
+ _vm->_dialogs->show(40229);
+ else if (_action.isAction(VERB_LOOK, NOUN_BAR_STOOL))
+ _vm->_dialogs->show(40230);
+ else if (_action.isAction(VERB_TAKE, NOUN_BAR_STOOL))
+ _vm->_dialogs->show(40231);
+ else if (_action.isAction(VERB_LOOK, NOUN_CACTUS))
+ _vm->_dialogs->show(40232);
+ else if (_action.isAction(VERB_TAKE, NOUN_CACTUS))
+ _vm->_dialogs->show(40233);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISCO_BALL))
+ _vm->_dialogs->show(40234);
+ else if (_action.isAction(VERB_LOOK, NOUN_UPPER_DANCE_FLOOR))
+ _vm->_dialogs->show(40235);
+ else if (_action.isAction(VERB_LOOK, NOUN_TREE))
+ _vm->_dialogs->show(40236);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLANT))
+ _vm->_dialogs->show(40237);
+ else if (_action.isAction(VERB_TAKE, NOUN_PLANT))
+ _vm->_dialogs->show(40238);
+ else if (_action.isAction(VERB_LOOK, NOUN_REPAIR_LIST) && _game._objects.isInRoom(OBJ_REPAIR_LIST))
+ _vm->_dialogs->show(40239);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene405::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene405::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*ROXCL_8");
+
+ if (_scene->_priorSceneId == 401) {
+ _game._player._playerPos = Common::Point(23, 123);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId == 406) {
+ _game._player._playerPos = Common::Point(300, 128);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId == 408) {
+ _game._player._playerPos = Common::Point(154, 109);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId == 413) {
+ _game._player._playerPos = Common::Point(284, 109);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(23, 123);
+ _game._player._facing = FACING_EAST;
+ }
+
+ if (_globals[kArmoryDoorOpen])
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ else
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+
+ if (_scene->_roomChanged) {
+ _globals[kArmoryDoorOpen] = false;
+ _game._objects.addToInventory(OBJ_SECURITY_CARD);
+ }
+
+ _game.loadQuoteSet(0x24F, 0);
+ sceneEntrySound();
+}
+
+void Scene405::step() {
+ if (_game._trigger == 80) {
+ _scene->_sequences.addTimer(20, 81);
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ }
+
+ if (_game._trigger == 81) {
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->show(40525);
+ }
+
+ if (_game._trigger == 70) {
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount ;
+ _game._player._visible = true;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _vm->_sound->command(19);
+ }
+
+ if (_game._trigger == 71) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _globals[kArmoryDoorOpen] = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 75) {
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount ;
+ _game._player._visible = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _globals[kArmoryDoorOpen] = true;
+ _game._player._stepEnabled = true;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle (_globals._spriteIndexes[2],
+ false, 1);
+ _vm->_sound->command(19);
+ }
+}
+
+void Scene405::preActions() {
+ if (_action.isAction(VERB_TAKE))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 401;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 406;
+
+ if (_action.isAction(VERB_CLOSE, NOUN_WIDE_DOOR) && _globals[kArmoryDoorOpen])
+ _game._player.walk(Common::Point(212, 113), FACING_NORTH);
+}
+
+void Scene405::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR))
+ _scene->_nextSceneId = 413;
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_WIDE_DOOR) && _globals[kArmoryDoorOpen])
+ _scene->_nextSceneId = 408;
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_WIDE_DOOR) && !_globals[kArmoryDoorOpen])
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(0x24F));
+ else if (_action.isAction(VERB_PUT, NOUN_SECURITY_CARD, NOUN_CARD_SLOT) && !_globals[kArmoryDoorOpen]) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], msgPos);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[3], 87);
+ } else if ((_action.isAction(VERB_PUT, NOUN_SECURITY_CARD, NOUN_CARD_SLOT) || _action.isAction(VERB_CLOSE, NOUN_WIDE_DOOR)) && _globals[kArmoryDoorOpen]) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], _game._player._playerPos);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[3], 87);
+ } else if (_action.isAction(VERB_PUT, NOUN_CARD_SLOT)) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], _game._player._playerPos);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[3], 87);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CANNON_BALLS))
+ _vm->_dialogs->show(40510);
+ else if (_action.isAction(VERB_TAKE, NOUN_CANNON_BALLS))
+ _vm->_dialogs->show(40511);
+ else if (_action.isAction(VERB_LOOK, NOUN_WATER_FOUNTAIN))
+ _vm->_dialogs->show(40512);
+ else if (_action.isAction(VERB_LOOK, NOUN_BACKBOARD) || _action.isAction(VERB_LOOK, NOUN_HOOP))
+ _vm->_dialogs->show(40513);
+ else if (_action.isAction(VERB_LOOK, NOUN_LIGHT))
+ _vm->_dialogs->show(40514);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARD_SLOT))
+ _vm->_dialogs->show(40515);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(40516);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(40517);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(40518);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR) || _action._lookFlag)
+ _vm->_dialogs->show(40519);
+ else if (_action.isAction(VERB_LOOK, NOUN_WIDE_DOOR)) {
+ if (_globals[kArmoryDoorOpen])
+ _vm->_dialogs->show(40521);
+ else
+ _vm->_dialogs->show(40520);
+ } else if (_action.isAction(VERB_LOOK, NOUN_DOOR))
+ _vm->_dialogs->show(40522);
+ else if (_action.isAction(VERB_LOOK, NOUN_COACH_LAMP))
+ _vm->_dialogs->show(40523);
+ else if (_action.isAction(VERB_LOOK, NOUN_SUPPORT))
+ _vm->_dialogs->show(40524);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene406::Scene406(MADSEngine *vm) : Scene4xx(vm) {
+ _hitStorageDoor = false;
+}
+
+void Scene406::synchronize(Common::Serializer &s) {
+ Scene4xx::synchronize(s);
+
+ s.syncAsByte(_hitStorageDoor);
+}
+
+void Scene406::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene406::enter() {
+ _game._player._visible = true;
+ if (_scene->_priorSceneId == 405) {
+ _game._player._playerPos = Common::Point(15, 129);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId == 407) {
+ _game._player._playerPos = Common::Point(270, 127);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId == 410) {
+ _game._player._playerPos = Common::Point(30, 108);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId == 411) {
+ _game._player._playerPos = Common::Point(153, 108);
+ _game._player._facing = FACING_SOUTH;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(15, 129);
+ _game._player._facing = FACING_EAST;
+ }
+
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*ROXCL_8");
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 1));
+
+ if (_scene->_roomChanged) {
+ _globals[kStorageDoorOpen] = false;
+ _game._objects.addToInventory(OBJ_SECURITY_CARD);
+ }
+
+ if (!_globals[kStorageDoorOpen])
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+
+ if (_scene->_priorSceneId != 411)
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ else {
+ _game._player._stepEnabled = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 3, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
+ _vm->_sound->command(19);
+ }
+
+ _game.loadQuoteSet(0x24F, 0);
+ _hitStorageDoor = false;
+ sceneEntrySound();
+}
+
+void Scene406::step() {
+ if (_game._trigger == 90) {
+ _game._player._stepEnabled = true;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ }
+
+ if (_game._trigger == 80)
+ _scene->_nextSceneId = 411;
+
+ if (_game._trigger == 100) {
+ _vm->_dialogs->show(40622);
+ _hitStorageDoor = true;
+ }
+
+ if (_game._trigger == 110) {
+ _scene->_sequences.addTimer(20, 111);
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ }
+
+ if (_game._trigger == 111) {
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->show(40613);
+ }
+
+ if (_game._trigger == 70) {
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _vm->_sound->command(19);
+ }
+
+ if (_game._trigger == 71) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _globals[kStorageDoorOpen] = false;
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 75) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0);
+ _globals[kStorageDoorOpen] = true;
+ _game._player._stepEnabled = true;
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _vm->_sound->command(19);
+ }
+}
+
+void Scene406::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_WEST))
+ _game._player._walkOffScreenSceneId = 405;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_EAST))
+ _game._player._walkOffScreenSceneId = 407;
+
+ if (_action.isAction(VERB_TAKE))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_LOOK, NOUN_SIGN) || _action.isAction(VERB_LOOK, NOUN_TRASH))
+ _game._player._needToWalk = true;
+}
+
+void Scene406::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR) && (_game._player._targetPos.x> 100)) {
+ _game._player._stepEnabled = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 3, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ _vm->_sound->command(19);
+ } else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR) && _globals[kStorageDoorOpen] && (_game._player._targetPos.x < 100))
+ _scene->_nextSceneId = 410;
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR) && !_globals[kStorageDoorOpen] && (_game._player._targetPos.x < 100)) {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(0x24F));
+ if (!_hitStorageDoor) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(80, 100);
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_SECURITY_CARD, NOUN_CARD_SLOT) && !_globals[kStorageDoorOpen]) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], msgPos);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[2], 87);
+ } else if (_action.isAction(VERB_PUT, NOUN_SECURITY_CARD, NOUN_CARD_SLOT) && _globals[kStorageDoorOpen]) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], msgPos);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[2], 87);
+ } else if (_action.isAction(VERB_PUT, NOUN_CARD_SLOT)) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 110);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[2], _game._player._playerPos);
+ _scene->_sequences.setScale(_globals._sequenceIndexes[2], 87);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TRASH))
+ _vm->_dialogs->show(40610);
+ else if (_action.isAction(VERB_TAKE, NOUN_TRASH))
+ _vm->_dialogs->show(40611);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARD_SLOT))
+ _vm->_dialogs->show(40612);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIRE_EXTINGUISHER))
+ _vm->_dialogs->show(40614);
+ else if (_action.isAction(VERB_TAKE, NOUN_FIRE_EXTINGUISHER))
+ _vm->_dialogs->show(40615);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_EAST))
+ _vm->_dialogs->show(40616);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_WEST))
+ _vm->_dialogs->show(40617);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR) || _action._lookFlag)
+ _vm->_dialogs->show(40618);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(40619);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOOR)) {
+ if (_globals[kStorageDoorOpen])
+ _vm->_dialogs->show(40621);
+ else
+ _vm->_dialogs->show(40620);
+ } else if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(40623);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGNPOST))
+ _vm->_dialogs->show(40624);
+ else if (_action.isAction(VERB_TAKE, NOUN_SIGNPOST))
+ _vm->_dialogs->show(40625);
+ else if (_action.isAction(VERB_LOOK, NOUN_BOULDER))
+ _vm->_dialogs->show(40626);
+ else if (_action.isAction(VERB_TAKE, NOUN_BOULDER))
+ _vm->_dialogs->show(40627);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN))
+ _vm->_dialogs->show(40628);
+ else if (_action.isAction(VERB_TAKE, NOUN_SIGN))
+ _vm->_dialogs->show(40629);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene407::Scene407(MADSEngine *vm) : Scene4xx(vm), _destPos(0, 0) {
+ _fromNorth = false;
+}
+
+void Scene407::synchronize(Common::Serializer &s) {
+ Scene4xx::synchronize(s);
+
+ s.syncAsByte(_fromNorth);
+ s.syncAsSint16LE(_destPos.x);
+ s.syncAsSint16LE(_destPos.y);
+}
+
+void Scene407::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene407::enter() {
+ if (_scene->_priorSceneId != -2)
+ _fromNorth = false;
+
+ if (_scene->_priorSceneId == 318) {
+ _game._player._playerPos = Common::Point(172, 92);
+ _game._player._facing = FACING_SOUTH;
+ _fromNorth = true;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(172, 132);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ _game.loadQuoteSet(0x250, 0);
+ sceneEntrySound();
+}
+
+void Scene407::step() {
+ if (_game._trigger == 70) {
+ _scene->_nextSceneId = 318;
+ _scene->_reloadSceneFlag = true;
+ }
+
+ if (_game._trigger == 80) {
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _fromNorth = false;
+ _game._player.walk(Common::Point(173, 104), FACING_SOUTH);
+ }
+}
+
+void Scene407::preActions() {
+ if (_action.isAction(VERB_TAKE))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_LOOK, NOUN_DOOR))
+ _game._player._needToWalk = true;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_NORTH)) {
+ _game._player.walk(Common::Point(172, 91), FACING_NORTH);
+ _fromNorth = false;
+ }
+
+ if (_game._player._needToWalk && _fromNorth) {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _destPos = Common::Point(171, 95);
+ else
+ _destPos = Common::Point(173, 96);
+
+ _game._player.walk(_destPos, FACING_SOUTH);
+ }
+}
+
+void Scene407::actions() {
+ if ((_game._player._playerPos == _destPos) && _fromNorth) {
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _vm->_sound->command(21);
+ _scene->loadAnimation(formAnimName('s', 1), 70);
+ _globals[kHasBeenScanned] = true;
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(60));
+ _vm->_sound->command(22);
+ }
+
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _vm->_sound->command(21);
+ _scene->loadAnimation(formAnimName('s', 2), 80);
+ _vm->_sound->command(23);
+ _globals[kHasBeenScanned] = true;
+ }
+ }
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_SOUTH) && !_fromNorth)
+ _scene->_nextSceneId = 406;
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_CORRIDOR_TO_NORTH))
+ _scene->_nextSceneId = 318;
+ else if (_action.isAction(VERB_LOOK, NOUN_SCANNER)) {
+ if (_globals[kHasBeenScanned])
+ _vm->_dialogs->show(40711);
+ else
+ _vm->_dialogs->show(40710);
+ } else if (_action.isAction(VERB_LOOK, NOUN_DOOR))
+ _vm->_dialogs->show(40712);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(40713);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_NORTH))
+ _vm->_dialogs->show(40714);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(40715);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene408::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_TARGET_MODULE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene408::enter() {
+ _game._player._playerPos = Common::Point(137, 150);
+ _game._player._facing = FACING_NORTH;
+
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*ROXRC_7");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('m', -1));
+
+ if (_game._objects.isInRoom(OBJ_TARGET_MODULE)) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+ int idx = _scene->_dynamicHotspots.add(NOUN_TARGET_MODULE, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(283, 128), FACING_NORTHEAST);
+ }
+ sceneEntrySound();
+}
+
+void Scene408::preActions() {
+ if ((_action.isAction(VERB_TAKE) && !_action.isObject(NOUN_TARGET_MODULE)) || _action.isAction(VERB_PULL, NOUN_PIN) || _action.isAction(VERB_OPEN, NOUN_CARTON))
+ _game._player._needToWalk = false;
+
+ if ((_action.isAction(VERB_LOOK, NOUN_TARGET_MODULE) && _game._objects.isInRoom(OBJ_TARGET_MODULE)) || _action.isAction(VERB_LOOK, NOUN_CHEST))
+ _game._player._needToWalk = true;
+}
+
+void Scene408::actions() {
+ if (_action.isAction(VERB_WALK_INTO, NOUN_CORRIDOR_TO_SOUTH)) {
+ _scene->_nextSceneId = 405;
+ _vm->_sound->command(58);
+ } else if (_action.isAction(VERB_TAKE, NOUN_TARGET_MODULE) && (_game._objects.isInRoom(OBJ_TARGET_MODULE) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(57);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], true, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[1]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _game._objects.addToInventory(OBJ_TARGET_MODULE);
+ _vm->_dialogs->showItem(OBJ_TARGET_MODULE, 40847);
+ break;
+
+ case 2:
+ _game._player._priorTimer = _game._player._ticksAmount + _scene->_frameStartTime;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_ARMORED_VEHICLE))
+ _vm->_dialogs->show(40810);
+ else if (_action.isAction(VERB_TAKE, NOUN_ARMORED_VEHICLE) || _action.isAction(VERB_TAKE, NOUN_ANVIL) || _action.isAction(VERB_TAKE, NOUN_TWO_TON_WEIGHT))
+ _vm->_dialogs->show(40811);
+ else if (_action.isAction(VERB_LOOK, NOUN_MISSILE))
+ _vm->_dialogs->show(40812);
+ else if (_action.isAction(VERB_TAKE, NOUN_MISSILE))
+ _vm->_dialogs->show(40813);
+ else if (_action.isAction(VERB_LOOK, NOUN_GRENADE))
+ _vm->_dialogs->show(40814);
+ else if (_action.isAction(VERB_TAKE, NOUN_GRENADE))
+ _vm->_dialogs->show(40815);
+ else if (_action.isAction(VERB_TAKE, NOUN_PIN) || _action.isAction(VERB_PULL, NOUN_PIN))
+ _vm->_dialogs->show(40816);
+ else if (_action.isAction(VERB_LOOK, NOUN_BLIMP))
+ _vm->_dialogs->show(40817);
+ else if (_action.isAction(VERB_TAKE, NOUN_BLIMP))
+ _vm->_dialogs->show(40818);
+ else if (_action.isAction(VERB_LOOK, NOUN_AMMUNITION))
+ _vm->_dialogs->show(40819);
+ else if (_action.isAction(VERB_TAKE, NOUN_AMMUNITION))
+ _vm->_dialogs->show(40820);
+ else if (_action.isAction(VERB_LOOK, NOUN_CATAPULT))
+ _vm->_dialogs->show(40821);
+ else if (_action.isAction(VERB_TAKE, NOUN_CATAPULT))
+ _vm->_dialogs->show(40822);
+ else if (_action.isAction(VERB_LOOK, NOUN_CHEST)) {
+ if (_game._objects.isInRoom(OBJ_TARGET_MODULE))
+ _vm->_dialogs->show(40823);
+ else
+ _vm->_dialogs->show(40824);
+ } else if (_action.isAction(VERB_TAKE, NOUN_CHEST))
+ _vm->_dialogs->show(40825);
+ else if (_action.isAction(VERB_LOOK, NOUN_SUIT_OF_ARMOR))
+ _vm->_dialogs->show(40826);
+ else if (_action.isAction(VERB_TAKE, NOUN_SUIT_OF_ARMOR))
+ _vm->_dialogs->show(40827);
+ else if (_action.isAction(VERB_LOOK, NOUN_ESCAPE_HATCH))
+ _vm->_dialogs->show(40828);
+ else if (_action.isAction(VERB_OPEN, NOUN_ESCAPE_HATCH) || _action.isAction(VERB_PULL, NOUN_ESCAPE_HATCH))
+ _vm->_dialogs->show(40829);
+ else if (_action.isAction(VERB_LOOK, NOUN_BARRELS))
+ _vm->_dialogs->show(40830);
+ else if (_action.isAction(VERB_TAKE, NOUN_BARRELS))
+ _vm->_dialogs->show(40831);
+ else if (_action.isAction(VERB_LOOK, NOUN_INFLATABLE_RAFT))
+ _vm->_dialogs->show(40832);
+ else if (_action.isAction(VERB_TAKE, NOUN_INFLATABLE_RAFT))
+ _vm->_dialogs->show(40833);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOMATO))
+ _vm->_dialogs->show(40834);
+ else if (_action.isAction(VERB_TAKE, NOUN_TOMATO))
+ _vm->_dialogs->show(40835);
+ else if (_action.isAction(VERB_LOOK, NOUN_ANVIL))
+ _vm->_dialogs->show(40836);
+ else if (_action.isAction(VERB_LOOK, NOUN_TWO_TON_WEIGHT))
+ _vm->_dialogs->show(40837);
+ else if (_action.isAction(VERB_LOOK, NOUN_POWDER_CONTAINER))
+ _vm->_dialogs->show(40838);
+ else if (_action.isAction(VERB_LOOK, NOUN_POWDER_PUFF))
+ _vm->_dialogs->show(40839);
+ else if (_action.isAction(VERB_TAKE, NOUN_POWDER_PUFF))
+ _vm->_dialogs->show(40840);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARTON))
+ _vm->_dialogs->show(40841);
+ else if (_action.isAction(VERB_TAKE, NOUN_CARTON))
+ _vm->_dialogs->show(40842);
+ else if (_action.isAction(VERB_OPEN, NOUN_CARTON))
+ _vm->_dialogs->show(40843);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(40844);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(40845);
+ else if (_action.isAction(VERB_LOOK, NOUN_TARGET_MODULE) && _game._objects.isInRoom(OBJ_TARGET_MODULE))
+ _vm->_dialogs->show(40846);
+ else if (_action.isAction(VERB_LOOK, NOUN_LOADING_RAMP))
+ _vm->_dialogs->show(40848);
+ else if (_action.isAction(VERB_OPEN, NOUN_CHEST))
+ _vm->_dialogs->show(40849);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene409::setup() {
+ _game._player._spritesPrefix = "";
+
+ // The original is calling Scene4xx::setAAName()
+ _game._aaName = Resources::formatAAName(4);
+}
+
+void Scene409::enter() {
+ _handSpriteId = _scene->_sprites.addSprites("*ROXHAND");
+ teleporterEnter();
+
+ // The original is calling Scene4xx::sceneEntrySound()
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else
+ _vm->_sound->command(10);
+}
+
+void Scene409::step() {
+ teleporterStep();
+}
+
+void Scene409::actions() {
+ if (teleporterActions()) {
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT))
+ _vm->_dialogs->show(40910);
+ else if (_action.isAction(VERB_PEER_THROUGH, NOUN_VIEWPORT))
+ _vm->_dialogs->show(40910);
+ else if (_action.isAction(VERB_LOOK, NOUN_KEYPAD))
+ _vm->_dialogs->show(40911);
+ else if (_action.isAction(VERB_INSPECT, NOUN_KEYPAD))
+ _vm->_dialogs->show(40911);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(40912);
+ else if (_action.isAction(VERB_LOOK, NOUN_1_KEY) || _action.isAction(VERB_LOOK, NOUN_2_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_3_KEY) || _action.isAction(VERB_LOOK, NOUN_4_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_5_KEY) || _action.isAction(VERB_LOOK, NOUN_6_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_7_KEY) || _action.isAction(VERB_LOOK, NOUN_8_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_9_KEY) || _action.isAction(VERB_LOOK, NOUN_0_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_SMILE_KEY) || _action.isAction(VERB_LOOK, NOUN_FROWN_KEY))
+ _vm->_dialogs->show(40913);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEVICE))
+ _vm->_dialogs->show(40914);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(40914);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene410::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene410::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('y', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*ROXRC_7");
+
+ if (_game._objects.isInRoom(OBJ_CHARGE_CASES))
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ else
+ _scene->_hotspots.activate(NOUN_CHARGE_CASES, false);
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(155, 150);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ sceneEntrySound();
+
+ _scene->loadAnimation(Resources::formatName(410, 'r', -1, EXT_AA, ""));
+ _scene->_activeAnimation->_resetFlag = true;
+}
+
+void Scene410::step() {
+ if (_scene->_activeAnimation->getCurrentFrame() == 1) {
+ if (_vm->getRandomNumber(1, 30) == 1)
+ _scene->_activeAnimation->setCurrentFrame(2);
+ else
+ _scene->_activeAnimation->setCurrentFrame(0);
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 9) {
+ if (_vm->getRandomNumber(1, 30) == 1)
+ _scene->_activeAnimation->setCurrentFrame(10);
+ else
+ _scene->_activeAnimation->setCurrentFrame(8);
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 5) {
+ if (_vm->getRandomNumber(1, 30) == 1)
+ _scene->_activeAnimation->setCurrentFrame(6);
+ else
+ _scene->_activeAnimation->setCurrentFrame(4);
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 3) {
+ if (_vm->getRandomNumber(1, 2) == 1)
+ _scene->_activeAnimation->setCurrentFrame(4);
+ else // == 2
+ _scene->_activeAnimation->setCurrentFrame(8);
+ }
+}
+
+void Scene410::preActions() {
+ if (_action.isAction(VERB_TAKE) && !_action.isObject(NOUN_CHARGE_CASES))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_LOOK, NOUN_CHARGE_CASES) && _game._objects.isInRoom(OBJ_CHARGE_CASES))
+ _game._player._needToWalk = true;
+
+ if (_action.isAction(VERB_OPEN, NOUN_SACKS) || _action.isAction(VERB_OPEN, NOUN_SACK))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_LOOK, NOUN_CAN))
+ _game._player._needToWalk = true;
+}
+
+void Scene410::actions() {
+ if (_action.isAction(VERB_WALK_INTO, NOUN_CORRIDOR_TO_SOUTH))
+ _scene->_nextSceneId = 406;
+ else if (_action.isAction(VERB_TAKE, NOUN_CHARGE_CASES) && (_game._objects.isInRoom(OBJ_CHARGE_CASES) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(57);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 3, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_hotspots.activate(NOUN_CHARGE_CASES, false);
+ _game._objects.addToInventory(OBJ_CHARGE_CASES);
+ _vm->_dialogs->showItem(OBJ_CHARGE_CASES, 41032);
+ break;
+
+ case 2:
+ _game._player._priorTimer = _game._player._ticksAmount + _scene->_frameStartTime;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_BARREL))
+ _vm->_dialogs->show(41010);
+ else if (_action.isAction(VERB_TAKE, NOUN_BARREL))
+ _vm->_dialogs->show(41011);
+ else if (_action.isAction(VERB_OPEN, NOUN_BARREL))
+ _vm->_dialogs->show(41012);
+ else if (_action.isAction(VERB_LOOK, NOUN_RUG))
+ _vm->_dialogs->show(41013);
+ else if (_action.isAction(VERB_TAKE, NOUN_RUG))
+ _vm->_dialogs->show(41014);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARTON) || _action.isAction(VERB_OPEN, NOUN_CARTON)) {
+ if (_game._objects.isInRoom(OBJ_CHARGE_CASES))
+ _vm->_dialogs->show(41015);
+ else
+ _vm->_dialogs->show(41016);
+ } else if (_action.isAction(VERB_LOOK, NOUN_FLOUR))
+ _vm->_dialogs->show(41017);
+ else if (_action.isAction(VERB_TAKE, NOUN_FLOUR))
+ _vm->_dialogs->show(41018);
+ else if (_action.isAction(VERB_LOOK, NOUN_SACKS))
+ _vm->_dialogs->show(41019);
+ else if (_action.isAction(VERB_LOOK, NOUN_SACK))
+ _vm->_dialogs->show(41019);
+ else if (_action.isAction(VERB_OPEN, NOUN_SACKS))
+ _vm->_dialogs->show(41020);
+ else if (_action.isAction(VERB_OPEN, NOUN_SACK))
+ _vm->_dialogs->show(41020);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUCKET_OF_TAR))
+ _vm->_dialogs->show(41021);
+ else if (_action.isAction(VERB_TAKE, NOUN_BUCKET_OF_TAR))
+ _vm->_dialogs->show(41022);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAN))
+ _vm->_dialogs->show(41023);
+ else if (_action.isAction(VERB_TAKE, NOUN_CAN))
+ _vm->_dialogs->show(41024);
+ else if (_action.isAction(VERB_LOOK, NOUN_CHARGE_CASES) && _game._objects.isInRoom(OBJ_CHARGE_CASES))
+ _vm->_dialogs->show(41025);
+ else if (_action.isAction(VERB_LOOK, NOUN_FENCE))
+ _vm->_dialogs->show(41027);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHELVES))
+ _vm->_dialogs->show(41028);
+ else if (_action.isAction(VERB_LOOK, NOUN_RAT))
+ _vm->_dialogs->show(41029);
+ else if (_action.isAction(VERB_TAKE, NOUN_RAT))
+ _vm->_dialogs->show(41030);
+ else if (_action.isAction(VERB_THROW, NOUN_RAT))
+ _vm->_dialogs->show(41031);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(41033);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene411::Scene411(MADSEngine *vm) : Scene4xx(vm) {
+ _curAnimationFrame = -1;
+ _newIngredient = -1;
+ _newQuantity = -1;
+ _resetFrame = -1;
+ _badThreshold = -1;
+
+ _killRox = false;
+ _makeMushroomCloud = false;
+}
+
+void Scene411::synchronize(Common::Serializer &s) {
+ Scene4xx::synchronize(s);
+
+ s.syncAsSint32LE(_curAnimationFrame);
+ s.syncAsSint32LE(_newIngredient);
+ s.syncAsSint32LE(_newQuantity);
+ s.syncAsSint32LE(_resetFrame);
+ s.syncAsSint32LE(_badThreshold);
+
+ s.syncAsByte(_killRox);
+ s.syncAsByte(_makeMushroomCloud);
+}
+
+bool Scene411::addIngredient() {
+ bool retVal = false;
+
+ switch (_newIngredient) {
+ case OBJ_LECITHIN:
+ if (_globals[kIngredientList + _globals[kNextIngredient]] == 1)
+ retVal = true;
+
+ _badThreshold = 1;
+ break;
+
+ case OBJ_ALIEN_LIQUOR:
+ if (_globals[kIngredientList + _globals[kNextIngredient]] == 0)
+ retVal = true;
+
+ _badThreshold = 0;
+ break;
+
+ case OBJ_FORMALDEHYDE:
+ if (_globals[kIngredientList + _globals[kNextIngredient]] == 3)
+ retVal = true;
+
+ _badThreshold = 3;
+ break;
+
+ case OBJ_PETROX:
+ if (_globals[kIngredientList + _globals[kNextIngredient]] == 2)
+ retVal = true;
+
+ _badThreshold = 2;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!retVal && (_globals[kNextIngredient] == 0))
+ _globals[kBadFirstIngredient] = _badThreshold;
+
+ if (_globals[kNextIngredient] == 0)
+ retVal = true;
+
+ return(retVal);
+}
+
+bool Scene411::addQuantity() {
+ bool retVal = false;
+
+ if (_globals[kIngredientQuantity + _globals[kNextIngredient]] == _newQuantity)
+ retVal = true;
+
+ if (!retVal && (_globals[kNextIngredient] == 0))
+ _globals[kBadFirstIngredient] = _badThreshold;
+
+ if (_globals[kNextIngredient] == 0)
+ retVal = true;
+
+ return(retVal);
+}
+
+int Scene411::computeQuoteAndQuantity() {
+ int quoteId;
+ int quantity;
+
+ switch (_action._activeAction._verbId) {
+ case 0x252:
+ quoteId = 0x26F;
+ quantity = 0;
+ break;
+
+ case 0x253:
+ quoteId = 0x271;
+ quantity = 0;
+ break;
+
+ case 0x254:
+ quoteId = 0x270;
+ quantity = 0;
+ break;
+
+ case 0x255:
+ quoteId = 0x272;
+ quantity = 0;
+ break;
+
+ case 0x256:
+ quoteId = 0x267;
+ quantity = 2;
+ break;
+
+ case 0x257:
+ quoteId = 0x269;
+ quantity = 2;
+ break;
+
+ case 0x258:
+ quoteId = 0x268;
+ quantity = 2;
+ break;
+
+ case 0x259:
+ quoteId = 0x26A;
+ quantity = 2;
+ break;
+
+ case 0x25A:
+ quoteId = 0x26B;
+ quantity = 3;
+ break;
+
+ case 0x25B:
+ quoteId = 0x26D;
+ quantity = 3;
+ break;
+
+ case 0x25C:
+ quoteId = 0x26C;
+ quantity = 3;
+ break;
+
+ case 0x25D:
+ quoteId = 0x26E;
+ quantity = 3;
+ break;
+
+ case 0x25E:
+ quoteId = 0x263;
+ quantity = 1;
+ break;
+
+ case 0x25F:
+ quoteId = 0x265;
+ quantity = 1;
+ break;
+
+ case 0x260:
+ quoteId = 0x264;
+ quantity = 1;
+ break;
+
+ case 0x261:
+ quoteId = 0x266;
+ quantity = 1;
+ break;
+
+ default:
+ quoteId = 0;
+ quantity = 0;
+ break;
+ }
+
+ _scene->_kernelMessages.add(Common::Point(202, 82), 0x1110, 32, 0, 120, _game.getQuote(quoteId));
+ return quantity;
+}
+
+void Scene411::handleKettleAction() {
+ switch (_globals[kNextIngredient]) {
+ case 1:
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4],
+ false, 15, 0, 0, 0);
+ break;
+
+ case 2:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4],
+ false, 6, 0, 0, 0);
+ break;
+
+ case 3:
+ _makeMushroomCloud = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene411::handleDialog() {
+ if ((_action._activeAction._verbId != 0x262) && (_game._trigger == 0)) {
+ if (_game._objects.isInInventory(_newIngredient)) {
+ switch (_newIngredient) {
+ case OBJ_FORMALDEHYDE:
+ _resetFrame = 17;
+ break;
+
+ case OBJ_PETROX:
+ _resetFrame = 55;
+ break;
+
+ case OBJ_LECITHIN:
+ _resetFrame = 36;
+ break;
+
+ default:
+ _resetFrame = 112;
+ break;
+ }
+
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_activeAnimation->setCurrentFrame(_resetFrame);
+ }
+ _scene->_kernelMessages.reset();
+ _newQuantity = computeQuoteAndQuantity ();
+
+ if ((_globals[kNextIngredient] == 1) && (_globals[kBadFirstIngredient] > -1))
+ _killRox = true;
+ else if (addIngredient() && addQuantity()) {
+ handleKettleAction();
+ _globals[kNextIngredient]++;
+ } else
+ _killRox = true;
+
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ } else if (_action._activeAction._verbId == 0x262)
+ _scene->_userInterface.setup(kInputBuildingSentences);
+}
+
+void Scene411::giveToRex(int object) {
+ switch (object) {
+ case 0:
+ _game._objects.addToInventory(OBJ_ALIEN_LIQUOR);
+ break;
+
+ case 1:
+ _game._objects.addToInventory(OBJ_LECITHIN);
+ break;
+
+ case 2:
+ _game._objects.addToInventory(OBJ_PETROX);
+ break;
+
+ case 3:
+ _game._objects.addToInventory(OBJ_FORMALDEHYDE);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene411::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_ALIEN_LIQUOR);
+ _scene->addActiveVocab(NOUN_FORMALDEHYDE);
+ _scene->addActiveVocab(NOUN_PETROX);
+ _scene->addActiveVocab(NOUN_LECITHIN);
+}
+
+void Scene411::enter() {
+ if (_scene->_priorSceneId == 411) {
+ if ((_globals[kNextIngredient] == 1) && (_globals[kBadFirstIngredient] > -1))
+ giveToRex(_globals[kBadFirstIngredient]);
+ else if (_globals[kNextIngredient] > 0) {
+ for (int i = 0; i < _globals[kNextIngredient]; i ++)
+ giveToRex(_globals[kIngredientList + i]);
+ }
+ _globals[kNextIngredient] = 0;
+ _globals[kBadFirstIngredient] = -1;
+ }
+
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('f', 0));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('f', 1));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('f', 2));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('c', 1));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('a', 6));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites("*ROXRC_9");
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 50, 0, 0, 0);
+
+ _game.loadQuoteSet(0x252, 0x25E, 0x25A, 0x256, 0x253, 0x25F, 0x25B, 0x257, 0x254, 0x260, 0x25C, 0x258, 0x255,
+ 0x261, 0x25D, 0x259, 0x262, 0x267, 0x263, 0x26B, 0x26F, 0x268, 0x264, 0x26C, 0x270, 0x26A, 0x266, 0x26E,
+ 0x272, 0x269, 0x265, 0x26D, 0x271, 0);
+
+ _dialog1.setup(0x5B, 0x252, 0x25E, 0x25A, 0x256, 0x262, -1);
+ _dialog2.setup(0x5C, 0x253, 0x25F, 0x25B, 0x257, 0x262, -1);
+ _dialog3.setup(0x5D, 0x254, 0x260, 0x25C, 0x258, 0x262, -1);
+ _dialog4.setup(0x5E, 0x255, 0x261, 0x25D, 0x259, 0x262, -1);
+
+ if (_globals[kNextIngredient] >= 4 && _game._objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ _scene->_hotspots.activate(NOUN_EXPLOSIVES, false);
+ _scene->_hotspots.activate(NOUN_KETTLE, true);
+ } else {
+ _scene->_hotspots.activate(NOUN_KETTLE, false);
+ _scene->_hotspots.activate(NOUN_EXPLOSIVES, true);
+ }
+
+ if (_globals[kNextIngredient] >= 4 && _game._objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], true, 6);
+ } else if (!_game._objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ switch (_globals[kNextIngredient]) {
+ case 1:
+ _vm->_sound->command(53);
+ break;
+
+ case 2:
+ _vm->_sound->command(53);
+ _vm->_sound->command(54);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 15, 0, 0, 0);
+ break;
+
+ case 3:
+ _vm->_sound->command(53);
+ _vm->_sound->command(54);
+ _vm->_sound->command(55);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 0, 0);
+ break;
+
+ case 4:
+ _vm->_sound->command(53);
+ _vm->_sound->command(54);
+ _vm->_sound->command(55);
+ _vm->_sound->command(56);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 0, 0);
+ break;
+
+ default:
+ _vm->_sound->command(10);
+ break;
+ }
+ }
+
+ if (_globals[kNextIngredient] >= 4 && _game._objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], true, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ }
+
+ if (_game._objects.isInRoom(OBJ_FORMALDEHYDE)) {
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FORMALDEHYDE, VERB_WALKTO, _globals._sequenceIndexes[7], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(206, 145), FACING_SOUTHEAST);
+ }
+
+ if (_game._objects.isInRoom(OBJ_PETROX)) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_PETROX, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(186, 112), FACING_NORTHEAST);
+ }
+
+ if (_game._objects.isInRoom(OBJ_LECITHIN)) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LECITHIN, VERB_WALKTO, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(220, 121), FACING_NORTHEAST);
+ }
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(60, 146);
+ _game._player._facing = FACING_NORTHEAST;
+ }
+
+ sceneEntrySound();
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_ALIEN_LIQUOR);
+ _game._objects.addToInventory(OBJ_CHARGE_CASES);
+ _game._objects.addToInventory(OBJ_TAPE_PLAYER);
+ _game._objects.addToInventory(OBJ_AUDIO_TAPE);
+ }
+
+ _scene->loadAnimation(formAnimName('a', -1));
+ _scene->_activeAnimation->setCurrentFrame(128);
+
+ _makeMushroomCloud = false;
+ _killRox = false;
+}
+
+void Scene411::step() {
+ if (_scene->_activeAnimation != nullptr) {
+ if (_curAnimationFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _curAnimationFrame = _scene->_activeAnimation->getCurrentFrame();
+ _resetFrame = -1;
+
+ switch (_curAnimationFrame) {
+ case 16:
+ _game._player._stepEnabled = true;
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _resetFrame = 128;
+ break;
+
+ case 35:
+ case 54:
+ case 71:
+ case 127:
+ if (_killRox) {
+ _resetFrame = 72;
+ } else {
+ _resetFrame = 0;
+ _game._objects.removeFromInventory(_newIngredient, NOWHERE);
+ switch (_globals[kNextIngredient]) {
+ case 1:
+ _vm->_sound->command(53);
+ break;
+
+ case 2:
+ _vm->_sound->command(54);
+ break;
+
+ case 3:
+ _vm->_sound->command(55);
+ break;
+
+ case 4:
+ _vm->_sound->command(56);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case 22:
+ case 41:
+ case 59:
+ case 115:
+ if (_makeMushroomCloud) {
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 5, 1, 0, 0);
+ _makeMushroomCloud = false;
+ _scene->_hotspots.activate(NOUN_EXPLOSIVES, false);
+ _scene->_hotspots.activate(NOUN_KETTLE, true);
+ }
+ break;
+
+ case 111:
+ _resetFrame = 111;
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ case 129:
+ _resetFrame = 128;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((_resetFrame >= 0) && (_resetFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(_resetFrame);
+ _curAnimationFrame = _resetFrame;
+ }
+ }
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 86)
+ _vm->_sound->command(59);
+}
+
+void Scene411::preActions() {
+ if (_action.isAction(VERB_LOOK, NOUN_PETROX) && (_game._objects.isInRoom(OBJ_PETROX)))
+ _game._player._needToWalk = true;
+
+ if (_action.isAction(VERB_LOOK, NOUN_LECITHIN) && (_game._objects.isInRoom(OBJ_LECITHIN)))
+ _game._player._needToWalk = true;
+
+ if (_action.isAction(VERB_LOOK, NOUN_FORMALDEHYDE) && (_game._objects.isInRoom(OBJ_FORMALDEHYDE)))
+ _game._player._needToWalk = true;
+
+ if (_action.isAction(VERB_LOOK, NOUN_EXPLOSIVES) || _action.isAction(VERB_LOOK, NOUN_KETTLE) || _action.isAction(VERB_LOOK, NOUN_MISHAP) ||
+ _action.isAction(VERB_LOOK, NOUN_ALCOVE) || _action.isAction(VERB_LOOK, NOUN_SINK) || _action.isAction(VERB_PUT, NOUN_SINK) ||
+ _action.isAction(VERB_LOOK, NOUN_EXPERIMENT) || _action.isAction(VERB_LOOK, NOUN_DRAWING_BOARD))
+ _game._player._needToWalk = true;
+
+ if (_action.isAction(VERB_PULL, NOUN_KNIFE_SWITCH) || _action.isAction(VERB_PUSH, NOUN_KNIFE_SWITCH))
+ _game._player._needToWalk = false;
+}
+
+void Scene411::actions() {
+ if (_game._screenObjects._inputMode != 1) {
+ handleDialog();
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_WALK_INTO, NOUN_CORRIDOR_TO_SOUTH)) {
+ _scene->_nextSceneId = 406;
+ _vm->_sound->command(10);
+ _action._inProgress = false;
+ return;
+ }
+
+ if ((_globals[kNextIngredient] >= 4) && (_action.isAction(VERB_TAKE, NOUN_EXPLOSIVES) || _action.isAction(VERB_PUT, NOUN_CHARGE_CASES, NOUN_EXPLOSIVES))
+ && !_game._objects[OBJ_CHARGE_CASES].getQuality(3)
+ && _game._objects.isInInventory(OBJ_CHARGE_CASES)) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(10);
+ _vm->_sound->command(57);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[10] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[10], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 1, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 110);
+ break;
+
+ case 110: {
+ int idx = _globals._sequenceIndexes[10];
+ _globals._sequenceIndexes[10] = _scene->_sequences.startCycle(_globals._spriteIndexes[10], false, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[10], idx);
+ _scene->_sequences.addTimer(180, 111);
+ }
+ break;
+
+ case 111:
+ _scene->_hotspots.activate(NOUN_KETTLE, true);
+ _scene->_hotspots.activate(NOUN_EXPLOSIVES, false);
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], true, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+
+ _globals._sequenceIndexes[10] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[10], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 1, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 112);
+ // No break on purpose
+ case 112:
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _game._objects[OBJ_CHARGE_CASES].setQuality(3, 1);
+ _vm->_dialogs->showItem(OBJ_CHARGE_CASES, 41142);
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ } else if (!_game._objects.isInInventory(OBJ_CHARGE_CASES) && _action.isAction(VERB_TAKE, NOUN_EXPLOSIVES)) {
+ _vm->_dialogs->show(41143);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_PETROX) && (_game._objects.isInRoom(OBJ_PETROX) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(57);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _game._objects.addToInventory(OBJ_PETROX);
+ _vm->_dialogs->showItem(OBJ_PETROX, 41120);
+ break;
+
+ case 2:
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_LECITHIN) && (_game._objects.isInRoom(OBJ_LECITHIN) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_sound->command(57);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _game._objects.addToInventory(OBJ_LECITHIN);
+ _vm->_dialogs->showItem(OBJ_LECITHIN, 41124);
+ break;
+
+ case 2:
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_FORMALDEHYDE) && _game._objects.isInRoom(OBJ_FORMALDEHYDE) && (_game._trigger == 0)) {
+ _vm->_sound->command(57);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[11] = _scene->_sequences.startCycle(_globals._spriteIndexes[11], false, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[11], 1);
+ _scene->_sequences.addTimer(20, 100);
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _game._objects.addToInventory(OBJ_FORMALDEHYDE);
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_game._trigger == 100) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _scene->_sequences.addTimer(20, 10);
+ }
+
+ if (_game._trigger == 10)
+ _vm->_dialogs->showItem(OBJ_FORMALDEHYDE, 41124);
+
+ if (_action.isAction(VERB_PUT, NOUN_KETTLE)) {
+ if (_action.isObject(NOUN_PETROX) || _action.isObject(NOUN_FORMALDEHYDE) || _action.isObject(NOUN_LECITHIN) || _action.isObject(NOUN_ALIEN_LIQUOR)) {
+ _newIngredient = _game._objects.getIdFromDesc(_action._activeAction._objectNameId);
+ switch (_newIngredient) {
+ case OBJ_ALIEN_LIQUOR:
+ _dialog1.start();
+ break;
+
+ case OBJ_FORMALDEHYDE:
+ _dialog3.start();
+ break;
+
+ case OBJ_PETROX:
+ _dialog4.start();
+ break;
+
+ case OBJ_LECITHIN:
+ _dialog2.start();
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+
+ if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(41110);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_PURIFIER))
+ _vm->_dialogs->show(41111);
+ else if (_action.isAction(VERB_LOOK, NOUN_LAB_EQUIPMENT))
+ _vm->_dialogs->show(41112);
+ else if (_action.isAction(VERB_LOOK, NOUN_KNIFE_SWITCH))
+ _vm->_dialogs->show(41113);
+ else if (_action.isAction(VERB_PUSH, NOUN_KNIFE_SWITCH) || _action.isAction(VERB_PULL, NOUN_KNIFE_SWITCH))
+ _vm->_dialogs->show(41114);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOXIC_WASTE))
+ _vm->_dialogs->show(41115);
+ else if (_action.isAction(VERB_TAKE, NOUN_TOXIC_WASTE))
+ _vm->_dialogs->show(41116);
+ else if (_action.isAction(VERB_LOOK, NOUN_DRAWING_BOARD))
+ _vm->_dialogs->show(41117);
+ else if (_action.isAction(VERB_LOOK, NOUN_EXPERIMENT))
+ _vm->_dialogs->show(41118);
+ else if (_action.isAction(VERB_LOOK, NOUN_PETROX) && _game._objects.isInRoom(OBJ_PETROX))
+ _vm->_dialogs->show(41119);
+ else if (_action.isAction(VERB_LOOK, NOUN_ALCOVE))
+ _vm->_dialogs->show(41121);
+ else if ((_action.isAction(VERB_LOOK, NOUN_FORMALDEHYDE)) && (_game._objects.isInRoom(OBJ_FORMALDEHYDE)))
+ _vm->_dialogs->show(41122);
+ else if ((_action.isAction(VERB_LOOK, NOUN_LECITHIN)) && (_game._objects.isInRoom(OBJ_LECITHIN)))
+ _vm->_dialogs->show(41123);
+ else if (_action.isAction(VERB_LOOK, NOUN_KETTLE)) {
+ if (_globals[kNextIngredient] > 0 && !_game._objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ _vm->_dialogs->show(41126);
+ } else if (_globals[kNextIngredient] == 0 || _game._objects[OBJ_CHARGE_CASES].getQuality(3)) {
+ _vm->_dialogs->show(41125);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_EXPLOSIVES) && _game._objects[OBJ_CHARGE_CASES].getQuality(3) == 0) {
+ _vm->_dialogs->show(41127);
+ } else if (_action.isAction(VERB_TAKE, NOUN_KETTLE))
+ _vm->_dialogs->show(41128);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONTROL_PANEL))
+ _vm->_dialogs->show(41129);
+ else if (_action.isAction(VERB_LOOK, NOUN_MISHAP))
+ _vm->_dialogs->show(41130);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(41131);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(41132);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_HORN))
+ _vm->_dialogs->show(41133);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEBRIS))
+ _vm->_dialogs->show(41134);
+ else if (_action.isAction(VERB_LOOK, NOUN_HEATER))
+ _vm->_dialogs->show(41135);
+ else if (_action.isAction(VERB_LOOK, NOUN_PIPE))
+ _vm->_dialogs->show(41136);
+ else if (_action.isAction(VERB_LOOK, NOUN_SINK))
+ _vm->_dialogs->show(41137);
+ else if (_action.isAction(VERB_PUT, NOUN_SINK))
+ _vm->_dialogs->show(41138);
+ else if (_action.isAction(VERB_TAKE, NOUN_EXPERIMENT))
+ _vm->_dialogs->show(41139);
+ else if (_action.isAction(VERB_LOOK, NOUN_ELECTRODES))
+ _vm->_dialogs->show(41140);
+ else if (_action.isAction(VERB_TAKE, NOUN_ELECTRODES))
+ _vm->_dialogs->show(41141);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene413::Scene413(MADSEngine *vm) : Scene4xx(vm) {
+ _rexDeath = -1;
+ _canMove = -1;
+}
+
+void Scene413::synchronize(Common::Serializer &s) {
+ Scene4xx::synchronize(s);
+
+ s.syncAsSint32LE(_rexDeath);
+ s.syncAsSint32LE(_canMove);
+}
+
+void Scene413::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene413::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 2));
+ _rexDeath = false;
+
+ if (_scene->_priorSceneId == 405) {
+ _game._player._playerPos = Common::Point(142, 146);
+ _game._player._facing = FACING_NORTH;
+ _game._player._visible = true;
+ } else if (_scene->_priorSceneId != -2) {
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _scene->loadAnimation(Resources::formatName(413, 'd', 1, EXT_AA, ""), 78);
+ _vm->_sound->command(30);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _rexDeath = true;
+ } else if (!_globals[kTeleporterCommand]) {
+ _game._player._playerPos = Common::Point(136, 117);
+ _game._player.walk(Common::Point(141, 130), FACING_SOUTH);
+ _game._player._facing = FACING_SOUTH;
+ _game._player._visible = true;
+ }
+ }
+
+ if ((_globals[kTeleporterCommand]) && (!_rexDeath)) {
+ switch (_globals[kTeleporterCommand]) {
+ case 1:
+ _vm->_sound->command(30);
+ _game._player._visible = false;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 19);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 76);
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _vm->_sound->command(30);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 20);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 77);
+ break;
+
+ case 3:
+ case 4:
+ _game._player._playerPos = Common::Point(136, 117);
+ _game._player._facing = FACING_SOUTH;
+ _game._player.walk(Common::Point(141, 130), FACING_SOUTH);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ _globals[kTeleporterCommand] = 0;
+ }
+
+ _canMove = true;
+ sceneEntrySound();
+}
+
+void Scene413::step() {
+ if (_scene->_activeAnimation && _scene->_activeAnimation->getCurrentFrame() == 38)
+ _scene->_activeAnimation->setCurrentFrame(37);
+
+ if (_scene->_activeAnimation && _scene->_activeAnimation->getCurrentFrame() == 21 && _canMove) {
+ _vm->_sound->command(27);
+ _canMove = false;
+ }
+
+ if (_game._trigger == 76) {
+ _game._player._playerPos = Common::Point(136, 117);
+ _game._player.walk(Common::Point(141, 130), FACING_SOUTH);
+ _game._player._facing = FACING_SOUTH;
+ _game._player.selectSeries();
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 77) {
+ _globals[kTeleporterCommand] = TELEPORTER_BEAM_IN;
+ _scene->_nextSceneId = _globals[kTeleporterDestination];
+ _scene->_reloadSceneFlag = true;
+ }
+
+ if (_game._trigger == 78) {
+ _scene->_reloadSceneFlag = true;
+ _scene->_nextSceneId = _scene->_priorSceneId;
+ _globals[kTeleporterCommand] = TELEPORTER_NONE;
+ }
+}
+
+void Scene413::preActions() {
+ if (_action.isAction(VERB_TAKE) || _action.isAction(VERB_PUT, NOUN_CONVEYOR_BELT))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_LOOK, NOUN_WOODEN_STATUE) || _action.isAction(VERB_LOOK, NOUN_DISPLAY)
+ || _action.isAction(VERB_LOOK, NOUN_PICTURE) || _action.isAction(VERB_LOOK, NOUN_PLANT)) {
+ _game._player._needToWalk = true;
+ }
+}
+
+void Scene413::actions() {
+ if (_action.isAction(VERB_WALK_INSIDE, NOUN_TELEPORTER)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_nextSceneId = 409;
+ } else if (_action.isAction(VERB_WALK_INSIDE, NOUN_CORRIDOR_TO_SOUTH))
+ _scene->_nextSceneId = 405;
+ else if (_action.isAction(VERB_LOOK, NOUN_WOODEN_STATUE))
+ _vm->_dialogs->show(41310);
+ else if (_action.isAction(VERB_TAKE, NOUN_WOODEN_STATUE))
+ _vm->_dialogs->show(41311);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONVEYOR_BELT))
+ _vm->_dialogs->show(41312);
+ else if (_action.isAction(VERB_PUT, NOUN_CONVEYOR_BELT))
+ _vm->_dialogs->show(41313);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(41314);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(41315);
+ else if (_action.isAction(VERB_LOOK, NOUN_CORRIDOR_TO_SOUTH))
+ _vm->_dialogs->show(41316);
+ else if (_action.isAction(VERB_LOOK, NOUN_PICTURE))
+ _vm->_dialogs->show(41317);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLANT))
+ _vm->_dialogs->show(41318);
+ else if (_action.isAction(VERB_TAKE, NOUN_PLANT))
+ _vm->_dialogs->show(41319);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(41320);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes4.h b/engines/mads/nebular/nebular_scenes4.h
new file mode 100644
index 0000000000..fbd5ce81f0
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes4.h
@@ -0,0 +1,258 @@
+/* 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 MADS_NEBULAR_SCENES4_H
+#define MADS_NEBULAR_SCENES4_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene4xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+
+ void sceneEntrySound();
+
+public:
+ Scene4xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene401 : public Scene4xx {
+private:
+ bool _northFl;
+ Common::Point _destPos;
+ uint32 _timer;
+
+public:
+ Scene401(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene402 : public Scene4xx {
+private:
+ bool _lightOn;
+ bool _blowingSmoke;
+ bool _leftWomanMoving;
+ bool _rightWomanMoving;
+ bool _firstTalkToGirlInChair;
+ bool _waitingGinnyMove;
+ bool _ginnyLooking;
+ bool _bigBeatFl;
+ bool _roxOnStool;
+ bool _bartenderSteady;
+ bool _bartenderHandsHips;
+ bool _bartenderLooksLeft;
+ bool _bartenderReady;
+ bool _bartenderTalking;
+ bool _bartenderCalled;
+ bool _conversationFl;
+ bool _activeTeleporter;
+ bool _activeArrows;
+ bool _activeArrow1;
+ bool _activeArrow2;
+ bool _activeArrow3;
+ bool _cutSceneReady;
+ bool _cutSceneNeeded;
+ bool _helgaReady;
+ bool _refuseAlienLiquor;
+
+ int _drinkTimer;
+ int _beatCounter;
+ int _bartenderMode;
+ int _bartenderDialogNode;
+ int _bartenderCurrentQuestion;
+ int _helgaTalkMode;
+ int _roxMode;
+ int _rexMode;
+ int _talkTimer;
+
+ Conversation _dialog1;
+ Conversation _dialog2;
+ Conversation _dialog3;
+ Conversation _dialog4;
+
+ void setDialogNode(int node);
+ void handleConversation1();
+ void handleConversation2();
+ void handleConversation3();
+ void handleConversation4();
+ void handleDialogs();
+
+public:
+ Scene402(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene405 : public Scene4xx {
+public:
+ Scene405(MADSEngine *vm) : Scene4xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene406 : public Scene4xx {
+private:
+ bool _hitStorageDoor;
+
+public:
+ Scene406(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene407 : public Scene4xx {
+private:
+ bool _fromNorth;
+ Common::Point _destPos;
+
+public:
+ Scene407(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene408 : public Scene4xx {
+public:
+ Scene408(MADSEngine *vm) : Scene4xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene409 : public SceneTeleporter {
+public:
+ Scene409(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene410 : public Scene4xx {
+public:
+ Scene410(MADSEngine *vm) : Scene4xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene411 : public Scene4xx {
+private:
+ int _curAnimationFrame;
+ int _newIngredient;
+ int _newQuantity;
+ int _resetFrame;
+ int _badThreshold;
+
+ bool _killRox;
+ bool _makeMushroomCloud;
+
+ Conversation _dialog1;
+ Conversation _dialog2;
+ Conversation _dialog3;
+ Conversation _dialog4;
+
+ void giveToRex(int object);
+ void handleDialog();
+ void handleKettleAction();
+
+ int computeQuoteAndQuantity();
+
+ bool addQuantity();
+ bool addIngredient();
+
+public:
+ Scene411(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene413 : public Scene4xx {
+private:
+ int _rexDeath;
+ int _canMove;
+
+public:
+ Scene413(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES4_H */
diff --git a/engines/mads/nebular/nebular_scenes5.cpp b/engines/mads/nebular/nebular_scenes5.cpp
new file mode 100644
index 0000000000..fd5e244872
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes5.cpp
@@ -0,0 +1,2872 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes5.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene5xx::setAAName() {
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene5xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+
+ Common::String oldName = _game._player._spritesPrefix;
+
+ if ((_scene->_nextSceneId == 502) || (_scene->_nextSceneId == 504) || (_scene->_nextSceneId == 505) || (_scene->_nextSceneId == 515))
+ _game._player._spritesPrefix = "";
+ else if (_globals[kSexOfRex] == REX_MALE)
+ _game._player._spritesPrefix = "RXM";
+ else if ((_scene->_nextSceneId == 501) || (_scene->_nextSceneId == 503) || (_scene->_nextSceneId == 551))
+ _game._player._spritesPrefix = "ROX";
+
+ _game._player._scalingVelocity = true;
+
+ if ((_scene->_nextSceneId == 512) || (_scene->_nextSceneId == 507))
+ _game._player._scalingVelocity = false;
+
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+void Scene5xx::sceneEntrySound() {
+ if (!_vm->_musicFlag) {
+ _vm->_sound->command(2);
+ return;
+ }
+
+ switch (_scene->_nextSceneId) {
+ case 501:
+ case 502:
+ case 504:
+ case 505:
+ case 506:
+ case 507:
+ case 508:
+ case 511:
+ case 512:
+ case 513:
+ case 515:
+ case 551:
+ if (_scene->_priorSceneId == 503)
+ _vm->_sound->command(38);
+ else
+ _vm->_sound->command(29);
+ break;
+ case 503:
+ _vm->_sound->command(41);
+ break;
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene501::Scene501(MADSEngine *vm) : Scene5xx(vm) {
+ _mainSequenceId = -1;
+ _mainSpriteId = -1;
+ _doorHotspotid = -1;
+
+ _rexPunched = false;
+}
+
+void Scene501::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_mainSequenceId);
+ s.syncAsSint16LE(_mainSpriteId);
+ s.syncAsSint16LE(_doorHotspotid);
+ s.syncAsByte(_rexPunched);
+}
+
+void Scene501::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_DOOR);
+ _scene->addActiveVocab(VERB_WALK_THROUGH);
+}
+
+void Scene501::handleSlotActions() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ int numTicks, frameIndex;
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _mainSpriteId = _globals._spriteIndexes[4];
+ numTicks = 8;
+ frameIndex = 3;
+ } else {
+ _mainSpriteId = _globals._spriteIndexes[5];
+ numTicks = 10;
+ frameIndex = 2;
+ }
+
+ _mainSequenceId = _scene->_sequences.startReverseCycle(_mainSpriteId, false, numTicks, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_mainSequenceId, 1, frameIndex);
+ _scene->_sequences.setMsgLayout(_mainSequenceId);
+ _vm->_sound->command(10);
+ _scene->_sequences.addSubEntry(_mainSequenceId, SEQUENCE_TRIGGER_SPRITE, frameIndex, 1);
+ _scene->_sequences.addSubEntry(_mainSequenceId, SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 12, 6, 0, 0);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _mainSequenceId);
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(15, 3);
+ break;
+
+ case 3:
+ _game._player.walk(Common::Point(282, 110), FACING_NORTH);
+ _scene->_sequences.addTimer(60, 4);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene501::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0));
+
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites("*RXCD_7");
+ } else {
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*ROXRC_9");
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites("*ROXCD_7");
+ }
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_DOOR, VERB_WALK_THROUGH, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _doorHotspotid = _scene->_dynamicHotspots.setPosition(idx,Common::Point(282, 110), FACING_NORTH);
+ _scene->_dynamicHotspots.setCursor(_doorHotspotid, CURSOR_GO_UP);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _rexPunched = true;
+
+ if (_scene->_priorSceneId == 504) {
+ _game._player._stepEnabled = false;
+ _game._player._playerPos = Common::Point(74, 121);
+ _game._player._facing = FACING_NORTHWEST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ if (_globals[kSexOfRex] == REX_MALE)
+ _scene->loadAnimation(formAnimName('G', 2), 70);
+ else
+ _scene->loadAnimation(formAnimName('R', 2), 70);
+ } else if (_scene->_priorSceneId == 503) {
+ _game._player._playerPos = Common::Point(317, 102);
+ _game._player._facing = FACING_SOUTHWEST;
+ _scene->_sequences.addTimer(15, 80);
+ } else if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(299, 131);
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_FAKE_ID);
+ _game._objects.addToInventory(OBJ_SECURITY_CARD);
+ _game._objects.addToInventory(OBJ_ID_CARD);
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x275, 0x276, 0x277, 0);
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _scene->_sequences.addTimer(2, 90);
+}
+
+void Scene501::step() {
+ if (_game._trigger == 90)
+ _vm->_dialogs->show(50127);
+
+ if (_game._trigger >= 80) {
+ switch (_game._trigger) {
+ case 80:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 12, 6, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _vm->_sound->command(11);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ break;
+
+ case 81:
+ _scene->_dynamicHotspots.remove(_doorHotspotid);
+ _game._player.walk(Common::Point(276, 110), FACING_SOUTHWEST);
+ _scene->_sequences.addTimer(120, 82);
+ break;
+
+ case 82:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _vm->_sound->command(12);
+ _doorHotspotid = _scene->_dynamicHotspots.add(NOUN_DOOR, VERB_WALK_THROUGH, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_globals._sequenceIndexes[3], Common::Point(282, 110), FACING_NORTH);
+ _scene->_dynamicHotspots.setCursor(_doorHotspotid, CURSOR_GO_UP);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 83);
+ break;
+
+ case 83:
+ _game._player._stepEnabled = true;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (_game._trigger >= 70 && _game._trigger <= 73) {
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(15, 71);
+ break;
+
+ case 71:
+ _game._player.walk(Common::Point(92, 130), FACING_SOUTH);
+ _scene->_sequences.addTimer(30, 72);
+ break;
+
+ case 72:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ break;
+
+ case 73:
+ _game._player._stepEnabled = true;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene501::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN) && (_action.isObject(NOUN_STREET_TO_EAST) || _action.isObject(NOUN_SIDEWALK_TO_EAST)))
+ _game._player._walkOffScreenSceneId = 551;
+}
+
+void Scene501::actions() {
+ if (_action.isAction(VERB_GET_INTO, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_sequences.addTimer(15, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_MALE)
+ _mainSpriteId = _globals._spriteIndexes[6];
+ else
+ _mainSpriteId = _globals._spriteIndexes[7];
+
+ _mainSequenceId = _scene->_sequences.addSpriteCycle(_mainSpriteId, false, 8, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_mainSequenceId);
+ _scene->_sequences.addSubEntry(_mainSequenceId, SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _mainSequenceId;
+ _mainSequenceId = _scene->_sequences.startCycle(_mainSpriteId, false, -2);
+ _scene->_sequences.setMsgLayout(_mainSequenceId);
+ _scene->_sequences.updateTimeout(_mainSequenceId, syncIdx);
+ _scene->_sequences.addTimer(30, 4);
+ }
+ break;
+
+ case 4:
+ _scene->_nextSceneId = 504;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_SECURITY_CARD, NOUN_CARD_SLOT))
+ _vm->_dialogs->show(50113);
+ else if (_action.isAction(VERB_PUT, NOUN_FAKE_ID, NOUN_CARD_SLOT)) {
+ switch (_game._trigger) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ handleSlotActions();
+ break;
+
+ case 4:
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _game._player._visible = false;
+ _vm->_sound->command(13);
+ _scene->loadAnimation(formAnimName('G', 1), 5);
+ } else {
+ _rexPunched = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 6, 120, _game.getQuote(0x277));
+ }
+ break;
+
+ case 5:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(30, 6);
+ break;
+
+ case 6:
+ if (_globals[kSexOfRex] == REX_MALE) {
+ if (_rexPunched) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x275));
+ _rexPunched = false;
+ } else {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x276));
+ }
+ }
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_ID_CARD, NOUN_CARD_SLOT)) {
+ switch (_game._trigger) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ handleSlotActions();
+ break;
+
+ case 4:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _scene->_dynamicHotspots.remove(_doorHotspotid);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _vm->_sound->command(11);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 6);
+ break;
+
+ case 6:
+ _game._player.walk(Common::Point(317, 102), FACING_NORTHEAST);
+ _scene->_sequences.addTimer(120, 7);
+ break;
+
+ case 7: {
+ _vm->_sound->command(12);
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _vm->_sound->command(12);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 8);
+ }
+ break;
+
+ case 8: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_nextSceneId = 503;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_STREET))
+ _vm->_dialogs->show(50121);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOOR))
+ _vm->_dialogs->show(50110);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARD_SLOT))
+ _vm->_dialogs->show(50112);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN))
+ _vm->_dialogs->show(50114);
+ else if (_action.isAction(VERB_TAKE, NOUN_SIGN))
+ _vm->_dialogs->show(50115);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIDEWALK_TO_EAST))
+ _vm->_dialogs->show(50118);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIDEWALK_TO_WEST) || _action.isAction(VERB_LOOK, NOUN_STREET_TO_WEST)
+ || _action.isAction(VERB_WALK_DOWN, NOUN_SIDEWALK_TO_WEST) || _action.isAction(VERB_WALK_DOWN, NOUN_STREET_TO_WEST))
+ _vm->_dialogs->show(50119);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(50120);
+ else if (_action.isAction(VERB_OPEN, NOUN_DOOR))
+ _vm->_dialogs->show(50122);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIRE_HYDRANT))
+ _vm->_dialogs->show(50123);
+ else if (_action.isAction(VERB_OPEN, NOUN_FIRE_HYDRANT))
+ _vm->_dialogs->show(50124);
+ else if (_action.isAction(VERB_LOOK, NOUN_EQUIPMENT_OVERHEAD))
+ _vm->_dialogs->show(50125);
+ else if (_action.isAction(VERB_LOOK, NOUN_PIPES) || _action.isAction(VERB_LOOK, NOUN_PIPE))
+ _vm->_dialogs->show(50126);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR)) {
+ if (!_game._visitedScenes.exists(504))
+ _vm->_dialogs->show(50116);
+ else
+ _vm->_dialogs->show(50117);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene502::setup() {
+ _game._player._spritesPrefix = "";
+ // The original is using Scene5xx_setAAName()
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene502::enter() {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _handSpriteId = _scene->_sprites.addSprites("*REXHAND");
+ else
+ _handSpriteId = _scene->_sprites.addSprites("*ROXHAND");
+
+ teleporterEnter();
+
+ // The original uses scene5xx_sceneEntrySound
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else if (_scene->_priorSceneId == 503)
+ _vm->_sound->command(38);
+ else
+ _vm->_sound->command(29);
+}
+
+void Scene502::step() {
+ teleporterStep();
+}
+
+void Scene502::actions() {
+ if (teleporterActions()) {
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT) || _action.isAction(VERB_PEER_THROUGH, NOUN_VIEWPORT))
+ _vm->_dialogs->show(50210);
+ else if (_action.isAction(VERB_LOOK, NOUN_KEYPAD))
+ _vm->_dialogs->show(50211);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(50212);
+ else if (_action.isAction(VERB_LOOK, NOUN_0_KEY) || _action.isAction(VERB_LOOK, NOUN_1_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_2_KEY) || _action.isAction(VERB_LOOK, NOUN_3_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_4_KEY) || _action.isAction(VERB_LOOK, NOUN_5_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_6_KEY) || _action.isAction(VERB_LOOK, NOUN_7_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_8_KEY) || _action.isAction(VERB_LOOK, NOUN_9_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_SMILE_KEY) || _action.isAction(VERB_LOOK, NOUN_ENTER_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_FROWN_KEY))
+ _vm->_dialogs->show(50213);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEVICE) || _action._lookFlag)
+ _vm->_dialogs->show(50214);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene503::Scene503(MADSEngine *vm) : Scene5xx(vm) {
+ _detonatorHotspotId = -1;
+}
+
+void Scene503::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_detonatorHotspotId);
+}
+
+void Scene503::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_DETONATORS);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene503::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', -1));
+
+ if (_globals[kSexOfRex] == REX_MALE)
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMBD_2");
+ else
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*ROXBD_2");
+
+ if (_game._objects[OBJ_DETONATORS]._roomNumber == _scene->_currentSceneId) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+ _detonatorHotspotId = _scene->_dynamicHotspots.add(NOUN_DETONATORS, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_detonatorHotspotId, Common::Point(254, 135), FACING_SOUTH);
+ }
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(191, 152);
+ _game._player._facing = FACING_NORTHWEST;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene503::actions() {
+ if (_action.isAction(VERB_WALK, NOUN_OUTSIDE))
+ _scene->_nextSceneId = 501;
+ else if (_action.isAction(VERB_TAKE, NOUN_DETONATORS)) {
+ if ( _game._trigger || !_game._objects.isInInventory(OBJ_DETONATORS)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 3, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_detonatorHotspotId);
+ _game._objects.addToInventory(OBJ_DETONATORS);
+ _vm->_dialogs->showItem(OBJ_DETONATORS, 50326);
+ break;
+
+ case 2:
+ if (_globals[kSexOfRex] == REX_MALE)
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ else
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(50328);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITORING_EQUIPMENT))
+ _vm->_dialogs->show(50310);
+ else if (_action.isAction(VERB_LOOK, NOUN_PHOTON_RIFLES))
+ _vm->_dialogs->show(50311);
+ else if (_action.isAction(VERB_TAKE, NOUN_PHOTON_RIFLES) || _action.isAction(VERB_TAKE, NOUN_NUCLEAR_SLINGSHOT))
+ _vm->_dialogs->show(50312);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY_CASE))
+ _vm->_dialogs->show(50313);
+ else if (_action.isAction(VERB_LOOK, NOUN_NUCLEAR_SLINGSHOT))
+ _vm->_dialogs->show(50314);
+ else if (_action.isAction(VERB_LOOK, NOUN_WATER_COOLER))
+ _vm->_dialogs->show(50315);
+ else if (_action.isAction(VERB_LOOK, NOUN_STORAGE_BOX))
+ _vm->_dialogs->show(50316);
+ else if (_action.isAction(VERB_OPEN, NOUN_STORAGE_BOX))
+ _vm->_dialogs->show(50317);
+ else if (_action.isAction(VERB_LOOK, NOUN_WARNING_LABEL))
+ _vm->_dialogs->show(50318);
+ else if (_action.isAction(VERB_LOOK, NOUN_DESK))
+ _vm->_dialogs->show(50319);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(50320);
+ else if (_action.isAction(VERB_LOOK, NOUN_FILE_CABINETS))
+ _vm->_dialogs->show(50322);
+ else if (_action.isAction(VERB_LOOK, NOUN_BOX)) {
+ if (_game._objects.isInRoom(OBJ_DETONATORS))
+ _vm->_dialogs->show(50323);
+ else
+ _vm->_dialogs->show(50324);
+ } else if (_action.isAction(VERB_LOOK, NOUN_DETONATORS) && (_action._savedFields._mainObjectSource == 4))
+ _vm->_dialogs->show(50325);
+ else if (_action.isAction(VERB_LOOK, NOUN_WINDOWS))
+ _vm->_dialogs->show(50327);
+ else if (_action.isAction(VERB_OPEN, NOUN_DISPLAY_CASE))
+ _vm->_dialogs->show(50329);
+ else if (_action.isAction(VERB_THROW, NOUN_DISPLAY_CASE) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId)))
+ _vm->_dialogs->show(50330);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene504::Scene504(MADSEngine *vm) : Scene5xx(vm) {
+ _carAnimationMode = -1;
+ _carFrame = -1;
+}
+
+void Scene504::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_carAnimationMode);
+ s.syncAsSint16LE(_carFrame);
+}
+
+void Scene504::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene504::enter() {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 2));
+
+ for (int i = 0; i < 4; i++)
+ _globals._spriteIndexes[5 + i] = _scene->_sprites.addSprites(formAnimName('m', i));
+
+ if (_globals[kSexOfRex] == REX_MALE)
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ else {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _scene->changeVariant(1);
+ }
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 0, 0, 0);
+ _carFrame = -1;
+
+ if ((_scene->_priorSceneId == 505) && (_globals[kHoverCarDestination] != _globals[kHoverCarLocation])){
+ _carAnimationMode = 1;
+ _scene->loadAnimation(formAnimName('A', -1));
+ _vm->_sound->command(14);
+ _scene->_sequences.addTimer(1, 70);
+ _game._player._stepEnabled = false;
+ } else {
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 3));
+ _carAnimationMode = 1;
+ _scene->loadAnimation(formAnimName('A', -1));
+ if ((_scene->_priorSceneId != -2) && (_scene->_priorSceneId != 505))
+ _globals[kHoverCarLocation] = _scene->_priorSceneId;
+
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
+ }
+
+ if (_globals[kTimebombTimer] > 10500)
+ _globals[kTimebombTimer] = 10500;
+
+ sceneEntrySound();
+}
+
+void Scene504::step() {
+ if ((_carAnimationMode == 1) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame;
+
+ if (_carFrame == 1)
+ nextFrame = 0;
+ else
+ nextFrame = -1;
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _carFrame = nextFrame;
+ }
+ }
+ }
+
+
+ if (_game._trigger >= 70) {
+ switch (_game._trigger) {
+ case 70:
+ if (_globals[kHoverCarDestination] != -1) {
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _carAnimationMode = 2;
+ if (((_globals[kHoverCarLocation] >= 500 && _globals[kHoverCarLocation] <= 599) &&
+ (_globals[kHoverCarDestination] >= 500 && _globals[kHoverCarDestination] <= 599)) ||
+ ((_globals[kHoverCarLocation] >= 600 && _globals[kHoverCarLocation] <= 699) &&
+ (_globals[kHoverCarDestination] >= 600 && _globals[kHoverCarDestination] <= 699))) {
+ _scene->loadAnimation(formAnimName('A', -1), 71);
+ } else if (_globals[kHoverCarLocation] > _globals[kHoverCarDestination])
+ _scene->loadAnimation(formAnimName('C', -1), 71);
+ else
+ _scene->loadAnimation(formAnimName('B', -1), 71);
+ }
+ break;
+
+ case 71:
+ _vm->_sound->command(15);
+ _scene->_nextSceneId = _globals[kHoverCarDestination];
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if ((_globals[kTimebombTimer] >= 10800) && (_globals[kTimebombStatus] == TIMEBOMB_ACTIVATED) && (_game._difficulty != 3)) {
+ _globals[kTimebombStatus] = TIMEBOMB_DEAD;
+ _globals[kTimebombTimer] = 0;
+ _globals[kCheckDaemonTimebomb] = false;
+ _scene->_nextSceneId = 620;
+ }
+}
+
+void Scene504::preActions() {
+ _game._player._needToWalk = false;
+}
+
+void Scene504::actions() {
+ if (_action.isAction(VERB_EXIT_FROM, NOUN_CAR)) {
+ _vm->_sound->command(15);
+ _scene->_nextSceneId = _globals[kHoverCarLocation];
+ } else if (_action.isAction(VERB_ACTIVATE, NOUN_CAR_CONTROLS)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _vm->_sound->command(39);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 13);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 18, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 14);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 13);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 6);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ }
+ break;
+
+ case 2:
+ _scene->_sequences.addTimer(10, 3);
+ break;
+
+ case 3:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _vm->_sound->command(34);
+ _scene->_sequences.addTimer(60, 4);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 14);
+ } else {
+ _vm->_sound->command(40);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 18, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 14);
+ _scene->_sequences.addTimer(120, 5);
+ }
+ break;
+
+ case 4:
+ _game._player._stepEnabled = true;
+ _globals[kHoverCarDestination] = _globals[kHoverCarLocation];
+ _scene->_nextSceneId = 505;
+ break;
+
+ case 5:
+ _game._player._stepEnabled = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
+ _vm->_dialogs->show(50421);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_INTERIOR_OF_CAR))
+ _vm->_dialogs->show(50412);
+ else if (_action.isAction(VERB_LOOK, NOUN_GLOVE_COMPARTMENT))
+ _vm->_dialogs->show(50410);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR_CONTROLS) || _action.isAction(VERB_LOOK, NOUN_DASHBOARD))
+ _vm->_dialogs->show(50411);
+ else if (_action.isAction(VERB_LOOK, NOUN_SCENT_PACKET))
+ _vm->_dialogs->show(50413);
+ else if (_action.isAction(VERB_LOOK, NOUN_SODA_CANS))
+ _vm->_dialogs->show(50414);
+ else if (_action.isAction(VERB_LOOK, NOUN_KITTY))
+ _vm->_dialogs->show(50415);
+ else if (_action.isAction(VERB_LOOK, NOUN_WINDSHIELD) || _action.isAction(VERB_LOOK_THROUGH, NOUN_WINDSHIELD))
+ _vm->_dialogs->show(50416);
+ else if (_action.isAction(VERB_LOOK, NOUN_REARVIEW_MIRROR))
+ _vm->_dialogs->show(50417);
+ else if (_action.isAction(VERB_TAKE, NOUN_REARVIEW_MIRROR))
+ _vm->_dialogs->show(50418);
+ else if (_action.isAction(VERB_LOOK, NOUN_MOLDY_SOCK))
+ _vm->_dialogs->show(50419);
+ else if (_action.isAction(VERB_TAKE, NOUN_MOLDY_SOCK))
+ _vm->_dialogs->show(50420);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene505::Scene505(MADSEngine *vm) : Scene5xx(vm) {
+ _frame = -1;
+ _nextButtonId = -1;
+ _homeSelectedId = -1;
+ _selectedId = -1;
+ _activeCars = -1;
+
+ for (int i = 0; i < 9; i++)
+ _carLocations[i] = -1;
+}
+
+void Scene505::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_frame);
+ s.syncAsSint16LE(_nextButtonId);
+ s.syncAsSint16LE(_homeSelectedId);
+ s.syncAsSint16LE(_selectedId);
+ s.syncAsSint16LE(_activeCars);
+
+ for (int i = 0; i < 9; i++)
+ s.syncAsSint16LE(_carLocations[i]);
+}
+
+void Scene505::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene505::enter() {
+ for (int i = 0; i < 9; i++)
+ _globals._spriteIndexes[i] = _scene->_sprites.addSprites(formAnimName('a', i + 1));
+
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('g', 1));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('g', 0));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('t', -1));
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('e', -1));
+
+ if (_scene->_priorSceneId != -2)
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 6, 1, 0, 0);
+
+ _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 6, 1, 120, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
+ _scene->_sequences.addTimer(30, 62);
+
+ _carLocations[0] = 501;
+ _carLocations[1] = 506;
+ _carLocations[2] = 511;
+ _carLocations[3] = 513;
+ _carLocations[4] = 601;
+ _carLocations[5] = 604;
+ _carLocations[6] = 607;
+ _carLocations[7] = 609;
+ _carLocations[8] = 612;
+
+ _activeCars = false;
+
+ for (int i = 0; i < 9; i++) {
+ if (_globals[kHoverCarLocation] == _carLocations[i]) {
+ _homeSelectedId = i;
+ if (_scene->_priorSceneId != -2)
+ _selectedId = i;
+ }
+ }
+
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _frame = -1;
+ _scene->loadAnimation(formAnimName('a', -1));
+ _scene->_activeAnimation->setCurrentFrame(86);
+
+ sceneEntrySound();
+ _vm->_sound->command(16);
+}
+
+void Scene505::step() {
+ if (_frame != _scene->_activeAnimation->getCurrentFrame()) {
+ _frame = _scene->_activeAnimation->getCurrentFrame();
+ int resetFrame = -1;
+
+ switch (_frame) {
+ case 4:
+ case 24:
+ case 33:
+ case 53:
+ case 62:
+ case 82:
+ if (_nextButtonId == 0x38A)
+ resetFrame = 4;
+ else if (_nextButtonId == 0x38B)
+ resetFrame = 33;
+ else if (_nextButtonId == 0x2DE)
+ resetFrame = 62;
+
+ break;
+
+ case 15:
+ case 44:
+ case 73: {
+ int this_button;
+ int old_select;
+ _vm->_sound->command(17);
+ old_select = _selectedId;
+ if (_frame == 15) {
+ this_button = 0x38A;
+ _selectedId = (_selectedId + 1) % 9;
+ } else if (_frame == 44) {
+ this_button = 0x38B;
+ _selectedId--;
+ if (_selectedId < 0)
+ _selectedId = 8;
+ } else {
+ this_button = 0x2DE;
+ if ((_globals[kTimebombStatus] == TIMEBOMB_ACTIVATED) && (_carLocations[_selectedId] == 501))
+ _vm->_dialogs->show(431);
+ else if (_selectedId != _homeSelectedId) {
+ _nextButtonId = 0;
+ _activeCars = true;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[0]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 63);
+ _vm->_sound->command(18);
+ }
+ }
+
+ if (_nextButtonId == this_button)
+ _nextButtonId = 0;
+
+ if (old_select != _selectedId) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[11]);
+ _globals._sequenceIndexes[11] = _scene->_sequences.startCycle(_globals._spriteIndexes[11], false, _selectedId + 1);
+ if (old_select != _homeSelectedId)
+ _scene->_sequences.remove(_globals._sequenceIndexes[0]);
+
+ if (_selectedId != _homeSelectedId) {
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0 + _selectedId], false, 24, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 1);
+ }
+ }
+ break;
+ }
+
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ if (_nextButtonId == 0x38A)
+ resetFrame = 29 - _frame;
+
+ break;
+
+ case 26:
+ case 55:
+ case 84:
+ if (_nextButtonId != 0)
+ resetFrame = 3;
+
+ break;
+
+ case 27:
+ case 56:
+ case 85:
+ if (_nextButtonId != 0)
+ resetFrame = 2;
+
+ break;
+
+ case 29:
+ case 58:
+ case 87:
+ if (_activeCars)
+ _globals[kHoverCarDestination] = _carLocations[_selectedId];
+
+ if (_nextButtonId == 0x38A)
+ resetFrame = 0;
+ else if (_nextButtonId == 0x38B)
+ resetFrame = 29;
+ else if (_nextButtonId == 0x2DE)
+ resetFrame = 58;
+ else
+ resetFrame = 86;
+ break;
+
+ case 47:
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+ case 52:
+ if (_nextButtonId == 0x38B)
+ resetFrame = 87 - _frame;
+
+ break;
+
+ case 76:
+ case 77:
+ case 78:
+ case 79:
+ case 80:
+ case 81:
+ if (_nextButtonId == 0x2DE)
+ resetFrame = 145 - _frame;
+
+ break;
+
+ default:
+ break;
+ }
+
+ if ((resetFrame >= 0) && (resetFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(resetFrame);
+ _frame = resetFrame;
+ }
+ }
+
+ switch (_game._trigger) {
+ case 60: {
+ _game._player._stepEnabled = true;
+ int syncIdx = _globals._sequenceIndexes[13];
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], syncIdx);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[_homeSelectedId], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _globals._sequenceIndexes[11] = _scene->_sequences.startCycle(_globals._spriteIndexes[11], false, _selectedId + 1);
+
+ if (_selectedId != _homeSelectedId) {
+ _globals._sequenceIndexes[0] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[0 + _selectedId], false, 24, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 1);
+ }
+ break;
+ }
+
+ case 61:
+ _globals._sequenceIndexes[10] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[10], false, 8, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 8);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[10], _globals._sequenceIndexes[9]);
+ break;
+
+ case 62:
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 8, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 61);
+ break;
+
+ case 63:
+ _globals[kHoverCarDestination] = _carLocations[_selectedId];
+ _scene->_nextSceneId = 504;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene505::actions() {
+ if (_action.isAction(VERB_PRESS))
+ _nextButtonId = _action._activeAction._objectNameId;
+ else if (_action.isAction(VERB_RETURN_TO, NOUN_INSIDE_OF_CAR))
+ _scene->_nextSceneId = 504;
+ else if (_action.isAction(VERB_LOOK, NOUN_VIEW_SCREEN))
+ _vm->_dialogs->show(50510);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONTROL_PANEL))
+ _vm->_dialogs->show(50511);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene506::Scene506(MADSEngine *vm) : Scene5xx(vm), _doorPos(0, 0) {
+ _heroFacing = FACING_DUMMY;
+
+ _doorDepth = -1;
+ _doorSpriteIdx = -1;
+ _doorSequenceIdx = -1;
+ _doorWord = -1;
+
+ _labDoorFl = false;
+ _firstDoorFl = false;
+ _actionFl = false;
+}
+
+void Scene506::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_doorPos.x);
+ s.syncAsSint16LE(_doorPos.y);
+
+ s.syncAsByte(_heroFacing);
+
+ s.syncAsSint16LE(_doorDepth);
+ s.syncAsSint16LE(_doorSpriteIdx);
+ s.syncAsSint16LE(_doorSequenceIdx);
+ s.syncAsSint16LE(_doorWord);
+
+ s.syncAsByte(_labDoorFl);
+ s.syncAsByte(_firstDoorFl);
+ s.syncAsByte(_actionFl);
+}
+
+void Scene506::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALK_INTO);
+ _scene->addActiveVocab(NOUN_SOFTWARE_STORE);
+ _scene->addActiveVocab(NOUN_LABORATORY);
+}
+
+void Scene506::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('q', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('q', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCD_3");
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LABORATORY, VERB_WALK_INTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ int hotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(65, 125), FACING_NORTHWEST);
+ _scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_LEFT);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ idx = _scene->_dynamicHotspots.add(NOUN_SOFTWARE_STORE, VERB_WALK_INTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ hotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(112, 102), FACING_NORTHWEST);
+ _scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_LEFT);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 13);
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
+ _firstDoorFl = true;
+ _actionFl = false;
+
+ if (_scene->_priorSceneId == 508) {
+ _game._player._playerPos = Common::Point(16, 111);
+ _game._player._facing = FACING_SOUTHEAST;
+ _scene->_sequences.addTimer(15, 80);
+ _game._player._stepEnabled = false;
+ } else if (_scene->_priorSceneId == 507) {
+ _game._player._playerPos = Common::Point(80, 102);
+ _game._player._facing = FACING_SOUTHEAST;
+ _scene->_sequences.addTimer(60, 80);
+ _game._player._stepEnabled = false;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(138, 116);
+ _game._player._facing = FACING_NORTHEAST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ }
+ sceneEntrySound();
+}
+
+void Scene506::step() {
+ if (_game._trigger >= 80) {
+ if (_firstDoorFl) {
+ _heroFacing = FACING_SOUTHEAST;
+ if (_scene->_priorSceneId == 507) {
+ _doorPos = Common::Point(112, 102);
+ _doorWord = 0x336;
+ } else {
+ _doorPos = Common::Point(65, 125);
+ _doorWord = 0x37D;
+ }
+ }
+ handleDoorSequences();
+ }
+
+ if (_game._trigger >= 70) {
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(6, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene506::handleDoorSequences() {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+
+ if (_firstDoorFl) {
+ if (_action.isAction(VERB_WALK_INTO, NOUN_SOFTWARE_STORE) || ((_scene->_priorSceneId == 507) && !_actionFl)) {
+ _doorDepth = 13;
+ _doorSpriteIdx = _globals._spriteIndexes[2];
+ _doorSequenceIdx = _globals._sequenceIndexes[2];
+ _labDoorFl = false;
+ } else {
+ _doorDepth = 10;
+ _doorSpriteIdx = _globals._spriteIndexes[1];
+ _doorSequenceIdx = _globals._sequenceIndexes[1];
+ _labDoorFl = true;
+ }
+ _firstDoorFl = false;
+ }
+
+ switch (_game._trigger) {
+ case 0:
+ case 80:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_doorSequenceIdx);
+ _doorSequenceIdx = _scene->_sequences.addSpriteCycle(_doorSpriteIdx, false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_doorSequenceIdx, _doorDepth);
+ _scene->changeVariant(1);
+ _scene->_sequences.addSubEntry(_doorSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ break;
+
+
+ case 81:
+ _doorSequenceIdx = _scene->_sequences.startCycle(_doorSpriteIdx, false, -2);
+ _scene->_sequences.setDepth(_doorSequenceIdx, _doorDepth);
+ _game._player._walkAnywhere = true;
+ _game._player.walk(_doorPos, _heroFacing);
+ _scene->_sequences.addTimer(120, 82);
+ break;
+
+ case 82:
+ _scene->_sequences.remove(_doorSequenceIdx);
+ _doorSequenceIdx = _scene->_sequences.startReverseCycle(_doorSpriteIdx, false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_doorSequenceIdx, _doorDepth);
+ if (_actionFl)
+ _scene->_sequences.addSubEntry(_doorSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 84);
+ else
+ _scene->_sequences.addSubEntry(_doorSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 83);
+
+ break;
+
+ case 83: {
+ _doorSequenceIdx = _scene->_sequences.startCycle(_doorSpriteIdx, false, 1);
+ int idx = _scene->_dynamicHotspots.add(_doorWord, VERB_WALK_INTO, _doorSequenceIdx, Common::Rect(0, 0, 0, 0));
+ int hotspotId = _scene->_dynamicHotspots.setPosition(idx, _doorPos, FACING_NORTHWEST);
+ _scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_LEFT);
+ _scene->_sequences.setDepth(_doorSequenceIdx, _doorDepth);
+ _firstDoorFl = true;
+ if (_labDoorFl) {
+ _globals._spriteIndexes[1] = _doorSpriteIdx;
+ _globals._sequenceIndexes[1] = _doorSequenceIdx;
+ } else {
+ _globals._spriteIndexes[2] = _doorSpriteIdx;
+ _globals._sequenceIndexes[2] = _doorSequenceIdx;
+ }
+ _game._player._stepEnabled = true;
+
+ }
+ break;
+
+ case 84:
+ _actionFl = false;
+ _game._player._stepEnabled = true;
+ if (_labDoorFl)
+ _scene->_nextSceneId = 508;
+ else
+ _scene->_nextSceneId = 507;
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene506::actions() {
+ if (_action.isAction(VERB_WALK_INTO, NOUN_LABORATORY)) {
+ if (_firstDoorFl) {
+ _heroFacing = FACING_NORTHWEST;
+ _doorPos = Common::Point(16, 111);
+ }
+ _actionFl = true;
+ handleDoorSequences();
+ } else if (_action.isAction(VERB_WALK_INTO, NOUN_SOFTWARE_STORE)) {
+ if (_firstDoorFl) {
+ _heroFacing = FACING_NORTHWEST;
+ _doorPos = Common::Point(80, 102);
+ }
+ _actionFl = true;
+ handleDoorSequences();
+ } else if (_action.isAction(VERB_GET_INTO, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_STREET))
+ _vm->_dialogs->show(50618);
+ else if (_action.isAction(VERB_LOOK, NOUN_RESTAURANT))
+ _vm->_dialogs->show(50610);
+ else if (_action.isAction(VERB_LOOK, NOUN_MOTEL))
+ _vm->_dialogs->show(50611);
+ else if (_action.isAction(VERB_LOOK, NOUN_CYCLE_SHOP))
+ _vm->_dialogs->show(50612);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_BIKE))
+ _vm->_dialogs->show(50613);
+ else if (_action.isAction(VERB_TAKE, NOUN_AIR_BIKE))
+ _vm->_dialogs->show(50614);
+ else if (_action.isAction(VERB_LOOK, NOUN_SOFTWARE_STORE))
+ _vm->_dialogs->show(50615);
+ else if (_action.isAction(VERB_LOOK, NOUN_LABORATORY))
+ _vm->_dialogs->show(50616);
+ else if (_action.isAction(VERB_LOOK, NOUN_STREET_TO_WEST) || _action.isAction(VERB_WALK_DOWN, NOUN_STREET_TO_WEST))
+ _vm->_dialogs->show(50617);
+ else if (_action.isAction(VERB_LOOK, NOUN_SOFTWARE_STORE_SIGN))
+ _vm->_dialogs->show(50619);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(50620);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKY))
+ _vm->_dialogs->show(50621);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene507::Scene507(MADSEngine *vm) : Scene5xx(vm) {
+ _penlightHotspotId = -1;
+}
+
+void Scene507::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_penlightHotspotId);
+}
+
+void Scene507::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_PENLIGHT);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene507::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('p', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMRD_3");
+
+ if ((_game._difficulty != DIFFICULTY_EASY) && (_game._objects[OBJ_PENLIGHT]._roomNumber == _scene->_currentSceneId)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+ _penlightHotspotId = _scene->_dynamicHotspots.add(NOUN_PENLIGHT, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_penlightHotspotId, Common::Point(233, 152), FACING_SOUTHEAST);
+ }
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(121, 147);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ sceneEntrySound();
+}
+void Scene507::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_ENTRANCE))
+ _scene->_nextSceneId = 506;
+ else if (_action.isAction(VERB_TAKE, NOUN_PENLIGHT)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_PENLIGHT)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_penlightHotspotId);
+ _vm->_sound->command(27);
+ _game._objects.addToInventory(OBJ_PENLIGHT);
+ _vm->_dialogs->showItem(OBJ_PENLIGHT, 50730);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(50722);
+ else if (_action.isAction(VERB_LOOK, NOUN_SWIRLING_LIGHT))
+ _vm->_dialogs->show(50710);
+ else if (_action.isAction(VERB_TAKE, NOUN_SWIRLING_LIGHT))
+ _vm->_dialogs->show(50711);
+ else if (_action.isAction(VERB_LOOK, NOUN_OLD_SOFTWARE))
+ _vm->_dialogs->show(50712);
+ else if (_action.isAction(VERB_TAKE, NOUN_OLD_SOFTWARE))
+ _vm->_dialogs->show(50713);
+ else if (_action.isAction(VERB_LOOK, NOUN_ADVERTISEMENT))
+ _vm->_dialogs->show(50714);
+ else if (_action.isAction(VERB_LOOK, NOUN_ADVERTISING_POSTER))
+ _vm->_dialogs->show(50715);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN)) {
+ if (_scene->_customDest.x < 100)
+ _vm->_dialogs->show(50726);
+ else
+ _vm->_dialogs->show(50716);
+ } else if (_action.isAction(VERB_LOOK, NOUN_HOTTEST_SOFTWARE))
+ _vm->_dialogs->show(50717);
+ else if (_action.isAction(VERB_LOOK, NOUN_SOFTWARE_SHELF))
+ _vm->_dialogs->show(50718);
+ else if (_action.isAction(VERB_LOOK, NOUN_SENSOR))
+ _vm->_dialogs->show(50719);
+ else if (_action.isAction(VERB_LOOK, NOUN_CASH_REGISTER))
+ _vm->_dialogs->show(50720);
+ else if (_action.isAction(VERB_LOOK, NOUN_PAD_OF_PAPER))
+ _vm->_dialogs->show(50721);
+ else if (_action.isAction(VERB_OPEN, NOUN_CASH_REGISTER))
+ _vm->_dialogs->show(50723);
+ else if (_action.isAction(VERB_LOOK, NOUN_BARGAIN_VAT))
+ _vm->_dialogs->show(50724);
+ else if (_action.isAction(VERB_LOOK, NOUN_WINDOW))
+ _vm->_dialogs->show(50725);
+ else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) {
+ if (_game._objects.isInRoom(OBJ_PENLIGHT))
+ _vm->_dialogs->show(50728);
+ else
+ _vm->_dialogs->show(50727);
+ } else if (_action.isAction(VERB_LOOK, NOUN_PENLIGHT) && !_game._objects.isInInventory(OBJ_PENLIGHT)) {
+ if (_game._objects.isInRoom(OBJ_PENLIGHT))
+ _vm->_dialogs->show(50729);
+ } else if (_action.isAction(VERB_LOOK, NOUN_EMERGENCY_LIGHT))
+ _vm->_dialogs->show(50731);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene508::Scene508(MADSEngine *vm) : Scene5xx(vm) {
+ _chosenObject = -1;
+}
+
+void Scene508::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_chosenObject);
+}
+
+void Scene508::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_SPINACH_PATCH_DOLL);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_LASER_BEAM);
+}
+
+void Scene508::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('m', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('h', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('l', 2));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('t', 0));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('l', 3));
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _globals[kLaserOn] = false;
+ _chosenObject = 0;
+ }
+
+ if (!_globals[kLaserOn]) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, -2);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(57, 116), FACING_NORTHEAST);
+ _scene->_hotspots.activate(NOUN_HOLE, false);
+ _scene->_hotspots.activate(NOUN_LASER_BEAM, false);
+ } else {
+ _scene->changeVariant(1);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 11);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(57, 116), FACING_NORTHEAST);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6);
+ if (_globals[kLaserHoleIsThere]) {
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, -2);
+ _scene->_hotspots.activate(NOUN_HOLE, true);
+ _scene->_hotspots.activate(NOUN_LASER_BEAM, true);
+ }
+ _vm->_sound->command(21);
+ }
+ _vm->_sound->command(20);
+
+ if (_scene->_priorSceneId == 515) {
+ _game._player._playerPos = Common::Point(57, 116);
+ _game._player._facing = FACING_NORTHEAST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(289, 139);
+ _game._player._facing = FACING_WEST;
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x273, 0);
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_COMPACT_CASE);
+ _game._objects.addToInventory(OBJ_REARVIEW_MIRROR);
+ }
+}
+
+void Scene508::preActions() {
+ if (_action.isAction(VERB_WALK, NOUN_OUTSIDE))
+ _game._player._walkOffScreenSceneId = 506;
+}
+
+void Scene508::handlePedestral() {
+ if (!_globals[kLaserOn])
+ _vm->_dialogs->show(50835);
+
+ if (_globals[kLaserHoleIsThere])
+ _vm->_dialogs->show(50836);
+
+ if (_globals[kLaserOn] && !_globals[kLaserHoleIsThere]) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 1:
+ if (_chosenObject == 2)
+ _game._objects.removeFromInventory(OBJ_COMPACT_CASE, 1);
+ else
+ _game._objects.removeFromInventory(OBJ_REARVIEW_MIRROR, 1);
+
+ _globals._sequenceIndexes[7] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[7], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, -2);
+ _scene->_hotspots.activate(NOUN_HOLE, true);
+ _scene->_hotspots.activate(NOUN_LASER_BEAM, true);
+ break;
+
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[6]);
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(120, 4);
+ break;
+
+ case 4:
+ _vm->_dialogs->show(50834);
+ _globals[kLaserHoleIsThere] = true;
+ _scene->_nextSceneId = 515;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene508::actions() {
+ if (_action.isAction(VERB_PULL, NOUN_LEVER)) {
+ if (!_globals[kLaserOn]) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 2, 120, _game.getQuote(0x273));
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 10, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 7);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], -1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3:
+ _vm->_sound->command(19);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 15, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[1]);
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(15, 5);
+ break;
+
+ case 4:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6);
+ break;
+
+ case 5:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _scene->loadAnimation(formAnimName('B', 1), 6);
+ break;
+
+ case 6: {
+ _vm->_sound->command(22);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 11);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(57, 116), FACING_NORTHEAST);
+ _scene->_kernelMessages.reset();
+ _scene->changeVariant(1);
+ _scene->_sequences.addTimer(30, 7);
+ }
+ break;
+
+ case 7:
+ _globals[kLaserOn] = true;
+ _vm->_dialogs->show(50833);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ _vm->_dialogs->show(50837);
+ }
+ } else if (_action.isAction(VERB_REFLECT, NOUN_REARVIEW_MIRROR, NOUN_LASER_BEAM) || _action.isAction(VERB_PUT, NOUN_REARVIEW_MIRROR, NOUN_PEDESTAL) || _action.isAction(VERB_PUT, NOUN_REARVIEW_MIRROR, NOUN_LASER_BEAM)) {
+ _chosenObject = 1;
+ handlePedestral();
+ } else if (_action.isAction(VERB_PUT, NOUN_COMPACT_CASE, NOUN_PEDESTAL) || _action.isAction(VERB_PUT, NOUN_COMPACT_CASE, NOUN_LASER_BEAM) || _action.isAction(VERB_REFLECT, NOUN_COMPACT_CASE, NOUN_LASER_BEAM)) {
+ _chosenObject = 2;
+ handlePedestral();
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(50822);
+ else if (_action.isAction(VERB_LOOK, NOUN_TARGET_AREA))
+ _vm->_dialogs->show(50810);
+ else if (_action.isAction(VERB_LOOK, NOUN_SPINACH_PATCH_DOLL))
+ _vm->_dialogs->show(50811);
+ else if (_action.isAction(VERB_TAKE, NOUN_SPINACH_PATCH_DOLL))
+ _vm->_dialogs->show(50812);
+ else if (_action.isAction(VERB_LOOK, NOUN_SAND_BAGS))
+ _vm->_dialogs->show(50816);
+ else if (_action.isAction(VERB_TAKE, NOUN_SAND_BAGS))
+ _vm->_dialogs->show(50817);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONTROL_STATION))
+ _vm->_dialogs->show(50818);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR)) {
+ if (_globals[kLaserOn])
+ _vm->_dialogs->show(50820);
+ else
+ _vm->_dialogs->show(50819);
+ } else if (_action.isAction(VERB_LOOK, NOUN_LASER_CANNON)) {
+ if (_globals[kLaserOn])
+ _vm->_dialogs->show(50822);
+ else
+ _vm->_dialogs->show(50821);
+ } else if (_action.isAction(VERB_TAKE, NOUN_LASER_CANNON))
+ _vm->_dialogs->show(50823);
+ else if (_action.isAction(VERB_LOOK, NOUN_LEVER)) {
+ if (_globals[kLaserOn])
+ _vm->_dialogs->show(50825);
+ else
+ _vm->_dialogs->show(50824);
+ } else if (_action.isAction(VERB_PUSH, NOUN_LEVER))
+ _vm->_dialogs->show(50826);
+ else if (_action.isAction(VERB_LOOK, NOUN_LASER_BEAM)) {
+ if (_globals[kLaserHoleIsThere])
+ _vm->_dialogs->show(50828);
+ else
+ _vm->_dialogs->show(50827);
+ } else if (_action.isAction(VERB_TAKE, NOUN_LASER_BEAM))
+ _vm->_dialogs->show(50829);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEILING)) {
+ if (_globals[kLaserHoleIsThere])
+ _vm->_dialogs->show(50831);
+ else
+ _vm->_dialogs->show(50830);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(50832);
+ else if (_action.isAction(VERB_LOOK, NOUN_PEDESTAL)) {
+ if (!_globals[kLaserOn])
+ _vm->_dialogs->show(50813);
+ else if (!_globals[kLaserHoleIsThere])
+ _vm->_dialogs->show(50814);
+ else
+ _vm->_dialogs->show(50815);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene511::Scene511(MADSEngine *vm) : Scene5xx(vm) {
+ _handingLine = false;
+ _lineMoving = false;
+
+ _lineAnimationMode = -1;
+ _lineFrame = -1;
+ _lineAnimationPosition = -1;
+}
+
+void Scene511::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsByte(_handingLine);
+ s.syncAsByte(_lineMoving);
+
+ s.syncAsSint16LE(_lineAnimationMode);
+ s.syncAsSint16LE(_lineFrame);
+ s.syncAsSint16LE(_lineAnimationPosition);
+}
+
+void Scene511::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_BOAT);
+ _scene->addActiveVocab(NOUN_FISHING_LINE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene511::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCD_6");
+
+ if (_scene->_priorSceneId != -2)
+ _handingLine = false;
+
+ if (_globals[kBoatRaised]) {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+ _scene->_hotspots.activate(NOUN_BOAT, false);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BOAT, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(75, 124), FACING_NORTH);
+ _scene->_hotspots.activate(NOUN_ROPE, false);
+ } else {
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('b', 2));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', 3));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 1));
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 1, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5);
+
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 4);
+
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6],5);
+
+ _scene->_hotspots.activate(NOUN_ROPE, true);
+ _scene->_hotspots.activate(NOUN_BOAT, true);
+ _scene->changeVariant(1);
+ }
+
+ int frame = 0;
+ if (_globals[kLineStatus] == 2)
+ frame = -1;
+ else if (_globals[kLineStatus] == 3)
+ frame = -2;
+
+ if (_globals[kLineStatus] == 2 || _globals[kLineStatus] == 3) {
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('b', 4));
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, frame);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[7], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(26, 153), FACING_NORTHEAST);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 3);
+ if (_globals[kBoatRaised])
+ _scene->changeVariant(2);
+ }
+
+ _lineFrame = -1;
+ _lineMoving = false;
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ if (_scene->_priorSceneId == 512) {
+ _game._player._playerPos = Common::Point(60, 112);
+ _game._player._facing = FACING_SOUTHEAST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(55, 152);
+ _game._player._facing = FACING_NORTHWEST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ } else if (_handingLine) {
+ _game._player._visible = false;
+ _lineAnimationMode = 1;
+ _lineAnimationPosition = 1;
+ _scene->loadAnimation(formAnimName('R', -1));
+ _lineFrame = 2;
+ }
+ sceneEntrySound();
+}
+
+void Scene511::step() {
+ if ((_lineAnimationMode == 1) && _scene->_activeAnimation) {
+ if (_lineFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _lineFrame = _scene->_activeAnimation->getCurrentFrame();
+ int resetFrame = -1;
+
+ if ((_lineAnimationPosition == 2) && (_lineFrame == 14))
+ _lineMoving = false;
+
+ if (_lineAnimationPosition == 1) {
+ if (_lineFrame == 3) {
+ _lineMoving = false;
+ resetFrame = 2;
+ }
+
+ if (_handingLine)
+ resetFrame = 2;
+ }
+
+ if ((resetFrame >= 0) && (resetFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(resetFrame);
+ _lineFrame = resetFrame;
+ }
+ }
+ }
+
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(6, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene511::preActions() {
+ if (!_handingLine)
+ return;
+
+ if (_action.isAction(VERB_LOOK) || _action.isObject(NOUN_FISHING_LINE) || _action.isAction(VERB_TALKTO))
+ _game._player._needToWalk = false;
+
+ if ((!_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_BOAT) || !_action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_BOAT)) && _game._player._needToWalk) {
+ if (_game._trigger == 0) {
+ _game._player._readyToWalk = false;
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation ();
+ _lineAnimationMode = 2;
+ _scene->loadAnimation(formAnimName('R',2), 1);
+ } else if (_game._trigger == 1) {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _game._objects.setRoom(OBJ_FISHING_LINE, 1);
+ _handingLine = false;
+ _game._player._stepEnabled = true;
+ _game._player._readyToWalk = true;
+ }
+ }
+}
+
+void Scene511::actions() {
+ if (_action.isAction(VERB_WALK_INTO, NOUN_RESTAURANT))
+ _scene->_nextSceneId = 512;
+ else if (_action.isAction(VERB_GET_INTO, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_FISHING_LINE)) {
+ if (!_globals[kBoatRaised]) {
+ if (_globals[kLineStatus] == 2) {
+ if (_globals[kLineStatus] != 3) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _lineAnimationMode = 1;
+ _lineAnimationPosition = 1;
+ _lineMoving = true;
+ _scene->loadAnimation(formAnimName('R', -1));
+ _scene->_sequences.addTimer(1, 1);
+ } else if (_game._trigger == 1) {
+ if (_lineMoving) {
+ _scene->_sequences.addTimer(1, 1);
+ } else {
+ _game._objects.addToInventory(OBJ_FISHING_LINE);
+ _lineMoving = true;
+ _handingLine = true;
+ _game._player._stepEnabled = true;
+ }
+ }
+ } else
+ _vm->_dialogs->show(51129);
+ } else
+ return;
+ } else {
+ _vm->_dialogs->show(51130);
+ }
+ } else if (_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_BOAT) || _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_BOAT)) {
+ if (_globals[kBoatRaised])
+ _vm->_dialogs->show(51131);
+ else if (_globals[kLineStatus] == 1)
+ _vm->_dialogs->show(51130);
+ else if (!_globals[kBoatRaised] && _handingLine) {
+ if (_globals[kLineStatus] != 3) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _lineMoving = true;
+ _lineAnimationPosition = 2;
+ _scene->_sequences.addTimer(1, 1);
+ } else if (_game._trigger == 1) {
+ if (_lineMoving)
+ _scene->_sequences.addTimer(1, 1);
+ else {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 4);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[7], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(26, 153), FACING_NORTHEAST);
+ _game._objects.removeFromInventory(OBJ_FISHING_LINE, 1);
+ _handingLine = false;
+ _lineMoving = true;
+ _globals[kLineStatus] = 3;
+ _game._player._stepEnabled = true;
+ }
+ }
+ }
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_STREET) || _action._lookFlag) {
+ if (_globals[kLineStatus] == 2)
+ _vm->_dialogs->show(51110);
+ else {
+ if (_globals[kLineStatus] == 3)
+ _vm->_dialogs->show(51111);
+ else
+ _vm->_dialogs->show(51112);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(51113);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIDEWALK))
+ _vm->_dialogs->show(51114);
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_SIDEWALK_TO_EAST) || _action.isAction(VERB_WALK_DOWN, NOUN_SIDEWALK_TO_WEST) || _action.isAction(VERB_WALK_DOWN, NOUN_STREET_TO_EAST))
+ _vm->_dialogs->show(51115);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLEASURE_DOME))
+ _vm->_dialogs->show(51116);
+ else if (_action.isAction(VERB_LOOK, NOUN_TICKET_BOOTH))
+ _vm->_dialogs->show(51117);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOME_ENTRANCE))
+ _vm->_dialogs->show(51118);
+ else if (_action.isAction(VERB_UNLOCK, NOUN_PADLOCK_KEY, NOUN_DOME_ENTRANCE) || _action.isAction(VERB_UNLOCK, NOUN_DOOR_KEY, NOUN_DOME_ENTRANCE))
+ _vm->_dialogs->show(51119);
+ else if ( (_action.isAction(VERB_PUT) || _action.isAction(VERB_THROW))
+ && (_action.isObject(NOUN_TIMEBOMB) || _action.isObject(NOUN_BOMB) || _action.isObject(NOUN_BOMBS))
+ && _action.isObject(NOUN_DOME_ENTRANCE))
+ _vm->_dialogs->show(51120);
+ else if (_action.isAction(VERB_LOOK, NOUN_RESTAURANT)) {
+ if (_globals[kBoatRaised])
+ _vm->_dialogs->show(51121);
+ else
+ _vm->_dialogs->show(51128);
+ } else if (_action.isAction(VERB_LOOK, NOUN_PORTHOLE))
+ _vm->_dialogs->show(51122);
+ else if (_action.isAction(VERB_LOOK, NOUN_FISHING_LINE) && (_action._mainObjectSource == 4) && (_globals[kLineStatus] == 2))
+ _vm->_dialogs->show(51126);
+ else if (_action.isAction(VERB_LOOK, NOUN_FISHING_LINE) && (_action._mainObjectSource == 4) && (_globals[kLineStatus] == 3))
+ _vm->_dialogs->show(51133);
+ else if (_action.isAction(VERB_LOOK, NOUN_STATUE))
+ _vm->_dialogs->show(51127);
+ else if (_action.isAction(VERB_LOOK, NOUN_BOAT))
+ if (_globals[kBoatRaised])
+ _vm->_dialogs->show(51123);
+ else if (_globals[kLineStatus] != 3)
+ _vm->_dialogs->show(51124);
+ else
+ _vm->_dialogs->show(51125);
+ else if (_action.isAction(VERB_LOOK, NOUN_FISHING_LINE) && (_globals[kLineStatus] == 3))
+ _vm->_dialogs->show(51125);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene512::Scene512(MADSEngine *vm) : Scene5xx(vm) {
+ _fishingRodHotspotId = -1;
+ _keyHotspotId = -1;
+}
+
+void Scene512::synchronize(Common::Serializer &s) {
+ Scene5xx::synchronize(s);
+
+ s.syncAsSint16LE(_fishingRodHotspotId);
+ s.syncAsSint16LE(_keyHotspotId);
+}
+
+void Scene512::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_FISHING_ROD);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_PADLOCK_KEY);
+ _scene->addActiveVocab(NOUN_REGISTER_DRAWER);
+}
+
+void Scene512::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('r', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites("*RXMRC_8");
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('x', 3));
+
+ if (_game._objects[OBJ_FISHING_ROD]._roomNumber == _scene->_currentSceneId) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+ _fishingRodHotspotId = _scene->_dynamicHotspots.add(NOUN_FISHING_ROD, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_fishingRodHotspotId, Common::Point(199, 101), FACING_NORTHEAST);
+ }
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _globals[kRegisterOpen] = false;
+
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
+ if (_game._difficulty == DIFFICULTY_EASY) {
+ if (_game._objects[OBJ_PADLOCK_KEY]._roomNumber == _scene->_currentSceneId) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 10, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 3);
+ _keyHotspotId = _scene->_dynamicHotspots.add(NOUN_PADLOCK_KEY, VERB_WALKTO, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_keyHotspotId, Common::Point(218, 152), FACING_NORTHEAST);
+ }
+ if (_globals[kRegisterOpen]) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
+ }
+ } else if (_globals[kRegisterOpen]) {
+ if (_game._objects[OBJ_PADLOCK_KEY]._roomNumber == _scene->_currentSceneId) {
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, true);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 3);
+ } else {
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ }
+ } else
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(144, 152);
+ _game._player._facing = FACING_NORTHEAST;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene512::actions() {
+ if (_action.isAction(VERB_WALK, NOUN_OUTSIDE))
+ _scene->_nextSceneId = 511;
+ else if (_action.isAction(VERB_TAKE, NOUN_FISHING_ROD)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_FISHING_ROD)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_fishingRodHotspotId);
+ _game._objects.addToInventory(OBJ_FISHING_ROD);
+ _vm->_dialogs->showItem(OBJ_FISHING_ROD, 51217);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_OPEN, NOUN_CASH_REGISTER)) {
+ if (!_globals[kRegisterOpen]) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_dialogs->show(51236);
+ _game._player._stepEnabled = false;
+ _game._player._facing = FACING_NORTH;
+ _scene->_sequences.addTimer(15, 1);
+ break;
+
+ case 1:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[8]);
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(30, 3);
+ break;
+
+ case 3:
+ _game._player._facing = FACING_NORTHEAST;
+ if (!_game._objects.isInRoom(OBJ_PADLOCK_KEY) || (_game._difficulty == DIFFICULTY_EASY)) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ } else {
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 5);
+ }
+ _vm->_sound->command(23);
+ break;
+
+ case 4:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addTimer(60, 6);
+ break;
+
+ case 5:
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 14, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 3);
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, true);
+ _scene->_sequences.addTimer(60, 6);
+ break;
+
+ case 6:
+ _globals[kRegisterOpen] = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else
+ _vm->_dialogs->show(51239);
+ } else if (_action.isAction(VERB_CLOSE, NOUN_CASH_REGISTER) && _globals[kRegisterOpen]) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ if (!_game._objects.isInRoom(OBJ_PADLOCK_KEY) || _game._difficulty == DIFFICULTY_EASY) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 3);
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 2:
+ _globals[kRegisterOpen] = false;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_PADLOCK_KEY)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_PADLOCK_KEY)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+
+ int endVal;
+ if (_game._player._playerPos == Common::Point(218, 152))
+ endVal = 3;
+ else
+ endVal = 2;
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, endVal);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, endVal, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ if (_game._player._playerPos == Common::Point(218, 152)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _scene->_dynamicHotspots.remove(_keyHotspotId);
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3);
+ _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false);
+ }
+ _vm->_sound->command(9);
+ _game._objects.addToInventory(OBJ_PADLOCK_KEY);
+ _vm->_dialogs->showItem(OBJ_PADLOCK_KEY, 51226);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(51225);
+ else if (_action.isAction(VERB_LOOK, NOUN_PADLOCK_KEY) && _game._objects.isInRoom(OBJ_PADLOCK_KEY))
+ _vm->_dialogs->show(51215);
+ else if (_action.isAction(VERB_LOOK, NOUN_FISHING_ROD) && (_scene->_activeAnimation->getCurrentFrame() == 4))
+ _vm->_dialogs->show(51216);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHIPS_WHEEL))
+ _vm->_dialogs->show(51218);
+ else if (_action.isAction(VERB_TAKE, NOUN_SHIPS_WHEEL))
+ _vm->_dialogs->show(51219);
+ else if (_action.isAction(VERB_LOOK, NOUN_PORTHOLE) || _action.isAction(VERB_PEER_THROUGH, NOUN_PORTHOLE))
+ _vm->_dialogs->show(51220);
+ else if (_action.isAction(VERB_LOOK, NOUN_TABLE))
+ _vm->_dialogs->show(51221);
+ else if (_action.isAction(VERB_LOOK, NOUN_STARFISH))
+ _vm->_dialogs->show(51222);
+ else if (_action.isAction(VERB_TAKE, NOUN_STARFISH))
+ _vm->_dialogs->show(51223);
+ else if (_action.isAction(VERB_LOOK, NOUN_OUTSIDE))
+ _vm->_dialogs->show(51224);
+ else if (_action.isAction(VERB_LOOK, NOUN_POSTER))
+ _vm->_dialogs->show(51227);
+ else if (_action.isAction(VERB_TAKE, NOUN_POSTER))
+ _vm->_dialogs->show(51228);
+ else if (_action.isAction(VERB_LOOK, NOUN_TROPHY)) {
+ if (_game._visitedScenes.exists(604))
+ _vm->_dialogs->show(51229);
+ else
+ _vm->_dialogs->show(51230);
+ } if (_action.isAction(VERB_LOOK, NOUN_CHAIR))
+ _vm->_dialogs->show(51231);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROPE))
+ _vm->_dialogs->show(51232);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROPE))
+ _vm->_dialogs->show(51233);
+ else if (_action.isAction(VERB_LOOK, NOUN_LAMP))
+ _vm->_dialogs->show(51234);
+ else if (_action.isAction(VERB_LOOK, NOUN_COUNTER))
+ _vm->_dialogs->show(51235);
+ else if (_action.isAction(VERB_LOOK, NOUN_ICE_CHESTS))
+ _vm->_dialogs->show(51237);
+ else if (_action.isAction(VERB_OPEN, NOUN_ICE_CHESTS))
+ _vm->_dialogs->show(51238);
+ else if (_action.isAction(VERB_LOOK, NOUN_CASH_REGISTER)) {
+ if (!_globals[kRegisterOpen])
+ _vm->_dialogs->show(51212);
+ else if (_game._objects.isInRoom(OBJ_PADLOCK_KEY))
+ _vm->_dialogs->show(51214);
+ else
+ _vm->_dialogs->show(51213);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene513::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_ELEVATOR_DOOR);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene513::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXCD_9");
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXMRC_9");
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+
+ if ((_scene->_priorSceneId == 751) || (_scene->_priorSceneId == 701)) {
+ _game._player._playerPos = Common::Point(296, 147);
+ _game._player._facing = FACING_WEST;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.addTimer(15, 80);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(63, 149);
+ _game._player._facing = FACING_NORTHEAST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ }
+
+ sceneEntrySound();
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_SECURITY_CARD);
+
+ _game.loadQuoteSet(0x278, 0);
+}
+
+void Scene513::step() {
+ switch (_game._trigger) {
+ case 80:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _vm->_sound->command(24);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ break;
+
+ case 81:
+ _game._player.walk(Common::Point(265, 152), FACING_WEST);
+ _scene->_sequences.addTimer(120, 82);
+ break;
+
+ case 82:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _vm->_sound->command(25);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 83);
+ break;
+
+ case 83:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(6, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene513::actions() {
+ if (_action.isAction(VERB_GET_INTO, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_ID_CARD, NOUN_CARD_SLOT) || _action.isAction(VERB_PUT, NOUN_FAKE_ID, NOUN_CARD_SLOT)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]);
+ _game._player._visible = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _vm->_sound->command(24);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x278));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 2:
+ _game._player.walk(Common::Point(296, 147), FACING_WEST);
+ _scene->_sequences.addTimer(120, 3);
+ break;
+
+ case 3:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _vm->_sound->command(25);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ break;
+
+ case 4:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _game._player._stepEnabled = true;
+ if (_globals[kCityFlooded])
+ _scene->_nextSceneId = 701;
+ else
+ _scene->_nextSceneId = 751;
+
+ break;
+
+ default:
+ break;
+ }
+ } else if ((_action._lookFlag) || _action.isAction(VERB_LOOK, NOUN_STREET))
+ _vm->_dialogs->show(51318);
+ else if (_action.isAction(VERB_LOOK, NOUN_ELEVATOR))
+ _vm->_dialogs->show(51310);
+ else if (_action.isAction(VERB_LOOK, NOUN_ELEVATOR_DOOR))
+ _vm->_dialogs->show(51311);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARD_SLOT))
+ _vm->_dialogs->show(51312);
+ else if (_action.isAction(VERB_LOOK, NOUN_HANDICAP_SIGN))
+ _vm->_dialogs->show(51313);
+ else if (_action.isAction(VERB_LOOK, NOUN_BIKE_RACK))
+ _vm->_dialogs->show(51314);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(51315);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN))
+ _vm->_dialogs->show(51316);
+ else if (_action.isAction(VERB_LOOK, NOUN_STREET_TO_WEST) || _action.isAction(VERB_WALK_DOWN, NOUN_STREET_TO_WEST))
+ _vm->_dialogs->show(51317);
+ else if (_action.isAction(VERB_OPEN, NOUN_ELEVATOR_DOOR) || _action.isAction(VERB_OPEN, NOUN_ELEVATOR))
+ _vm->_dialogs->show(51319);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(51321);
+ else if (_action.isAction(VERB_LOOK, NOUN_BRICK_WALL))
+ _vm->_dialogs->show(51322);
+ else if (_action.isAction(VERB_PUT, NOUN_SECURITY_CARD, NOUN_CARD_SLOT))
+ _vm->_dialogs->show(51320);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene515::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene515::enter() {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.addTimer(30, 70);
+
+ sceneEntrySound();
+}
+
+void Scene515::step() {
+ if (_game._trigger == 70)
+ _scene->loadAnimation(formAnimName('A', -1), 71);
+ else if (_game._trigger == 71)
+ _scene->_nextSceneId = 508;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene551::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene551::enter() {
+ if (_globals[kSexOfRex] == REX_MALE)
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ else
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 1));
+
+ if (_scene->_priorSceneId == 501)
+ _game._player._playerPos = Common::Point(18, 130);
+ else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(124, 119);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ if (_globals[kTeleporterCommand]) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+
+ char sepChar;
+ if (_globals[kSexOfRex] == REX_MALE)
+ sepChar = 'e';
+ else
+ sepChar = 'u';
+
+ int suffixNum;
+ int trigger;
+
+ switch (_globals[kTeleporterCommand]) {
+ case 1:
+ suffixNum = 3;
+ trigger = 75;
+ _globals[kTeleporterUnderstood] = true;
+ break;
+
+ case 2:
+ suffixNum = 1;
+ trigger = 80;
+ break;
+
+ case 4:
+ suffixNum = 2;
+ trigger = 90;
+ break;
+
+ default:
+ trigger = 0;
+ suffixNum = 0;
+ }
+
+ _globals[kTeleporterCommand] = 0;
+
+ if (suffixNum > 0)
+ _scene->loadAnimation(formAnimName(sepChar, suffixNum), trigger);
+ else {
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+ }
+
+ sceneEntrySound();
+}
+
+void Scene551::step() {
+ switch (_game._trigger) {
+ case 75:
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ break;
+
+ case 80:
+ _globals[kTeleporterCommand] = 1;
+ _scene->_nextSceneId = _globals[kTeleporterDestination];
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ case 90:
+ if (_globals[kSexOfRex] == REX_MALE) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 8);
+ } else {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ }
+ _vm->_sound->command(28);
+ _scene->_sequences.addTimer(60, 91);
+ break;
+
+ case 91:
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene551::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN) && (_action.isObject(NOUN_STREET_TO_WEST) || _action.isObject(NOUN_SIDEWALK_TO_WEST)))
+ _game._player._walkOffScreenSceneId = 501;
+}
+
+void Scene551::actions() {
+ if (_action.isAction(VERB_STEP_INTO, NOUN_TELEPORTER))
+ _scene->_nextSceneId = 502;
+ else if ((_action._lookFlag))
+ _vm->_dialogs->show(55117);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKELETON))
+ _vm->_dialogs->show(55110);
+ else if (_action.isAction(VERB_LOOK, NOUN_ELEVATOR_SHAFT))
+ _vm->_dialogs->show(55111);
+ else if (_action.isAction(VERB_WALKTO, NOUN_ELEVATOR_SHAFT))
+ _vm->_dialogs->show(55112);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(55113);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(55114);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(55115);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIDEWALK_TO_WEST)) {
+ if (_game._visitedScenes.exists(505))
+ _vm->_dialogs->show(55116);
+ else
+ _vm->_dialogs->show(55115);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SIDEWALK))
+ _vm->_dialogs->show(55118);
+ else if (_action.isAction(VERB_LOOK, NOUN_EQUIPMENT_OVERHEAD))
+ _vm->_dialogs->show(55119);
+ else if (_action.isAction(VERB_LOOK, NOUN_RAILING))
+ _vm->_dialogs->show(55120);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes5.h b/engines/mads/nebular/nebular_scenes5.h
new file mode 100644
index 0000000000..2face26508
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes5.h
@@ -0,0 +1,254 @@
+/* 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 MADS_NEBULAR_SCENES5_H
+#define MADS_NEBULAR_SCENES5_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene5xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+
+ void sceneEntrySound();
+
+public:
+ Scene5xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene501 : public Scene5xx{
+private:
+ int _mainSequenceId;
+ int _mainSpriteId;
+ int _doorHotspotid;
+ bool _rexPunched;
+
+ void handleSlotActions();
+
+public:
+ Scene501(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene502 : public SceneTeleporter {
+public:
+ Scene502(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene503 : public Scene5xx{
+private:
+ int _detonatorHotspotId;
+
+public:
+ Scene503(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene504 : public Scene5xx{
+private:
+ int _carAnimationMode;
+ int _carFrame;
+
+public:
+ Scene504(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene505 : public Scene5xx{
+private:
+ int _frame;
+ int _nextButtonId;
+ int _homeSelectedId;
+ int _selectedId;
+ int _activeCars;
+
+ int _carLocations[9];
+
+public:
+ Scene505(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene506 : public Scene5xx{
+private:
+ Common::Point _doorPos;
+ Facing _heroFacing;
+
+ int _doorDepth;
+ int _doorSpriteIdx;
+ int _doorSequenceIdx;
+ int _doorWord;
+
+ bool _labDoorFl;
+ bool _firstDoorFl;
+ bool _actionFl;
+
+ void handleDoorSequences();
+
+public:
+ Scene506(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene507 : public Scene5xx{
+private:
+ int _penlightHotspotId;
+
+public:
+ Scene507(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene508 : public Scene5xx{
+private:
+ int _chosenObject;
+
+ void handlePedestral();
+
+public:
+ Scene508(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene511 : public Scene5xx{
+private:
+ bool _handingLine;
+ bool _lineMoving;
+
+ int _lineAnimationMode;
+ int _lineFrame;
+ int _lineAnimationPosition;
+
+public:
+ Scene511(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene512 : public Scene5xx{
+private:
+ int _fishingRodHotspotId;
+ int _keyHotspotId;
+
+public:
+ Scene512(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene513 : public Scene5xx{
+public:
+ Scene513(MADSEngine *vm) : Scene5xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene515 : public Scene5xx{
+public:
+ Scene515(MADSEngine *vm) : Scene5xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions() {};
+};
+
+class Scene551 : public Scene5xx{
+public:
+ Scene551(MADSEngine *vm) : Scene5xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES5_H */
diff --git a/engines/mads/nebular/nebular_scenes6.cpp b/engines/mads/nebular/nebular_scenes6.cpp
new file mode 100644
index 0000000000..eb85fa86e1
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes6.cpp
@@ -0,0 +1,4743 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes6.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene6xx::setAAName() {
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene6xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+ Common::String oldName = _game._player._spritesPrefix;
+
+ if ((_scene->_nextSceneId == 605) || (_scene->_nextSceneId == 620))
+ _game._player._spritesPrefix = "";
+ else if (_globals[kSexOfRex] == REX_MALE)
+ _game._player._spritesPrefix = "RXM";
+ else
+ _game._player._spritesPrefix = "ROX";
+
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ _game._player._scalingVelocity = true;
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+void Scene6xx::sceneEntrySound() {
+ if (!_vm->_musicFlag) {
+ _vm->_sound->command(2);
+ return;
+ }
+
+ switch (_scene->_nextSceneId) {
+ case 601:
+ case 602:
+ case 603:
+ case 604:
+ case 605:
+ case 607:
+ case 608:
+ case 609:
+ case 610:
+ case 612:
+ case 620:
+ _vm->_sound->command(29);
+ break;
+ case 611:
+ _vm->_sound->command(24);
+ break;
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene601::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_LASER_BEAM);
+ _scene->addActiveVocab(VERB_LOOK_AT);
+}
+
+void Scene601::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXCD_4");
+
+ if (_globals[kLaserHoleIsThere]) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_LOOK_AT, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ }
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+
+ if (_scene->_priorSceneId == 504) {
+ _game._player._playerPos = Common::Point(73, 148);
+ _game._player._facing = FACING_WEST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(229, 129);
+ _game._player._facing = FACING_SOUTHWEST;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene601::step() {
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(30, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene601::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_ENTRANCE))
+ _scene->_nextSceneId = 602;
+ else if (_action.isAction(VERB_GET_INSIDE, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_STREET)) {
+ if (!_globals[kLaserHoleIsThere])
+ _vm->_dialogs->show(60110);
+ else
+ _vm->_dialogs->show(60111);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(60112);
+ else if (_action.isAction(VERB_LOOK, NOUN_PAPERS))
+ _vm->_dialogs->show(60113);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(60114);
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_STREET))
+ _vm->_dialogs->show(60115);
+ else if (_action.isAction(VERB_LOOK, NOUN_BALCONY))
+ _vm->_dialogs->show(60116);
+ else if (_action.isAction(VERB_LOOK, NOUN_ENTRANCE))
+ _vm->_dialogs->show(60117);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(60118);
+ else if (_action.isAction(VERB_LOOK, NOUN_CITY))
+ _vm->_dialogs->show(60119);
+ else if (_action.isAction(VERB_LOOK, NOUN_FOUNTAIN))
+ _vm->_dialogs->show(60120);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene602::Scene602(MADSEngine *vm) : Scene6xx(vm) {
+ _lastSpriteIdx = -1;
+ _lastSequenceIdx = -1;
+ _cycleIndex = -1;
+ _safeMode = -1;
+}
+
+void Scene602::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_lastSpriteIdx);
+ s.syncAsSint16LE(_lastSequenceIdx);
+ s.syncAsSint16LE(_cycleIndex);
+ s.syncAsSint16LE(_safeMode);
+}
+
+void Scene602::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_SAFE);
+ _scene->addActiveVocab(NOUN_LASER_BEAM);
+}
+
+void Scene602::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('h', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('l', 0));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXMRC_9");
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _globals[kSafeStatus] = 0;
+
+ if (_globals[kLaserHoleIsThere]) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 9);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 9);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(80, 134), FACING_NORTHEAST);
+ _scene->changeVariant(1);
+ } else
+ _scene->_hotspots.activate(NOUN_HOLE, false);
+
+ if (_globals[kSafeStatus] == 0) {
+ _lastSpriteIdx = _globals._spriteIndexes[2];
+ _cycleIndex = -1;
+ } else if (_globals[kSafeStatus] == 1) {
+ _lastSpriteIdx = _globals._spriteIndexes[2];
+ _cycleIndex = -2;
+ } else if (_globals[kSafeStatus] == 3) {
+ _lastSpriteIdx = _globals._spriteIndexes[3];
+ _cycleIndex = -2;
+ } else {
+ _lastSpriteIdx = _globals._spriteIndexes[3];
+ _cycleIndex = -1;
+ }
+
+ _lastSequenceIdx = _scene->_sequences.startCycle(_lastSpriteIdx, false, _cycleIndex);
+ _scene->_sequences.setDepth(_lastSequenceIdx, 14);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SAFE, VERB_WALKTO, _lastSequenceIdx, Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(185, 113), FACING_NORTHWEST);
+
+ if (_game._objects.isInRoom(OBJ_DOOR_KEY)) {
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('k', -1));
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 15);
+ if (_globals[kSafeStatus] == 0 || _globals[kSafeStatus] == 2)
+ _scene->_hotspots.activate(NOUN_DOOR_KEY, false);
+ } else
+ _scene->_hotspots.activate(NOUN_DOOR_KEY, false);
+
+ if (_scene->_priorSceneId == 603) {
+ _game._player._playerPos = Common::Point(228, 126);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(50, 127);
+ _game._player._facing = FACING_EAST;
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x2F1, 0x2F2, 0x2F3, 0);
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_NOTE);
+ _game._objects.addToInventory(OBJ_REARVIEW_MIRROR);
+ _game._objects.addToInventory(OBJ_COMPACT_CASE);
+ }
+}
+
+void Scene602::handleSafeActions() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 1:
+ if (_safeMode == 1 || _safeMode == 3) {
+ if (_globals[kSafeStatus] == 0 && _safeMode == 1) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2F1));
+ _scene->_sequences.addTimer(120, 4);
+ } else {
+ _scene->_sequences.remove(_lastSequenceIdx);
+ if (_safeMode == 3)
+ _lastSpriteIdx = _globals._spriteIndexes[2];
+ else
+ _lastSpriteIdx = _globals._spriteIndexes[3];
+
+ _lastSequenceIdx = _scene->_sequences.addSpriteCycle(_lastSpriteIdx, false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_lastSequenceIdx, 14);
+ if (_game._objects[OBJ_DOOR_KEY]._roomNumber == _scene->_currentSceneId)
+ _scene->_hotspots.activate(NOUN_DOOR_KEY, true);
+
+ _scene->_sequences.addSubEntry(_lastSequenceIdx,
+ SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ } else {
+ _scene->_sequences.remove(_lastSequenceIdx);
+ if (_globals[kSafeStatus] == 1)
+ _lastSpriteIdx = _globals._spriteIndexes[2];
+ else
+ _lastSpriteIdx = _globals._spriteIndexes[3];
+
+ _lastSequenceIdx = _scene->_sequences.startReverseCycle(_lastSpriteIdx, false, 12, 1, 0, 0);
+ _scene->_sequences.setDepth(_lastSequenceIdx, 14);
+ if (_game._objects[OBJ_DOOR_KEY]._roomNumber == _scene->_currentSceneId)
+ _scene->_hotspots.activate(NOUN_DOOR_KEY, false);
+
+ _scene->_sequences.addSubEntry(_lastSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ }
+ break;
+
+ case 2: {
+ int synxIdx = _lastSequenceIdx;
+ _lastSequenceIdx = _scene->_sequences.startCycle(_lastSpriteIdx, false, _cycleIndex);
+ _scene->_sequences.setDepth(_lastSequenceIdx, 14);
+ _scene->_sequences.updateTimeout(_lastSequenceIdx, synxIdx);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SAFE, VERB_WALKTO, _lastSequenceIdx, Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(185, 113), FACING_NORTHWEST);
+ if (_safeMode == 3) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2F3));
+ _scene->_sequences.addTimer(120, 4);
+ } else
+ _scene->_sequences.addTimer(60, 4);
+ break;
+ }
+
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[5]);
+ _game._player._visible = true;
+ break;
+
+ case 4:
+ if (_safeMode == 1) {
+ if (_globals[kSafeStatus] == 2)
+ _globals[kSafeStatus] = 3;
+ } else if (_safeMode == 2) {
+ if (_globals[kSafeStatus] == 3)
+ _globals[kSafeStatus] = 2;
+ else
+ _globals[kSafeStatus] = 0;
+ } else
+ _globals[kSafeStatus] = 1;
+
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene602::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_HALLWAY))
+ _scene->_nextSceneId = 601;
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY))
+ _scene->_nextSceneId = 603;
+ else if (_action.isAction(VERB_OPEN, NOUN_SAFE) && ((_globals[kSafeStatus] == 0) || (_globals[kSafeStatus] == 2))) {
+ _safeMode = 1;
+ _cycleIndex = -2;
+ handleSafeActions();
+ } else if (_action.isAction(VERB_CLOSE, NOUN_SAFE) && ((_globals[kSafeStatus] == 1) || (_globals[kSafeStatus] == 3))) {
+ _safeMode = 2;
+ _cycleIndex = -1;
+ handleSafeActions();
+ } else if (_action.isAction(VERB_UNLOCK, NOUN_COMBINATION, NOUN_SAFE)) {
+ if ((_globals[kSafeStatus] == 0) && (_game._difficulty != DIFFICULTY_HARD)) {
+ _safeMode = 3;
+ _cycleIndex = -2;
+ handleSafeActions();
+ }
+ } else if ((_action.isAction(VERB_PUT, NOUN_REARVIEW_MIRROR, NOUN_LASER_BEAM) || _action.isAction(VERB_PUT, NOUN_COMPACT_CASE, NOUN_LASER_BEAM)
+ || _action.isAction(VERB_REFLECT, NOUN_COMPACT_CASE, NOUN_LASER_BEAM) || _action.isAction(VERB_REFLECT, NOUN_REARVIEW_MIRROR, NOUN_LASER_BEAM)) && (_globals[kSafeStatus] == 0)) {
+ switch (_game._trigger) {
+ case 0:
+ _vm->_dialogs->show(60230);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _scene->_sequences.remove(_lastSequenceIdx);
+ _scene->loadAnimation(formAnimName('L', 1), 1);
+ break;
+
+ case 1: {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _lastSpriteIdx = _globals._spriteIndexes[3];
+ _lastSequenceIdx = _scene->_sequences.startCycle(_lastSpriteIdx, false, -1);
+ _scene->_sequences.setDepth(_lastSequenceIdx, 14);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SAFE, VERB_WALKTO, _lastSequenceIdx, Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(185, 113), FACING_NORTHWEST);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 9);
+ idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(80, 134), FACING_NORTHEAST);
+ _scene->_sequences.addTimer(60, 2);
+ }
+ break;
+
+ case 2:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2F2));
+ _globals[kSafeStatus] = 2;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_DOOR_KEY) && (_game._trigger || _game._objects.isInRoom(OBJ_DOOR_KEY))) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _scene->_hotspots.activate(NOUN_DOOR_KEY, false);
+ _vm->_sound->command(9);
+ _game._objects.addToInventory(OBJ_DOOR_KEY);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[5]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_DOOR_KEY, 835);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(60210);
+ else if (_action.isAction(VERB_LOOK, NOUN_FLOOR))
+ _vm->_dialogs->show(60211);
+ else if (_action.isAction(VERB_LOOK, NOUN_HALLWAY))
+ _vm->_dialogs->show(60212);
+ else if (_action.isAction(VERB_LOOK, NOUN_TABLE))
+ _vm->_dialogs->show(60213);
+ else if (_action.isAction(VERB_LOOK, NOUN_CHAIR) || _action.isAction(VERB_LOOK, NOUN_LOUNGE_CHAIR))
+ _vm->_dialogs->show(60214);
+ else if (_action.isAction(VERB_LOOK, NOUN_NEON_LIGHTS))
+ _vm->_dialogs->show(60215);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIREPLACE))
+ _vm->_dialogs->show(60216);
+ else if (_action.isAction(VERB_LOOK, NOUN_PICTURE))
+ _vm->_dialogs->show(60217);
+ else if (_action.isAction(VERB_LOOK, NOUN_LAMP))
+ _vm->_dialogs->show(60218);
+ else if (_action.isAction(VERB_LOOK, NOUN_MASKS))
+ _vm->_dialogs->show(60219);
+ else if (_action.isAction(VERB_LOOK, NOUN_GLASS_BLOCK_WALL))
+ _vm->_dialogs->show(60220);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOORWAY))
+ _vm->_dialogs->show(60221);
+ else if (_action.isAction(VERB_LOOK, NOUN_SAFE)) {
+ if (_globals[kSafeStatus] == 0)
+ _vm->_dialogs->show(60222);
+ else if (_globals[kSafeStatus] == 1) {
+ if (!_game._objects.isInRoom(OBJ_DOOR_KEY))
+ _vm->_dialogs->show(60223);
+ else
+ _vm->_dialogs->show(60224);
+ } else if (_globals[kSafeStatus] == 2)
+ _vm->_dialogs->show(60234);
+ else if (_game._objects.isInRoom(OBJ_DOOR_KEY))
+ _vm->_dialogs->show(60235);
+ else
+ _vm->_dialogs->show(60236);
+ } else if (_action.isAction(VERB_UNLOCK, NOUN_DOOR_KEY, NOUN_SAFE) || _action.isAction(VERB_UNLOCK, NOUN_PADLOCK_KEY, NOUN_SAFE))
+ _vm->_dialogs->show(60225);
+ else if (_action.isAction(VERB_PULL, NOUN_SAFE))
+ _vm->_dialogs->show(60226);
+ else if (_action.isAction(VERB_PUT, NOUN_FIREPLACE) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId)))
+ _vm->_dialogs->show(60227);
+ else if (_action.isAction(VERB_LOOK, NOUN_HOLE))
+ _vm->_dialogs->show(60228);
+ else if (_action.isAction(VERB_LOOK, NOUN_LASER_BEAM))
+ _vm->_dialogs->show(60229);
+ else if (_action.isAction(VERB_LOOK, NOUN_FLOWER_BOX))
+ _vm->_dialogs->show(60231);
+ else if (_action.isAction(VERB_THROW, NOUN_BOMB, NOUN_SAFE) || _action.isAction(VERB_THROW, NOUN_BOMBS, NOUN_SAFE))
+ _vm->_dialogs->show(60232);
+ else if (_action.isAction(VERB_PUT, NOUN_TIMEBOMB))
+ _vm->_dialogs->show(60233);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene603::Scene603(MADSEngine *vm) : Scene6xx(vm) {
+ _compactCaseHotspotId = -1;
+ _noteHotspotId = -1;
+}
+
+void Scene603::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_compactCaseHotspotId);
+ s.syncAsSint16LE(_noteHotspotId);
+}
+
+void Scene603::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_COMPACT_CASE);
+ _scene->addActiveVocab(NOUN_NOTE);
+}
+
+void Scene603::enter() {
+ if (_game._objects[OBJ_COMPACT_CASE]._roomNumber == _scene->_currentSceneId) {
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXMRD_3");
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _compactCaseHotspotId = _scene->_dynamicHotspots.add(NOUN_COMPACT_CASE, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_compactCaseHotspotId, Common::Point(250, 152), FACING_SOUTHEAST);
+ }
+
+ if ((_game._difficulty != DIFFICULTY_HARD) && (_game._objects[OBJ_NOTE]._roomNumber == _scene->_currentSceneId)) {
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('p', -1));
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 14);
+ _noteHotspotId = _scene->_dynamicHotspots.add(NOUN_NOTE, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_noteHotspotId, Common::Point(242, 118), FACING_NORTHEAST);
+ }
+
+ if (_scene->_priorSceneId != -2)
+ _game._player._playerPos = Common::Point(113, 134);
+
+ sceneEntrySound();
+}
+
+void Scene603::actions() {
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_LIVINGROOM))
+ _scene->_nextSceneId = 602;
+ else if (_action.isAction(VERB_TAKE, NOUN_COMPACT_CASE)) {
+ if ( _game._trigger || !_game._objects.isInInventory(OBJ_COMPACT_CASE)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 5);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_compactCaseHotspotId);
+ _game._objects.addToInventory(OBJ_COMPACT_CASE);
+ _vm->_dialogs->showItem(OBJ_COMPACT_CASE, 60330);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_NOTE)) {
+ if ( _game._trigger || !_game._objects.isInInventory(OBJ_NOTE)) {
+ if (_game._trigger == 0) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addTimer(15, 1);
+ } else if (_game._trigger == 1) {
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _scene->_dynamicHotspots.remove(_noteHotspotId);
+ _game._objects.addToInventory(OBJ_NOTE);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ }
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(60310);
+ else if (_action.isAction(VERB_LOOK, NOUN_BED))
+ _vm->_dialogs->show(60311);
+ else if (_action.isAction(VERB_LOOK, NOUN_WIG_STAND))
+ _vm->_dialogs->show(60312);
+ else if (_action.isAction(VERB_TAKE, NOUN_WIG_STAND))
+ _vm->_dialogs->show(60313);
+ else if (_action.isAction(VERB_LOOK, NOUN_REVIEW))
+ _vm->_dialogs->show(60314);
+ else if (_action.isAction(VERB_LOOK, NOUN_SOUVENIR_TICKETS))
+ _vm->_dialogs->show(60315);
+ else if (_action.isAction(VERB_LOOK, NOUN_PHOTOGRAPH))
+ _vm->_dialogs->show(60316);
+ else if (_action.isAction(VERB_LOOK, NOUN_LAMP))
+ _vm->_dialogs->show(60317);
+ else if (_action.isAction(VERB_LOOK, NOUN_DIRECTORS_SLATE) || _action.isAction(VERB_LOOK, NOUN_CROP) || _action.isAction(VERB_LOOK, NOUN_MEGAPHONE))
+ _vm->_dialogs->show(60318);
+ else if (_action.isAction(VERB_LOOK, NOUN_SNAPSHOT))
+ _vm->_dialogs->show(60319);
+ else if (_action.isAction(VERB_TAKE, NOUN_SNAPSHOT))
+ _vm->_dialogs->show(60320);
+ else if (_action.isAction(VERB_LOOK, NOUN_PERFUME))
+ _vm->_dialogs->show(60321);
+ else if (_action.isAction(VERB_TAKE, NOUN_PERFUME))
+ _vm->_dialogs->show(60322);
+ else if (_action.isAction(VERB_TAKE, NOUN_NOTE))
+ _vm->_dialogs->show(60323);
+ else if (_action.isAction(VERB_LOOK, NOUN_NOTE)) {
+ if (_game._objects[OBJ_NOTE]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(60324);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CORNER_TABLE)) {
+ if (_game._objects[OBJ_NOTE]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(60326);
+ else
+ _vm->_dialogs->show(60325);
+ } else if (_action.isAction(VERB_LOOK, NOUN_VANITY)) {
+ if (_game._objects[OBJ_COMPACT_CASE]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(60327);
+ else
+ _vm->_dialogs->show(60328);
+ } else if (_action.isAction(VERB_LOOK, NOUN_COMPACT_CASE) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(60329);
+ // For the next two checks, the second part of the check wasn't surrounded par parenthesis, which was obviously wrong
+ else if (_action.isAction(VERB_LOOK) && (_action.isObject(NOUN_BRA) || _action.isObject(NOUN_BOA) || _action.isObject(NOUN_SLIP)))
+ _vm->_dialogs->show(60331);
+ else if (_action.isAction(VERB_TAKE) && (_action.isObject(NOUN_BRA) || _action.isObject(NOUN_BOA) || _action.isObject(NOUN_SLIP)))
+ _vm->_dialogs->show(60332);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene604::Scene604(MADSEngine *vm) : Scene6xx(vm) {
+ _timebombHotspotId = -1;
+ _bombMode = -1;
+ _monsterFrame = -1;
+
+ _monsterTimer = 0;
+
+ _monsterActive = false;
+ _animationActiveFl = false;
+}
+
+void Scene604::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_timebombHotspotId);
+ s.syncAsSint16LE(_bombMode);
+ s.syncAsSint16LE(_monsterFrame);
+
+ s.syncAsUint32LE(_monsterTimer);
+
+ s.syncAsByte(_monsterActive);
+ s.syncAsByte(_animationActiveFl);
+}
+
+void Scene604::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_SEA_MONSTER);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_TIMEBOMB);
+}
+
+void Scene604::enter() {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCD_9");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(Resources::formatName(620, 'b', 0, EXT_SS, ""));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXMRC_9");
+
+ if (_globals[kTimebombStatus] == 1) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, -1);
+ _timebombHotspotId = _scene->_dynamicHotspots.add(NOUN_TIMEBOMB, VERB_WALKTO, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_timebombHotspotId, Common::Point(166, 118), FACING_NORTHEAST);
+ }
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_TIMEBOMB);
+
+ _vm->_palette->setEntry(252, 63, 37, 26);
+ _vm->_palette->setEntry(253, 45, 24, 17);
+ _animationActiveFl = false;
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(72, 149);
+ _game._player._facing = FACING_NORTHEAST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ _animationActiveFl = true;
+ } else {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ }
+
+ _monsterTimer = _scene->_frameStartTime;
+ _monsterActive = false;
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x2E7, 0x2E8, 0x2E9, 0x2EA, 0x2EB, 0x2EC, 0x2ED, 0x2EE, 0x2EF, 0x2F0, 0);
+}
+
+void Scene604::step() {
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(30, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _game._player._stepEnabled = true;
+ _animationActiveFl = false;
+ break;
+
+ default:
+ break;
+ }
+
+ if (_monsterActive && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _monsterFrame) {
+ _monsterFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextMonsterFrame = -1;
+
+ switch (_monsterFrame) {
+ case 50:
+ case 137:
+ case 174: {
+ int randVal = _vm->getRandomNumber(1, 1000);
+ if ((randVal <= 450) && (_game._player._special)) {
+ if (_game._player._special == 1)
+ nextMonsterFrame = 50;
+ else if (_game._player._special == 2)
+ nextMonsterFrame = 84;
+ else
+ nextMonsterFrame = 137;
+ } else if (randVal <= 150)
+ nextMonsterFrame = 50;
+ else if (randVal <= 300)
+ nextMonsterFrame = 84;
+ else if (randVal <= 450)
+ nextMonsterFrame = 137;
+ else if (randVal < 750)
+ nextMonsterFrame = 13;
+ else
+ nextMonsterFrame = 114;
+
+ }
+ break;
+
+ case 84:
+ nextMonsterFrame = 14;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((nextMonsterFrame >= 0) && (nextMonsterFrame != _monsterFrame)) {
+ _scene->_activeAnimation->setCurrentFrame(nextMonsterFrame);
+ _monsterFrame = nextMonsterFrame;
+ }
+ }
+ }
+
+ if ((!_monsterActive && !_animationActiveFl) && (_scene->_frameStartTime > (_monsterTimer + 4))) {
+ _monsterTimer = _scene->_frameStartTime;
+ if ((_vm->getRandomNumber(1, 1000) < 25) || !_game._visitedScenes._sceneRevisited) {
+ _monsterActive = true;
+ _scene->freeAnimation();
+ _scene->loadAnimation(formAnimName('m', -1));
+ }
+ }
+}
+
+void Scene604::handleBombActions() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ if (_bombMode == 1)
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1);
+ else
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 2);
+
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, -1);
+ _timebombHotspotId = _scene->_dynamicHotspots.add(NOUN_TIMEBOMB, VERB_WALKTO, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_timebombHotspotId, Common::Point(166, 118), FACING_NORTHEAST);
+ _game._objects.setRoom(OBJ_TIMEBOMB, _scene->_currentSceneId);
+ break;
+
+ case 2:
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _scene->_dynamicHotspots.remove(_timebombHotspotId);
+ _game._objects.addToInventory(OBJ_TIMEBOMB);
+ break;
+
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[5]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ if (_bombMode == 1) {
+ _vm->_dialogs->show(60421);
+ _globals[kTimebombStatus] = TIMEBOMB_ACTIVATED;
+ _globals[kTimebombTimer] = 0;
+ } else {
+ _vm->_dialogs->show(60423);
+ _globals[kTimebombStatus] = TIMEBOMB_DEACTIVATED;
+ _globals[kTimebombTimer] = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene604::actions() {
+ if (_action.isAction(VERB_GET_INSIDE, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if ((_action.isAction(VERB_PUT, NOUN_LEDGE) || _action.isAction(VERB_PUT, NOUN_VIEWPORT) || _action.isAction(VERB_THROW, NOUN_VIEWPORT))
+ && (_action.isObject(NOUN_BOMB) || _action.isObject(NOUN_BOMBS)))
+ _vm->_dialogs->show(60420);
+ else if (_action.isAction(VERB_PUT, NOUN_TIMEBOMB, NOUN_LEDGE) || _action.isAction(VERB_PUT, NOUN_TIMEBOMB, NOUN_VIEWPORT)) {
+ _bombMode = 1;
+ if ((_game._difficulty == DIFFICULTY_HARD) || _globals[kWarnedFloodCity])
+ handleBombActions();
+ else if ((_game._objects.isInInventory(OBJ_POLYCEMENT) && _game._objects.isInInventory(OBJ_CHICKEN))
+ && ((_globals[kLineStatus] == LINE_TIED) || ((_game._difficulty == DIFFICULTY_EASY) && (!_globals[kBoatRaised]))))
+ handleBombActions();
+ else if (_game._difficulty == DIFFICULTY_EASY)
+ _vm->_dialogs->show(60424);
+ else {
+ _vm->_dialogs->show(60425);
+ _globals[kWarnedFloodCity] = true;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_TIMEBOMB)) {
+ if (_game._trigger || !_game._objects.isInInventory(OBJ_TIMEBOMB)) {
+ _bombMode = 2;
+ handleBombActions();
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(60411);
+ else if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT)) {
+ if (_monsterActive) {
+ _vm->_dialogs->show(60413);
+ } else {
+ _vm->_dialogs->show(60412);
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(60414);
+ else if (_action.isAction(VERB_LOOK, NOUN_VENT))
+ _vm->_dialogs->show(60415);
+ else if (_action.isAction(VERB_LOOK, NOUN_INDICATOR))
+ _vm->_dialogs->show(60416);
+ else if (_action.isAction(VERB_LOOK, NOUN_SCULPTURE))
+ _vm->_dialogs->show(60417);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(60418);
+ else if (_action.isAction(VERB_LOOK, NOUN_FOUNTAIN))
+ _vm->_dialogs->show(60419);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene605::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene605::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('r', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', -1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('l', -1));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('p', -1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('n', -1));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('f', -1));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 15, 0, 0, 0);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 0);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 14, 0, 0, 0);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 13, 0, 0, 0);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 17, 0, 0, 0);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 18, 0, 0, 0);
+
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.addTimer(600, 70);
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ sceneEntrySound();
+ _vm->_sound->command(22);
+}
+
+void Scene605::step() {
+ if (_game._trigger == 70) {
+ _vm->_sound->command(23);
+ if (_globals[kResurrectRoom] >= 700)
+ _vm->_dialogs->show(60598);
+ else
+ _vm->_dialogs->show(60599);
+
+ _scene->_nextSceneId = _globals[kResurrectRoom];
+ }
+}
+
+void Scene605::actions() {
+ return;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene607::Scene607(MADSEngine *vm) : Scene6xx(vm) {
+ _dogTimer = 0;
+ _lastFrameTime = 0;
+
+ _dogLoop = false;
+ _dogEatsRex = false;
+ _dogBarking = false;
+ _shopAvailable = false;
+
+ _animationMode = -1;
+ _animationActive = -1;
+ _counter = -1;
+}
+
+void Scene607::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsUint32LE(_dogTimer);
+ s.syncAsUint32LE(_lastFrameTime);
+
+ s.syncAsByte(_dogLoop);
+ s.syncAsByte(_dogEatsRex);
+ s.syncAsByte(_dogBarking);
+ s.syncAsByte(_shopAvailable);
+
+ s.syncAsSint16LE(_animationMode);
+ s.syncAsSint16LE(_animationActive);
+ s.syncAsSint16LE(_counter);
+}
+
+void Scene607::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_OBNOXIOUS_DOG);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene607::enter() {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXCD_3");
+
+ if (!_game._visitedScenes._sceneRevisited && (_scene->_priorSceneId != 608))
+ _globals[kDogStatus] = 1;
+
+ if ((_scene->_priorSceneId == 608) && (_globals[kDogStatus] < 3))
+ _globals[kDogStatus] = 3;
+
+ _animationActive = 0;
+
+ if ((_globals[kDogStatus] == 1) && (_game._difficulty != DIFFICULTY_EASY)) {
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('g', 3));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('g', 7));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', 0));
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
+ _dogBarking = false;
+ _dogLoop = false;
+ _shopAvailable = false;
+ _dogEatsRex = false;
+ _dogTimer = 0;
+ } else
+ _scene->_hotspots.activate(NOUN_OBNOXIOUS_DOG, false);
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+
+ if (_scene->_priorSceneId == 608) {
+ _game._player._playerPos = Common::Point(297, 50);
+ _game._player._facing = FACING_SOUTHEAST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(40, 104);
+ _game._player._facing = FACING_SOUTHEAST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->loadAnimation(formAnimName('R', 1), 80);
+ } else if (_globals[kDogStatus] == 2) {
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('g', 3));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('g', 7));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', 0));
+ }
+
+ sceneEntrySound();
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_BONES);
+
+ _vm->_palette->setEntry(252, 63, 44, 30);
+ _vm->_palette->setEntry(253, 63, 20, 22);
+ _game.loadQuoteSet(0x2F8, 0x2F7, 0x2F6, 0x2F9, 0x2FA, 0);
+}
+
+void Scene607::step() {
+ if (_globals[kDogStatus] == 2) {
+ int32 diff = _scene->_frameStartTime - _lastFrameTime;
+ if ((diff >= 0) && (diff <= 4))
+ _dogTimer += diff;
+ else
+ _dogTimer++;
+
+ _lastFrameTime = _scene->_frameStartTime;
+ }
+
+ if ((_dogTimer >= 480) && !_dogLoop && !_shopAvailable && (_globals[kDogStatus] == 2) && !_game._player._special) {
+ _vm->_sound->command(14);
+ _dogLoop = true;
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 10, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 91);
+ _dogLoop = false;
+ _dogTimer = 0;
+ }
+
+ if (_game._trigger == 91) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
+ _dogBarking = false;
+ _globals[kDogStatus] = 1;
+ _scene->_hotspots.activate(NOUN_OBNOXIOUS_DOG, true);
+ }
+
+ if (!_dogEatsRex && (_game._difficulty != DIFFICULTY_EASY) && !_animationActive && (_globals[kDogStatus] == 1)
+ && !_dogBarking && (_vm->getRandomNumber(1, 50) == 10)) {
+ _dogBarking = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 8, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
+ _scene->_kernelMessages.reset();
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 100);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ _counter = 0;
+ }
+
+ if ((_game._trigger == 70) && !_dogEatsRex && (_globals[kDogStatus] == 1) && !_animationActive) {
+ int syncIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], syncIdx);
+ _scene->_kernelMessages.reset();
+ _dogBarking = false;
+ }
+
+ if (_game._trigger == 100) {
+ _counter++;
+ _vm->_sound->command(12);
+
+ if ((_counter >= 1) && (_counter <= 4)) {
+ Common::Point pos(0, 0);
+ switch (_counter) {
+ case 1:
+ pos = Common::Point(237, 5);
+ break;
+
+ case 2:
+ pos = Common::Point(270, 15);
+ break;
+
+ case 3:
+ pos = Common::Point(237, 25);
+ break;
+
+ case 4:
+ pos = Common::Point(270, 36);
+ break;
+
+ default:
+ break;
+ }
+ _scene->_kernelMessages.add(pos, 0xFDFC, 0, 0, 120, _game.getQuote(0x2F9));
+ }
+ }
+
+ if (_game._player._moving && (_game._difficulty != DIFFICULTY_EASY) && !_shopAvailable && (_globals[kDogStatus] == 1) && (_scene->_rails.getNext() > 0)) {
+ _game._player.cancelCommand();
+ _game._player.startWalking(Common::Point(268, 72), FACING_NORTHEAST);
+ _scene->_rails.resetNext();
+ }
+
+ if ((_game._player._special > 0) && (_game._difficulty != DIFFICULTY_EASY) && (_globals[kDogStatus] == 1) && _game._player._stepEnabled)
+ _game._player._stepEnabled = false;
+
+ if ((_game._difficulty != DIFFICULTY_EASY) && (_globals[kDogStatus] == 1) && (_game._player._playerPos == Common::Point(268, 72))
+ && (_game._trigger || !_dogEatsRex)) {
+ _dogEatsRex = true;
+ switch (_game._trigger) {
+ case 91:
+ case 0:
+ _animationActive = 1;
+ _game._player._visible = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -1, 7);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2FA));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
+ _scene->_sequences.addTimer(10, 64);
+ break;
+
+ case 60: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 5, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 8, 45);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 61);
+ }
+ break;
+
+ case 61: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 3, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 46, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 62);
+ }
+ break;
+
+ case 62: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _animationActive = 2;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_sequences.addTimer(60, 63);
+ }
+ break;
+
+ case 63:
+ _vm->_dialogs->show(60729);
+ _animationActive = 0;
+ _dogEatsRex = false;
+ _scene->_reloadSceneFlag = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ case 64:
+ if (_dogEatsRex && (_animationActive == 1)) {
+ _vm->_sound->command(12);
+ _scene->_sequences.addTimer(10, 64);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (_game._trigger) {
+ case 80:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(6, 81);
+ break;
+
+ case 81:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 82);
+ break;
+
+ case 82:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene607::handleThrowingBone() {
+ _animationActive = -1;
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._player._visible = false;
+ _scene->loadAnimation(formAnimName('D', _animationMode), 1);
+ break;
+
+ case 1:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+
+ if (_animationMode != 1)
+ _scene->_hotspots.activate(NOUN_OBNOXIOUS_DOG, false);
+ else {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
+ }
+
+ _dogBarking = false;
+ if (_game._objects.isInInventory(OBJ_BONE)) {
+ _game._objects.setRoom(OBJ_BONE, 1);
+ if (_animationMode == 1)
+ _globals[kBone202Status] = 0;
+ } else {
+ _game._objects.setRoom(OBJ_BONES, 1);
+ _game._objects.addToInventory(OBJ_BONE);
+ }
+
+ _scene->_sequences.addTimer(60, 2);
+ break;
+
+ case 2: {
+ int quoteId = 0x2F8;
+ if (_animationMode == 1)
+ quoteId = 0x2F7;
+
+ if (_animationMode == 2) {
+ _globals[kDogStatus] = 2;
+ _dogTimer = 0;
+ }
+
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(quoteId));
+ _scene->_sequences.addTimer(60, 3);
+ }
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _animationActive = 0;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene607::preActions() {
+ if (_action.isAction(VERB_TALKTO, NOUN_OBNOXIOUS_DOG))
+ _game._player._needToWalk = false;
+
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_SIDE_ENTRANCE) && (_globals[kDogStatus] == 2) && (_game._difficulty != DIFFICULTY_EASY)) {
+ _shopAvailable = true;
+ _dogTimer = 0;
+ }
+
+ if (_action.isAction(VERB_THROW, NOUN_BONES, NOUN_OBNOXIOUS_DOG) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_OBNOXIOUS_DOG))
+ _game._player.walk(Common::Point(193, 100), FACING_NORTHEAST);
+
+ if (_action.isAction(VERB_THROW, NOUN_BONES, NOUN_FENCE) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_FENCE))
+ _game._player.walk(Common::Point(201, 107), FACING_SOUTHEAST);
+}
+
+void Scene607::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_SIDE_ENTRANCE))
+ _scene->_nextSceneId = 608;
+ else if (_action.isAction(VERB_GET_INSIDE, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_THROW, NOUN_BONES, NOUN_OBNOXIOUS_DOG) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_OBNOXIOUS_DOG)) {
+ if (_game._difficulty != DIFFICULTY_EASY) {
+ _animationMode = 1;
+ _scene->_kernelMessages.reset();
+ if (_game._trigger == 0)
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2F6));
+
+ handleThrowingBone();
+ }
+ } else if ((_action.isAction(VERB_THROW, NOUN_BONES, NOUN_FENCE) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_FENCE)) && (_game._difficulty != DIFFICULTY_EASY)
+ && ((_globals[kDogStatus] == 1) || _game._trigger)) {
+ _animationMode = 2;
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2F6));
+ }
+ handleThrowingBone();
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_STREET)) {
+ if ((_globals[kDogStatus] == 1) || (_game._difficulty == DIFFICULTY_EASY))
+ _vm->_dialogs->show(60710);
+ else
+ _vm->_dialogs->show(60711);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(60712);
+ else if (_action.isAction(VERB_LOOK, NOUN_FENCE))
+ _vm->_dialogs->show(60713);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(60714);
+ else if (_action.isAction(VERB_LOOK, NOUN_MANHOLE))
+ _vm->_dialogs->show(60715);
+ else if (_action.isAction(VERB_LOOK, NOUN_FIRE_HYDRANT) && (_globals[kDogStatus] == 1))
+ _vm->_dialogs->show(60716);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIGN))
+ _vm->_dialogs->show(60717);
+ else if (_action.isAction(VERB_LOOK, NOUN_BROKEN_WINDOW))
+ _vm->_dialogs->show(60718);
+ else if (_action.isAction(VERB_LOOK, NOUN_GARAGE_DOOR))
+ _vm->_dialogs->show(60719);
+ else if (_action.isAction(VERB_LOOK, NOUN_SIDEWALK))
+ _vm->_dialogs->show(60720);
+ else if (_action.isAction(VERB_LOOK, NOUN_AIR_HOSE))
+ _vm->_dialogs->show(60721);
+ else if (_action.isAction(VERB_LOOK, NOUN_AUTO_SHOP)) {
+ if (_globals[kDogStatus] == 1)
+ _vm->_dialogs->show(60723);
+ else
+ _vm->_dialogs->show(60722);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SIDE_ENTRANCE)) {
+ if (_globals[kDogStatus] == 1)
+ _vm->_dialogs->show(60725);
+ else
+ _vm->_dialogs->show(60724);
+ } else if (_action.isAction(VERB_LOOK, NOUN_OBNOXIOUS_DOG))
+ _vm->_dialogs->show(60726);
+ else if (_action.isAction(VERB_TALKTO, NOUN_OBNOXIOUS_DOG))
+ _vm->_dialogs->show(60727);
+ else if (_action.isAction(VERB_LOOK, NOUN_BARRICADE))
+ _vm->_dialogs->show(60728);
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_STREET))
+ _vm->_dialogs->show(60730);
+ else if (_action.isObject(NOUN_GARAGE_DOOR) && (_action.isAction(VERB_OPEN) || _action.isAction(VERB_PUSH) || _action.isAction(VERB_PULL)))
+ _vm->_dialogs->show(60731);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene608::Scene608(MADSEngine *vm) : Scene6xx(vm) {
+ _carMode = -1;
+ _carFrame = -1;
+ _carMoveMode = -1;
+ _dogDeathMode = -1;
+ _carHotspotId = -1;
+ _barkCount = -1;
+ _polycementHotspotId = -1;
+ _animationMode = -1;
+ _nextTrigger = -1;
+ _throwMode = -1;
+
+ _resetPositionsFl = false;
+ _dogActiveFl = false;
+ _dogBarkingFl = false;
+ _dogFirstEncounter = false;
+ _rexBeingEaten = false;
+ _dogHitWindow = false;
+ _checkFl = false;
+ _dogSquashFl = false;
+ _dogSafeFl = false;
+ _buttonPressedonTimeFl = false;
+ _dogUnderCar = false;
+ _dogYelping = false;
+
+ _dogWindowTimer = -1;
+ _dogRunTimer = -1;
+
+ _dogTimer1 = 0;
+ _dogTimer2 = 0;
+}
+
+void Scene608::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_carMode);
+ s.syncAsSint16LE(_carFrame);
+ s.syncAsSint16LE(_carMoveMode);
+ s.syncAsSint16LE(_dogDeathMode);
+ s.syncAsSint16LE(_carHotspotId);
+ s.syncAsSint16LE(_barkCount);
+ s.syncAsSint16LE(_polycementHotspotId);
+ s.syncAsSint16LE(_animationMode);
+ s.syncAsSint16LE(_nextTrigger);
+ s.syncAsSint16LE(_throwMode);
+
+ s.syncAsByte(_resetPositionsFl);
+ s.syncAsByte(_dogActiveFl);
+ s.syncAsByte(_dogBarkingFl);
+ s.syncAsByte(_dogFirstEncounter);
+ s.syncAsByte(_rexBeingEaten);
+ s.syncAsByte(_dogHitWindow);
+ s.syncAsByte(_checkFl);
+ s.syncAsByte(_dogSquashFl);
+ s.syncAsByte(_dogSafeFl);
+ s.syncAsByte(_buttonPressedonTimeFl);
+ s.syncAsByte(_dogUnderCar);
+ s.syncAsByte(_dogYelping);
+
+ s.syncAsSint32LE(_dogWindowTimer);
+ s.syncAsSint32LE(_dogRunTimer);
+
+ s.syncAsUint32LE(_dogTimer1);
+ s.syncAsUint32LE(_dogTimer2);
+}
+
+void Scene608::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_POLYCEMENT);
+ _scene->addActiveVocab(NOUN_CAR);
+ _scene->addActiveVocab(NOUN_OBNOXIOUS_DOG);
+}
+
+void Scene608::resetDogVariables() {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_OBNOXIOUS_DOG, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(194, 142), FACING_EAST);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 4);
+ _dogBarkingFl = false;
+ _dogFirstEncounter = false;
+}
+
+void Scene608::restoreAnimations() {
+ _scene->freeAnimation();
+ _carMode = 0;
+ _game._player._stepEnabled = true;
+ if (_throwMode == 6)
+ _dogSquashFl = true;
+
+ if (_globals[kCarStatus] == 0) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _scene->loadAnimation(formAnimName('A', -1));
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[8]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(6);
+ }
+}
+
+void Scene608::setCarAnimations() {
+ _scene->freeAnimation();
+ if (_globals[kCarStatus] == 0) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[6], Common::Point(143, 98));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 6);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[7], Common::Point(141, 67));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 15);
+ } else {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[6], Common::Point(143, 128));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 6);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[7], Common::Point(141, 97));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 15);
+ _globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[8], Common::Point(144, 126));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 5);
+ }
+}
+
+void Scene608::handleThrowingBone() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ setCarAnimations();
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _animationMode = -1;
+ _game._player._visible = false;
+ _carMode = _throwMode;
+ if (_throwMode == 4)
+ _scene->loadAnimation(formAnimName('X', 2), 1);
+ else if (_throwMode == 5)
+ _scene->loadAnimation(formAnimName('X', 1), 1);
+ else
+ _scene->loadAnimation(formAnimName('X', 3), 1);
+ break;
+
+ case 1:
+ _nextTrigger = 1;
+ _scene->_sequences.addTimer(1, 2);
+ break;
+
+ case 2:
+ if (_nextTrigger != 2)
+ _scene->_sequences.addTimer(1, 2);
+ else {
+ if (_game._objects.isInInventory(OBJ_BONE))
+ _game._objects.setRoom(OBJ_BONE, 1);
+ else {
+ _game._objects.setRoom(OBJ_BONES, 1);
+ _game._objects.addToInventory(OBJ_BONE);
+ }
+ _scene->_sequences.addTimer(60, 3);
+ }
+ break;
+
+ case 3:
+ if (_throwMode != 6) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x304));
+ _scene->_sequences.addTimer(120, 4);
+ } else
+ restoreAnimations();
+ break;
+
+ case 4:
+ restoreAnimations();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene608::enter() {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMRD_7");
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('c', 2));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('c', 1));
+
+ if (_game._objects.isInRoom(OBJ_POLYCEMENT)) {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', -1));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_POLYCEMENT, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _polycementHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(249, 129), FACING_NORTHEAST);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6);
+ }
+
+ if (_game._objects.isInRoom(OBJ_REARVIEW_MIRROR)) {
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('m', -1));
+ _globals._sequenceIndexes[12] = _scene->_sequences.startCycle(_globals._spriteIndexes[12], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_REARVIEW_MIRROR, VERB_WALKTO, _globals._sequenceIndexes[12], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(71, 113), FACING_NORTHEAST);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 15);
+ }
+
+ if (_game._difficulty == DIFFICULTY_HARD) {
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('g', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('g', 1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('g', 2));
+ _globals._spriteIndexes[10] = _scene->_sprites.addSprites(formAnimName('h', 2));
+ _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('h', 3));
+ _rexBeingEaten = false;
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _globals[kDogStatus] = 3;
+ _dogActiveFl = true;
+ } else
+ _dogActiveFl = (_globals[kDogStatus] != 4);
+ } else {
+ _globals[kDogStatus] = 4;
+ _dogActiveFl = false;
+ }
+
+ _dogSquashFl = false;
+ _buttonPressedonTimeFl = false;
+ _dogWindowTimer = 0;
+ _dogRunTimer = 0;
+ _dogHitWindow = false;
+ _checkFl = false;
+ _dogUnderCar = false;
+ _dogYelping = false;
+
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _globals[kCarStatus] = 0;
+
+ _animationMode = 0;
+ _carMoveMode = 0;
+ _carFrame = -1;
+
+ if (_globals[kCarStatus] == 0) {
+ _carMode = 0;
+ _dogDeathMode = 0;
+ _resetPositionsFl = false;
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(99, 69, 99 + 82, 69 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ _scene->loadAnimation(formAnimName('A', -1));
+ } else if (_globals[kCarStatus] == 3) {
+ _carMode = 0;
+ _dogDeathMode = 0;
+ _resetPositionsFl = false;
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(100, 100, 100 + 82, 100 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(6);
+ } else if (_globals[kCarStatus] == 1) {
+ _carMode = 2;
+ _dogDeathMode = 0;
+ _resetPositionsFl = false;
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(99, 69, 99 + 82, 69 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ _scene->loadAnimation(formAnimName('C', -1));
+ } else if (_globals[kCarStatus] == 2) {
+ _carMode = 1;
+ _dogDeathMode = 2;
+ _resetPositionsFl = true;
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(99, 69, 99 + 82, 69 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ _scene->loadAnimation(formAnimName('B', -1));
+ } else {
+ _carMode = 3;
+ _dogDeathMode = 2;
+ _resetPositionsFl = true;
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(100, 100, 100 + 82, 100 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ _scene->loadAnimation(formAnimName('D', -1));
+ }
+
+ _vm->_palette->setEntry(252, 63, 44, 30);
+ _vm->_palette->setEntry(253, 63, 20, 22);
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(46, 132);
+ _game._player._facing = FACING_EAST;
+ if (_game._difficulty == DIFFICULTY_HARD) {
+ if (!_game._visitedScenes._sceneRevisited)
+ _dogFirstEncounter = true;
+ else if (_dogActiveFl)
+ resetDogVariables();
+ }
+ } else if ((_game._difficulty == DIFFICULTY_HARD) && !_dogFirstEncounter && _dogActiveFl) {
+ if (!_dogUnderCar)
+ resetDogVariables();
+ else {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 10, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 6);
+ }
+ }
+
+ sceneEntrySound();
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_BONES);
+
+ _game.loadQuoteSet(0x2FB, 0x2FC, 0x2FE, 0x2FD, 0x2FF, 0x300, 0x301, 0x302, 0x303, 0x304, 0);
+}
+
+void Scene608::step() {
+ if (_dogFirstEncounter) {
+ long diff = _scene->_frameStartTime - _dogTimer1;
+ if ((diff >= 0) && (diff <= 1))
+ _dogWindowTimer += diff;
+ else
+ _dogWindowTimer++;
+
+ _dogTimer1 = _scene->_frameStartTime;
+ }
+
+ if (_dogActiveFl && (_dogWindowTimer >= 2) && !_dogHitWindow) {
+ _dogHitWindow = true;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 11, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1);
+ _vm->_sound->command(14);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ _dogWindowTimer = 0;
+ }
+
+ if (_game._trigger == 70)
+ resetDogVariables();
+
+ if ((_game._difficulty == DIFFICULTY_HARD) && !_animationMode && _dogActiveFl && !_dogFirstEncounter && !_dogUnderCar) {
+ if (!_dogBarkingFl) {
+ if (_vm->getRandomNumber(1, 50) == 10) {
+ _dogBarkingFl = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 5, 8, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 4);
+ int idx = _scene->_dynamicHotspots.add(NOUN_OBNOXIOUS_DOG, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(194, 142), FACING_EAST);
+ _barkCount = 0;
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 2, 100);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 60);
+ }
+ } else if (_game._trigger == 60) {
+ int syncIdx = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], syncIdx);
+ _scene->_kernelMessages.reset();
+ _dogBarkingFl = false;
+ }
+ }
+
+ if ((_game._trigger == 100) && _dogBarkingFl) {
+ _vm->_sound->command(12);
+ _barkCount++;
+
+ if ((_barkCount >= 1) && (_barkCount <= 4)) {
+ Common::Point _barkPos(0, 0);
+ switch (_barkCount) {
+ case 1:
+ _barkPos = Common::Point(197, 66);
+ break;
+
+ case 2:
+ _barkPos = Common::Point(230, 76);
+ break;
+
+ case 3:
+ _barkPos = Common::Point(197, 86);
+ break;
+
+ case 4:
+ _barkPos = Common::Point(230, 97);
+ break;
+
+ default:
+ break;
+ }
+ _scene->_kernelMessages.add(_barkPos, 0xFDFC, 0, 0, 120, _game.getQuote(0x2FB));
+ }
+ }
+
+ if (_dogSquashFl && !_dogFirstEncounter && _dogUnderCar && _dogActiveFl) {
+ long diff = _scene->_frameStartTime - _dogTimer2;
+ if ((diff >= 0) && (diff <= 4))
+ _dogRunTimer += diff;
+ else
+ _dogRunTimer++;
+
+ _dogTimer2 = _scene->_frameStartTime;
+ }
+
+ if (_dogRunTimer >= 480 && !_checkFl && !_buttonPressedonTimeFl && !_dogFirstEncounter && _dogUnderCar && _dogActiveFl) {
+ _checkFl = true;
+ _dogSquashFl = false;
+ _dogSafeFl = true;
+ _checkFl = false;
+ _dogRunTimer = 0;
+ } else {
+ _dogSafeFl = false;
+ if (_game._player._moving && (_game._difficulty == DIFFICULTY_HARD) && _dogActiveFl && (_scene->_rails.getNext() > 0) && _dogUnderCar)
+ _dogSafeFl = true;
+ }
+
+ if (_dogActiveFl && _dogSafeFl && !_buttonPressedonTimeFl) {
+ _dogDeathMode = 0;
+ _globals[kCarStatus] = 0;
+ _carMode = 0;
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _dogUnderCar = false;
+ _dogYelping = false;
+ _scene->_kernelMessages.reset();
+ _globals._sequenceIndexes[11] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[11], false, 6, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 92);
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2FF));
+ }
+
+ if (_game._trigger == 92) {
+ resetDogVariables();
+ _animationMode = 0;
+ }
+
+ if ((_carMode == 4) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+
+ if (_carFrame == 10) {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ } else if (_carFrame == 56) {
+ resetDogVariables();
+ _animationMode = 0;
+ _nextTrigger = 2;
+ }
+ }
+ }
+
+ if ((_carMode == 5) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+ if (_carFrame == 10) {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ } else if (_carFrame == 52) {
+ resetDogVariables();
+ _animationMode = 0;
+ _nextTrigger = 2;
+ }
+ }
+ }
+
+ if ((_carMode == 6) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+
+ if (_carFrame == 11) {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ } else if (_carFrame == 41) {
+ _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 10, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 6);
+ _dogUnderCar = true;
+ _nextTrigger = 2;
+ }
+ }
+ }
+
+ if (_dogUnderCar) {
+ if (!_dogYelping) {
+ if (_vm->getRandomNumber(1, 50) == 10) {
+ _dogYelping = true;
+ _barkCount = 0;
+ _scene->_sequences.addTimer(12, 110);
+ _scene->_sequences.addTimer(22, 111);
+ _scene->_sequences.addTimer(120, 112);
+ }
+ _scene->_kernelMessages.reset();
+ }
+ } else
+ _dogYelping = false;
+
+ if (_game._trigger == 110) {
+ _vm->_sound->command(12);
+ _scene->_kernelMessages.add(Common::Point(150, 97), 0xFDFC, 0, 0, 60, _game.getQuote(0x303));
+ }
+
+ if (_game._trigger == 111) {
+ _vm->_sound->command(12);
+ _scene->_kernelMessages.add(Common::Point(183, 93), 0xFDFC, 0, 0, 60, _game.getQuote(0x303));
+ }
+
+ if (_game._trigger == 112)
+ _dogYelping = false;
+
+ if ((_carMode == 0) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+
+ if ((_globals[kCarStatus] == 0) || (_globals[kCarStatus] == 3)) {
+ switch (_carMoveMode) {
+ case 0:
+ if (_globals[kCarStatus] == 0)
+ nextFrame = 0;
+ else
+ nextFrame = 6;
+ break;
+
+ case 1:
+ if (_scene->_activeAnimation->getCurrentFrame() >= 12) {
+ nextFrame = 0;
+ _carMoveMode = 0;
+ _globals[kCarStatus] = 0;
+ }
+ break;
+
+ case 2:
+ if (_scene->_activeAnimation->getCurrentFrame() >= 6) {
+ nextFrame = 6;
+ _carMoveMode = 0;
+ _globals[kCarStatus] = 3;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _carFrame = nextFrame;
+ }
+ }
+ }
+
+ if ((_carMode == 2) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+
+ if (_carMoveMode == 0)
+ nextFrame = 28;
+ else if (_scene->_activeAnimation->getCurrentFrame() >= 28) {
+ nextFrame = 28;
+ _carMoveMode = 0;
+ }
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _carFrame = nextFrame;
+ }
+ }
+ }
+
+ if ((_carMode == 3) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+
+ if (_resetPositionsFl) {
+ nextFrame = 0;
+ _carMoveMode = 0;
+ } else if (_carMoveMode == 0)
+ nextFrame = 6;
+ else if (_scene->_activeAnimation->getCurrentFrame() >= 6) {
+ nextFrame = 6;
+ _carMoveMode = 0;
+ }
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _carFrame = nextFrame;
+ }
+ }
+ }
+
+
+ if ((_carMode == 1) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _carFrame) {
+ _carFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+
+ if (_resetPositionsFl) {
+ nextFrame = 0;
+ _carMoveMode = 0;
+ } else if (_carMoveMode == 0)
+ nextFrame = 6;
+ else if (_scene->_activeAnimation->getCurrentFrame() >= 6) {
+ nextFrame = 6;
+ _carMoveMode = 0;
+ }
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _carFrame = nextFrame;
+ }
+ }
+ }
+
+ if (_game._player._moving && (_game._difficulty == DIFFICULTY_HARD) && _dogActiveFl && (_scene->_rails.getNext() > 0)) {
+ _game._player.cancelCommand();
+ _game._player.startWalking(Common::Point(194, 142), FACING_EAST);
+ _scene->_rails.resetNext();
+ if (_dogUnderCar)
+ _dogSafeFl = true;
+ }
+
+ if (_game._player._special > 0 && (_game._difficulty == DIFFICULTY_HARD) && _dogActiveFl && _game._player._stepEnabled)
+ _game._player._stepEnabled = false;
+
+ if ((_game._difficulty == DIFFICULTY_HARD) && _dogActiveFl && (_game._player._playerPos == Common::Point(194, 142))
+ && (_game._trigger || !_rexBeingEaten)) {
+ _rexBeingEaten = true;
+ switch (_game._trigger) {
+ case 0:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _animationMode = 1;
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 1, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ _scene->_sequences.addTimer(10, 85);
+ break;
+
+ case 80:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 3, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], -1);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2FC));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ break;
+
+ case 81: {
+ int syncIdx = _globals._sequenceIndexes[9];
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], false, 5, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 6, 38);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], syncIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 82);
+ }
+ break;
+
+ case 82: {
+ int syncIdx = _globals._sequenceIndexes[9];
+ _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], false, 15, 5, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 39, 40);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], syncIdx);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 83);
+ }
+ break;
+
+ case 83: {
+ _animationMode = 2;
+ int syncIdx = _globals._sequenceIndexes[9];
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], syncIdx);
+ _scene->_sequences.addTimer(60, 84);
+ }
+ break;
+
+ case 84:
+ _rexBeingEaten = false;
+ _animationMode = 0;
+ _scene->_reloadSceneFlag = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ case 85:
+ if (_rexBeingEaten && (_animationMode == 1)) {
+ _vm->_sound->command(12);
+ _scene->_sequences.addTimer(10, 85);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene608::preActions() {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+
+ if ((_action.isAction(VERB_THROW, NOUN_BONE, NOUN_REAR_OF_GARAGE) || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_REAR_OF_GARAGE)
+ || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_FRONT_OF_GARAGE) || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_FRONT_OF_GARAGE)
+ || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_OBNOXIOUS_DOG) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_OBNOXIOUS_DOG)) && _dogActiveFl) {
+ _game._player._stepEnabled = false;
+ _game._player.walk(Common::Point(56, 146), FACING_EAST);
+ }
+
+ if ((_action.isAction(VERB_THROW, NOUN_BONES, NOUN_AREA_BEHIND_CAR) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_AREA_BEHIND_CAR)
+ || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_DANGER_ZONE) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_DANGER_ZONE)) && _dogActiveFl) {
+ _game._player._stepEnabled = false;
+ _game._player.walk(Common::Point(75, 136), FACING_EAST);
+ }
+
+ if (_action.isAction(VERB_PUSH, NOUN_DOWN_BUTTON) && _dogUnderCar) {
+ _buttonPressedonTimeFl = true;
+ _dogDeathMode = 1;
+ } else
+ _buttonPressedonTimeFl = false;
+}
+
+void Scene608::actions() {
+ if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOORWAY))
+ _scene->_nextSceneId = 607;
+ else if (_action.isAction(VERB_PUSH, NOUN_DOWN_BUTTON)) {
+ _game._player._stepEnabled = true;
+ switch (_game._trigger) {
+ case 0:
+ if ((_globals[kCarStatus] == 0) || (_globals[kCarStatus] == 1) || (_globals[kCarStatus] == 2)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ } else
+ _vm->_dialogs->show(60839);
+ break;
+
+ case 1:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._visible = true;
+ if (_dogDeathMode == 0)
+ _carMode = 0;
+ else if (_dogDeathMode == 1) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x300));
+ _globals[kCarStatus] = 1;
+ _carMode = 2;
+ _globals[kDogStatus] = 4;
+ _dogActiveFl = false;
+ _dogUnderCar = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[10]);
+ _scene->freeAnimation();
+ _scene->loadAnimation(formAnimName('C', -1));
+ } else {
+ _resetPositionsFl = false;
+ _carMode = 1;
+ _scene->freeAnimation();
+ _scene->loadAnimation(formAnimName('B', -1));
+ }
+
+ _carMoveMode = 2;
+ _scene->_sequences.addTimer(1, 2);
+ break;
+
+ case 2:
+ if (_carMoveMode != 0)
+ _scene->_sequences.addTimer(1, 2);
+ else {
+ _scene->_dynamicHotspots.remove(_carHotspotId);
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(100, 100, 100 + 82, 100 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ if (_globals[kCarStatus] == 1)
+ _scene->_sequences.addTimer(120, 3);
+ else {
+ if (_dogDeathMode == 0)
+ _globals[kCarStatus] = 3;
+ else {
+ _globals[kCarStatus] = 4;
+ _carMode = 3;
+ _dogDeathMode = 2;
+ }
+ _game._player._stepEnabled = true;
+ }
+ }
+ break;
+
+ case 3:
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x302));
+ _globals[kCarStatus] = 4;
+ _carMode = 3;
+ _dogDeathMode = 2;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PUSH, NOUN_UP_BUTTON)) {
+ switch (_game._trigger) {
+ case 0:
+ if ((_globals[kCarStatus] == 3) || (_globals[kCarStatus] == 4)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 3);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ } else
+ _vm->_dialogs->show(60840);
+ break;
+
+ case 1:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._visible = true;
+ if (_dogDeathMode == 0)
+ _carMode = 0;
+ else {
+ _carMode = 3;
+ _resetPositionsFl = false;
+ _scene->freeAnimation();
+ _scene->loadAnimation(formAnimName('D', -1));
+ }
+ _carMoveMode = 1;
+ _scene->_sequences.addTimer(1, 2);
+ break;
+
+ case 2: {
+ if (_carMoveMode != 0)
+ _scene->_sequences.addTimer(1, 2);
+ else if (_dogDeathMode == 0)
+ _globals[kCarStatus] = 0;
+ else if (_dogDeathMode == 2) {
+ _globals[kCarStatus] = 2;
+ _carMode = 3;
+ _dogDeathMode = 2;
+ }
+ _scene->_dynamicHotspots.remove(_carHotspotId);
+ int idx = _scene->_dynamicHotspots.add(NOUN_CAR, VERB_WALKTO, -1, Common::Rect(99, 69, 99 + 82, 69 + 25));
+ _carHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(96, 132), FACING_NORTHEAST);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_THROW, NOUN_BONE, NOUN_REAR_OF_GARAGE) || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_REAR_OF_GARAGE)
+ || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_OBNOXIOUS_DOG) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_OBNOXIOUS_DOG)) {
+ _game._player._stepEnabled = true;
+ if (_dogActiveFl) {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2FE));
+ }
+ _throwMode = 4;
+ handleThrowingBone();
+ } else
+ _vm->_dialogs->show(60841);
+ } else if (_action.isAction(VERB_THROW, NOUN_BONE, NOUN_FRONT_OF_GARAGE) || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_FRONT_OF_GARAGE)) {
+ _game._player._stepEnabled = true;
+ if (_dogActiveFl) {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2FD));
+ }
+ _throwMode = 5;
+ handleThrowingBone();
+ } else
+ _vm->_dialogs->show(60841);
+ } else if (_action.isAction(VERB_THROW, NOUN_BONES, NOUN_AREA_BEHIND_CAR) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_AREA_BEHIND_CAR)
+ || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_DANGER_ZONE) || _action.isAction(VERB_THROW, NOUN_BONE, NOUN_DANGER_ZONE)) {
+ _game._player._stepEnabled = true;
+ if ((_globals[kCarStatus] == 0) && _dogActiveFl) {
+ if (_dogActiveFl) {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x301));
+ }
+ _throwMode = 6;
+ handleThrowingBone();
+ } else
+ _vm->_dialogs->show(60841);
+ } else
+ _vm->_dialogs->show(60842);
+ } else if (_action.isAction(VERB_TAKE, NOUN_POLYCEMENT) && (_game._trigger || !_game._objects.isInInventory(OBJ_POLYCEMENT))) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_polycementHotspotId);
+ break;
+
+ case 2:
+ _game._objects.addToInventory(OBJ_POLYCEMENT);
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->showItem(OBJ_POLYCEMENT, 60833);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_REARVIEW_MIRROR) && (_game._trigger || !_game._objects.isInInventory(OBJ_REARVIEW_MIRROR))) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[12]);
+ _game._objects.addToInventory(OBJ_REARVIEW_MIRROR);
+ _vm->_dialogs->showItem(OBJ_REARVIEW_MIRROR, 60827);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag) {
+ if (_game._difficulty != DIFFICULTY_HARD)
+ _vm->_dialogs->show(60810);
+ else if (_globals[kDogStatus] == 4)
+ _vm->_dialogs->show(60812);
+ else
+ _vm->_dialogs->show(60811);
+ } else if (_action.isAction(VERB_LOOK) && (_action.isObject(NOUN_MUFFLER) || _action.isObject(NOUN_CAR_SEAT) || _action.isObject(NOUN_HUBCAP)
+ || _action.isObject(NOUN_COILS) || _action.isObject(NOUN_QUARTER_PANEL)))
+ _vm->_dialogs->show(60813);
+ else if (_action.isAction(VERB_TAKE) && (_action.isObject(NOUN_MUFFLER) || _action.isObject(NOUN_CAR_SEAT) || _action.isObject(NOUN_HUBCAP)
+ || _action.isObject(NOUN_COILS) || _action.isObject(NOUN_QUARTER_PANEL)))
+ _vm->_dialogs->show(60814);
+ else if (_action.isAction(VERB_LOOK, NOUN_GARAGE_FLOOR) || _action.isAction(VERB_LOOK, NOUN_FRONT_OF_GARAGE) || _action.isAction(VERB_LOOK, NOUN_REAR_OF_GARAGE)) {
+ if (_dogActiveFl)
+ _vm->_dialogs->show(60815);
+ else
+ _vm->_dialogs->show(60816);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SPARE_RIBS))
+ _vm->_dialogs->show(60817);
+ else if (_action.isAction(VERB_TAKE, NOUN_SPARE_RIBS)) {
+ if (_game._difficulty == DIFFICULTY_HARD)
+ _vm->_dialogs->show(60818);
+ else
+ _vm->_dialogs->show(60819);
+ } else if (_action.isAction(VERB_LOOK, NOUN_UP_BUTTON))
+ _vm->_dialogs->show(60820);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOWN_BUTTON))
+ _vm->_dialogs->show(60821);
+ else if (_action.isAction(VERB_LOOK, NOUN_TRASH_CAN))
+ _vm->_dialogs->show(60822);
+ else if (_action.isAction(VERB_LOOK, NOUN_CALENDAR))
+ _vm->_dialogs->show(60823);
+ else if (_action.isAction(VERB_LOOK, NOUN_STORAGE_BOX)) {
+ if (_game._objects[OBJ_REARVIEW_MIRROR]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(60825);
+ else
+ _vm->_dialogs->show(60824);
+ } else if (_action.isAction(VERB_OPEN, NOUN_STORAGE_BOX))
+ _vm->_dialogs->show(60826);
+ else if (_action.isAction(VERB_LOOK, NOUN_REARVIEW_MIRROR) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(60828);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOOL_BOX)) {
+ if (_game._objects[OBJ_POLYCEMENT]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(60829);
+ else
+ _vm->_dialogs->show(60830);
+ } else if (_action.isAction(VERB_OPEN, NOUN_TOOL_BOX))
+ _vm->_dialogs->show(60831);
+ else if ((_action.isAction(VERB_LOOK, NOUN_POLYCEMENT)) && (_game._objects.isInRoom(OBJ_POLYCEMENT)))
+ _vm->_dialogs->show(60832);
+ else if (_action.isAction(VERB_LOOK, NOUN_GREASE_CAN) || _action.isAction(VERB_LOOK, NOUN_OIL_CAN))
+ _vm->_dialogs->show(60834);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR_LIFT))
+ _vm->_dialogs->show(60835);
+ else if (_action.isAction(VERB_LOOK, NOUN_CHAIR) || _action.isAction(VERB_LOOK, NOUN_HAT))
+ _vm->_dialogs->show(60836);
+ else if (_action.isAction(VERB_LOOK, NOUN_DANGER_ZONE))
+ _vm->_dialogs->show(60838);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene609::Scene609(MADSEngine *vm) : Scene6xx(vm) {
+ _videoDoorMode = -1;
+}
+
+void Scene609::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_videoDoorMode);
+}
+
+void Scene609::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene609::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('h', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCD_9");
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXMRC_9");
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _globals[kBeenInVideoStore] = false;
+
+ if (_scene->_priorSceneId == 611) {
+ _game._player._playerPos = Common::Point(264, 69);
+ _game._player._facing = FACING_SOUTHWEST;
+ } else if (_scene->_priorSceneId == 610) {
+ _game._player._playerPos = Common::Point(23, 90);
+ _game._player._facing = FACING_EAST;
+ _scene->_sequences.addTimer(60, 60);
+ _game._player._stepEnabled = false;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(86, 136);
+ _game._player._facing = FACING_NORTHEAST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ }
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_DOOR_KEY);
+ if (_game._difficulty != DIFFICULTY_EASY)
+ _game._objects.addToInventory(OBJ_PENLIGHT);
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x305, 0x306, 0x307, 0x308, 0x309, 0);
+}
+
+void Scene609::step() {
+ switch (_game._trigger) {
+ case 60:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 61);
+ break;
+
+ case 61:
+ _scene->_hotspots.activate(NOUN_VIDEO_STORE_DOOR, false);
+ _game._player.walk(Common::Point(101, 100), FACING_EAST);
+ _scene->_sequences.addTimer(180, 62);
+ break;
+
+ case 62:
+ _scene->_sequences.remove( _globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_hotspots.activate(NOUN_VIDEO_STORE_DOOR, true);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 63);
+ break;
+
+ case 63:
+ if (!_globals[kHasTalkedToHermit] && (_game._difficulty != DIFFICULTY_HARD)) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(287, 73));
+ _scene->_sequences.setScale(_globals._sequenceIndexes[3], 47);
+ }
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(6, 71);
+ break;
+
+ case 71:
+ if (!_globals[kHasTalkedToHermit]) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(287, 73));
+ _scene->_sequences.setScale(_globals._sequenceIndexes[3], 47);
+ }
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene609::enterStore() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ if (_videoDoorMode == 2)
+ _scene->_sequences.addTimer(1, 4);
+ else {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x305));
+ _scene->_sequences.addTimer(120, 1);
+ }
+ break;
+
+ case 1:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x306));
+ _scene->_sequences.addTimer(60, 2);
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 11, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[5]);
+ _game._player._visible = true;
+ _game._objects.setRoom(OBJ_DOOR_KEY, 1);
+ _scene->_sequences.addTimer(15, 4);
+ break;
+
+ case 4:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], true, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addTimer(15, 5);
+ break;
+
+ case 5:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 6);
+ break;
+
+ case 6:
+ _scene->_hotspots.activate(NOUN_VIDEO_STORE_DOOR, false);
+ if (_videoDoorMode == 1) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 180, _game.getQuote(0x307));
+ }
+ _game._player.walk(Common::Point(23, 90), FACING_WEST);
+ _scene->_sequences.addTimer(180, 7);
+ break;
+
+ case 7:
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 8);
+ break;
+
+ case 8:
+ _scene->_hotspots.activate(NOUN_VIDEO_STORE_DOOR, true);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ _globals[kBeenInVideoStore] = true;
+ _game._player._stepEnabled = true;
+ _scene->_nextSceneId = 610;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene609::preActions() {
+ if (_action.isAction(VERB_UNLOCK, NOUN_DOOR_KEY, NOUN_VIDEO_STORE_DOOR))
+ _game._player.walk(Common::Point(78, 99), FACING_NORTHWEST);
+}
+
+void Scene609::actions() {
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_ALLEY))
+ _scene->_nextSceneId = 611;
+ else if (_action.isAction(VERB_WALK_THROUGH, NOUN_VIDEO_STORE_DOOR)) {
+ if (!_globals[kBeenInVideoStore]) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x308));
+ _scene->_sequences.addTimer(120, 1);
+ break;
+
+ case 1:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], true, 1);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addTimer(30, 2);
+ break;
+
+ case 2:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(60, 3);
+ break;
+
+ case 3:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x309));
+ _scene->_sequences.addTimer(120, 4);
+ break;
+
+ case 4:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ _videoDoorMode = 2;
+ enterStore();
+ }
+ } else if (_action.isAction(VERB_UNLOCK, NOUN_DOOR_KEY, NOUN_VIDEO_STORE_DOOR)) {
+ _videoDoorMode = 1;
+ enterStore();
+ } else if (_action.isAction(VERB_GET_INSIDE, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(60910);
+ else if (_action.isAction(VERB_LOOK, NOUN_STREET))
+ _vm->_dialogs->show(60911);
+ else if (_action.isAction(VERB_LOOK, NOUN_SPOT_A_POT))
+ _vm->_dialogs->show(60912);
+ else if (_action.isAction(VERB_LOOK, NOUN_VIDEO_STORE))
+ _vm->_dialogs->show(60913);
+ else if (_action.isAction(VERB_LOOK, NOUN_BILLBOARD))
+ _vm->_dialogs->show(60914);
+ else if (_action.isAction(VERB_LOOK, NOUN_STATUE))
+ _vm->_dialogs->show(60915);
+ else if (_action.isAction(VERB_LOOK, NOUN_CAR))
+ _vm->_dialogs->show(60916);
+ else if (_action.isAction(VERB_LOOK, NOUN_NEWSSTAND))
+ _vm->_dialogs->show(60917);
+ else if (_action.isAction(VERB_LOOK, NOUN_VIDEO_STORE_DOOR)) {
+ if (!_globals[kBeenInVideoStore])
+ _vm->_dialogs->show(60918);
+ else
+ _vm->_dialogs->show(60919);
+ } else if (_action.isAction(VERB_WALK_DOWN, NOUN_STREET))
+ _vm->_dialogs->show(60730);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene610::Scene610(MADSEngine *vm) : Scene6xx(vm) {
+ _handsetHotspotId = -1;
+ _checkVal = -1;
+
+ _cellCharging = false;
+
+ _cellChargingTimer = -1;
+ _lastFrameTimer = 0;
+}
+
+void Scene610::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_handsetHotspotId);
+ s.syncAsSint16LE(_checkVal);
+
+ s.syncAsByte(_cellCharging);
+
+ s.syncAsSint32LE(_cellChargingTimer);
+ s.syncAsUint32LE(_lastFrameTimer);
+}
+
+void Scene610::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_PHONE_HANDSET);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene610::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('p', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMRC_9");
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 1));
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 60, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 13);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 30, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9);
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _cellCharging = false;
+
+ if (_game._objects[OBJ_PHONE_HANDSET]._roomNumber == _scene->_currentSceneId) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+ _handsetHotspotId = _scene->_dynamicHotspots.add(NOUN_PHONE_HANDSET, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_handsetHotspotId, Common::Point(132, 121), FACING_NORTHWEST);
+ if ((_globals[kHandsetCellStatus] == 2) && (_game._difficulty == DIFFICULTY_HARD) && !_globals[kDurafailRecharged])
+ _globals[kHandsetCellStatus] = 1;
+ }
+
+ if (_scene->_roomChanged && _game._difficulty != DIFFICULTY_EASY)
+ _game._objects.addToInventory(OBJ_PENLIGHT);
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(175, 152);
+ _game._player._facing = FACING_NORTHWEST;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene610::step() {
+ if (_cellCharging) {
+ long diff = _scene->_frameStartTime - _lastFrameTimer;
+ if ((diff >= 0) && (diff <= 60))
+ _cellChargingTimer += diff;
+ else
+ _cellChargingTimer++;
+
+ _lastFrameTimer = _scene->_frameStartTime;
+ }
+
+ // CHECKME: _checkVal is always false, could be removed
+ if ((_cellChargingTimer >= 60) && !_checkVal) {
+ _checkVal = true;
+ _globals[kHandsetCellStatus] = 1;
+ _cellCharging = false;
+ _checkVal = false;
+ _cellChargingTimer = 0;
+ }
+}
+
+void Scene610::actions() {
+ if (_action.isAction(VERB_EXIT_FROM, NOUN_VIDEO_STORE))
+ _scene->_nextSceneId = 609;
+ else if (_action.isAction(VERB_TAKE, NOUN_PHONE_HANDSET)) {
+ if ( _game._trigger || !_game._objects.isInInventory(OBJ_PHONE_HANDSET)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_handsetHotspotId);
+ _game._objects.addToInventory(OBJ_PHONE_HANDSET);
+ _vm->_dialogs->showItem(OBJ_PHONE_HANDSET, 61017);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_PHONE_HANDSET, NOUN_PHONE_CRADLE)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 0, 0, 0);
+ _handsetHotspotId = _scene->_dynamicHotspots.add(NOUN_PHONE_HANDSET, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(_handsetHotspotId, Common::Point(132, 121), FACING_NORTHWEST);
+ _game._objects.setRoom(OBJ_PHONE_HANDSET, _scene->_currentSceneId);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ if ((_globals[kHandsetCellStatus] == 2) && (_game._difficulty == DIFFICULTY_HARD) && !_globals[kDurafailRecharged])
+ _cellCharging = true;
+
+ _vm->_dialogs->show(61032);
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_LOOK, NOUN_PIPPY_BILLBOARD))
+ _vm->_dialogs->show(61010);
+ else if (_action.isAction(VERB_LOOK, NOUN_CIVILIZATION_AD))
+ _vm->_dialogs->show(61011);
+ else if (_action.isAction(VERB_LOOK, NOUN_MARX_BROS_POSTER))
+ _vm->_dialogs->show(61012);
+ else if (_action.isAction(VERB_LOOK, NOUN_VIDEO_MONITOR))
+ _vm->_dialogs->show(61013);
+ else if (_action.isAction(VERB_LOOK, NOUN_VIDEO_STORE))
+ _vm->_dialogs->show(61014);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(61015);
+ else if (_action.isAction(VERB_LOOK, NOUN_LOGO))
+ _vm->_dialogs->show(61018);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEMENT)) {
+ if (_game._visitedScenes.exists(601))
+ _vm->_dialogs->show(61020);
+ else
+ _vm->_dialogs->show(61019);
+ } else if (_action.isAction(VERB_LOOK, NOUN_COUNTER))
+ _vm->_dialogs->show(61021);
+ else if (_action.isAction(VERB_LOOK, NOUN_PHONE_ANTENNA))
+ _vm->_dialogs->show(61022);
+ else if (_action.isAction(VERB_LOOK, NOUN_SMELLY_SNEAKER))
+ _vm->_dialogs->show(61023);
+ else if (_action.isAction(VERB_TAKE, NOUN_SMELLY_SNEAKER))
+ _vm->_dialogs->show(61024);
+ else if (_action.isAction(VERB_LOOK, NOUN_SPOTLIGHT))
+ _vm->_dialogs->show(61025);
+ else if (_action.isAction(VERB_LOOK, NOUN_PHONE_HANDSET) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(61026);
+ else if (_action.isAction(VERB_LOOK, NOUN_PHONE_CRADLE))
+ _vm->_dialogs->show(61027);
+ else if (_action.isAction(VERB_LOOK, NOUN_RETURN_SLOT))
+ _vm->_dialogs->show(61028);
+ else if (_action.isAction(VERB_PUT, NOUN_RETURN_SLOT)
+ && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId)))
+ _vm->_dialogs->show(61029);
+ else if ( _action.isObject(NOUN_CLASSIC_VIDEOS) || _action.isObject(NOUN_MORE_CLASSIC_VIDEOS) || _action.isObject(NOUN_DRAMA_VIDEOS)
+ || _action.isObject(NOUN_NEW_RELEASE_VIDEOS) || _action.isObject(NOUN_PORNO_VIDEOS) || _action.isObject(NOUN_EDUCATIONAL_VIDEOS)
+ || _action.isObject(NOUN_INSTRUCTIONAL_VIDEOS) || _action.isObject(NOUN_WORKOUT_VIDEOS) || _action.isObject(NOUN_FOREIGN_VIDEOS)
+ || _action.isObject(NOUN_ADVENTURE_VIDEOS) || _action.isObject(NOUN_COMEDY_VIDEOS)) {
+ if (_action.isAction(VERB_LOOK))
+ _vm->_dialogs->show(61030);
+ else if (_action.isAction(VERB_TAKE))
+ _vm->_dialogs->show(61031);
+ else
+ return;
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene611::Scene611(MADSEngine *vm) : Scene6xx(vm), _defaultDialogPos(0, 0) {
+ _seenRatFl = false;
+ _eyesRunningFl = false;
+ _shouldRemoveEyes = false;
+ _ratPresentFl = false;
+ _duringDialogFl = false;
+ _resetBatterieText = false;
+ _hermitTalkingFl = false;
+ _hermitMovingFl = false;
+ _alreadyTalkingFl = false;
+ _giveBatteriesFl = false;
+ _startTradingFl = false;
+ _check1Fl = false;
+ _stickFingerFl = false;
+
+ _randVal = -1;
+ _ratHotspotId = -1;
+ _hermitDialogNode = -1;
+ _hermitDisplayedQuestion = -1;
+ _nextFrame = -1;
+ _hermitMode = -1;
+
+ _ratTimer = 0;
+}
+
+void Scene611::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsByte(_seenRatFl);
+ s.syncAsByte(_eyesRunningFl);
+ s.syncAsByte(_shouldRemoveEyes);
+ s.syncAsByte(_ratPresentFl);
+ s.syncAsByte(_duringDialogFl);
+ s.syncAsByte(_resetBatterieText);
+ s.syncAsByte(_hermitTalkingFl);
+ s.syncAsByte(_hermitMovingFl);
+ s.syncAsByte(_alreadyTalkingFl);
+ s.syncAsByte(_giveBatteriesFl);
+ s.syncAsByte(_startTradingFl);
+ s.syncAsByte(_check1Fl);
+ s.syncAsByte(_stickFingerFl);
+
+ s.syncAsSint16LE(_randVal);
+ s.syncAsSint16LE(_ratHotspotId);
+ s.syncAsSint16LE(_hermitDialogNode);
+ s.syncAsSint16LE(_hermitDisplayedQuestion);
+ s.syncAsSint16LE(_nextFrame);
+ s.syncAsSint16LE(_hermitMode);
+
+ s.syncAsUint32LE(_ratTimer);
+
+ s.syncAsSint16LE(_defaultDialogPos.x);
+ s.syncAsSint16LE(_defaultDialogPos.y);
+}
+
+void Scene611::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_RAT);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene611::handleRatMoves() {
+ _ratPresentFl = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 11, -2);
+ _ratTimer = _game._player._priorTimer;
+ _scene->_dynamicHotspots.remove(_ratHotspotId);
+}
+
+void Scene611::handleTrading() {
+ if (_game._objects.isInInventory(OBJ_DURAFAIL_CELLS))
+ _game._objects.setRoom(OBJ_DURAFAIL_CELLS, 1);
+
+ if (_game._objects.isInInventory(OBJ_PHONE_CELLS))
+ _game._objects.setRoom(OBJ_PHONE_CELLS, 1);
+
+ _game._objects.addToInventory(OBJ_FAKE_ID);
+}
+
+void Scene611::setDialogNode(int node) {
+ if (node > 0)
+ _hermitDialogNode = node;
+
+ _game._player._stepEnabled = true;
+
+ switch (node) {
+ case 0:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _duringDialogFl = false;
+ _hermitDialogNode = 0;
+ break;
+
+ case 1:
+ _dialog1.start();
+ _duringDialogFl = true;
+ _hermitDialogNode = 1;
+ break;
+
+ case 2:
+ _dialog2.start();
+ _duringDialogFl = true;
+ _hermitDialogNode = 2;
+ break;
+
+ default:
+ break;
+ }
+}
+
+bool Scene611::check2ChargedBatteries() {
+ if ((_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && !_game._objects.isInInventory(OBJ_PHONE_CELLS))
+ || (!_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS)))
+ return true;
+
+ return false;
+}
+
+bool Scene611::check4ChargedBatteries() {
+ if (_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS) && _globals[136])
+ return true;
+
+ return false;
+}
+
+void Scene611::handleTalking(int delay) {
+ if (_hermitTalkingFl)
+ _alreadyTalkingFl = true;
+
+ _hermitTalkingFl = true;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(delay, 100);
+}
+
+void Scene611::handleSubDialog1() {
+ switch (_action._activeAction._verbId) {
+ case 0x287:
+ _stickFingerFl = true;
+ _nextFrame = 34;
+ _hermitMovingFl = false;
+ _hermitMode = 5;
+ displayHermitQuestions(5);
+ _dialog1.write(0x287, false);
+ if (!_dialog1.read(0x288))
+ _dialog1.write(0x28E, true);
+
+ _dialog2.write(0x29C, true);
+ _dialog2.write(0x29D, true);
+ _dialog2.write(0x29E, true);
+ setDialogNode(2);
+ break;
+
+ case 0x288:
+ handleTalking(500);
+ displayHermitQuestions(6);
+ _dialog1.write(0x288, false);
+ _dialog1.write(0x289, true);
+ if (!_dialog1.read(0x287))
+ _dialog1.write(0x28E, true);
+
+ setDialogNode(1);
+ break;
+
+ case 0x289:
+ handleTalking(500);
+ displayHermitQuestions(10);
+ _dialog1.write(0x289, false);
+ _dialog1.write(0x28A, true);
+ _dialog1.write(0x28B, true);
+ setDialogNode(1);
+ break;
+
+ case 0x28A:
+ handleTalking(500);
+ displayHermitQuestions(11);
+ _dialog1.write(0x28A, false);
+ setDialogNode(1);
+ break;
+
+ case 0x28B:
+ handleTalking(500);
+ displayHermitQuestions(12);
+ _dialog1.write(0x28C, true);
+ _dialog1.write(0x28D, true);
+ _dialog1.write(0x28B, false);
+ setDialogNode(1);
+ break;
+
+ case 0x28C:
+ handleTalking(500);
+ displayHermitQuestions(13);
+ _dialog1.write(0x28C, false);
+ setDialogNode(1);
+ break;
+
+ case 0x28D:
+ handleTalking(500);
+ displayHermitQuestions(14);
+ _dialog1.write(0x290, true);
+ _dialog1.write(0x28D, false);
+ _dialog1.write(0x28F, true);
+ setDialogNode(1);
+ break;
+
+ case 0x28E:
+ handleTalking(500);
+ displayHermitQuestions(15);
+ _dialog1.write(0x295, true);
+ _dialog1.write(0x28E, false);
+ setDialogNode(1);
+ break;
+
+ case 0x290:
+ handleTalking(500);
+ displayHermitQuestions(17);
+ _dialog1.write(0x290, false);
+ _dialog1.write(0x28E, false);
+ if (!_dialog1.read(0x28F))
+ _dialog1.write(0x291, true);
+
+ setDialogNode(1);
+ break;
+
+ case 0x291:
+ handleTalking(500);
+ displayHermitQuestions(18);
+ _dialog1.write(0x291, false);
+ if ((!_game._objects.isInInventory(OBJ_DURAFAIL_CELLS)) && (!_game._objects.isInInventory(OBJ_PHONE_CELLS))) {
+ _dialog1.write(0x292, true);
+ _dialog1.write(0x293, true);
+ }
+
+ if ((_game._objects.isInInventory(OBJ_DURAFAIL_CELLS)) || (_game._objects.isInInventory(OBJ_PHONE_CELLS)))
+ _dialog1.write(0x294, true);
+
+ if (!_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && !_game._objects.isInInventory(OBJ_PHONE_CELLS))
+ _globals[kExecuted_1_11] = true;
+
+ setDialogNode(1);
+ break;
+
+ case 0x28F:
+ handleTalking(500);
+ displayHermitQuestions(16);
+ _dialog1.write(0x28F, false);
+ if (!_dialog1.read(0x290))
+ _dialog1.write(0x291, true);
+
+ setDialogNode(1);
+ break;
+
+ case 0x295:
+ handleTalking(500);
+ displayHermitQuestions(20);
+ _dialog1.write(0x295, false);
+ setDialogNode(1);
+ break;
+
+ case 0x292:
+ handleTalking(500);
+ displayHermitQuestions(19);
+ _dialog1.write(0x292, false);
+ _dialog1.write(0x293, false);
+ setDialogNode(1);
+ break;
+
+ case 0x293: {
+ handleTalking(200);
+ _scene->_kernelMessages.reset();
+
+ Common::String curQuote = _game.getQuote(0x2D1);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y), 0xFDFC, 0, 0, 120, curQuote);
+
+ curQuote = _game.getQuote(0x2D2);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 120, curQuote);
+
+ _dialog1.write(0x293, false);
+ setDialogNode(0);
+ }
+ break;
+
+ case 0x294: {
+ bool hermitPleasedFl = false;
+
+ switch (_game._difficulty) {
+ case DIFFICULTY_EASY:
+ hermitPleasedFl = _game._objects.isInInventory(OBJ_DURAFAIL_CELLS) || _game._objects.isInInventory(OBJ_PHONE_CELLS);
+ break;
+
+ case DIFFICULTY_MEDIUM:
+ hermitPleasedFl = _game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS);
+ break;
+
+ default: // HARD
+ hermitPleasedFl = check4ChargedBatteries();
+ break;
+ }
+
+ if (hermitPleasedFl) {
+ _hermitDisplayedQuestion = 21;
+ if (!_giveBatteriesFl)
+ setDialogNode(0);
+ else
+ _giveBatteriesFl = false;
+ } else if (((_game._difficulty == DIFFICULTY_MEDIUM) || (_game._difficulty == DIFFICULTY_HARD)) && check2ChargedBatteries()) {
+ _hermitDisplayedQuestion = 22;
+ if (!_giveBatteriesFl)
+ setDialogNode(0);
+ else
+ _giveBatteriesFl = false;
+ } else {
+ _hermitDisplayedQuestion = 23;
+ if (!_giveBatteriesFl)
+ setDialogNode(0);
+ else
+ _giveBatteriesFl = false;
+ }
+ _startTradingFl = true;
+ }
+ break;
+
+ case 0x296: {
+ _scene->_kernelMessages.reset();
+
+ Common::String curQuote = _game.getQuote(0x2E6);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 120, curQuote);
+
+ setDialogNode(0);
+ handleTalking(200);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene611::handleSubDialog2() {
+ switch (_action._activeAction._verbId) {
+ case 0x29C:
+ displayHermitQuestions(7);
+ setDialogNode(1);
+ handleTalking(500);
+ break;
+
+ case 0x29D:
+ displayHermitQuestions(8);
+ setDialogNode(1);
+ handleTalking(500);
+ break;
+
+ case 0x29E:
+ displayHermitQuestions(9);
+ setDialogNode(1);
+ handleTalking(500);
+ break;
+
+ case 0x29F: {
+ _scene->_kernelMessages.reset();
+ Common::String curQuote = _game.getQuote(0x2A7);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 120, curQuote);
+ setDialogNode(0);
+ _dialog2.write(0x29F, false);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene611::handleDialog() {
+ if (_game._trigger == 0) {
+ _scene->_kernelMessages.reset();
+ _game._player._stepEnabled = false;
+
+ Common::String curQuote = _game.getQuote(_action._activeAction._verbId);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+
+ if (width > 200) {
+ Common::String subQuote1, subQuote2;
+ _game.splitQuote(curQuote, subQuote1, subQuote2);
+ _scene->_kernelMessages.add(Common::Point(0, -14), 0x1110, 34, 0, 150, subQuote1);
+
+ if (_action._activeAction._verbId == 0x29D)
+ _scene->_kernelMessages.add(Common::Point(-18, 0), 0x1110, 34, 1, 150, subQuote2);
+ else if (_action._activeAction._verbId == 0x28A)
+ _scene->_kernelMessages.add(Common::Point(-10, 0), 0x1110, 34, 1, 150, subQuote2);
+ else
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 1, 150, subQuote2);
+
+ _scene->_sequences.addTimer(170, 50);
+ } else {
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 1, 120, curQuote);
+ _scene->_sequences.addTimer(140, 50);
+ }
+ } else if (_game._trigger == 50) {
+ if (_hermitDialogNode == 1)
+ handleSubDialog1();
+ else if (_hermitDialogNode == 2)
+ handleSubDialog2();
+ }
+}
+
+void Scene611::displayHermitQuestions(int question) {
+ _scene->_kernelMessages.reset();
+ _hermitDisplayedQuestion = question;
+
+ switch (question) {
+ case 1: {
+ Common::String curQuote = _game.getQuote(0x281);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x282);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 2: {
+ Common::String curQuote = _game.getQuote(0x283);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x284);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 3: {
+ Common::String curQuote = _game.getQuote(0x285);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 4: {
+ Common::String curQuote = _game.getQuote(0x286);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 5: {
+ Common::String curQuote = _game.getQuote(0x297);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y - 14), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x298);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x299);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 6: {
+ Common::String curQuote = _game.getQuote(0x29A);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x29B);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 7: {
+ Common::String curQuote = _game.getQuote(0x2A0);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2A1);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 8: {
+ Common::String curQuote = _game.getQuote(0x2A2);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2A3);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2A4);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 9: {
+ Common::String curQuote = _game.getQuote(0x2A5);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2A6);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 10: {
+ Common::String curQuote = _game.getQuote(0x2A8);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2A9);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2AA);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 11: {
+ Common::String curQuote = _game.getQuote(0x2AB);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2AC);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2AD);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2AE);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 12: {
+ Common::String curQuote = _game.getQuote(0x2AF);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2B0);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2B1);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2B2);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 13: {
+ Common::String curQuote = _game.getQuote(0x2B3);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2B4);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2B5);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2B6);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ _scene->_kernelMessages.add(Common::Point(11, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x2B7));
+ _scene->_kernelMessages.add(Common::Point(11, _defaultDialogPos.y + 73), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x2B8));
+ _scene->_kernelMessages.add(Common::Point(11, _defaultDialogPos.y + 87), 0xFDFC, 0, 0, 9999999, _game.getQuote(0x2B9));
+ }
+ break;
+
+ case 14: {
+ Common::String curQuote = _game.getQuote(0x2BA);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2BB);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2BC);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2BD);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 15: {
+ Common::String curQuote = _game.getQuote(0x2BE);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2BF);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C0);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C1);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 16: {
+ Common::String curQuote = _game.getQuote(0x2C2);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C3);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C4);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C5);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C6);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 17: {
+ Common::String curQuote = _game.getQuote(0x2C7);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C8);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2C0);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2CA);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 18: {
+ Common::String curQuote = _game.getQuote(0x2CB);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2CC);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2CD);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 19: {
+ Common::String curQuote = _game.getQuote(0x2CE);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2CF);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2D0);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 20: {
+ Common::String curQuote = _game.getQuote(0x2E1);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2E2);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2E3);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2E4);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2E5);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 21: {
+ Common::String curQuote = _game.getQuote(0x2D3);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2D4);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2D5);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2D6);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote);
+
+ curQuote = _game.getQuote(0x2D7);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote);
+ }
+ break;
+
+ case 22: {
+ Common::String curQuote = _game.getQuote(0x2D8);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2D9);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2DA);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2DB);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 700, curQuote);
+ }
+ break;
+
+ case 23: {
+ Common::String curQuote = _game.getQuote(0x2DC);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2DD);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2DE);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2DF);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 700, curQuote);
+
+ curQuote = _game.getQuote(0x2E0);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 700, curQuote);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene611::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXMRC_9");
+
+ _game.loadQuoteSet(0x279, 0x27A, 0x27B, 0x27C, 0x27D, 0x27E, 0x27F, 0x280, 0x281, 0x282, 0x283, 0x284,
+ 0x285, 0x286, 0x287, 0x288, 0x289, 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290, 0x291, 0x292,
+ 0x293, 0x294, 0x295, 0x296, 0x297, 0x298, 0x299, 0x29A, 0x29B, 0x29C, 0x29D, 0x29E, 0x29F, 0x2A0,
+ 0x2A1, 0x2A2, 0x2A3, 0x2A4, 0x2A5, 0x2A6, 0x2A7, 0x2A8, 0x2A9, 0x2AA, 0x2AB, 0x2AC, 0x2AD, 0x2AE,
+ 0x2AF, 0x2B0, 0x2B1, 0x2B2, 0x2B3, 0x2B4, 0x2B5, 0x2B6, 0x2B7, 0x2B8, 0x2B9, 0x2BA, 0x2BB, 0x2BC,
+ 0x2BD, 0x2BE, 0x2BF, 0x2C0, 0x2C1, 0x2C2, 0x2C3, 0x2C4, 0x2C5, 0x2C6, 0x2C7, 0x2C8, 0x2C9, 0x2CA,
+ 0x2CB, 0x2CC, 0x2CD, 0x2CE, 0x2CF, 0x2D0, 0x2D1, 0x2D2, 0x2D3, 0x2D4, 0x2D5, 0x2D6, 0x2D7, 0x2D8,
+ 0x2D9, 0x2DA, 0x2DB, 0x2DC, 0x2DD, 0x2DE, 0x2DF, 0x2E0, 0x2E1, 0x2E2, 0x2E3, 0x2E4, 0x2E5, 0x2E6,
+ 0x323, 0x324, 0);
+
+ _dialog1.setup(0x82, 0x287, 0x288, 0x289, 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290,
+ 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0);
+
+ _dialog2.setup(0x83, 0x29C, 0x29D, 0x29E, 0x29F, 0);
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ _dialog1.set(0x82, 0x287, 0x288, 0x296, 0);
+ _dialog2.set(0x83, 0x29F, 0);
+ }
+
+ _vm->_palette->setEntry(252, 51, 51, 47);
+ _vm->_palette->setEntry(253, 37, 37, 37);
+
+ _ratPresentFl = false;
+ _seenRatFl = true;
+ _eyesRunningFl = false;
+ _shouldRemoveEyes = false;
+ _randVal = 0;
+ _defaultDialogPos = Common::Point(264, 43);
+ _giveBatteriesFl = false;
+ _resetBatterieText = false;
+ _alreadyTalkingFl = false;
+ _startTradingFl = false;
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(22, 132);
+ _game._player._facing = FACING_EAST;
+ _duringDialogFl = false;
+ }
+
+ if (!_globals[kHasTalkedToHermit]) {
+ _scene->loadAnimation(Resources::formatName(611, 'h', -1, EXT_AA, ""), 0);
+ _scene->loadAnimation(Resources::formatName(203, 'a', -1, EXT_AA, ""), 81);
+ _nextFrame = 47;
+ _hermitMode = 1;
+ _hermitTalkingFl = false;
+ _hermitMovingFl = true;
+ _check1Fl = true;
+ _stickFingerFl = false;
+ } else {
+ _hermitMode = 0;
+ _scene->_hotspots.activate(NOUN_HERMIT, false);
+ }
+
+ // CHECKME: The last line of the block looks extremely useless
+ if (_globals[kExecuted_1_11]) {
+ _dialog1.write(0x294, true);
+ _dialog1.write(0x292, false);
+ _globals[kExecuted_1_11] = true;
+ }
+
+ if (_duringDialogFl) {
+ _game._player._playerPos = Common::Point(237, 129);
+ _game._player._facing = FACING_NORTHEAST;
+
+ switch (_hermitDialogNode) {
+ case 0:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _hermitDialogNode = 1;
+ break;
+
+ case 1:
+ _dialog1.start();
+ break;
+
+ case 2:
+ _dialog2.start();
+ break;
+
+ default:
+ break;
+ }
+ displayHermitQuestions(_hermitDisplayedQuestion);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene611::step() {
+ if (_seenRatFl && (_vm->getRandomNumber(1, 100) == 10)) {
+ _seenRatFl = false;
+ _scene->_sequences.addTimer(1, 80);
+ }
+
+ if (_game._trigger == 80) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _ratPresentFl = true;
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ } else if (_game._trigger == 81) {
+ int syncId = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 20, 0, 0, 0);
+ int idx = _scene->_dynamicHotspots.add(NOUN_RAT, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _ratHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(272, 154), FACING_SOUTHEAST);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 9, 10);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], syncId);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ _ratTimer = _game._player._priorTimer;
+ }
+
+ if (_ratPresentFl && ((_game._player._priorTimer - _ratTimer) > 1200))
+ handleRatMoves();
+
+ if (!_eyesRunningFl) {
+ _randVal = _vm->getRandomNumber(1, 30);
+ _eyesRunningFl = true;
+ _scene->_sequences.addTimer(1, 70);
+ }
+
+ if (_game._trigger == 70) {
+ switch (_randVal) {
+ case 2:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 6:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 12, 3, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 4);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 7:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 9:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 13:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 7);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 14:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 15:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 24, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 5, 8);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 17:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 20, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 9, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 21:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 9);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 25:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 10);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 27:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 11);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _shouldRemoveEyes = true;
+ _scene->_sequences.addTimer(60, 71);
+ break;
+
+ case 29:
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 20, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ default:
+ _scene->_sequences.addTimer(1, 71);
+ break;
+ }
+ }
+
+ if (_game._trigger == 71) {
+ if (_shouldRemoveEyes) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _shouldRemoveEyes = false;
+ }
+ _eyesRunningFl = false;
+ _randVal = 0;
+ }
+
+ if (_game._trigger == 100) {
+ if (_alreadyTalkingFl)
+ _alreadyTalkingFl = false;
+ else
+ _hermitMovingFl = true;
+ }
+
+ if (_stickFingerFl && (_scene->_activeAnimation->getCurrentFrame() == 47)) {
+ _stickFingerFl = false;
+ _hermitMovingFl = true;
+ _hermitMode = 1;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 240) && _check1Fl) {
+ _check1Fl = false;
+ _scene->_kernelMessages.add(Common::Point(33, 88), 0xFDFC, 0, 0, 90, _game.getQuote(0x27E));
+ _scene->_sequences.addTimer(120, 120);
+ }
+
+ if (_game._trigger == 120) {
+ int msgIdx = _scene->_kernelMessages.add(Common::Point(28, 102), 0xFDFC, 0, 0, 90, _game.getQuote(0x27F));
+ _scene->_kernelMessages.setQuoted(msgIdx, 4, true);
+ _scene->_sequences.addTimer(100, 121);
+ }
+
+ if (_game._trigger == 121) {
+ int msgIdx = _scene->_kernelMessages.add(Common::Point(23, 116), 0xFDFC, 0, 0, 90, _game.getQuote(0x280));
+ _scene->_kernelMessages.setQuoted(msgIdx, 4, true);
+ }
+
+ if (_hermitMode == 1) {
+ if (_startTradingFl) {
+ _hermitMode = 6;
+ _hermitMovingFl = false;
+ _hermitTalkingFl = false;
+ _scene->_sequences.addTimer(1, 110);
+ } else if (_hermitTalkingFl) {
+ _hermitMode = 2;
+ _nextFrame = 18;
+ _hermitMovingFl = false;
+ } else {
+ switch (_vm->getRandomNumber(1, 5)) {
+ case 1:
+ _nextFrame = 46;
+ break;
+
+ case 2:
+ _nextFrame = 47;
+ break;
+
+ case 3:
+ _nextFrame = 48;
+ break;
+
+ case 4:
+ _nextFrame = 49;
+ break;
+
+ case 5:
+ _nextFrame = 50;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_hermitMode == 2) {
+ if (_startTradingFl) {
+ _hermitMode = 6;
+ _hermitMovingFl = false;
+ _hermitTalkingFl = false;
+ _scene->_sequences.addTimer(1, 110);
+ } else if (_hermitMovingFl) {
+ _hermitMode = 1;
+ _nextFrame = 47;
+ _hermitTalkingFl = false;
+ } else {
+ switch (_vm->getRandomNumber(1, 4)) {
+ case 1:
+ _nextFrame = 18;
+ break;
+
+ case 2:
+ _nextFrame = 20;
+ break;
+
+ case 3:
+ _nextFrame = 22;
+ break;
+
+ case 4:
+ _nextFrame = 24;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 254)
+ _game._player._stepEnabled = true;
+
+ if (_game._trigger == 110) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 111);
+ }
+
+ if (_game._trigger == 111) {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _nextFrame = 1;
+ }
+
+ if (_game._trigger == 112) {
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ }
+
+ if (_hermitMode == 6) {
+ if ((_scene->_activeAnimation->getCurrentFrame() == 9) && _check1Fl) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 112);
+ _check1Fl = false;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 17) && !_check1Fl) {
+ _nextFrame = 26;
+ _hermitMode = 4;
+ _check1Fl = true;
+ }
+ }
+
+ if (_hermitMode == 4) {
+ if ((_scene->_activeAnimation->getCurrentFrame() == 33) && _check1Fl) {
+ displayHermitQuestions(_hermitDisplayedQuestion);
+ _nextFrame = 1;
+ _check1Fl = false;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 9) && !_check1Fl) {
+ _nextFrame = 8;
+ _scene->_sequences.addTimer(1, 113);
+ _check1Fl = true;
+ }
+ }
+
+ if (_game._trigger == 113) {
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 114);
+ }
+
+ if (_game._trigger == 114) {
+ _resetBatterieText = true;
+ int syncIdx = _globals._sequenceIndexes[3];
+ _nextFrame = 10;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 115);
+ }
+
+ if ((_nextFrame >= 0) && (_nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(_nextFrame);
+ _nextFrame = -1;
+ }
+
+ if (_game._trigger == 115) {
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player._visible = true;
+ if (_hermitDisplayedQuestion == 21) {
+ _game._player._stepEnabled = false;
+ handleTrading();
+ _hermitMode = 0;
+ _startTradingFl = false;
+ _nextFrame = 52;
+ _globals[kHasTalkedToHermit] = true;
+ _scene->_hotspots.activate(NOUN_HERMIT, false);
+ } else {
+ _game._player._stepEnabled = true;
+ _hermitMode = 1;
+ _nextFrame = 47;
+ _hermitTalkingFl = false;
+ _startTradingFl = false;
+ _check1Fl = true;
+ }
+ }
+}
+
+void Scene611::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_ALLEY))
+ _game._player._walkOffScreenSceneId = 609;
+
+ if (_resetBatterieText)
+ _scene->_kernelMessages.reset();
+}
+
+void Scene611::actions() {
+ if (_game._screenObjects._inputMode == 1)
+ handleDialog();
+ else if ((_action.isAction(VERB_GIVE, NOUN_PHONE_CELLS, NOUN_HERMIT)) || (_action.isAction(VERB_GIVE, NOUN_DURAFAIL_CELLS, NOUN_HERMIT))) {
+ _action._activeAction._verbId = 0x294;
+ _giveBatteriesFl = true;
+ handleSubDialog1();
+ } else if (_action.isAction(VERB_GIVE, NOUN_HERMIT)) {
+ _scene->_kernelMessages.reset();
+
+ Common::String curQuote = _game.getQuote(0x323);
+ int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ int quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y), 0xFDFC, 0, 0, 120, curQuote);
+
+ curQuote = _game.getQuote(0x324);
+ width = _vm->_font->getWidth(curQuote, _scene->_textSpacing);
+ quotePosX = _defaultDialogPos.x - (width / 2);
+ _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 14), 0xFDFC, 0, 0, 120, curQuote);
+ } else if (_game._trigger == 90) {
+ if (_dialog2.read(0x29C) && _dialog2.read(0x29D) && _dialog2.read(0x29E)) {
+ handleTalking(180);
+ if (_vm->getRandomNumber(1, 2) == 1)
+ displayHermitQuestions(1);
+ else
+ displayHermitQuestions(2);
+ } else {
+ handleTalking(180);
+ if (_vm->getRandomNumber(1, 2) == 1)
+ displayHermitQuestions(3);
+ else
+ displayHermitQuestions(4);
+ }
+
+ _duringDialogFl = true;
+ if (_dialog2.read(0x29F)) {
+ _hermitDialogNode = 1;
+ _dialog1.start();
+ _duringDialogFl = true;
+ } else {
+ _hermitDialogNode = 2;
+ _dialog2.write(0x29F, true);
+ _dialog2.start();
+ _duringDialogFl = true;
+ }
+ } else if (_action.isAction(VERB_TALKTO, NOUN_HERMIT)) {
+ if (!_dialog1.read(0x287)) {
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x27A));
+ _scene->_sequences.addTimer(120, 90);
+ } else {
+ int nextQuote = 0;
+ switch (_vm->getRandomNumber(1, 3)) {
+ case 1:
+ nextQuote = 0x27B;
+ break;
+
+ case 2:
+ nextQuote = 0x27C;
+ break;
+
+ case 3:
+ nextQuote = 0x27D;
+ break;
+ }
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(nextQuote));
+ _scene->_sequences.addTimer(120, 90);
+ }
+ } else if ((_action.isAction(VERB_WALKTO) || _action.isAction(VERB_LOOK)) && _action.isObject(NOUN_RAT)) {
+ switch (_game._trigger) {
+ case 0:
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x279));
+ _scene->_sequences.addTimer(60, 1);
+ break;
+
+ case 1:
+ handleRatMoves();
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag) {
+ if (_globals[kHasTalkedToHermit])
+ _vm->_dialogs->show(61111);
+ else
+ _vm->_dialogs->show(61110);
+ } else if (_action.isAction(VERB_LOOK, NOUN_HERMIT))
+ _vm->_dialogs->show(61112);
+ else if (_action.isAction(VERB_LOOK, NOUN_TRASH))
+ _vm->_dialogs->show(61113);
+ else if (_action.isAction(VERB_TAKE, NOUN_TRASH))
+ _vm->_dialogs->show(61114);
+ else if (_action.isAction(VERB_LOOK, NOUN_CARDBOARD_BOX))
+ _vm->_dialogs->show(61115);
+ else if (_action.isAction(VERB_TAKE, NOUN_CARDBOARD_BOX))
+ _vm->_dialogs->show(61116);
+ else if (_action.isAction(VERB_OPEN, NOUN_CARDBOARD_BOX))
+ _vm->_dialogs->show(61117);
+ else if (_action.isAction(VERB_LOOK, NOUN_REFRIGERATOR))
+ _vm->_dialogs->show(61118);
+ else if (_action.isAction(VERB_OPEN, NOUN_REFRIGERATOR))
+ _vm->_dialogs->show(61119);
+ else if (_action.isAction(VERB_TAKE, NOUN_REFRIGERATOR))
+ _vm->_dialogs->show(61120);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(61121);
+ else if (_action.isAction(VERB_LOOK, NOUN_GRAFFITI))
+ _vm->_dialogs->show(61122);
+ else if (_action.isAction(VERB_LOOK, NOUN_METAL_PIPE))
+ _vm->_dialogs->show(61123);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene612::Scene612(MADSEngine *vm) : Scene6xx(vm) {
+ _actionMode = -1;
+ _cycleIndex = -1;
+}
+
+void Scene612::synchronize(Common::Serializer &s) {
+ Scene6xx::synchronize(s);
+
+ s.syncAsSint16LE(_actionMode);
+ s.syncAsSint16LE(_cycleIndex);
+}
+
+void Scene612::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_FISHING_LINE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene612::handleWinchMovement() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 5);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 5, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ // CHECKME: Is the "else" block useful as action is always equal to 1 at this point?
+ // Or is it a missing bit of code we could fix?
+ if (_actionMode == 1) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 17, 7, 0, 0);
+ _vm->_sound->command(19);
+ _game._objects.setRoom(OBJ_PADLOCK_KEY, 1);
+ _globals[kBoatRaised] = false;
+ } else {
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 17, 9, 0, 0);
+ _vm->_sound->command(18);
+ }
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]);
+ _game._player._visible = true;
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, _cycleIndex);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x2F4));
+ _game._player._stepEnabled = true;
+
+ _vm->_dialogs->show(61217);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene612::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', -1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('p', -1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXCD_3");
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXRC_6");
+
+ if ((_globals[kLineStatus] == 2) || (_globals[kLineStatus] == 3)) {
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('f', -1));
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(34, 117), FACING_SOUTHEAST);
+ }
+
+ if (_globals[kBoatRaised])
+ _cycleIndex = -2;
+ else
+ _cycleIndex = -1;
+
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, _cycleIndex);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1);
+
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(280, 75);
+ _game._player._facing = FACING_SOUTHWEST;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 3);
+ _scene->loadAnimation(formAnimName('R', 1), 70);
+ }
+
+ sceneEntrySound();
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_PADLOCK_KEY);
+
+ _game.loadQuoteSet(0x2F5, 0x2F4, 0);
+}
+
+void Scene612::step() {
+ switch (_game._trigger) {
+ case 70:
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _scene->_sequences.addTimer(6, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 72);
+ break;
+
+ case 72:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene612::actions() {
+ if (_action.isAction(VERB_GET_INSIDE, NOUN_CAR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 3);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[1], syncIdx);
+ _scene->_sequences.addTimer(6, 2);
+ }
+ break;
+
+ case 2:
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], true, 10, 1, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], true, -2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_nextSceneId = 504;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_UNLOCK, NOUN_PADLOCK_KEY, NOUN_CONTROL_BOX)) {
+ _cycleIndex = -2;
+ _actionMode = 1;
+ handleWinchMovement();
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_EXPRESSWAY))
+ _vm->_dialogs->show(61210);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROPE) || _action.isAction(VERB_LOOK, NOUN_ARMATURE)) {
+ if (_globals[kBoatRaised])
+ _vm->_dialogs->show(61211);
+ else
+ _vm->_dialogs->show(61212);
+ } else if (_action.isAction(VERB_TAKE, NOUN_ROPE))
+ _vm->_dialogs->show(61213);
+ else if (_action.isAction(VERB_LOOK, NOUN_CONTROL_BOX)) {
+ if (_globals[kBoatRaised])
+ _vm->_dialogs->show(61214);
+ else
+ _vm->_dialogs->show(61216);
+ } else if (_action.isAction(VERB_OPEN, NOUN_CONTROL_BOX))
+ _vm->_dialogs->show(61215);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDINGS))
+ _vm->_dialogs->show(61218);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOME))
+ _vm->_dialogs->show(61219);
+ else if (_action.isAction(VERB_LOOK, NOUN_STATUE))
+ _vm->_dialogs->show(61220);
+ else if (_action.isAction(VERB_LOOK, NOUN_MAINTENANCE_BUILDING))
+ _vm->_dialogs->show(61221);
+ else if (_action.isAction(VERB_OPEN, NOUN_MAINTENANCE_BUILDING))
+ _vm->_dialogs->show(61222);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(61223);
+ else if (_action.isAction(VERB_LOOK, NOUN_SUPPORT))
+ _vm->_dialogs->show(61224);
+ else if (_action.isAction(VERB_WALK_DOWN, NOUN_EXPRESSWAY_TO_EAST) || _action.isAction(VERB_WALK_DOWN, NOUN_EXPRESSWAY_TO_WEST))
+ _vm->_dialogs->show(61225);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene620::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene620::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_sequences.addTimer(30, 70);
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ sceneEntrySound();
+}
+
+void Scene620::step() {
+ switch (_game._trigger) {
+ case 70:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->loadAnimation(formAnimName('E', -1), 71);
+ break;
+
+ case 71:
+ if (_scene->_priorSceneId == 751) {
+ _globals[kCityFlooded] = true;
+ _globals[kTeleporterRoom + 5] = 0;
+ _scene->_nextSceneId = 701;
+ } else if (_scene->_priorSceneId == 752) {
+ _globals[kCityFlooded] = true;
+ _globals[kTeleporterRoom + 5] = 0;
+ _scene->_nextSceneId = 702;
+ } else if (_scene->_priorSceneId < 501 || _scene->_priorSceneId > 752) {
+ _globals[kCityFlooded] = true;
+ _globals[kTeleporterRoom + 5] = 0;
+ _scene->_nextSceneId = _scene->_priorSceneId;
+ } else if (_scene->_priorSceneId >= 501 && _scene->_priorSceneId <= 612) {
+ _globals[kResurrectRoom] = _globals[kHoverCarLocation];
+ _game._objects.addToInventory(OBJ_TIMEBOMB);
+ _globals[kTimebombStatus] = 0;
+ _globals[kTimebombTimer] = 0;
+ _scene->_nextSceneId = 605;
+ }
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes6.h b/engines/mads/nebular/nebular_scenes6.h
new file mode 100644
index 0000000000..c5cac56626
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes6.h
@@ -0,0 +1,322 @@
+/* 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 MADS_NEBULAR_SCENES6_H
+#define MADS_NEBULAR_SCENES6_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene6xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+
+ void sceneEntrySound();
+
+public:
+ Scene6xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene601 : public Scene6xx{
+public:
+ Scene601(MADSEngine *vm) : Scene6xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene602 : public Scene6xx{
+private:
+ int _lastSpriteIdx;
+ int _lastSequenceIdx;
+ int _cycleIndex;
+ int _safeMode;
+
+ void handleSafeActions();
+
+public:
+ Scene602(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene603 : public Scene6xx{
+private:
+ int _compactCaseHotspotId;
+ int _noteHotspotId;
+
+public:
+ Scene603(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene604 : public Scene6xx{
+private:
+ int _timebombHotspotId;
+ int _bombMode;
+ int _monsterFrame;
+
+ uint32 _monsterTimer;
+
+ bool _monsterActive;
+ bool _animationActiveFl;
+
+ void handleBombActions();
+
+public:
+ Scene604(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene605 : public Scene6xx{
+public:
+ Scene605(MADSEngine *vm) : Scene6xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene607 : public Scene6xx{
+private:
+ uint32 _dogTimer;
+ uint32 _lastFrameTime;
+
+ bool _dogLoop;
+ bool _dogEatsRex;
+ bool _dogBarking;
+ bool _shopAvailable;
+
+ int _animationMode;
+ int _animationActive;
+ int _counter;
+
+ void handleThrowingBone();
+
+public:
+ Scene607(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene608 : public Scene6xx{
+private:
+ int _carMode;
+ int _carFrame;
+ int _carMoveMode;
+ int _dogDeathMode;
+ int _carHotspotId;
+ int _barkCount;
+ int _polycementHotspotId;
+ int _animationMode;
+ int _nextTrigger;
+ int _throwMode;
+
+ bool _resetPositionsFl;
+ bool _dogActiveFl;
+ bool _dogBarkingFl;
+ bool _dogFirstEncounter;
+ bool _rexBeingEaten;
+ bool _dogHitWindow;
+ bool _checkFl;
+ bool _dogSquashFl;
+ bool _dogSafeFl;
+ bool _buttonPressedonTimeFl;
+ bool _dogUnderCar;
+ bool _dogYelping;
+
+ long _dogWindowTimer;
+ long _dogRunTimer;
+
+ uint32 _dogTimer1;
+ uint32 _dogTimer2;
+
+ void resetDogVariables();
+ void restoreAnimations();
+ void setCarAnimations();
+ void handleThrowingBone();
+
+public:
+ Scene608(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene609 : public Scene6xx{
+private:
+ int _videoDoorMode;
+
+ void enterStore();
+
+public:
+ Scene609(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene610 : public Scene6xx{
+private:
+ int _handsetHotspotId;
+ int _checkVal;
+
+ bool _cellCharging;
+
+ long _cellChargingTimer;
+ uint32 _lastFrameTimer;
+
+public:
+ Scene610(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene611 : public Scene6xx{
+private:
+ bool _seenRatFl;
+ bool _eyesRunningFl;
+ bool _shouldRemoveEyes;
+ bool _ratPresentFl;
+ bool _duringDialogFl;
+ bool _resetBatterieText;
+ bool _hermitTalkingFl;
+ bool _hermitMovingFl;
+ bool _alreadyTalkingFl;
+ bool _giveBatteriesFl;
+ bool _startTradingFl;
+ bool _check1Fl;
+ bool _stickFingerFl;
+
+ int _randVal;
+ int _ratHotspotId;
+ int _hermitDialogNode;
+ int _hermitDisplayedQuestion;
+ int _nextFrame;
+ int _hermitMode;
+
+ uint32 _ratTimer;
+
+ Conversation _dialog1;
+ Conversation _dialog2;
+
+ Common::Point _defaultDialogPos;
+
+ void handleTrading();
+ void handleRatMoves();
+ void handleDialog();
+ void handleSubDialog1();
+ void handleSubDialog2();
+ void handleTalking(int delay);
+ void setDialogNode(int node);
+ void displayHermitQuestions(int question);
+
+ bool check2ChargedBatteries();
+ bool check4ChargedBatteries();
+
+public:
+ Scene611(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene612 : public Scene6xx{
+private:
+ int _actionMode;
+ int _cycleIndex;
+
+ void handleWinchMovement();
+
+public:
+ Scene612(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene620 : public Scene6xx{
+public:
+ Scene620(MADSEngine *vm) : Scene6xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions() {};
+};
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES6_H */
diff --git a/engines/mads/nebular/nebular_scenes7.cpp b/engines/mads/nebular/nebular_scenes7.cpp
new file mode 100644
index 0000000000..d59f7ff5f3
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes7.cpp
@@ -0,0 +1,2678 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes7.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene7xx::setAAName() {
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene7xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+
+ Common::String oldName = _game._player._spritesPrefix;
+
+ if ((_scene->_nextSceneId == 703) || (_scene->_nextSceneId == 704) || (_scene->_nextSceneId == 705)
+ || (_scene->_nextSceneId == 707) || (_scene->_nextSceneId == 710) || (_scene->_nextSceneId == 711))
+ _game._player._spritesPrefix = "";
+ else if (_globals[kSexOfRex] == REX_MALE)
+ _game._player._spritesPrefix = "RXM";
+ else
+ _game._player._spritesPrefix = "ROX";
+
+ _game._player._scalingVelocity = true;
+
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+}
+
+void Scene7xx::sceneEntrySound() {
+ if (!_vm->_musicFlag) {
+ _vm->_sound->command(2);
+ return;
+ }
+
+ switch (_scene->_nextSceneId) {
+ case 701:
+ case 702:
+ case 704:
+ case 705:
+ case 751:
+ _vm->_sound->command(38);
+ break;
+ case 703:
+ if (_globals[kMonsterAlive] == 0)
+ _vm->_sound->command(24);
+ else
+ _vm->_sound->command(27);
+ break;
+ case 706:
+ case 707:
+ case 710:
+ case 711:
+ _vm->_sound->command(25);
+ break;
+ default:
+ break;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene701::Scene701(MADSEngine *vm) : Scene7xx(vm) {
+ _fishingLineId = -1;
+}
+
+void Scene701::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+
+ s.syncAsSint16LE(_fishingLineId);
+}
+
+void Scene701::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_BOAT);
+ _scene->addActiveVocab(VERB_CLIMB_INTO);
+ _scene->addActiveVocab(NOUN_FISHING_LINE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene701::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 5));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RM202A1");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('b', 8));
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+ _game._objects.addToInventory(OBJ_TWINKIFRUIT);
+ _game._objects.addToInventory(OBJ_BOMB);
+ _game._objects.addToInventory(OBJ_CHICKEN);
+ _game._objects.addToInventory(OBJ_BONES);
+
+ _globals[kCityFlooded] = true;
+ _globals[kLineStatus] = LINE_TIED;
+ _globals[kBoatRaised] = false;
+ }
+
+ if (_globals[kBoatStatus] == BOAT_UNFLOODED) {
+ if (_globals[kBoatRaised])
+ _globals[kBoatStatus] = BOAT_GONE;
+ else if (_globals[kLineStatus] == LINE_TIED)
+ _globals[kBoatStatus] = BOAT_TIED_FLOATING;
+ else if (_game._difficulty == DIFFICULTY_HARD)
+ _globals[kBoatStatus] = BOAT_ADRIFT;
+ else
+ _globals[kBoatStatus] = BOAT_TIED;
+ }
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+
+ int boatStatus = (_scene->_priorSceneId == 703) ? BOAT_GONE : _globals[kBoatStatus];
+
+ switch (boatStatus) {
+ case BOAT_TIED_FLOATING:
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 20, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 10);
+ break;
+ case BOAT_ADRIFT:
+ _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 20, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 10);
+ break;
+ case BOAT_TIED:
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ break;
+ case BOAT_GONE:
+ _scene->_hotspots.activate(NOUN_BOAT, false);
+ break;
+ default:
+ break;
+ }
+
+ if (_globals[kLineStatus] == LINE_DROPPED || _globals[kLineStatus] == LINE_TIED) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _fishingLineId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(234, 129), FACING_NORTHEAST);
+ }
+
+ if (_scene->_priorSceneId == 702) {
+ _game._player._playerPos = Common::Point(309, 138);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId == 710) {
+ _game._player._playerPos = Common::Point(154, 129);
+ _game._player._facing = FACING_NORTH;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(155, 129));
+ _scene->_sequences.addTimer(15, 60);
+ } else if (_scene->_priorSceneId == 703) {
+ _game._player._playerPos = Common::Point(231, 127);
+ _game._player._facing = FACING_SOUTH;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(formAnimName('B', 1), 80);
+ _vm->_sound->command(28);
+ } else if (_scene->_priorSceneId != -2 && _scene->_priorSceneId != 620) {
+ _game._player._playerPos = Common::Point(22, 131);
+ _game._player._facing = FACING_EAST;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.addTimer(60, 70);
+ }
+
+ _game.loadQuoteSet(0x310, 0x30F, 0);
+ sceneEntrySound();
+}
+
+void Scene701::step() {
+ switch(_game._trigger) {
+ case 60:
+ _scene->_sequences.remove(_globals._sequenceIndexes[5]);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(155, 129));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 61);
+ break;
+
+ case 61:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[5]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ case 70:
+ _vm->_sound->command(16);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 71:
+ _game._player.walk(Common::Point(61, 131), FACING_EAST);
+ _scene->_sequences.addTimer(120, 72);
+ break;
+
+ case 72:
+ _vm->_sound->command(17);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 73);
+ break;
+
+ case 73:
+ _game._player._stepEnabled = true;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_kernelMessages.reset();
+ break;
+
+ case 80: {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BOAT, VERB_CLIMB_INTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(234, 129), FACING_NORTH);
+ _globals[kBoatStatus] = BOAT_TIED;
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene701::preActions() {
+ if (_action.isAction(VERB_WALKTO, NOUN_EAST_END_OF_PLATFORM))
+ _game._player._walkOffScreenSceneId = 702;
+
+ if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _game._player.walk(Common::Point(154, 129), FACING_NORTHEAST);
+
+ if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_BUILDING))
+ _game._player.walk(Common::Point(154, 129), FACING_NORTH);
+}
+
+void Scene701::actions() {
+ if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM))
+ return;
+
+ if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_BUILDING) && _game._objects[OBJ_VASE]._roomNumber == 706) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(155, 129));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int temp = _globals._sequenceIndexes[5];
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(155, 129));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], temp);
+ _scene->_sequences.addTimer(15, 2);
+ }
+ break;
+
+ case 2:
+ _scene->_nextSceneId = 710;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_STEP_INTO, NOUN_ELEVATOR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _vm->_sound->command(16);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x310, 34, 0, 120, _game.getQuote(0x30D));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _game._player.walk(Common::Point(22, 131), FACING_EAST);
+ _scene->_sequences.addTimer(120, 3);
+ break;
+
+ case 3:
+ _vm->_sound->command(17);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ break;
+
+ case 4:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _globals[kResurrectRoom] = 701;
+ _scene->_nextSceneId = 605;
+ break;
+
+ default:
+ break;
+ }
+ } else if ((_action.isAction(VERB_PULL, NOUN_BOAT) || _action.isAction(VERB_TAKE, NOUN_BOAT) ||
+ _action.isAction(VERB_PULL, NOUN_FISHING_LINE) || _action.isAction(VERB_TAKE, NOUN_FISHING_LINE)) &&
+ !_game._objects.isInInventory(OBJ_FISHING_LINE)) {
+ if (_globals[kBoatStatus] == BOAT_TIED_FLOATING) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _scene->_dynamicHotspots.remove(_fishingLineId);
+ _scene->_hotspots.activate(NOUN_BOAT, false);
+ _game._player._visible = false;
+ _scene->loadAnimation(formAnimName('E', -1), 1);
+ break;
+
+ case 1: {
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1);
+ _scene->_sequences.setDepth (_globals._sequenceIndexes[2], 9);
+ int idx = _scene->_dynamicHotspots.add(NOUN_BOAT, VERB_CLIMB_INTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(231, 127), FACING_NORTH);
+ _scene->_sequences.addTimer(15, 2);
+ }
+ break;
+
+ case 2:
+ _globals[kBoatStatus] = BOAT_TIED;
+ _globals[kLineStatus] = LINE_NOW_UNTIED;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_globals[kBoatStatus] == BOAT_TIED) {
+ _vm->_dialogs->show(70125);
+ } else if (_globals[kLineStatus] == LINE_DROPPED) {
+ _globals[kLineStatus] = LINE_NOW_UNTIED;
+ _game._objects.addToInventory(OBJ_FISHING_LINE);
+ _vm->_sound->command(15);
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _vm->_dialogs->showItem(OBJ_FISHING_LINE, 70126);
+ } else {
+ _vm->_dialogs->show(70127);
+ }
+ } else if (_action.isAction(VERB_CLIMB_INTO, NOUN_BOAT) && _globals[kBoatStatus] == BOAT_TIED) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _game._player._visible = false;
+ _scene->loadAnimation(formAnimName('B', 0), 1);
+ break;
+
+ case 1:
+ _scene->_nextSceneId = 703;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action._lookFlag) {
+ if (_globals[kBoatStatus] != BOAT_GONE) {
+ if (_globals[kBoatStatus] == BOAT_TIED)
+ _vm->_dialogs->show(70128);
+ else
+ _vm->_dialogs->show(70110);
+ } else
+ _vm->_dialogs->show(70111);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SUBMERGED_CITY))
+ _vm->_dialogs->show(70112);
+ else if (_action.isAction(VERB_LOOK, 0))
+ _vm->_dialogs->show(70113);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM))
+ _vm->_dialogs->show(70114);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEMENT_PYLON))
+ _vm->_dialogs->show(70115);
+ else if (_action.isAction(VERB_LOOK, NOUN_HOOK)) {
+ if (_globals[kLineStatus] == LINE_NOT_DROPPED || _globals[kLineStatus] == LINE_NOW_UNTIED)
+ _vm->_dialogs->show(70116);
+ else
+ _vm->_dialogs->show(70117);
+ } else if (_action.isAction(VERB_LOOK, NOUN_ROCK))
+ _vm->_dialogs->show(70118);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCK))
+ _vm->_dialogs->show(70119);
+ else if (_action.isAction(VERB_LOOK, NOUN_EAST_END_OF_PLATFORM))
+ _vm->_dialogs->show(70120);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(70121);
+ else if (_action.isAction(VERB_LOOK, NOUN_BOAT)) {
+ if (_globals[kBoatStatus] == BOAT_ADRIFT || _globals[kBoatStatus] == BOAT_TIED_FLOATING)
+ _vm->_dialogs->show(70122);
+ else
+ _vm->_dialogs->show(70123);
+ } else if (_action.isAction(VERB_CAST, NOUN_FISHING_ROD, NOUN_BOAT) && _game._objects.isInInventory(OBJ_FISHING_LINE))
+ _vm->_dialogs->show(70124);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene702::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene702::enter() {
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites("*RXMBD_8");
+
+ if (_scene->_priorSceneId == 701) {
+ _game._player._playerPos = Common::Point(13, 145);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId != -2 && _scene->_priorSceneId != 620) {
+ _game._player._playerPos = Common::Point(289, 138);
+ _game._player.walk(Common::Point(262, 148), FACING_WEST);
+ _game._player._facing = FACING_WEST;
+ _game._player._visible = true;
+ }
+
+ if (_game._globals[kTeleporterCommand]) {
+ switch(_game._globals[kTeleporterCommand]) {
+ case TELEPORTER_BEAM_OUT:
+ case TELEPORTER_WRONG:
+ case TELEPORTER_STEP_OUT:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ default:
+ break;
+ }
+
+ _game._globals[kTeleporterCommand] = TELEPORTER_NONE;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene702::preActions() {
+ if (_action.isAction(VERB_WALKTO, NOUN_WEST_END_OF_PLATFORM))
+ _game._player._walkOffScreenSceneId = 701;
+}
+
+void Scene702::actions() {
+ if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM))
+ ; // Only set the action as finished
+ else if (_action.isAction(VERB_STEP_INTO, NOUN_TELEPORTER)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_nextSceneId = 711;
+ } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._mainObjectSource == 4) && (!_game._objects.isInInventory(OBJ_BONES) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+ case 1:
+ _vm->_sound->command(0xF);
+ if (_game._objects.isInInventory(OBJ_BONE))
+ _game._objects.setRoom(OBJ_BONE, 1);
+ _game._objects.addToInventory(OBJ_BONES);
+ _vm->_dialogs->show(OBJ_BONES, 70218);
+ break;
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[12]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ default:
+ break;
+ }
+ } else if (_action._lookFlag)
+ _vm->_dialogs->show(70210);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM))
+ _vm->_dialogs->show(70211);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEMENT_BLOCK))
+ _vm->_dialogs->show(70212);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCK))
+ _vm->_dialogs->show(70213);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCK))
+ _vm->_dialogs->show(70214);
+ else if (_action.isAction(VERB_LOOK, NOUN_WEST_END_OF_PLATFORM))
+ _vm->_dialogs->show(70215);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(70216);
+ else if (_action.isAction(VERB_LOOK, NOUN_BONES) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(70217);
+ else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._mainObjectSource == 4)) {
+ if (_game._objects.isInInventory(OBJ_BONES))
+ _vm->_dialogs->show(70219);
+ } else if (_action.isAction(VERB_LOOK, NOUN_SUBMERGED_CITY))
+ _vm->_dialogs->show(70220);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene703::Scene703(MADSEngine *vm) : Scene7xx(vm) {
+ _monsterMode = -1;
+ _boatFrame = -1;
+ _curSequence = -1;
+ _boatDir = -1;
+
+ _useBomb = false;
+ _startMonsterTimer = false;
+ _rexDeathFl = false;
+ _restartTrigger70Fl = false;
+
+ _lastFrameTime = 0;
+ _monsterTime = 0;
+}
+
+void Scene703::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+
+ s.syncAsSint16LE(_monsterMode);
+ s.syncAsSint16LE(_boatFrame);
+ s.syncAsSint16LE(_curSequence);
+ s.syncAsSint16LE(_boatDir);
+
+ s.syncAsByte(_useBomb);
+ s.syncAsByte(_startMonsterTimer);
+ s.syncAsByte(_rexDeathFl);
+ s.syncAsByte(_restartTrigger70Fl);
+
+ s.syncAsUint32LE(_lastFrameTime);
+ s.syncAsUint32LE(_monsterTime);
+}
+
+void Scene703::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene703::handleBottleInterface() {
+ switch (_globals[kBottleStatus]) {
+ case 0:
+ _dialog1.write(0x311, true);
+ _dialog1.write(0x312, true);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 1:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, true);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 2:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, false);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 3:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, false);
+ _dialog1.write(0x313, false);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene703::setBottleSequence() {
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _game._player._stepEnabled = false;
+ if (_boatDir == 2)
+ _curSequence = 6;
+ else
+ _curSequence = 7;
+}
+
+void Scene703::handleFillBottle(int quote) {
+ switch (quote) {
+ case 0x311:
+ _globals[kBottleStatus] = 1;
+ setBottleSequence();
+ break;
+
+ case 0x312:
+ _globals[kBottleStatus] = 2;
+ setBottleSequence();
+ break;
+
+ case 0x313:
+ _globals[kBottleStatus] = 3;
+ setBottleSequence();
+ break;
+
+ case 0x314:
+ _globals[kBottleStatus] = 4;
+ setBottleSequence();
+ break;
+
+ case 0x315:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene703::enter() {
+ _game._player._visible = false;
+
+ if (!_game._visitedScenes._sceneRevisited) {
+ if (_scene->_priorSceneId == 704)
+ _globals[kMonsterAlive] = false;
+ else
+ _globals[kMonsterAlive] = true;
+ }
+
+ _startMonsterTimer = true;
+ _rexDeathFl = true;
+ _monsterTime = 0;
+ _restartTrigger70Fl = true;
+ _useBomb = false;
+ _boatFrame = -1;
+
+ if (!_globals[kMonsterAlive])
+ _scene->_hotspots.activate(NOUN_SEA_MONSTER, false);
+
+ if (_scene->_priorSceneId == 704) {
+ _game._player._stepEnabled = false;
+ _curSequence = 2;
+ _boatDir = 2;
+ _monsterMode = 0;
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(34);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._stepEnabled = false;
+ _boatDir = 1;
+ if (_globals[kMonsterAlive]) {
+ _monsterMode = 1;
+ _curSequence = 0;
+ _scene->loadAnimation(formAnimName('B', -1));
+ } else {
+ _curSequence = 0;
+ _monsterMode = 0;
+ _scene->loadAnimation(formAnimName('A', -1));
+ }
+ } else if (_globals[kMonsterAlive]) {
+ _curSequence = 0;
+ _boatDir = 1;
+ _monsterMode = 1;
+ _scene->loadAnimation(formAnimName('B', -1));
+ _scene->_activeAnimation->setCurrentFrame(39);
+ } else if (_boatDir == 1) {
+ _curSequence = 0;
+ _monsterMode = 0;
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(9);
+ } else if (_boatDir == 2) {
+ _curSequence = 0;
+ _monsterMode = 0;
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(56);
+ }
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_TWINKIFRUIT);
+ _game._objects.addToInventory(OBJ_BOMB);
+ _game._objects.addToInventory(OBJ_CHICKEN);
+ _game._objects.addToInventory(OBJ_BONES);
+ }
+
+ _game.loadQuoteSet(0x311, 0x312, 0x313, 0x314, 0x315, 0);
+ _dialog1.setup(0x98, 0x311, 0x312, 0x313, 0x314, 0x315, 0);
+ sceneEntrySound();
+ _vm->_sound->command(28);
+}
+
+void Scene703::step() {
+ if (_startMonsterTimer) {
+ long diff = _scene->_frameStartTime - _lastFrameTime;
+ if ((diff >= 0) && (diff <= 12))
+ _monsterTime += diff;
+ else
+ _monsterTime++;
+
+ _lastFrameTime = _scene->_frameStartTime;
+ }
+
+ if ((_monsterTime >= 2400) && !_rexDeathFl && !_useBomb) {
+ _startMonsterTimer = false;
+ _rexDeathFl = true;
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _monsterMode = 3;
+ _scene->loadAnimation(formAnimName('D', -1));
+ _rexDeathFl = false;
+ _monsterTime = 0;
+ }
+
+
+ if (_game._trigger == 70)
+ _scene->_reloadSceneFlag = true;
+
+ if ((_monsterMode == 3) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _boatFrame) {
+ _boatFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextBoatFrame = -1;
+
+ if (_boatFrame == 62) {
+ nextBoatFrame = 61;
+ if (_restartTrigger70Fl) {
+ _restartTrigger70Fl = false;
+ _scene->_sequences.addTimer(15, 70);
+ }
+ }
+
+ if ((nextBoatFrame >= 0) && (nextBoatFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextBoatFrame);
+ _boatFrame = nextBoatFrame;
+ }
+ }
+ }
+
+ if (_game._trigger == 70)
+ _scene->_reloadSceneFlag = true;
+
+ if ((_monsterMode == 0) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _boatFrame) {
+ _boatFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextBoatFrame = -1;
+
+ switch (_boatFrame) {
+ case 11:
+ if (_curSequence == 7) {
+ _curSequence = 0;
+ nextBoatFrame = 100;
+ } else if (_curSequence == 5)
+ nextBoatFrame = 82;
+ else if (_curSequence == 1)
+ nextBoatFrame = 11;
+ else {
+ nextBoatFrame = 9;
+ if (!_game._player._stepEnabled)
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ case 34:
+ if (_curSequence != 2)
+ _scene->_nextSceneId = 704;
+ break;
+
+ case 57:
+ if (_curSequence == 6) {
+ _curSequence = 0;
+ nextBoatFrame = 91;
+ } else if (_curSequence == 4)
+ nextBoatFrame = 73;
+ else if (_curSequence == 3)
+ nextBoatFrame = 57;
+ else {
+ nextBoatFrame = 56;
+ if (!_game._player._stepEnabled)
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ case 73:
+ _scene->_nextSceneId = 701;
+ break;
+
+ case 82:
+ nextBoatFrame = 11;
+ break;
+
+ case 91:
+ nextBoatFrame = 57;
+ break;
+
+ case 100:
+ nextBoatFrame = 56;
+ if (!_game._player._stepEnabled) {
+ _scene->_sequences.addTimer(30, 80);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ case 110:
+ nextBoatFrame = 9;
+ if (!_game._player._stepEnabled) {
+ _scene->_sequences.addTimer(30, 80);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if ((nextBoatFrame >= 0) && (nextBoatFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextBoatFrame);
+ _boatFrame = nextBoatFrame;
+ }
+ }
+ }
+
+ if (_game._trigger == 80) {
+ switch (_globals[kBottleStatus]) {
+ case 0:
+ _vm->_dialogs->show(432);
+ break;
+
+ case 1:
+ _vm->_dialogs->show(70324);
+ break;
+
+ case 2:
+ _vm->_dialogs->show(70325);
+ break;
+
+ case 3:
+ _vm->_dialogs->show(70326);
+ break;
+
+ case 4:
+ _vm->_dialogs->show(70327);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+ if ((_monsterMode == 1) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _boatFrame) {
+ _boatFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextBoatFrame = -1;
+
+ switch (_boatFrame) {
+ case 39:
+ _game._player._stepEnabled = true;
+ _startMonsterTimer = true;
+ _rexDeathFl = false;
+ break;
+
+ case 40:
+ case 49:
+ case 54:
+ case 67:
+ case 78:
+ case 87:
+ case 96:
+ case 105:
+ case 114:
+ case 123:
+ if (_curSequence == 8)
+ nextBoatFrame = 129;
+
+ break;
+
+ case 129:
+ nextBoatFrame = 39;
+ break;
+
+ case 151:
+ _scene->_nextSceneId = 701;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((nextBoatFrame >= 0) && (nextBoatFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextBoatFrame);
+ _boatFrame = nextBoatFrame;
+ }
+ }
+ }
+
+ if ((_monsterMode == 2) && (_scene->_activeAnimation != nullptr)) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _boatFrame) {
+ _boatFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextBoatFrame = -1;
+
+ switch (_boatFrame) {
+ case 14:
+ if (!_useBomb) {
+ if (_game._difficulty == DIFFICULTY_HARD)
+ _game._objects.setRoom(OBJ_CHICKEN, 1);
+ else
+ _vm->_dialogs->show(70319);
+ }
+ nextBoatFrame = 80;
+ break;
+
+ case 33:
+ if (_game._objects.isInInventory(OBJ_BONES)) {
+ _game._objects.setRoom(OBJ_BONES, 1);
+ _game._objects.addToInventory(OBJ_BONE);
+ } else
+ _game._objects.setRoom(OBJ_BONE, 1);
+
+ nextBoatFrame = 80;
+ break;
+
+ case 53:
+ _game._objects.setRoom(OBJ_TWINKIFRUIT, 1);
+ nextBoatFrame = 80;
+ _curSequence = 9;
+ break;
+
+ case 80:
+ if (_game._difficulty == DIFFICULTY_HARD) {
+ _game._objects.setRoom(OBJ_BOMB, 1);
+ _vm->_dialogs->show(70318);
+ } else
+ _vm->_dialogs->show(70317);
+
+ _scene->freeAnimation();
+ _monsterMode = 1;
+ _scene->loadAnimation(formAnimName('B', -1));
+ _scene->_activeAnimation->setCurrentFrame(39);
+ _game._player._stepEnabled = true;
+ break;
+
+ case 91:
+ if (!_useBomb) {
+ _scene->freeAnimation();
+ _monsterMode = 1;
+ _scene->loadAnimation(formAnimName('B', -1));
+ _scene->_activeAnimation->setCurrentFrame(39);
+ _game._player._stepEnabled = true;
+ } else
+ _game._objects.setRoom(OBJ_CHICKEN_BOMB, 1);
+
+ break;
+
+ case 126:
+ _scene->_hotspots.activate(NOUN_SEA_MONSTER, false);
+ _globals[kMonsterAlive] = false;
+ _scene->freeAnimation();
+ _monsterMode = 0;
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(9);
+ _game._player._stepEnabled = true;
+ if (_game._storyMode == STORYMODE_NAUGHTY)
+ _vm->_dialogs->show(70321);
+ else
+ _vm->_dialogs->show(70322);
+
+ break;
+
+ default:
+ break;
+ }
+
+ if ((nextBoatFrame >= 0) && (nextBoatFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextBoatFrame);
+ _boatFrame = nextBoatFrame;
+ }
+ }
+ }
+}
+
+void Scene703::actions() {
+ if (_game._screenObjects._inputMode == 1)
+ handleFillBottle(_action._activeAction._verbId);
+ else if (_action.isAction(VERB_STEER_TOWARDS, NOUN_DOCK_TO_SOUTH)) {
+ _game._player._stepEnabled = false;
+ if (_globals[kMonsterAlive])
+ _curSequence = 8;
+ else if (_boatDir == 1)
+ _curSequence = 5;
+ else
+ _curSequence = 3;
+ } else if (_action.isAction(VERB_STEER_TOWARDS, NOUN_BUILDING_TO_NORTH)) {
+ _game._player._stepEnabled = false;
+ if (_globals[kMonsterAlive]) {
+ _startMonsterTimer = false;
+ _rexDeathFl = true;
+ _monsterTime = 0;
+ _scene->freeAnimation();
+ _monsterMode = 3;
+ _scene->loadAnimation(formAnimName('D', -1));
+ } else if (_boatDir == 2)
+ _curSequence = 4;
+ else
+ _curSequence = 1;
+ } else if (_action.isAction(VERB_THROW, NOUN_BONE, NOUN_SEA_MONSTER) || _action.isAction(VERB_THROW, NOUN_BONES, NOUN_SEA_MONSTER)) {
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _monsterMode = 2;
+ _scene->loadAnimation(formAnimName('C', -1));
+ _scene->_activeAnimation->setCurrentFrame(19);
+ } else if (_action.isAction(VERB_THROW, NOUN_CHICKEN, NOUN_SEA_MONSTER)) {
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _monsterMode = 2;
+ _scene->loadAnimation(formAnimName('C', -1));
+ } else if (_action.isAction(VERB_THROW, NOUN_TWINKIFRUIT, NOUN_SEA_MONSTER)) {
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _monsterMode = 2;
+ _scene->loadAnimation(formAnimName('C', -1));
+ _scene->_activeAnimation->setCurrentFrame(39);
+ } else if (_action.isAction(VERB_THROW, NOUN_BOMB, NOUN_SEA_MONSTER)) {
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _monsterMode = 2;
+ _scene->loadAnimation(formAnimName('C', -1));
+ _scene->_activeAnimation->setCurrentFrame(59);
+ } else if (_action.isAction(VERB_THROW, NOUN_CHICKEN_BOMB, NOUN_SEA_MONSTER)) {
+ _useBomb = true;
+ _game._player._stepEnabled = false;
+ _scene->freeAnimation();
+ _monsterMode = 2;
+ _scene->loadAnimation(formAnimName('C', -1));
+ } else if (_action.isAction(VERB_PUT, NOUN_BOTTLE, NOUN_WATER) || _action.isAction(VERB_FILL, NOUN_BOTTLE, NOUN_WATER)) {
+ if (_globals[kBottleStatus] != 4) {
+ handleBottleInterface();
+ _dialog1.start();
+ } else
+ _vm->_dialogs->show(70323);
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_SEA_MONSTER)) {
+ if (_globals[kMonsterAlive])
+ _vm->_dialogs->show(70310);
+ } else if (_action.isAction(VERB_LOOK, NOUN_WATER)) {
+ if (!_globals[kMonsterAlive])
+ _vm->_dialogs->show(70311);
+ else
+ _vm->_dialogs->show(70312);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BUILDING_TO_NORTH)) {
+ if (_globals[kMonsterAlive])
+ _vm->_dialogs->show(70313);
+ else if (_game._visitedScenes.exists(710))
+ _vm->_dialogs->show(70314);
+ else
+ _vm->_dialogs->show(70315);
+ } else if (_action.isAction(VERB_LOOK, NOUN_VOLCANO_RIM))
+ _vm->_dialogs->show(70316);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene704::Scene704(MADSEngine *vm) : Scene7xx(vm) {
+ _bottleHotspotId = -1;
+ _boatCurrentFrame = -1;
+ _animationMode = -1;
+ _boatDirection = -1;
+
+ _takeBottleFl = false;
+}
+
+void Scene704::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+
+ s.syncAsSint16LE(_bottleHotspotId);
+ s.syncAsSint16LE(_boatCurrentFrame);
+ s.syncAsSint16LE(_animationMode);
+ s.syncAsSint16LE(_boatDirection);
+
+ s.syncAsByte(_takeBottleFl);
+}
+
+void Scene704::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+ _scene->addActiveVocab(NOUN_BOTTLE);
+ _scene->addActiveVocab(VERB_LOOK_AT);
+}
+
+void Scene704::handleBottleInterface() {
+ switch (_globals[kBottleStatus]) {
+ case 0:
+ _dialog1.write(0x311, true);
+ _dialog1.write(0x312, true);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 1:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, true);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 2:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, false);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 3:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, false);
+ _dialog1.write(0x313, false);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene704::setBottleSequence() {
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _game._player._stepEnabled = false;
+ if (_boatDirection == 2)
+ _animationMode = 6;
+ else
+ _animationMode = 7;
+}
+
+void Scene704::handleFillBottle(int quote) {
+ switch (quote) {
+ case 0x311:
+ _globals[kBottleStatus] = 1;
+ setBottleSequence();
+ break;
+
+ case 0x312:
+ _globals[kBottleStatus] = 2;
+ setBottleSequence();
+ break;
+
+ case 0x313:
+ _globals[kBottleStatus] = 3;
+ setBottleSequence();
+ break;
+
+ case 0x314:
+ _globals[kBottleStatus] = 4;
+ setBottleSequence();
+ break;
+
+ case 0x315:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene704::enter() {
+ if (_game._objects[OBJ_BOTTLE]._roomNumber == _scene->_currentSceneId) {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ if (_scene->_priorSceneId == 705) {
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(123, 125));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ } else {
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(190, 122));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ }
+ int idx = _scene->_dynamicHotspots.add(NOUN_BONES, VERB_LOOK_AT, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _bottleHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(-2, 0), FACING_NONE);
+ }
+
+ _game._player._visible = false;
+ _takeBottleFl = false;
+ _boatCurrentFrame = -1;
+
+ if (_scene->_priorSceneId == 705) {
+ _game._player._stepEnabled = false;
+ _animationMode = 2;
+ _boatDirection = 2;
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(36);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._stepEnabled = false;
+ _boatDirection = 1;
+ _scene->loadAnimation(formAnimName('A', -1));
+ } else if (_boatDirection == 1) {
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(8);
+ } else if (_boatDirection == 2) {
+ if (_game._objects[OBJ_BOTTLE]._roomNumber == _scene->_currentSceneId) {
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(123, 125));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ }
+ _scene->loadAnimation(formAnimName('A', -1));
+ _scene->_activeAnimation->setCurrentFrame(57);
+ }
+
+ if (_scene->_roomChanged)
+ _globals[kMonsterAlive] = false;
+
+ _game.loadQuoteSet(0x311, 0x312, 0x313, 0x314, 0x315, 0);
+ _dialog1.setup(0x98, 0x311, 0x312, 0x313, 0x314, 0x315, 0);
+
+ sceneEntrySound();
+ _vm->_sound->command(28);
+}
+
+void Scene704::step() {
+ if (_scene->_activeAnimation != nullptr) {
+ if (_scene->_activeAnimation->getCurrentFrame() != _boatCurrentFrame) {
+ _boatCurrentFrame = _scene->_activeAnimation->getCurrentFrame();
+ int nextFrame = -1;
+
+ switch (_boatCurrentFrame) {
+ case 10:
+ switch (_animationMode) {
+ case 1:
+ nextFrame = 10;
+ break;
+ case 5:
+ nextFrame = 74;
+ break;
+ case 7:
+ _animationMode = 0;
+ nextFrame = 92;
+ break;
+ default:
+ if (!_game._player._stepEnabled)
+ _game._player._stepEnabled = true;
+
+ nextFrame = 8;
+ break;
+ }
+ break;
+
+ case 36:
+ if (_animationMode != 2)
+ _scene->_nextSceneId = 705;
+ break;
+
+ case 59:
+ switch (_animationMode) {
+ case 3:
+ nextFrame = 59;
+ break;
+
+ case 4:
+ nextFrame = 65;
+ break;
+
+ case 6:
+ _animationMode = 0;
+ nextFrame = 83;
+ break;
+
+ default:
+ if (!_game._player._stepEnabled) {
+ _game._player._stepEnabled = true;
+ }
+ nextFrame = 57;
+ break;
+ }
+ break;
+
+ case 65:
+ _scene->_nextSceneId = 703;
+ break;
+
+ case 74:
+ nextFrame = 10;
+ break;
+
+ case 83:
+ nextFrame = 59;
+ break;
+
+ case 90:
+ if (_takeBottleFl) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_bottleHotspotId);
+ _game._objects.addToInventory(OBJ_BOTTLE);
+ _vm->_sound->command(15);
+ _vm->_dialogs->showItem(OBJ_BOTTLE, 70415);
+ }
+ break;
+
+ case 92:
+ nextFrame = 57;
+ if (!_game._player._stepEnabled && !_takeBottleFl) {
+ _scene->_sequences.addTimer(30, 70);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ case 98:
+ if (_takeBottleFl) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_bottleHotspotId);
+ _game._objects.addToInventory(OBJ_BOTTLE);
+ _vm->_sound->command(15);
+ _vm->_dialogs->showItem(OBJ_BOTTLE, 70415);
+ }
+ break;
+
+ case 101:
+ nextFrame = 8;
+ if (!_game._player._stepEnabled && !_takeBottleFl) {
+ _scene->_sequences.addTimer(30, 70);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if ((nextFrame >= 0) && (nextFrame != _scene->_activeAnimation->getCurrentFrame())) {
+ _scene->_activeAnimation->setCurrentFrame(nextFrame);
+ _boatCurrentFrame = nextFrame;
+ }
+ }
+ }
+
+ if (_game._trigger == 70) {
+ switch (_globals[kBottleStatus]) {
+ case 0:
+ _vm->_dialogs->show(432);
+ break;
+
+ case 1:
+ _vm->_dialogs->show(70324);
+ break;
+
+ case 2:
+ _vm->_dialogs->show(70325);
+ break;
+
+ case 3:
+ _vm->_dialogs->show(70326);
+ break;
+
+ case 4:
+ _vm->_dialogs->show(70327);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene704::actions() {
+ if (_game._screenObjects._inputMode == 1)
+ handleFillBottle(_action._activeAction._verbId);
+ else if (_action.isAction(VERB_STEER_TOWARDS, NOUN_OPEN_WATER_TO_SOUTH)) {
+ _game._player._stepEnabled = false;
+ if (_boatDirection == 1)
+ _animationMode = 5;
+ else
+ _animationMode = 3;
+ } else if (_action.isAction(VERB_STEER_TOWARDS, NOUN_BUILDING_TO_NORTH)) {
+ _game._player._stepEnabled = false;
+ if (_boatDirection == 2)
+ _animationMode = 4;
+ else
+ _animationMode = 1;
+ } else if (_action.isAction(VERB_TAKE, NOUN_BOTTLE)) {
+ if (!_game._objects.isInInventory(OBJ_BOTTLE)) {
+ _game._player._stepEnabled = false;
+ _takeBottleFl = true;
+ if (_boatDirection == 2) {
+ _animationMode = 6;
+ } else {
+ _animationMode = 7;
+ }
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_BOTTLE, NOUN_WATER) || _action.isAction(VERB_FILL, NOUN_BOTTLE, NOUN_WATER)) {
+ if (_game._objects.isInInventory(OBJ_BOTTLE)) {
+ if (_globals[kBottleStatus] != 4) {
+ _takeBottleFl = false;
+ handleBottleInterface();
+ _dialog1.start();
+ } else
+ _vm->_dialogs->show(70323);
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_WATER))
+ _vm->_dialogs->show(70410);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING_TO_NORTH)) {
+ if (_game._visitedScenes.exists(710))
+ _vm->_dialogs->show(70411);
+ else
+ _vm->_dialogs->show(70412);
+ } else if (_action.isAction(VERB_LOOK, NOUN_VOLCANO_RIM))
+ _vm->_dialogs->show(70413);
+ else if (_action.isAction(VERB_LOOK, NOUN_BOTTLE) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(70414);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_WATER_TO_SOUTH))
+ _vm->_dialogs->show(70416);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKY))
+ _vm->_dialogs->show(70417);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene705::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene705::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+}
+
+void Scene705::handleBottleInterface() {
+ switch (_globals[kBottleStatus]) {
+ case 0:
+ _dialog1.write(0x311, true);
+ _dialog1.write(0x312, true);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 1:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, true);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 2:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, false);
+ _dialog1.write(0x313, true);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ case 3:
+ _dialog1.write(0x311, false);
+ _dialog1.write(0x312, false);
+ _dialog1.write(0x313, false);
+ _dialog1.write(0x314, true);
+ _dialog1.write(0x315, true);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene705::setBottleSequence() {
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->loadAnimation(formAnimName('F', -1), 90);
+}
+
+void Scene705::handleFillBottle(int quote) {
+ switch (quote) {
+ case 0x311:
+ _globals[kBottleStatus] = 1;
+ setBottleSequence();
+ break;
+
+ case 0x312:
+ _globals[kBottleStatus] = 2;
+ setBottleSequence();
+ break;
+
+ case 0x313:
+ _globals[kBottleStatus] = 3;
+ setBottleSequence();
+ break;
+
+ case 0x314:
+ _globals[kBottleStatus] = 4;
+ setBottleSequence();
+ break;
+
+ case 0x315:
+ _scene->_userInterface.setup(kInputBuildingSentences);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene705::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 0));
+
+ _game._player._visible = false;
+
+ if (_scene->_priorSceneId == 706) {
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._stepEnabled = false;
+ _scene->_sequences.addTimer(1, 80);
+ _vm->_sound->command(28);
+ } else
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+
+ if (_scene->_roomChanged)
+ _game._objects.addToInventory(OBJ_BOTTLE);
+
+ _game.loadQuoteSet(0x311, 0x312, 0x313, 0x314, 0x315, 0);
+ _dialog1.setup(0x98, 0x311, 0x312, 0x313, 0x314, 0x315, 0);
+ sceneEntrySound();
+}
+
+void Scene705::step() {
+ switch (_game._trigger) {
+ case 70:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 71: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 80:
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 9, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ break;
+
+ case 81: {
+ _vm->_sound->command(19);
+ int syncIdx = _globals._sequenceIndexes[1];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ switch (_game._trigger) {
+ case 90:
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.addTimer(30, 91);
+ break;
+
+ case 91:
+ switch (_globals[kBottleStatus]) {
+ case 0:
+ _vm->_dialogs->show(432);
+ break;
+
+ case 1:
+ _vm->_dialogs->show(70324);
+ break;
+
+ case 2:
+ _vm->_dialogs->show(70325);
+ break;
+
+ case 3:
+ _vm->_dialogs->show(70326);
+ break;
+
+ case 4:
+ _vm->_dialogs->show(70327);
+ break;
+
+ default:
+ break;
+ }
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene705::actions() {
+ if (_game._screenObjects._inputMode == 1)
+ handleFillBottle(_action._activeAction._verbId);
+ else if (_action.isAction(VERB_STEER_TOWARDS, NOUN_OPEN_WATER_TO_SOUTH)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ _vm->_sound->command(18);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_nextSceneId = 704;
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_CLIMB_THROUGH, NOUN_WINDOW)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[3]);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 16);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[3];
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 16);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx);
+ _scene->_nextSceneId = 706;
+ _game._player._stepEnabled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_FILL, NOUN_BOTTLE, NOUN_WATER) || _action.isAction(VERB_PUT, NOUN_BOTTLE, NOUN_WATER)) {
+ if (_globals[kBottleStatus] != 4) {
+ handleBottleInterface();
+ _dialog1.start();
+ } else
+ _vm->_dialogs->show(70323);
+ } if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_WATER))
+ _vm->_dialogs->show(70511);
+ else if (_action.isAction(VERB_LOOK, NOUN_VOLCANO_RIM))
+ _vm->_dialogs->show(70512);
+ else if (_action.isAction(VERB_LOOK, NOUN_OPEN_WATER_TO_SOUTH))
+ _vm->_dialogs->show(70513);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKY))
+ _vm->_dialogs->show(70514);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING))
+ _vm->_dialogs->show(70515);
+ else if (_action.isAction(VERB_LOOK, NOUN_WINDOW))
+ _vm->_dialogs->show(70516);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene706::Scene706(MADSEngine *vm) : Scene7xx(vm) {
+ _vaseHotspotId = -1;
+ _vaseMode = -1;
+ _animationMode = -1;
+ _animationFrame = -1;
+
+ _emptyPedestral = false;
+}
+
+void Scene706::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+
+ s.syncAsSint16LE(_vaseHotspotId);
+ s.syncAsSint16LE(_vaseMode);
+ s.syncAsSint16LE(_animationMode);
+ s.syncAsSint16LE(_animationFrame);
+
+ s.syncAsByte(_emptyPedestral);
+}
+
+void Scene706::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_BOTTLE);
+ _scene->addActiveVocab(NOUN_VASE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene706::handleRexDeath() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->loadAnimation(formAnimName('a', -1), 2);
+ break;
+
+ case 2:
+ if (_animationMode == 1)
+ _vm->_dialogs->show(70625);
+ else if (_globals[kBottleStatus] < 2)
+ _vm->_dialogs->show(70628);
+ else
+ _vm->_dialogs->show(70629);
+
+ _game._objects.setRoom(OBJ_VASE, _scene->_currentSceneId);
+ if (_animationMode == 2)
+ _game._objects.setRoom(OBJ_BOTTLE, 2);
+
+ _animationMode = 0;
+ _scene->_reloadSceneFlag = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene706::handleTakeVase() {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 4, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 7, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _vm->_sound->command(9);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _scene->_dynamicHotspots.remove(_vaseHotspotId);
+ _game._objects.addToInventory(OBJ_VASE);
+ if (_vaseMode == 1) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 4);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(195, 99));
+ int idx = _scene->_dynamicHotspots.add(NOUN_BOTTLE, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(175, 124), FACING_SOUTHEAST);
+ _game._objects.setRoom(OBJ_BOTTLE, _scene->_currentSceneId);
+ }
+ break;
+
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[3]);
+ _game._player._visible = true;
+ _vm->_dialogs->showItem(OBJ_VASE, 70630);
+ _game._player._stepEnabled = true;
+ break;
+ }
+}
+
+void Scene706::enter() {
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites("*RXMRC_3");
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('b', -1));
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _emptyPedestral = false;
+
+ if (_game._objects[OBJ_VASE]._roomNumber == _scene->_currentSceneId) {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('v', -1));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 4);
+ int idx = _scene->_dynamicHotspots.add(NOUN_VASE, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _vaseHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(175, 124), FACING_SOUTHEAST);
+ } else if (_game._objects.isInRoom(OBJ_BOTTLE)) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 4);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(195, 99));
+ int idx = _scene->_dynamicHotspots.add(NOUN_BOTTLE, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(175, 124), FACING_SOUTHEAST);
+ }
+
+ _game._player._visible = true;
+
+ if (_scene->_priorSceneId == 707) {
+ _game._player._playerPos = Common::Point(277, 103);
+ _game._player._facing = FACING_SOUTHWEST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(167, 152);
+ _game._player._facing = FACING_NORTH;
+ }
+
+ if (_globals[kTeleporterCommand]) {
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+
+ switch (_globals[kTeleporterCommand]) {
+ case 1:
+ _scene->loadAnimation(formAnimName('E', 1), 75);
+ break;
+
+ case 2:
+ _scene->loadAnimation(formAnimName('E', -1), 80);
+ break;
+
+ default:
+ _game._player.walk(Common::Point(264, 116), FACING_SOUTHWEST);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ }
+ _globals[kTeleporterCommand] = 0;
+ }
+
+ _animationMode = 0;
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_BOTTLE);
+ _globals[kBottleStatus] = 2;
+ }
+
+ sceneEntrySound();
+}
+
+void Scene706::step() {
+ if (_game._trigger == 75) {
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount;
+ _game._player.walk(Common::Point(264, 116), FACING_SOUTHWEST);
+ }
+
+ if (_game._trigger == 80) {
+ _globals[kTeleporterCommand] = 1;
+ _scene->_nextSceneId = _globals[kTeleporterDestination];
+ _scene->_reloadSceneFlag = true;
+ }
+
+ if (_scene->_activeAnimation != nullptr) {
+ if ((_animationMode != 0) && (_scene->_activeAnimation->getCurrentFrame() != _animationFrame)) {
+ _animationFrame = _scene->_activeAnimation->getCurrentFrame();
+
+ if (_animationFrame == 6) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._objects.setRoom(OBJ_VASE, 2);
+
+ if (_animationMode == 2) {
+ _game._objects.setRoom(OBJ_BOTTLE, 1);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 4);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(195, 99));
+ int idx = _scene->_dynamicHotspots.add(NOUN_BOTTLE, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(175, 124), FACING_SOUTHEAST);
+ }
+ }
+ }
+ }
+}
+
+void Scene706::preActions() {
+ if (_action.isAction(VERB_LOOK, NOUN_PORTRAIT))
+ _game._player._needToWalk = true;
+}
+
+void Scene706::actions() {
+ if (_action.isAction(VERB_WALK_INSIDE, NOUN_TELEPORTER)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_nextSceneId = 707;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_EXIT, NOUN_ROOM)) {
+ _scene->_nextSceneId = 705;
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_VASE)) {
+ if (_game._difficulty != DIFFICULTY_EASY) {
+ _animationMode = 1;
+ handleRexDeath();
+ } else if (_game._trigger || !_game._objects.isInInventory(OBJ_VASE)) {
+ handleTakeVase();
+ _emptyPedestral = true;
+ }
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_BOTTLE, NOUN_PEDESTAL)) {
+ if ((_globals[kBottleStatus] == 2 && _game._difficulty == DIFFICULTY_HARD) ||
+ (_globals[kBottleStatus] != 0 && _game._difficulty != DIFFICULTY_HARD)) {
+ if (!_game._objects.isInInventory(OBJ_VASE) || _game._trigger) {
+ _vaseMode = 1;
+ handleTakeVase();
+ _action._inProgress = false;
+ return;
+ }
+ } else if (_game._objects.isInRoom(OBJ_VASE) || _game._trigger) {
+ _animationMode = 2;
+ handleRexDeath();
+ _action._inProgress = false;
+ return;
+ }
+ }
+
+ if (_action.isAction(VERB_PUT, NOUN_PEDESTAL) && _game._objects.isInInventory(_game._objects.getIdFromDesc(_action._activeAction._objectNameId))) {
+ int objectId = _game._objects.getIdFromDesc(_action._activeAction._objectNameId);
+ if (_game._objects[objectId].hasQuality(10))
+ _vm->_dialogs->show(70626);
+ else
+ _vm->_dialogs->show(70627);
+ } else if (_action.isAction(VERB_TAKE, NOUN_BOTTLE) && _game._objects.isInInventory(OBJ_VASE))
+ _vm->_dialogs->show(70631);
+ else if (_action._lookFlag) {
+ if (_game._objects[OBJ_VASE]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(70610);
+ else
+ _vm->_dialogs->show(70611);
+ } else if (_action.isAction(VERB_LOOK, NOUN_FLOOR))
+ _vm->_dialogs->show(70612);
+ else if (_action.isAction(VERB_LOOK, NOUN_PILLAR))
+ _vm->_dialogs->show(70613);
+ else if (_action.isAction(VERB_LOOK, NOUN_OLD_TEA_CUP))
+ _vm->_dialogs->show(70614);
+ else if (_action.isAction(VERB_TAKE, NOUN_OLD_TEA_CUP))
+ _vm->_dialogs->show(70615);
+ else if (_action.isAction(VERB_LOOK, NOUN_OLD_VASE))
+ _vm->_dialogs->show(70616);
+ else if (_action.isAction(VERB_LOOK, NOUN_PORTRAIT))
+ _vm->_dialogs->show(70617);
+ else if (_action.isAction(VERB_LOOK, NOUN_NAME_PLATE))
+ _vm->_dialogs->show(70618);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(70619);
+ else if (_action.isAction(VERB_LOOK, NOUN_PEDESTAL)) {
+ if (_game._objects[OBJ_VASE]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(70620);
+ else if (_game._objects[OBJ_BOTTLE]._roomNumber == _scene->_currentSceneId)
+ _vm->_dialogs->show(70622);
+ else
+ _vm->_dialogs->show(70621);
+ } else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(70623);
+ else if (_action.isAction(VERB_LOOK, NOUN_VASE) && (_game._objects[OBJ_VASE]._roomNumber == _scene->_currentSceneId))
+ _vm->_dialogs->show(70624);
+ else if (_action.isAction(VERB_LOOK, NOUN_BOTTLE) && (_action._mainObjectSource == 4))
+ _vm->_dialogs->show(70632);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene707::setup() {
+ _game._player._spritesPrefix = "";
+ // The original calls Scene7xx::setAAName()
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene707::enter() {
+ _handSpriteId = _scene->_sprites.addSprites("*REXHAND");
+ teleporterEnter();
+
+ // The original uses Scene7xx_sceneEntrySound
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else
+ _vm->_sound->command(25);
+}
+
+void Scene707::step() {
+ teleporterStep();
+}
+
+void Scene707::actions() {
+ if (teleporterActions()) {
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT) || _action.isAction(VERB_PEER_THROUGH, NOUN_VIEWPORT))
+ _vm->_dialogs->show(70710);
+ else if (_action.isAction(VERB_LOOK, NOUN_KEYPAD))
+ _vm->_dialogs->show(70711);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(70712);
+ else if (_action.isAction(VERB_LOOK, NOUN_0_KEY) || _action.isAction(VERB_LOOK, NOUN_1_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_2_KEY) || _action.isAction(VERB_LOOK, NOUN_3_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_4_KEY) || _action.isAction(VERB_LOOK, NOUN_5_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_6_KEY) || _action.isAction(VERB_LOOK, NOUN_7_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_8_KEY) || _action.isAction(VERB_LOOK, NOUN_9_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_SMILE_KEY) || _action.isAction(VERB_LOOK, NOUN_ENTER_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_FROWN_KEY))
+ _vm->_dialogs->show(70713);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEVICE) || _action._lookFlag)
+ _vm->_dialogs->show(70714);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene710::setup() {
+ _game._player._spritesPrefix = "";
+ setAAName();
+}
+
+void Scene710::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+
+ if (_game._objects[OBJ_VASE]._roomNumber == 706) {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', -1));
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0);
+ }
+
+ _game._player._visible = false;
+ _scene->_sequences.addTimer(600, 70);
+
+ sceneEntrySound();
+}
+
+void Scene710::step() {
+ if (_game._trigger == 70) {
+ if (_game._globals[kCityFlooded])
+ _scene->_nextSceneId = 701;
+ else
+ _scene->_nextSceneId = 751;
+ }
+}
+
+void Scene710::actions() {
+ if (_action.isAction(VERB_PUT_DOWN, NOUN_BINOCULARS)) {
+ _game._player._stepEnabled = false;
+
+ if (_game._globals[kCityFlooded])
+ _scene->_nextSceneId = 701;
+ else
+ _scene->_nextSceneId = 751;
+
+ _action._inProgress = false;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene711::setup() {
+ // The original was calling Scene7xx::setPlayerSpreitesPrefix()
+ _vm->_sound->command(5);
+ Common::String oldName = _game._player._spritesPrefix;
+ _game._player._spritesPrefix = "";
+ _game._player._scalingVelocity = true;
+
+ if (oldName != _game._player._spritesPrefix)
+ _game._player._spritesChanged = true;
+
+ _vm->_palette->setEntry(16, 10, 63, 63);
+ _vm->_palette->setEntry(17, 10, 45, 45);
+
+ // The original was calling Scene7xx::setAAName()
+ _game._aaName = Resources::formatAAName(5);
+
+ _game._player._spritesPrefix = "";
+}
+
+void Scene711::enter() {
+ if (_globals[kSexOfRex] == REX_FEMALE)
+ _handSpriteId = _scene->_sprites.addSprites("*ROXHAND");
+ else
+ _handSpriteId = _scene->_sprites.addSprites("*REXHAND");
+
+ teleporterEnter();
+
+ // The original was using Scene7xx_SceneEntrySound()
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else
+ _vm->_sound->command(25);
+}
+
+void Scene711::step() {
+ teleporterStep();
+}
+
+void Scene711::actions() {
+ if (teleporterActions())
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene751::Scene751(MADSEngine *vm) : Scene7xx(vm) {
+ _rexHandingLine = false;
+}
+
+void Scene751::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+
+ s.syncAsByte(_rexHandingLine);
+}
+
+void Scene751::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_FISHING_LINE);
+ _scene->addActiveVocab(VERB_WALKTO);
+}
+
+void Scene751::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites("*RM701X0");
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('f', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RM202A1");
+
+ if (!_game._visitedScenes._sceneRevisited)
+ _rexHandingLine = false;
+
+ if (_globals[kLineStatus] == 2 || _globals[kLineStatus] == 3) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(268, 140), FACING_NORTHWEST);
+ }
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+
+ if (_scene->_priorSceneId == 752) {
+ _game._player._playerPos = Common::Point(309, 138);
+ _game._player._facing = FACING_WEST;
+ } else if (_scene->_priorSceneId == 710) {
+ _game._player._playerPos = Common::Point(154, 129);
+ _game._player._facing = FACING_NORTH;
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129));
+ _scene->_sequences.addTimer(15, 70);
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(22, 131);
+ _game._player._facing = FACING_EAST;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.addTimer(60, 60);
+ } else if (_rexHandingLine) {
+ _game._player._visible = false;
+ _game._player._playerPos = Common::Point(268, 140);
+ _game._player._facing = FACING_NORTHWEST;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 7);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ } else if (_globals[kLineStatus] == 2) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(268, 140), FACING_NORTHWEST);
+ }
+
+ if (_scene->_roomChanged) {
+ _game._objects.addToInventory(OBJ_FISHING_LINE);
+ _game._objects.addToInventory(OBJ_BINOCULARS);
+ }
+
+ sceneEntrySound();
+ _game.loadQuoteSet(0x30A, 0x30B, 0x30C, 0x30D, 0x30E, 0);
+
+ if (_globals[kTimebombTimer] > 0)
+ _globals[kTimebombTimer] = 10200;
+}
+
+void Scene751::step() {
+ switch (_game._trigger) {
+ case 70:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 71:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((_globals[kTimebombTimer] >= 10800) && (_globals[kTimebombStatus] == 1)) {
+ _globals[kTimebombStatus] = 3;
+ _globals[kTimebombTimer] = 0;
+ _globals[kCheckDaemonTimebomb] = false;
+ _scene->_nextSceneId = 620;
+ }
+
+ switch (_game._trigger) {
+ case 60:
+ _vm->_sound->command(16);
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 61);
+ break;
+
+ case 61:
+ _game._player.walk(Common::Point(61, 131), FACING_EAST);
+ _scene->_sequences.addTimer(120, 62);
+ break;
+
+ case 62:
+ _vm->_sound->command(17);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 63);
+ break;
+
+ case 63:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _game._player._stepEnabled = true;
+ _scene->_kernelMessages.reset();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Scene751::preActions() {
+ if (_action.isAction(VERB_LOOK, NOUN_TALL_BUILDING))
+ _game._player.walk(Common::Point(154, 129), FACING_NORTHEAST);
+
+ if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_TALL_BUILDING))
+ _game._player.walk(Common::Point(154, 129), FACING_NORTH);
+
+ if (_action.isAction(VERB_WALKTO, NOUN_EAST_END_OF_PLATFORM))
+ _game._player._walkOffScreenSceneId = 752;
+
+ if (!_rexHandingLine)
+ return;
+
+ if (_action.isAction(VERB_LOOK) || _action.isObject(NOUN_FISHING_LINE) || _action.isAction(VERB_TALKTO))
+ _game._player._needToWalk = false;
+
+ if ((!_action.isAction(VERB_PUT, NOUN_FISHING_LINE, NOUN_HOOK) || !_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_HOOK) || !_action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_HOOK))
+ && (_game._player._needToWalk)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._readyToWalk = false;
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 11, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, 7);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _rexHandingLine = false;
+ _game._player._stepEnabled = true;
+ _game._player._readyToWalk = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void Scene751::actions() {
+ if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM))
+ ; // Nothing
+ else if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_TALL_BUILDING)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129));
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_sequences.addTimer(15, 2);
+ }
+ break;
+
+ case 2:
+ _scene->_nextSceneId = 710;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_STEP_INTO, NOUN_ELEVATOR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _vm->_sound->command(16);
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_kernelMessages.reset();
+ _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0x30D));
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1:
+ _game._player.walk(Common::Point(22, 131), FACING_EAST);
+ _scene->_sequences.addTimer(120, 3);
+ break;
+
+ case 3:
+ _vm->_sound->command(17);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 4);
+ break;
+
+ case 4:
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, -1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10);
+ _scene->_sequences.addTimer(60, 5);
+ break;
+
+ case 5:
+ _game._player._stepEnabled = true;
+ _scene->_nextSceneId = 513;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PUT, NOUN_FISHING_LINE, NOUN_HOOK) || _action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_HOOK) || _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_HOOK)) {
+ if (_globals[kLineStatus] == 1) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, 6);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], -1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1);
+ break;
+
+ case 1: {
+ int syncIdx = _globals._sequenceIndexes[2];
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 7);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[2], syncIdx);
+ _scene->_sequences.addTimer(30, 2);
+ }
+ break;
+
+ case 2:
+ _rexHandingLine = true;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 8, -2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 3);
+ break;
+
+ case 3: {
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[2]);
+ _game._player._visible = true;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, -1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7);
+ int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(268, 140), FACING_NORTHWEST);
+ _scene->_kernelMessages.reset();
+ _game._objects.setRoom(OBJ_FISHING_LINE, _scene->_currentSceneId);
+ _rexHandingLine = false;
+ _globals[kLineStatus] = 2;
+ _game._player._stepEnabled = true;
+ _vm->_dialogs->show(75120);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_CITY))
+ _vm->_dialogs->show(75110);
+ else if (_action.isAction(VERB_LOOK, NOUN_ELEVATOR))
+ _vm->_dialogs->show(75112);
+ else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM))
+ _vm->_dialogs->show(75113);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEMENT_PYLON))
+ _vm->_dialogs->show(75114);
+ else if ((_action.isAction(VERB_LOOK, NOUN_HOOK) || _action.isAction(VERB_LOOK, NOUN_FISHING_LINE))
+ && (_globals[kLineStatus] == 2 || _globals[kLineStatus] == 3))
+ _vm->_dialogs->show(75116);
+ else if (_action.isAction(VERB_LOOK, NOUN_HOOK))
+ _vm->_dialogs->show(75115);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCK))
+ _vm->_dialogs->show(75117);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCK))
+ _vm->_dialogs->show(75118);
+ else if (_action.isAction(VERB_LOOK, NOUN_EAST_END_OF_PLATFORM))
+ _vm->_dialogs->show(75119);
+ else if (_action.isAction(VERB_TAKE, NOUN_FISHING_LINE) && (_globals[kLineStatus] == 3 || _globals[kLineStatus] == 2))
+ _vm->_dialogs->show(75121);
+ else if (_action.isAction(VERB_LOOK, NOUN_TALL_BUILDING))
+ _vm->_dialogs->show(75122);
+ else if (_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_CEMENT_PYLON) || _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_CEMENT_PYLON))
+ _vm->_dialogs->show(75123);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene752::Scene752(MADSEngine *vm) : Scene7xx(vm) {
+ _cardId = -1;
+}
+
+void Scene752::synchronize(Common::Serializer &s) {
+ Scene7xx::synchronize(s);
+
+ s.syncAsSint16LE(_cardId);
+}
+
+void Scene752::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+
+ _scene->addActiveVocab(NOUN_ID_CARD);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(VERB_LOOK_AT);
+ _scene->addActiveVocab(NOUN_LASER_BEAM);
+}
+
+void Scene752::enter() {
+ _globals._spriteIndexes[14] = _scene->_sprites.addSprites(formAnimName('l', -1));
+ _globals._spriteIndexes[12] = _scene->_sprites.addSprites("*RXMBD_8");
+
+ if (_scene->_priorSceneId == 751) {
+ _game._player._playerPos = Common::Point(13, 145);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(289, 138);
+ _game._player.walk(Common::Point(262, 148), FACING_WEST);
+ _game._player._facing = FACING_WEST;
+ _game._player._visible = true;
+ }
+
+ if (_game._objects[OBJ_ID_CARD]._roomNumber == 752) {
+ _globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('i', -1));
+ _globals._sequenceIndexes[13] = _scene->_sequences.startCycle(_globals._spriteIndexes[13], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_ID_CARD, VERB_WALKTO, _globals._sequenceIndexes[13], Common::Rect(0, 0, 0, 0));
+ _cardId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(234, 135), FACING_NORTH);
+ }
+
+ if (_game._globals[kLaserHoleIsThere]) {
+ _globals._sequenceIndexes[14] = _scene->_sequences.startCycle(_globals._spriteIndexes[14], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[14], 13);
+ int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_LOOK_AT, _globals._sequenceIndexes[14], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(215, 130), FACING_NORTHWEST);
+ }
+
+ if (_game._globals[kTeleporterCommand]) {
+ switch(_game._globals[kTeleporterCommand]) {
+ case TELEPORTER_BEAM_OUT:
+ case TELEPORTER_WRONG:
+ case TELEPORTER_STEP_OUT:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ default:
+ break;
+ }
+
+ _game._globals[kTeleporterCommand] = TELEPORTER_NONE;
+ }
+
+ if (_globals._timebombTimer > 0)
+ _globals._timebombTimer = 10800 - 600;
+
+ sceneEntrySound();
+}
+
+void Scene752::step() {
+ if (_globals._timebombTimer >= 10800 && _game._globals[kTimebombStatus] == TIMEBOMB_ACTIVATED) {
+ _globals[kTimebombStatus] = TIMEBOMB_DEAD;
+ _globals._timebombTimer = 0;
+ _globals[kCheckDaemonTimebomb] = false;
+ _scene->_nextSceneId = 620;
+ }
+}
+
+void Scene752::preActions() {
+ if (_action.isAction(VERB_WALKTO, NOUN_WEST_END_OF_PLATFORM)) {
+ _game._player._walkOffScreenSceneId = 751;
+ }
+}
+
+void Scene752::actions() {
+ if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM))
+ ;
+ else if (_action.isAction(VERB_STEP_INTO, NOUN_TELEPORTER)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_nextSceneId = 711;
+ } else if (_action.isAction(VERB_TAKE, NOUN_ID_CARD) && (!_game._objects.isInInventory(OBJ_ID_CARD) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+ case 1:
+ _vm->_sound->command(0xF);
+ _scene->_sequences.remove(_globals._sequenceIndexes[13]);
+ _game._objects.addToInventory(OBJ_ID_CARD);
+ _scene->_dynamicHotspots.remove(_cardId);
+ _vm->_dialogs->show(OBJ_ID_CARD, 830);
+ break;
+ case 2:
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._mainObjectSource == 4) && (!_game._objects.isInInventory(OBJ_BONES) || _game._trigger)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+ case 1:
+ _vm->_sound->command(0xF);
+ if (_game._objects.isInInventory(OBJ_BONE))
+ _game._objects.setRoom(OBJ_BONE, 1);
+ _game._objects.addToInventory(OBJ_BONES);
+ _vm->_dialogs->show(OBJ_BONES, 75221);
+ break;
+ case 2:
+ _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[12]);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+ default:
+ break;
+ }
+ } else if (_action._lookFlag || _action.isAction(VERB_LOOK, NOUN_CITY)) {
+ if (_globals[kLaserHoleIsThere])
+ _vm->_dialogs->show(75212);
+ else
+ _vm->_dialogs->show(75210);
+ } else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM))
+ _vm->_dialogs->show(75213);
+ else if (_action.isAction(VERB_LOOK, NOUN_CEMENT_BLOCK))
+ _vm->_dialogs->show(75214);
+ else if (_action.isAction(VERB_LOOK, NOUN_ROCK))
+ _vm->_dialogs->show(75215);
+ else if (_action.isAction(VERB_TAKE, NOUN_ROCK))
+ _vm->_dialogs->show(75216);
+ else if (_action.isAction(VERB_LOOK, NOUN_WEST_END_OF_PLATFORM))
+ _vm->_dialogs->show(75217);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(75218);
+ else if ((_action.isAction(VERB_LOOK, NOUN_BONES) || _action.isAction(VERB_LOOK, NOUN_ID_CARD)) && (_action._mainObjectSource == 4)) {
+ if (_game._objects[OBJ_ID_CARD]._roomNumber == 752)
+ _vm->_dialogs->show(75219);
+ else
+ _vm->_dialogs->show(75220);
+ } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._mainObjectSource == 4)) {
+ if (_game._objects.isInInventory(OBJ_BONES))
+ _vm->_dialogs->show(75222);
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes7.h b/engines/mads/nebular/nebular_scenes7.h
new file mode 100644
index 0000000000..dfb3c0f16e
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes7.h
@@ -0,0 +1,238 @@
+/* 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 MADS_NEBULAR_SCENES7_H
+#define MADS_NEBULAR_SCENES7_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene7xx : public NebularScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void setAAName();
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix();
+
+ void sceneEntrySound();
+
+public:
+ Scene7xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene701 : public Scene7xx {
+private:
+ int _fishingLineId;
+
+public:
+ Scene701(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+ virtual void step();
+};
+
+class Scene702 : public Scene7xx {
+public:
+ Scene702(MADSEngine *vm) : Scene7xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene703 : public Scene7xx{
+private:
+ int _monsterMode;
+ int _boatFrame;
+ int _curSequence;
+ int _boatDir;
+
+ bool _useBomb;
+ bool _startMonsterTimer;
+ bool _rexDeathFl;
+ bool _restartTrigger70Fl;
+
+ uint32 _lastFrameTime;
+ uint32 _monsterTime;
+
+ Conversation _dialog1;
+
+ void handleBottleInterface();
+ void setBottleSequence();
+ void handleFillBottle(int quote);
+
+public:
+ Scene703(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene704 : public Scene7xx{
+private:
+ int _bottleHotspotId;
+ int _boatCurrentFrame;
+ int _animationMode;
+ int _boatDirection;
+
+ bool _takeBottleFl;
+
+ Conversation _dialog1;
+
+ void handleFillBottle(int quote);
+ void setBottleSequence();
+ void handleBottleInterface();
+
+public:
+ Scene704(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene705 : public Scene7xx{
+private:
+ Conversation _dialog1;
+
+ void handleFillBottle(int quote);
+ void setBottleSequence();
+ void handleBottleInterface();
+
+public:
+ Scene705(MADSEngine *vm) : Scene7xx(vm) {}
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene706 : public Scene7xx{
+private:
+ int _vaseHotspotId;
+ int _vaseMode;
+ int _animationMode;
+ int _animationFrame;
+
+ bool _emptyPedestral;
+
+ void handleTakeVase();
+ void handleRexDeath();
+
+public:
+ Scene706(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene707 : public SceneTeleporter {
+public:
+ Scene707(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene710 : public Scene7xx {
+public:
+ Scene710(MADSEngine *vm) : Scene7xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene711 : public SceneTeleporter {
+public:
+ Scene711(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene751 : public Scene7xx{
+private:
+ bool _rexHandingLine;
+
+public:
+ Scene751(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene752 : public Scene7xx {
+private:
+ int _cardId;
+
+public:
+ Scene752(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES7_H */
diff --git a/engines/mads/nebular/nebular_scenes8.cpp b/engines/mads/nebular/nebular_scenes8.cpp
new file mode 100644
index 0000000000..66502831cc
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes8.cpp
@@ -0,0 +1,1524 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/nebular/nebular_scenes8.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+void Scene8xx::setPlayerSpritesPrefix() {
+ _vm->_sound->command(5);
+ if ((_globals[kFromCockpit] && !_globals[kExitShip]) ||
+ _scene->_nextSceneId == 804 || _scene->_nextSceneId == 805 ||
+ _scene->_nextSceneId == 808 || _scene->_nextSceneId == 810) {
+ _game._player._spritesPrefix = "";
+ } else
+ _game._player._spritesPrefix = _globals[kSexOfRex] == SEX_FEMALE ? "ROX" : "RXM";
+
+ _vm->_palette->setEntry(16, 0x0A, 0x3F, 0x3F);
+ _vm->_palette->setEntry(17, 0x0A, 0x2D, 0x2D);
+}
+
+void Scene8xx::setAAName() {
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene8xx::sceneEntrySound() {
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else {
+ switch (_scene->_nextSceneId) {
+ case 801:
+ case 802:
+ case 803:
+ case 804:
+ case 806:
+ case 807:
+ case 808:
+ _vm->_sound->command(20);
+ break;
+
+ case 805:
+ _vm->_sound->command(23);
+ break;
+
+ case 810:
+ _vm->_sound->command(10);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene801::Scene801(MADSEngine *vm) : Scene8xx(vm) {
+ _walkThroughDoor = false;
+}
+
+void Scene801::synchronize(Common::Serializer &s) {
+ Scene8xx::synchronize(s);
+
+ s.syncAsByte(_walkThroughDoor);
+}
+
+void Scene801::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene801::enter() {
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 3));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('a', -1));
+
+ if (_scene->_priorSceneId != 802) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 13);
+ }
+
+ if ((_globals[kCameFromCut]) && (_globals[kCutX] != 0)) {
+ _game._player._playerPos = Common::Point(_globals[kCutX], _globals[kCutY]);
+ _game._player._facing = (Facing)_globals[kCutFacing];
+ _globals[kCutX] = 0;
+ _globals[kCameFromCut] = false;
+ _globals[kReturnFromCut] = false;
+ _globals[kBeamIsUp] = false;
+ _globals[kForceBeamDown] = false;
+ _globals[kDontRepeat] = false;
+ } else if (_scene->_priorSceneId == 808) {
+ _game._player._playerPos = Common::Point(148, 110);
+ _game._player._facing = FACING_NORTH;
+ } else if (_scene->_priorSceneId == 802) {
+ _game._player._playerPos = Common::Point(307, 111);
+ _game._player.walk(Common::Point(270, 118), FACING_WEST);
+ _game._player._visible = true;
+ } else if ((_scene->_priorSceneId != -2) && !_globals[kTeleporterCommand]) {
+ _game._player._playerPos = Common::Point(8, 117);
+ _game._player.walk(Common::Point(41, 115), FACING_EAST);
+ _game._player._visible = true;
+ }
+
+ _globals[kBetweenRooms] = false;
+
+ if (_globals[kTeleporterCommand]) {
+ _game._player._stepEnabled = false;
+ switch (_globals[kTeleporterCommand]) {
+ case 1:
+ _game._player._playerPos = Common::Point(8, 117);
+ _globals[kTeleporterUnderstood] = true;
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 13);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 75);
+ _vm->_sound->command(30);
+ break;
+
+ case 2:
+ _game._player._playerPos = Common::Point(8, 117);
+ _globals[kTeleporterUnderstood] = true;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 13);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 8090);
+ _vm->_sound->command(30);
+ break;
+
+ case 3:
+ case 4:
+ _game._player._playerPos = Common::Point(8, 117);
+ _game._player.walk(Common::Point(41, 115), FACING_EAST);
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ _globals[kTeleporterCommand] = 0;
+ }
+
+ _walkThroughDoor = false;
+ if (_scene->_priorSceneId == 802) {
+ _game._player._stepEnabled = false;
+ _walkThroughDoor = true;
+ }
+
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 11, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], -1, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 14);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 9, 0, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -1, -2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 14);
+
+ sceneEntrySound();
+}
+
+void Scene801::step() {
+ if (_game._trigger == 75) {
+ if (_globals[kSexOfRex] == REX_FEMALE) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 8);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 140);
+ } else {
+ _game._player._stepEnabled = true;
+ _game._player._visible = true;
+ _game._player._playerPos = Common::Point(8, 117);
+ _game._player.walk(Common::Point(41, 115), FACING_EAST);
+ }
+ }
+
+ if (_game._trigger == 140) {
+ _vm->_sound->command(27);
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, 8);
+ _scene->_sequences.addTimer(100, 141);
+ }
+
+ if (_game._trigger == 141) {
+ _scene->_reloadSceneFlag = true;
+ _scene->_nextSceneId = _scene->_priorSceneId;
+ _globals[kTeleporterCommand] = 0;
+ }
+
+ if (_game._trigger == 80) {
+ _globals[kTeleporterCommand] = 1;
+ _scene->_nextSceneId = _globals[kTeleporterDestination];
+ _scene->_reloadSceneFlag = true;
+ }
+
+ if (_walkThroughDoor && (_game._player._playerPos == Common::Point(270, 118))) {
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 10);
+ _walkThroughDoor = false;
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 120);
+ }
+
+ if (_game._trigger == 120) {
+ _vm->_sound->command(12);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 10);
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 90) {
+ _game._player.walk(Common::Point(307, 111), FACING_EAST);
+ _scene->_sequences.addTimer(80, 130);
+ }
+
+ if (_game._trigger == 130) {
+ _vm->_sound->command(12);
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 10);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 110);
+ }
+
+ if (_game._trigger == 110) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 10);
+ _scene->_nextSceneId = 802;
+ }
+}
+
+void Scene801::preActions() {
+ if (_action.isAction(VERB_LOOK, NOUN_CONTROL_PANEL)) {
+ _game._player.walk(Common::Point(148, 110), FACING_NORTH);
+ _game._player._needToWalk = true;
+ _game._player._readyToWalk = true;
+ }
+
+ if (_action.isAction(VERB_WALK_INSIDE, NOUN_TELEPORTER) && _globals[kBeamIsUp]) {
+ _globals[kCutX] = _game._player._playerPos.x;
+ _globals[kCutY] = _game._player._playerPos.y;
+ _globals[kCutFacing] = _game._player._facing;
+ _globals[kForceBeamDown] = true;
+ _globals[kDontRepeat] = true;
+ _scene->_nextSceneId = 803;
+ }
+}
+
+void Scene801::actions() {
+ if (_action.isAction(VERB_LOOK, NOUN_CONTROL_PANEL))
+ _scene->_nextSceneId = 808;
+ else if (_action.isAction(VERB_WALK_INSIDE, NOUN_TELEPORTER)) {
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _scene->_nextSceneId = 807;
+ } else if (_action.isAction(VERB_WALK_THROUGH, NOUN_DOOR) && (_game._player._playerPos == Common::Point(270, 118))) {
+ _game._player._stepEnabled = false;
+ _game._player._facing = FACING_EAST;
+ _game._player.selectSeries();
+ _globals[kBetweenRooms] = true;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 13);
+ _vm->_sound->command(11);
+ } else if (_action.isAction(VERB_LOOK, NOUN_CEILING))
+ _vm->_dialogs->show(80110);
+ else if (_action.isAction(VERB_LOOK, NOUN_MONITOR))
+ _vm->_dialogs->show(80111);
+ else if (_action.isAction(VERB_LOOK, NOUN_TELEPORTER))
+ _vm->_dialogs->show(80112);
+ else if (_action.isAction(VERB_LOOK, NOUN_EQUIPMENT) || _action._lookFlag)
+ _vm->_dialogs->show(80113);
+ else if (_action.isAction(VERB_LOOK, NOUN_SPEAKER))
+ _vm->_dialogs->show(80114);
+ else if (_action.isAction(VERB_LOOK, NOUN_EYE_CHART))
+ _vm->_dialogs->show(80115);
+ else if (_action.isAction(VERB_LOOK, NOUN_WALL))
+ _vm->_dialogs->show(80116);
+ else if (_action.isAction(VERB_LOOK, NOUN_DOOR))
+ _vm->_dialogs->show(80117);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene802::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_SHIELD_MODULATOR);
+ _scene->addActiveVocab(VERB_WALKTO);
+ _scene->addActiveVocab(NOUN_REMOTE);
+}
+
+void Scene802::enter() {
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites("*RXMRC_8");
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('f', 2));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('f', 0));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('f', 1));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites("*RXMBD_8");
+ _globals[kBetweenRooms] = false;
+
+ if ((_globals[kCameFromCut]) && (_globals[kCutX] != 0)) {
+ _game._player._playerPos.x = _globals[kCutX];
+ _game._player._playerPos.y = _globals[kCutY];
+ _game._player._facing = (Facing)_globals[kCutFacing];
+ _globals[kCutX] = 0;
+ _globals[kCameFromCut] = false;
+ _globals[kReturnFromCut] = false;
+ _globals[kBeamIsUp] = false;
+ _globals[kForceBeamDown] = false;
+ _globals[kDontRepeat] = false;
+ _globals[kAntigravClock] = _scene->_frameStartTime;
+ } else if (_scene->_priorSceneId == 801) {
+ _game._player._playerPos = Common::Point(15, 129);
+ _game._player._facing = FACING_EAST;
+ } else if (_scene->_priorSceneId == 803) {
+ _game._player._playerPos = Common::Point(303, 119);
+ _game._player._facing = FACING_WEST;
+
+ } else if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(15, 129);
+ _game._player._facing = FACING_EAST;
+ }
+
+ _game._player._visible = true;
+
+
+
+ if (_globals[kHasWatchedAntigrav] && !_globals[kRemoteSequenceRan]) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _scene->_sequences.addTimer(200, 70);
+ }
+
+ if ((_globals[kRemoteOnGround]) && (!_game._objects.isInInventory(OBJ_REMOTE))) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_REMOTE, VERB_WALKTO,_globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(107, 99), FACING_NORTH);
+ }
+
+ if (!_game._objects.isInInventory(OBJ_SHIELD_MODULATOR) && !_globals[kShieldModInstalled]) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SHIELD_MODULATOR, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(93, 97), FACING_NORTH);
+ }
+ sceneEntrySound();
+}
+
+void Scene802::step() {
+ if (_game._trigger == 70) {
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 19);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 4, 72);
+ }
+
+ if (_game._trigger == 71) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 8);
+ int idx = _scene->_dynamicHotspots.add(NOUN_REMOTE, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(107, 99), FACING_NORTH);
+
+ _globals[kRemoteSequenceRan] = true;
+ _globals[kRemoteOnGround] = true;
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 72)
+ _vm->_sound->command(13);
+}
+
+void Scene802::preActions() {
+ if (_action.isAction(VERB_WALK_TOWARDS, NOUN_BUILDING_TO_WEST))
+ _game._player._walkOffScreenSceneId = 801;
+
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_EAST)) {
+ _game._player._walkOffScreenSceneId = 803;
+ _globals[kForceBeamDown] = false;
+ }
+
+ if (_action.isAction(VERB_TAKE, NOUN_SHIP))
+ _game._player._needToWalk = false;
+}
+
+void Scene802::actions() {
+ if (_action.isAction(VERB_TAKE, NOUN_SHIELD_MODULATOR) && !_game._objects.isInInventory(OBJ_SHIELD_MODULATOR)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _vm->_sound->command(9);
+ break;
+
+ case 2:
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _game._objects.addToInventory(OBJ_SHIELD_MODULATOR);
+ _vm->_dialogs->showItem(OBJ_SHIELD_MODULATOR, 80215);
+ break;
+
+ default:
+ break;
+ }
+ } else if ((_action.isAction(VERB_TAKE, NOUN_REMOTE)) && (!_game._objects.isInInventory(OBJ_REMOTE))) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 7, 2, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 4, 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2);
+ break;
+
+ case 1:
+ _scene->_sequences.remove(_globals._sequenceIndexes[4]);
+ _vm->_sound->command(9);
+ _globals[kRemoteOnGround] = false;
+ break;
+
+ case 2:
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _scene->_sequences.addTimer(20, 3);
+ break;
+
+ case 3:
+ _game._player._stepEnabled = true;
+ _game._objects.addToInventory(OBJ_REMOTE);
+ _vm->_dialogs->showItem(OBJ_REMOTE, 80223);
+ break;
+
+ default:
+ break;
+ }
+ } else if (!_globals[kRemoteOnGround] && (_game._objects.isInInventory(OBJ_SHIELD_MODULATOR) || _globals[kShieldModInstalled])
+ && (_action.isAction(VERB_LOOK, NOUN_LAUNCH_PAD) || _action._lookFlag))
+ _vm->_dialogs->show(80210);
+ else if (!_globals[kRemoteOnGround]&& !_game._objects.isInInventory(OBJ_SHIELD_MODULATOR) && !_globals[kShieldModInstalled]
+ && (_action.isAction(VERB_LOOK, NOUN_LAUNCH_PAD) || _action._lookFlag))
+ _vm->_dialogs->show(80211);
+ else if (_globals[kRemoteOnGround] && !_game._objects.isInInventory(OBJ_SHIELD_MODULATOR) && !_globals[kShieldModInstalled]
+ && (_action.isAction(VERB_LOOK, NOUN_LAUNCH_PAD) || _action._lookFlag))
+ _vm->_dialogs->show(80213);
+ else if (_globals[kRemoteOnGround] && (_game._objects.isInInventory(OBJ_SHIELD_MODULATOR) || _globals[kShieldModInstalled])
+ && (_action.isAction(VERB_LOOK, NOUN_LAUNCH_PAD) || _action._lookFlag))
+ _vm->_dialogs->show(80212);
+ else if (!_game._objects.isInInventory(OBJ_SHIELD_MODULATOR) && !_globals[kShieldModInstalled] && _action.isAction(VERB_LOOK, NOUN_SHIELD_MODULATOR))
+ _vm->_dialogs->show(80214);
+ else if (_globals[kRemoteOnGround] && _action.isAction(VERB_LOOK, NOUN_REMOTE))
+ _vm->_dialogs->show(80216);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHIP)) {
+ if ((!_game._objects.isInInventory(OBJ_SHIELD_MODULATOR)) && (!_globals[kShieldModInstalled]))
+ _vm->_dialogs->show(80218);
+ else
+ _vm->_dialogs->show(80217);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BUSHES))
+ _vm->_dialogs->show(80219);
+ else if (_action.isAction(VERB_LOOK, NOUN_PATH_TO_EAST))
+ _vm->_dialogs->show(80220);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKY))
+ _vm->_dialogs->show(80221);
+ else if (_action.isAction(VERB_TAKE, NOUN_SHIP))
+ _vm->_dialogs->show(80222);
+ else if (_action.isAction(VERB_LOOK, NOUN_TREE) || _action.isAction(VERB_LOOK, NOUN_TREES))
+ _vm->_dialogs->show(80224);
+ else if (_action.isAction(VERB_LOOK, NOUN_BUILDING_TO_WEST))
+ _vm->_dialogs->show(80225);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene803::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(NOUN_GUTS);
+ _scene->addActiveVocab(VERB_WALKTO);
+
+ if ((!_globals[kFromCockpit] && _globals[kReturnFromCut] && !_globals[kBeamIsUp])
+ || (_globals[kFromCockpit] && !_globals[kExitShip])) {
+ _game._player._spritesPrefix = "";
+ _game._player._spritesChanged = true;
+ }
+}
+
+void Scene803::enter() {
+ _globals[kBetweenRooms] = false;
+ _game._player._visible = false;
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('f', 1));
+ _globals._spriteIndexes[9] = _scene->_sprites.addSprites("*RXMBD_2");
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('d', 1));
+
+ _game.loadQuoteSet(0x31B, 0x31C, 0x31D, 0x31E, 0x31F, 0x320, 0x321, 0x322, 0);
+
+ if (_globals[kHoppyDead]) {
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('e', 1));
+ _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1);
+ int idx = _scene->_dynamicHotspots.add(NOUN_GUTS, VERB_WALKTO, _globals._sequenceIndexes[7], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(66, 123), FACING_SOUTH);
+ }
+
+ if (!_globals[kBeamIsUp] && !_globals[kReturnFromCut] && (!_globals[kFromCockpit] || _globals[kExitShip])) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 2, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ }
+
+ if (!_globals[kFromCockpit]) {
+ if (!_globals[kReturnFromCut]) {
+ if (_scene->_priorSceneId != -2) {
+ _game._player._playerPos = Common::Point(15, 130);
+ _game._player._facing = FACING_EAST;
+ }
+ _game._player._visible = true;
+ } else if (!_globals[kBeamIsUp]){
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 3));
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('a', 2));
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 15);
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ _vm->_sound->command(14);
+ }
+
+ if (_globals[kBeamIsUp] && !_globals[kReturnFromCut]){
+ if (_globals[kForceBeamDown])
+ _game._player._visible = false;
+ else
+ _game._player._visible = true;
+
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _vm->_sound->command(15);
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 6);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 100);
+ }
+ } else if (!_globals[kExitShip]) {
+ if (!_globals[kBeamIsUp]) {
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 8, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 130);
+ _vm->_sound->command(14);
+ } else {
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('c', 1));
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 1);
+ _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 8, 1, 0, 0);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 1);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 140);
+ }
+ } else {
+ _game._player._stepEnabled = false;
+ _game._player._playerPos = Common::Point(197, 96);
+ _game._player._facing = FACING_SOUTHWEST;
+ _game._player._visible = true;
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('d', 1));
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 19);
+ _scene->_sequences.addTimer(1, 150);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene803::step() {
+ if (_game._trigger == 120) {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 19);
+ _scene->_nextSceneId = 804;
+ }
+
+ if (_game._trigger == 100) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 2, 2);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1);
+ if (!_globals[kHoppyDead]) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 7, 12);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5],SEQUENCE_TRIGGER_EXPIRE, 0, 101);
+ } else {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, -2);
+ int idx = _scene->_dynamicHotspots.add(NOUN_GUTS, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(66, 123), FACING_SOUTH);
+ _vm->_sound->command(16);
+ _globals[kCameFromCut] = true;
+ _globals[kBeamIsUp] = false;
+ _globals[kReturnFromCut] = false;
+ _globals[kDontRepeat] = false;
+ _globals[kHoppyDead] = true;
+ _globals[kHasWatchedAntigrav] = true;
+
+ if (_globals[kForceBeamDown])
+ _scene->_nextSceneId = _scene->_priorSceneId;
+ else
+ _game._player._stepEnabled = true;
+ }
+ }
+
+ if (_game._trigger == 101) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], false, -2);
+ int idx = _scene->_dynamicHotspots.add(NOUN_GUTS, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(66, 123), FACING_SOUTH);
+ _vm->_sound->command(16);
+ _globals[kCameFromCut] = true;
+ _globals[kBeamIsUp] = false;
+ _globals[kReturnFromCut] = false;
+ _globals[kDontRepeat] = false;
+ _globals[kHoppyDead] = true;
+ _globals[kHasWatchedAntigrav] = true;
+
+ if (_globals[kForceBeamDown])
+ _scene->_nextSceneId = _scene->_priorSceneId;
+ else
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 80) {
+ if (!_globals[kHoppyDead])
+ _scene->_sequences.addTimer(350, 70);
+
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 3);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
+ }
+
+ if (_game._trigger == 70) {
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _vm->_sound->command(31);
+ }
+
+ if (_game._trigger == 71)
+ _scene->_sequences.addTimer(200, 110);
+
+ if (_game._trigger == 90) {
+ int syncIdx = _globals._sequenceIndexes[4];
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 0, 0, 0);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 4, 9);
+ if (_globals[kHoppyDead])
+ _scene->_sequences.addTimer(200, 110);
+ }
+
+ if (_game._trigger == 110)
+ _scene->_nextSceneId = 808;
+
+ if (_game._trigger == 130) {
+ _globals[kBeamIsUp] = true;
+ _scene->_nextSceneId = 804;
+ }
+
+ if (_game._trigger == 140) {
+ if (!_globals[kWindowFixed]) {
+ _scene->_nextSceneId = 810;
+ _globals[kInSpace] = true;
+ } else {
+ if (!_globals[kShieldModInstalled])
+ _game._winStatus = 1;
+ else if (!_globals[kTargetModInstalled])
+ _game._winStatus = 2;
+ else
+ _game._winStatus = 3;
+
+ _vm->quitGame();
+ }
+ }
+
+ if (_game._trigger == 150) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[6]);
+ _vm->_sound->command(18);
+ _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 19);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 151);
+ }
+
+ if (_game._trigger == 151) {
+ _globals[kBeamIsUp] = false;
+ _globals[kFromCockpit] = false;
+ _globals[kExitShip] = false;
+ _game._player._stepEnabled = true;
+ }
+}
+
+void Scene803::preActions() {
+ if (_action.isAction(VERB_WALK_DOWN, NOUN_PATH_TO_WEST))
+ _game._player._walkOffScreenSceneId = 802;
+
+ if (_action.isAction(VERB_TAKE, NOUN_SHIP))
+ _game._player._needToWalk = false;
+}
+
+void Scene803::actions() {
+ if (_action.isAction(VERB_TAKE, NOUN_GUTS)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _game._player._visible = false;
+ _globals._sequenceIndexes[9] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[9]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 160);
+ break;
+
+ case 160: {
+ int syncIdx = _globals._sequenceIndexes[9];
+ _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 4);
+ _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], syncIdx);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[9]);
+ _scene->_sequences.addTimer(60, 161);
+ }
+ break;
+
+ case 161: {
+ int quoteId = 0x31A + _vm->getRandomNumber(1, 8);
+ _scene->_kernelMessages.add(Common::Point(64, 67), 0x1110, 32, 0, 80, _game.getQuote(quoteId));
+ _scene->_sequences.addTimer(60, 162);
+ }
+ break;
+
+ case 162:
+ _scene->_sequences.remove(_globals._sequenceIndexes[9]);
+ _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 1, 4);
+ _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[9]);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 163);
+ break;
+
+ case 163:
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
+ _game._player._visible = true;
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_ENTER, NOUN_SHIP)) {
+ _vm->_sound->command(17);
+ _game._player._stepEnabled = false;
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 19);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 4);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 120);
+ _globals[kBeamIsUp] = false;
+ } else if (_action.isAction(VERB_LOOK, NOUN_LAUNCH_PAD))
+ _vm->_dialogs->show(80310);
+ else if (_action._lookFlag)
+ _vm->_dialogs->show(80310);
+ else if (_action.isAction(VERB_LOOK, NOUN_PAD_TO_WEST))
+ _vm->_dialogs->show(80311);
+ else if (_action.isAction(VERB_LOOK, NOUN_GUTS)) {
+ if (_game._storyMode == STORYMODE_NICE)
+ _vm->_dialogs->show(80312);
+ else
+ _vm->_dialogs->show(80313);
+ } else if (_action.isAction(VERB_LOOK, NOUN_BUSHES))
+ _vm->_dialogs->show(80315);
+ else if (_action.isAction(VERB_LOOK, NOUN_SHIP))
+ _vm->_dialogs->show(80317);
+ else if (_action.isAction(VERB_LOOK, NOUN_TOWER))
+ _vm->_dialogs->show(80318);
+ else if (_action.isAction(VERB_LOOK, NOUN_TREE) || _action.isAction(VERB_LOOK, NOUN_TREES))
+ _vm->_dialogs->show(80319);
+ else if (_action.isAction(VERB_LOOK, NOUN_SKY))
+ _vm->_dialogs->show(80320);
+ else if (_action.isAction(VERB_TAKE, NOUN_SHIP))
+ _vm->_dialogs->show(80321);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene804::Scene804(MADSEngine *vm) : Scene8xx(vm) {
+ _messWithThrottle = false;
+ _movingThrottle = false;
+ _throttleGone = false;
+ _dontPullThrottleAgain = false;
+ _pullThrottleReally = false;
+ _alreadyOrgan = false;
+ _alreadyPop = false;
+
+ _throttleCounter = 0;
+ _resetFrame = -1;
+}
+
+void Scene804::synchronize(Common::Serializer &s) {
+ Scene8xx::synchronize(s);
+
+ s.syncAsByte(_messWithThrottle);
+ s.syncAsByte(_movingThrottle);
+ s.syncAsByte(_throttleGone);
+ s.syncAsByte(_dontPullThrottleAgain);
+ s.syncAsByte(_pullThrottleReally);
+ s.syncAsByte(_alreadyOrgan);
+ s.syncAsByte(_alreadyPop);
+
+ s.syncAsSint16LE(_resetFrame);
+ s.syncAsUint32LE(_throttleCounter);
+}
+
+void Scene804::setup() {
+ Scene8xx::setPlayerSpritesPrefix();
+ Scene8xx::setAAName();
+}
+
+void Scene804::enter() {
+ _messWithThrottle = false;
+ _throttleCounter = 0;
+ _movingThrottle = false;
+ _throttleGone = false;
+ _dontPullThrottleAgain = false;
+ _resetFrame = -1;
+ _pullThrottleReally = false;
+ _alreadyOrgan = false;
+ _alreadyPop = false;
+
+
+ if (_globals[kCopyProtectFailed]) {
+ // Copy protection failed
+ _globals[kInSpace] = true;
+ _globals[kWindowFixed] = 0;
+ }
+
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('x', 0));
+ _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('x', 1));
+ _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('x', 2));
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('x', 3));
+ _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('x', 4));
+ _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('f', 1));
+
+ _game.loadQuoteSet(791, 0);
+
+ if (_globals[kInSpace]) {
+ if (_globals[kWindowFixed]) {
+ _globals._sequenceIndexes[5] = _scene->_sequences.startCycle(_globals._spriteIndexes[5], 0, 1);
+ _scene->_sequences.addTimer(60, 100);
+ } else {
+ _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1);
+ _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], false, 4, 0, 0, 0);
+ _scene->_sequences.addTimer(160, 70);
+ _game._player._stepEnabled = false;
+ }
+ } else {
+ if (_globals[kBeamIsUp] == 0)
+ _globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 1);
+
+ if (_globals[kWindowFixed] == 0)
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(133, 139));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
+ }
+
+ _scene->loadAnimation(Resources::formatName(804, 'r', 1, EXT_AA, ""));
+
+ Scene8xx::sceneEntrySound();
+
+ if (_globals[kInSpace] && !_globals[kWindowFixed]) {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _vm->_sound->command(19);
+ }
+}
+
+void Scene804::step() {
+ if (!_messWithThrottle) {
+
+ if ((_throttleGone) && (_movingThrottle) && (_scene->_activeAnimation->getCurrentFrame() == 39)) {
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle
+ (_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(133, 139));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
+ _throttleGone = false;
+ }
+
+ if ((_movingThrottle) && (_scene->_activeAnimation->getCurrentFrame() == 42)) {
+ _resetFrame = 0;
+ _movingThrottle = false;
+ }
+
+ if (_game._trigger == 70) {
+ _resetFrame = 42;
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 65)
+ _scene->_sequences.remove(_globals._sequenceIndexes[7]);
+
+ switch (_game._storyMode) {
+ case STORYMODE_NAUGHTY:
+ if (_scene->_activeAnimation->getCurrentFrame() == 81) {
+ _resetFrame = 80;
+ _globals[kInSpace] = false;
+ _globals[kBeamIsUp] = true;
+
+ assert(!_globals[kCopyProtectFailed]);
+ _game._winStatus = 4;
+ _vm->quitGame();
+ }
+ break;
+
+ case STORYMODE_NICE:
+ if (_scene->_activeAnimation->getCurrentFrame() == 68) {
+ _resetFrame = 66;
+ _globals[kInSpace] = false;
+ _globals[kBeamIsUp] = true;
+
+ assert(!_globals[kCopyProtectFailed]);
+ _game._winStatus = 4;
+ _vm->quitGame();
+ }
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 34) {
+ _resetFrame = 36;
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 37) {
+ _resetFrame = 36;
+ if (!_dontPullThrottleAgain) {
+ _dontPullThrottleAgain = true;
+ _scene->_sequences.addTimer(60, 80);
+ }
+ }
+
+ if (_game._trigger == 80) {
+ _scene->_nextSceneId = 803;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 7) && (!_globals[kWindowFixed])) {
+ _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1);
+ _scene->_sequences.addTimer(20, 110);
+ _globals[kWindowFixed] = true;
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 10) {
+ _resetFrame = 0;
+ _game._player._stepEnabled = true;
+ _game._objects.setRoom(OBJ_POLYCEMENT, NOWHERE);
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 1) {
+ int randomVal = _vm->getRandomNumber(29) + 1;
+ switch (randomVal) {
+ case 1:
+ _resetFrame = 25;
+ break;
+ case 2:
+ _resetFrame = 27;
+ break;
+ case 3:
+ _resetFrame = 29;
+ break;
+ default:
+ _resetFrame = 0;
+ break;
+ }
+ }
+
+ switch (_scene->_activeAnimation->getCurrentFrame()) {
+ case 26:
+ case 28:
+ case 31:
+ _resetFrame = 0;
+ break;
+ }
+ } else {
+ if ((_scene->_activeAnimation->getCurrentFrame() == 36) && (!_throttleGone)) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _throttleGone = true;
+ }
+
+ if (_scene->_activeAnimation->getCurrentFrame() == 39) {
+ _movingThrottle = false;
+ switch (_throttleCounter) {
+ case 1:
+ break;
+ case 3:
+ _scene->_sequences.addTimer(130, 120);
+ break;
+ }
+ }
+
+ if (!_movingThrottle) {
+ ++_throttleCounter;
+ _movingThrottle = true;
+ if (_throttleCounter < 4) {
+ _resetFrame = 34;
+ } else {
+ _messWithThrottle = false;
+ _throttleCounter = 0;
+ _game._player._stepEnabled = true;
+ }
+ }
+ }
+
+ if (_game._trigger == 120) {
+ _vm->_dialogs->show(80422);
+ }
+
+ if (_game._trigger == 110) {
+ _vm->_dialogs->show(80426);
+ }
+
+ if (_pullThrottleReally) {
+ _resetFrame = 32;
+ _pullThrottleReally = false;
+ }
+
+ if (_resetFrame >= 0) {
+ if (_resetFrame != _scene->_activeAnimation->getCurrentFrame()) {
+ _scene->_activeAnimation->setCurrentFrame(_resetFrame);
+ _resetFrame = -1;
+ }
+ }
+
+ if (_game._trigger == 90) {
+ _scene->_nextSceneId = 803;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 72) && !_alreadyPop) {
+ _vm->_sound->command(21);
+ _alreadyPop = true;
+ }
+
+ if ((_scene->_activeAnimation->getCurrentFrame() == 80) && !_alreadyOrgan) {
+ _vm->_sound->command(22);
+ _alreadyOrgan = true;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene805::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+ _scene->addActiveVocab(VERB_REMOVE);
+ _scene->addActiveVocab(NOUN_TARGET_MODULE);
+ _scene->addActiveVocab(NOUN_SHIELD_MODULATOR);
+}
+
+void Scene805::enter() {
+ _game._player._visible = false;
+ _scene->_userInterface.setup(kInputLimitedSentences);
+
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('a', 1));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 2));
+
+ if (_globals[kShieldModInstalled]) {
+ _scene->_hotspots.activate(OBJ_SHIELD_MODULATOR, false);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 25);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SHIELD_MODULATOR, VERB_REMOVE, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY);
+ }
+
+ if (_globals[kTargetModInstalled]) {
+ _scene->_hotspots.activate(OBJ_TARGET_MODULE, false);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 12);
+ int idx = _scene->_dynamicHotspots.add(NOUN_TARGET_MODULE, VERB_REMOVE, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene805::step() {
+ if (_game._trigger == 70) {
+ _scene->_hotspots.activate(OBJ_SHIELD_MODULATOR, false);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 25);
+ int idx = _scene->_dynamicHotspots.add(NOUN_SHIELD_MODULATOR, VERB_REMOVE, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY);
+ _globals[kShieldModInstalled] = true;
+ _game._objects.setRoom(OBJ_SHIELD_MODULATOR, NOWHERE);
+ _game._player._stepEnabled = true;
+ _vm->_sound->command(24);
+ }
+
+ if (_game._trigger == 80) {
+ _scene->_hotspots.activate(OBJ_TARGET_MODULE, false);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 12);
+ int idx = _scene->_dynamicHotspots.add(NOUN_TARGET_MODULE, VERB_REMOVE, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0));
+ _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY);
+ _globals[kTargetModInstalled] = true;
+ _game._objects.setRoom(OBJ_TARGET_MODULE, NOWHERE);
+ _game._player._stepEnabled = true;
+ _vm->_sound->command(24);
+ }
+
+ if (_game._trigger == 71) {
+ _scene->_hotspots.activate(OBJ_SHIELD_MODULATOR, true);
+ _globals[kShieldModInstalled] = false;
+ _game._objects.addToInventory(OBJ_SHIELD_MODULATOR);
+ _game._player._stepEnabled = true;
+ }
+
+ if (_game._trigger == 81) {
+ _scene->_hotspots.activate(OBJ_TARGET_MODULE, true);
+ _globals[kTargetModInstalled] = false;
+ _game._objects.addToInventory(OBJ_TARGET_MODULE);
+ _game._player._stepEnabled = true;
+ }
+}
+
+void Scene805::preActions() {
+ _game._player._needToWalk = false;
+}
+
+void Scene805::actions() {
+ if (_action.isAction(VERB_EXIT, NOUN_SERVICE_PANEL))
+ _scene->_nextSceneId = 804;
+ else if (_action.isAction(VERB_INSTALL, NOUN_SHIELD_MODULATOR) && _game._objects.isInInventory(OBJ_SHIELD_MODULATOR)) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], -1, -2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_INSTALL, NOUN_TARGET_MODULE) && _game._objects.isInInventory(OBJ_TARGET_MODULE)) {
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, -2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_REMOVE, NOUN_SHIELD_MODULATOR) && _globals[kShieldModInstalled]) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], -1, -2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_REMOVE, NOUN_TARGET_MODULE) && _globals[kTargetModInstalled]) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0);
+ _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, -2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ _game._player._stepEnabled = false;
+ } else if (_action.isAction(VERB_INSTALL, NOUN_SHIELD_MODULATOR) && !_game._objects.isInInventory(OBJ_SHIELD_MODULATOR))
+ _vm->_dialogs->show(80511);
+ else if (_action.isAction(VERB_INSTALL, NOUN_TARGET_MODULE) && !_game._objects.isInInventory(OBJ_TARGET_MODULE))
+ _vm->_dialogs->show(80510);
+ else if (_action.isAction(VERB_REMOVE, NOUN_LIFE_SUPPORT_MODULE))
+ _vm->_dialogs->show(80512);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Scene807::setup() {
+ _game._player._spritesPrefix = "";
+ // The original was calling Scene8xx::setAAName()
+ _game._aaName = Resources::formatAAName(5);
+}
+
+void Scene807::enter() {
+ if (_globals[kSexOfRex] == REX_FEMALE)
+ _handSpriteId = _scene->_sprites.addSprites("*ROXHAND");
+ else
+ _handSpriteId = _scene->_sprites.addSprites("*REXHAND");
+
+ teleporterEnter();
+
+ // The original uses Scene8xx::SceneEntrySound()
+ if (!_vm->_musicFlag)
+ _vm->_sound->command(2);
+ else
+ _vm->_sound->command(20);
+}
+
+void Scene807::step() {
+ teleporterStep();
+}
+
+void Scene807::actions() {
+ if (teleporterActions()) {
+ _action._inProgress = false;
+ return;
+ }
+
+ if (_action.isAction(VERB_LOOK, NOUN_VIEWPORT))
+ _vm->_dialogs->show(80710);
+ else if (_action.isAction(VERB_PEER_THROUGH, NOUN_VIEWPORT))
+ _vm->_dialogs->show(80710);
+ else if (_action.isAction(VERB_LOOK, NOUN_KEYPAD) && _action.isAction(VERB_INSPECT, NOUN_KEYPAD))
+ _vm->_dialogs->show(80711);
+ else if (_action.isAction(VERB_LOOK, NOUN_DISPLAY))
+ _vm->_dialogs->show(80712);
+ else if (_action.isAction(VERB_LOOK, NOUN_1_KEY) || _action.isAction(VERB_LOOK, NOUN_2_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_3_KEY) || _action.isAction(VERB_LOOK, NOUN_4_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_5_KEY) || _action.isAction(VERB_LOOK, NOUN_6_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_7_KEY) || _action.isAction(VERB_LOOK, NOUN_8_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_9_KEY) || _action.isAction(VERB_LOOK, NOUN_0_KEY)
+ || _action.isAction(VERB_LOOK, NOUN_SMILE_KEY) || _action.isAction(VERB_LOOK, NOUN_FROWN_KEY))
+ _vm->_dialogs->show(80713);
+ else if (_action.isAction(VERB_LOOK, NOUN_DEVICE) && _action._lookFlag)
+ _vm->_dialogs->show(80714);
+ else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene808::Scene808(MADSEngine *vm) : Scene8xx(vm) {
+ _goingTo803 = false;
+}
+
+void Scene808::synchronize(Common::Serializer &s) {
+ Scene8xx::synchronize(s);
+
+ s.syncAsByte(_goingTo803);
+}
+
+void Scene808::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene808::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+
+ _globals._spriteIndexes[4] = _scene->_sprites.addSprites ("*REXHAND");
+ _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0));
+ _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('b', 1));
+ _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 2));
+
+ if (_globals[kTopButtonPushed])
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ else
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+
+ _goingTo803 = false;
+
+ if (_globals[kCameFromCut] && _globals[kCutX] != 0) {
+ _globals[kCutX] = 0;
+ _globals[kCameFromCut] = false;
+ _globals[kReturnFromCut] = false;
+ _globals[kBeamIsUp] = false;
+ _globals[kForceBeamDown] = false;
+ _globals[kDontRepeat] = false;
+ } else if ((_scene->_priorSceneId == 803) && _globals[kReturnFromCut]){
+ _globals[kDontRepeat] = false;
+ _globals[kBeamIsUp] = true;
+ _globals[kAntigravClock] = _scene->_frameStartTime;
+ _globals[kAntigravTiming] = _scene->_frameStartTime;
+ _globals[kForceBeamDown] = false;
+ _globals[kReturnFromCut] = false;
+ }
+
+ _globals[kBetweenRooms] = false;
+
+ if (_globals[kBeamIsUp]) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ }
+
+ sceneEntrySound();
+}
+
+void Scene808::actions() {
+ if (_action.isAction(VERB_PRESS, NOUN_START_BUTTON_2)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 211));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ break;
+
+ case 70:
+ if (!_globals[kBeamIsUp] && !_globals[kTopButtonPushed]) {
+ _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 8);
+ _goingTo803 = true;
+ _vm->_sound->command(20);
+ _vm->_sound->command(25);
+ }
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 211));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
+ break;
+
+ case 71:
+ _game._player._stepEnabled = true;
+ if (_goingTo803 && !_globals[kTopButtonPushed]) {
+ _goingTo803 = false;
+ _globals[kReturnFromCut] = true;
+ _scene->_nextSceneId = 803;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PRESS, NOUN_TIMER_BUTTON_2)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 186));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
+ break;
+ case 90:
+ if (_globals[kTopButtonPushed]) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[1]);
+ _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 8);
+ _vm->_sound->command(20);
+ }
+ _globals[kTopButtonPushed] = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 186));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 91);
+ break;
+
+ case 91:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PRESS, NOUN_REMOTE_BUTTON_2)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 163));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ break;
+
+ case 80:
+ if (!_globals[kTopButtonPushed]) {
+ _scene->_sequences.remove(_globals._sequenceIndexes[2]);
+ _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1);
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8);
+ _vm->_sound->command(20);
+ }
+ _globals[kTopButtonPushed] = true;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 163));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 81);
+ break;
+
+ case 81:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PRESS, NOUN_START_BUTTON_1)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(168, 211));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 70);
+ break;
+
+ case 70:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PRESS, NOUN_REMOTE_BUTTON_1)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(172, 163));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 80);
+ break;
+
+ case 80:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_PRESS, NOUN_TIMER_BUTTON_1)) {
+ switch (_game._trigger) {
+ case 0:
+ _game._player._stepEnabled = false;
+ _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0);
+ _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(172, 186));
+ _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2);
+ _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 90);
+ break;
+
+ case 90:
+ _game._player._stepEnabled = true;
+ break;
+
+ default:
+ break;
+ }
+ } else if (_action.isAction(VERB_EXIT, NOUN_PANEL)) {
+ _scene->_nextSceneId = 801;
+ _globals[kBetweenRooms] = true;
+ } else
+ return;
+
+ _action._inProgress = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+Scene810::Scene810(MADSEngine *vm) : Scene8xx(vm) {
+ _moveAllowed = false;
+}
+
+void Scene810::synchronize(Common::Serializer &s) {
+ Scene8xx::synchronize(s);
+
+ s.syncAsByte(_moveAllowed);
+}
+
+void Scene810::setup() {
+ setPlayerSpritesPrefix();
+ setAAName();
+}
+
+void Scene810::enter() {
+ _scene->_userInterface.setup(kInputLimitedSentences);
+ _game._player._visible = false;
+ _game._player._stepEnabled = false;
+ _scene->loadAnimation(Resources::formatName(810, 'a', -1, EXT_AA, ""));
+ _moveAllowed = true;
+
+ sceneEntrySound();
+}
+
+void Scene810::step() {
+ if ((_scene->_activeAnimation->getCurrentFrame() == 200) && _moveAllowed) {
+ _scene->_sequences.addTimer(100, 70);
+ _moveAllowed = false;
+ }
+
+ if (_game._trigger == 70)
+ _scene->_nextSceneId = 804;
+}
+
+/*------------------------------------------------------------------------*/
+
+} // End of namespace Nebular
+} // End of namespace MADS
diff --git a/engines/mads/nebular/nebular_scenes8.h b/engines/mads/nebular/nebular_scenes8.h
new file mode 100644
index 0000000000..39e022e31f
--- /dev/null
+++ b/engines/mads/nebular/nebular_scenes8.h
@@ -0,0 +1,165 @@
+/* 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 MADS_NEBULAR_SCENES8_H
+#define MADS_NEBULAR_SCENES8_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/nebular/nebular_scenes.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+class Scene8xx : public NebularScene {
+protected:
+ /**
+ * Initial setup code shared by several scenes
+ */
+ void setPlayerSpritesPrefix();
+
+ /**
+ * Initial setup code shared by several scenes
+ */
+ void setAAName();
+
+ /**
+ * Common scene enter code used by multiple scenes
+ */
+ void sceneEntrySound();
+public:
+ Scene8xx(MADSEngine *vm) : NebularScene(vm) {}
+};
+
+class Scene801 : public Scene8xx{
+private:
+ bool _walkThroughDoor;
+
+public:
+ Scene801(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene802 : public Scene8xx{
+public:
+ Scene802(MADSEngine *vm) : Scene8xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene803 : public Scene8xx{
+public:
+ Scene803(MADSEngine *vm) : Scene8xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene804 : public Scene8xx {
+private:
+ bool _messWithThrottle;
+ bool _movingThrottle;
+ bool _throttleGone;
+ bool _dontPullThrottleAgain;
+ bool _pullThrottleReally;
+ bool _alreadyOrgan;
+ bool _alreadyPop;
+ uint32 _throttleCounter;
+ int _resetFrame;
+
+public:
+ Scene804(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions() {};
+};
+
+class Scene805 : public Scene8xx{
+public:
+ Scene805(MADSEngine *vm) : Scene8xx(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void preActions();
+ virtual void actions();
+};
+
+class Scene807 : public SceneTeleporter {
+public:
+ Scene807(MADSEngine *vm) : SceneTeleporter(vm) {}
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions();
+};
+
+class Scene808 : public Scene8xx{
+private:
+ bool _goingTo803;
+
+public:
+ Scene808(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void actions();
+};
+
+class Scene810 : public Scene8xx{
+private:
+ bool _moveAllowed;
+
+public:
+ Scene810(MADSEngine *vm);
+ void synchronize(Common::Serializer &s);
+
+ virtual void setup();
+ virtual void enter();
+ virtual void step();
+ virtual void actions() {};
+};
+
+} // End of namespace Nebular
+} // End of namespace MADS
+
+#endif /* MADS_NEBULAR_SCENES8_H */
diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp
new file mode 100644
index 0000000000..fc2755db2f
--- /dev/null
+++ b/engines/mads/nebular/sound_nebular.cpp
@@ -0,0 +1,3119 @@
+/* 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 "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+#include "common/algorithm.h"
+#include "common/debug.h"
+#include "common/memstream.h"
+#include "mads/sound.h"
+#include "mads/nebular/sound_nebular.h"
+
+namespace MADS {
+
+namespace Nebular {
+
+bool AdlibChannel::_channelsEnabled;
+
+AdlibChannel::AdlibChannel() {
+ _activeCount = 0;
+ _field1 = 0;
+ _field2 = 0;
+ _field3 = 0;
+ _field4 = 0;
+ _sampleIndex = 0;
+ _volume = 0;
+ _field7 = 0;
+ _field8 = 0;
+ _field9 = 0;
+ _fieldA = 0;
+ _fieldB = 0;
+ _fieldC = 0;
+ _fieldD = 0;
+ _fieldE = 0;
+ _ptr1 = nullptr;
+ _pSrc = nullptr;
+ _ptr3 = nullptr;
+ _ptr4 = nullptr;
+ _field17 = 0;
+ _field19 = 0;
+ _soundData = nullptr;
+ _field1D = 0;
+ _field1E = 0;
+ _field1F = 0;
+
+ _field20 = 0;
+}
+
+void AdlibChannel::reset() {
+ _activeCount = 0;
+ _field1 = 0;
+ _field2 = 0;
+ _field3 = 0;
+}
+
+void AdlibChannel::enable(int flag) {
+ if (_activeCount) {
+ _fieldE = flag;
+
+ // WORKAROUND: Original set _soundData pointer to flag. Since this seems
+ // just intended to invalidate any prior pointer, I've replaced it with
+ // a simple null pointer
+ _soundData = nullptr;
+ }
+
+ _channelsEnabled = true;
+}
+
+void AdlibChannel::setPtr2(byte *pData) {
+ _pSrc = pData;
+ _field2 = 0xFF;
+ _fieldA = 1;
+ _field9 = 1;
+}
+
+void AdlibChannel::load(byte *pData) {
+ _ptr1 = _pSrc = _ptr3 = pData;
+ _ptr4 = _soundData = pData;
+ _fieldA = 0xFF;
+ _activeCount = 1;
+ _fieldD = 64;
+ _field1 = 0;
+ _field1F = 0;
+ _field2 = _field3 = 0;
+ _volume = _field7 = 0;
+ _field1D = _field1E = 0;
+ _fieldE = 0;
+ _field9 = 0;
+ _fieldB = 0;
+ _field17 = 0;
+ _field19 = 0;
+}
+
+void AdlibChannel::check(byte *nullPtr) {
+ if (_activeCount && _fieldE) {
+ if (!_field1E) {
+ _pSrc = nullPtr;
+ _fieldE = 0;
+ } else {
+ _field2 = 0xFF;
+ _fieldA = 4;
+ if (!_field9)
+ _field9 = 1;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------*/
+
+AdlibSample::AdlibSample(Common::SeekableReadStream &s) {
+ _attackRate = s.readByte();
+ _decayRate = s.readByte();
+ _sustainLevel = s.readByte();
+ _releaseRate = s.readByte();
+ _egTyp = s.readByte() != 0;
+ _ksr = s.readByte() != 0;
+ _totalLevel = s.readByte();
+ _scalingLevel = s.readByte();
+ _waveformSelect = s.readByte();
+ _freqMultiple = s.readByte();
+ _feedback = s.readByte();
+ _ampMod = s.readByte() != 0;
+ _vib = s.readByte();
+ _alg = s.readByte();
+ _fieldE = s.readByte();
+ s.skip(1);
+ _freqMask = s.readUint16LE();
+ _freqBase = s.readUint16LE();
+ _field14 = s.readUint16LE();
+}
+
+/*-----------------------------------------------------------------------*/
+
+ASound::ASound(Audio::Mixer *mixer, const Common::String &filename, int dataOffset) {
+ // Open up the appropriate sound file
+ if (!_soundFile.open(filename))
+ error("Could not open file - %s", filename.c_str());
+
+ // Initialize fields
+ _commandParam = 0;
+ _activeChannelPtr = nullptr;
+ _samplePtr = nullptr;
+ _frameCounter = 0;
+ _isDisabled = false;
+ _v1 = 0;
+ _v2 = 0;
+ _activeChannelNumber = 0;
+ _freqMask1 = _freqMask2 = 0;
+ _freqBase1 = _freqBase2 = 0;
+ _channelNum1 = _channelNum2 = 0;
+ _v7 = 0;
+ _v8 = 0;
+ _v9 = 0;
+ _v10 = 0;
+ _pollResult = 0;
+ _resultFlag = 0;
+ _nullData[0] = _nullData[1] = 0;
+ Common::fill(&_ports[0], &_ports[256], 0);
+ _stateFlag = false;
+ _activeChannelReg = 0;
+ _v11 = 0;
+ _randomSeed = 1234;
+ _amDep = _vibDep = _splitPoint = true;
+
+ _samplesTillCallback = 0;
+ _samplesTillCallbackRemainder = 0;
+ _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
+ _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
+
+ for (int i = 0; i < 11; ++i) {
+ _channelData[i]._field0 = 0;
+ _channelData[i]._freqMask = 0;
+ _channelData[i]._freqBase = 0;
+ _channelData[i]._field6 = 0;
+ }
+
+ AdlibChannel::_channelsEnabled = false;
+
+ // Store passed parameters, and setup OPL
+ _dataOffset = dataOffset;
+ _mixer = mixer;
+ _opl = OPL::Config::create();
+ assert(_opl);
+
+ _opl->init(getRate());
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1,
+ Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+ // Initialize the Adlib
+ adlibInit();
+
+ // Reset the adlib
+ command0();
+}
+
+ASound::~ASound() {
+ Common::List<CachedDataEntry>::iterator i;
+ for (i = _dataCache.begin(); i != _dataCache.end(); ++i)
+ delete[] (*i)._data;
+
+ _mixer->stopHandle(_soundHandle);
+ delete _opl;
+}
+
+void ASound::adlibInit() {
+ write(4, 0x60);
+ write(4, 0x80);
+ write(2, 0xff);
+ write(4, 0x21);
+ write(4, 0x60);
+ write(4, 0x80);
+}
+
+int ASound::stop() {
+ command0();
+ int result = _pollResult;
+ _pollResult = 0;
+ return result;
+}
+
+int ASound::poll() {
+ // Update any playing sounds
+ update();
+
+ // Return result
+ int result = _pollResult;
+ _pollResult = 0;
+ return result;
+}
+
+void ASound::noise() {
+ int randomVal = getRandomNumber();
+
+ if (_v1) {
+ setFrequency(_channelNum1, ((randomVal ^ 0xFFFF) & _freqMask1) + _freqBase1);
+ }
+
+ if (_v2) {
+ setFrequency(_channelNum2, (randomVal & _freqMask2) + _freqBase2);
+ }
+}
+
+void ASound::write(int reg, int val) {
+ _queue.push(RegisterValue(reg, val));
+}
+
+int ASound::write2(int state, int reg, int val) {
+ // TODO: Original has a state parameter, not used when in Adlib mode?
+ _ports[reg] = val;
+ write(reg, val);
+ return state;
+}
+
+void ASound::flush() {
+ Common::StackLock slock(_driverMutex);
+
+ while (!_queue.empty()) {
+ RegisterValue v = _queue.pop();
+ _opl->writeReg(v._regNum, v._value);
+ }
+}
+
+void ASound::channelOn(int reg, int volume) {
+ write2(8, reg, (_ports[reg] & 0xC0) | (volume & 0x3F));
+}
+
+void ASound::channelOff(int reg) {
+ write2(8, reg, _ports[reg] | 0x3F);
+}
+
+void ASound::resultCheck() {
+ if (_resultFlag != 1) {
+ _resultFlag = 1;
+ _pollResult = 1;
+ }
+}
+
+byte *ASound::loadData(int offset, int size) {
+ // First scan for an existing copy
+ Common::List<CachedDataEntry>::iterator i;
+ for (i = _dataCache.begin(); i != _dataCache.end(); ++i) {
+ CachedDataEntry &e = *i;
+ if (e._offset == offset)
+ return e._data;
+ }
+
+ // No existing entry found, so load up data and store as a new entry
+ CachedDataEntry rec;
+ rec._offset = offset;
+ rec._data = new byte[size];
+ _soundFile.seek(_dataOffset + offset);
+ _soundFile.read(rec._data, size);
+ _dataCache.push_back(rec);
+
+ // Return the data
+ return rec._data;
+}
+
+void ASound::playSound(int offset, int size) {
+ // Load the specified data block
+ playSoundData(loadData(offset, size));
+}
+
+void ASound::playSoundData(byte *pData, int startingChannel) {
+ // Scan for a high level free channel
+ for (int i = startingChannel; i < ADLIB_CHANNEL_COUNT; ++i) {
+ if (!_channels[i]._activeCount) {
+ _channels[i].load(pData);
+ return;
+ }
+ }
+
+ // None found, do a secondary scan for an interruptable channel
+ for (int i = ADLIB_CHANNEL_COUNT - 1; i >= startingChannel; --i) {
+ if (_channels[i]._fieldE == 0xFF) {
+ _channels[i].load(pData);
+ return;
+ }
+ }
+}
+
+bool ASound::isSoundActive(byte *pData) {
+ for (int i = 0; i < ADLIB_CHANNEL_MIDWAY; ++i) {
+ if (_channels[i]._activeCount && _channels[i]._soundData == pData)
+ return true;
+ }
+
+ return false;
+}
+
+void ASound::setFrequency(int channel, int freq) {
+ write2(8, 0xA0 + channel, freq & 0xFF);
+ write2(8, 0xB0 + channel, (freq >> 8) | 0x20);
+}
+
+int ASound::getRandomNumber() {
+ int v = 0x9248 + (int)_randomSeed;
+ _randomSeed = ((v >> 3) | (v << 13)) & 0xFFFF;
+ return _randomSeed;
+}
+
+void ASound::update() {
+ getRandomNumber();
+ if (_isDisabled)
+ return;
+
+ ++_frameCounter;
+ pollChannels();
+ checkChannels();
+
+ if (_v1 == _v2) {
+ if (_resultFlag != -1) {
+ _resultFlag = -1;
+ _pollResult = -1;
+ }
+ } else {
+ if (_v1) {
+ _freqBase1 += _v7;
+ if (!--_v1) {
+ if (!_v2 || _channelNum1 != _channelNum2) {
+ write2(8, 0xA0 + _channelNum1, 0);
+ write2(8, 0xB0 + _channelNum1, 0);
+ }
+ }
+ }
+
+ if (_v2) {
+ _freqBase2 += _v8;
+ if (!--_v2) {
+ if (!_v1 || _channelNum2 != _channelNum1) {
+ write2(8, 0xA0 + _channelNum2, 0);
+ write2(8, 0xB0 + _channelNum2, 0);
+ }
+ }
+ }
+ }
+}
+
+void ASound::pollChannels() {
+ _activeChannelNumber = 0;
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i) {
+ _activeChannelPtr = &_channels[i];
+ pollActiveChannel();
+ }
+}
+
+void ASound::checkChannels() {
+ if (AdlibChannel::_channelsEnabled) {
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i].check(_nullData);
+ }
+}
+
+void ASound::pollActiveChannel() {
+ AdlibChannel *chan = _activeChannelPtr;
+
+ if (chan->_activeCount) {
+ if (chan->_field8 > 0 && --chan->_field8 == 0)
+ updateOctave();
+
+ bool updateFlag = true;
+ if (--_activeChannelPtr->_activeCount <= 0) {
+ for (;;) {
+ byte *pSrc = chan->_pSrc;
+ if (!chan->_ptr1) {
+ warning("pollActiveChannel(): No data found for sound channel");
+ break;
+ }
+ if (!(*pSrc & 0x80) || (*pSrc <= 0xF0)) {
+ if (updateFlag)
+ updateActiveChannel();
+
+ chan->_field4 = *pSrc++;
+ chan->_activeCount = *pSrc++;
+ chan->_pSrc += 2;
+
+ if (!chan->_field4 || !chan->_activeCount) {
+ updateOctave();
+ } else {
+ chan->_field8 = chan->_activeCount - chan->_field7;
+ updateChannelState();
+ }
+
+ // Break out of processing loop
+ break;
+ } else {
+ updateFlag = false;
+
+ switch ((~*pSrc) & 0xF) {
+ case 0:
+ if (!chan->_field17) {
+ if (*++pSrc == 0) {
+ chan->_pSrc += 2;
+ chan->_ptr3 = chan->_pSrc;
+ chan->_field17 = 0;
+ } else {
+ chan->_field17 = *pSrc;
+ chan->_pSrc = chan->_ptr3;
+ }
+ } else if (--chan->_field17) {
+ chan->_pSrc = chan->_ptr3;
+ } else {
+ chan->_pSrc += 2;
+ chan->_ptr3 = chan->_pSrc;
+ }
+ break;
+
+ case 1:
+ if (!chan->_field19) {
+ if (*++pSrc == 0) {
+ chan->_pSrc += 2;
+ chan->_ptr4 = chan->_pSrc;
+ chan->_ptr3 = chan->_pSrc;
+ chan->_field17 = 0;
+ chan->_field19 = 0;
+ } else {
+ chan->_field19 = *pSrc;
+ chan->_pSrc = chan->_ptr4;
+ chan->_ptr3 = chan->_ptr4;
+ }
+ } else if (--chan->_field19) {
+ chan->_ptr4 = chan->_pSrc;
+ chan->_ptr3 = chan->_pSrc;
+ } else {
+ chan->_pSrc += 2;
+ chan->_ptr4 = chan->_pSrc;
+ chan->_ptr3 = chan->_pSrc;
+ }
+ break;
+
+ case 2:
+ // Loop sound data
+ chan->_field1 = 0;
+ chan->_field2 = chan->_field3 = 0;
+ chan->_volume = chan->_field7 = 0;
+ chan->_field1D = chan->_field1E = 0;
+ chan->_field8 = 0;
+ chan->_field9 = 0;
+ chan->_fieldB = 0;
+ chan->_field17 = 0;
+ chan->_field19 = 0;
+ chan->_fieldD = 0x40;
+ chan->_ptr1 = chan->_soundData;
+ chan->_pSrc = chan->_soundData;
+ chan->_ptr3 = chan->_soundData;
+ chan->_ptr4 = chan->_soundData;
+
+ chan->_pSrc += 2;
+ break;
+
+ case 3:
+ chan->_sampleIndex = *++pSrc;
+ chan->_pSrc += 2;
+ loadSample(chan->_sampleIndex);
+ break;
+
+ case 4:
+ chan->_field7 = *++pSrc;
+ chan->_pSrc += 2;
+ break;
+
+ case 5:
+ chan->_field1 = *++pSrc;
+ chan->_pSrc += 2;
+ break;
+
+ case 6:
+ ++pSrc;
+ if (chan->_fieldE) {
+ chan->_pSrc += 2;
+ } else {
+ chan->_volume = *pSrc >> 1;
+ updateFlag = true;
+ chan->_pSrc += 2;
+ }
+ break;
+
+ case 7:
+ ++pSrc;
+ if (!chan->_fieldE) {
+ chan->_fieldA = *pSrc;
+ chan->_field2 = *++pSrc;
+ chan->_field9 = 1;
+ }
+
+ chan->_pSrc += 3;
+ break;
+
+ case 8:
+ chan->_field1D = *++pSrc;
+ chan->_pSrc += 2;
+ break;
+
+ case 9: {
+ int v1 = *++pSrc;
+ ++pSrc;
+ int v2 = (v1 - 1) & getRandomNumber();
+ int v3 = pSrc[v2];
+ int v4 = pSrc[v1];
+
+ pSrc[v4 + v1 + 1] = v3;
+ chan->_pSrc += v1 + 3;
+ break;
+ }
+
+ case 10:
+ ++pSrc;
+ if (chan->_fieldE) {
+ chan->_pSrc += 2;
+ } else {
+ chan->_field1E = *pSrc >> 1;
+ updateFlag = true;
+ chan->_pSrc += 2;
+ }
+ break;
+
+ case 11:
+ chan->_fieldD = *++pSrc;
+ updateFlag = true;
+ chan->_pSrc += 2;
+ break;
+
+ case 12:
+ chan->_fieldC = *++pSrc;
+ chan->_field3 = *++pSrc;
+ chan->_fieldB = 1;
+ chan->_pSrc += 2;
+ break;
+
+ case 13:
+ ++pSrc;
+ chan->_pSrc += 2;
+ break;
+
+ case 14:
+ chan->_field1F = *++pSrc;
+ chan->_pSrc += 2;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ if (chan->_field1)
+ updateFNumber();
+
+ updateFlag = false;
+ if (chan->_field9 || chan->_fieldB) {
+ if (!--chan->_field9) {
+ chan->_field9 = chan->_fieldA;
+ if (chan->_field2) {
+ int8 newVal = (int8)chan->_field2 + (int8)chan->_field1E;
+ if (newVal < 0) {
+ chan->_field9 = 0;
+ newVal = 0;
+ } else if (newVal > 63) {
+ chan->_field9 = 0;
+ newVal = 63;
+ }
+
+ chan->_field1E = newVal;
+ updateFlag = true;
+ }
+ }
+
+ if (!--chan->_fieldB) {
+ chan->_fieldB = chan->_fieldC;
+ if (chan->_field3) {
+ chan->_fieldD = chan->_field3;
+ updateFlag = true;
+ }
+ }
+
+ if (updateFlag)
+ updateActiveChannel();
+ }
+ }
+
+ ++_activeChannelNumber;
+}
+
+void ASound::updateOctave() {
+ int reg = 0xB0 + _activeChannelNumber;
+ write2(8, reg, _ports[reg] & 0xDF);
+}
+
+static int _vList1[] = {
+ 0x200, 0x21E, 0x23F, 0x261, 0x285, 0x2AB,
+ 0x2D4, 0x2FF, 0x32D, 0x35D, 0x390, 0x3C7
+};
+
+void ASound::updateChannelState() {
+ updateActiveChannel();
+
+ if (_channelData[_activeChannelNumber]._field0) {
+ if (_channelNum1 == _activeChannelNumber)
+ _stateFlag = 0;
+ if (_channelNum2 == _activeChannelNumber)
+ _stateFlag = 1;
+
+ if (!_stateFlag) {
+ _stateFlag = 1;
+ if (_v1)
+ write2(8, 0xB0 + _channelNum1, _ports[0xB0 + _channelNum1] & 0xDF);
+
+ _channelNum1 = _activeChannelNumber;
+ _v1 = _channelData[_channelNum1]._field0;
+ _freqMask1 = _channelData[_channelNum1]._freqMask;
+ _freqBase1 = _channelData[_channelNum1]._freqBase;
+ _v7 = _channelData[_channelNum1]._field6;
+ } else {
+ _stateFlag = 0;
+ if (_v2)
+ write2(8, 0xB0 + _channelNum2, _ports[0xB0 + _channelNum2] & 0xDF);
+
+ _channelNum2 = _activeChannelNumber;
+ _v2 = _channelData[_channelNum2]._field0;
+ _freqMask2 = _channelData[_channelNum2]._freqMask;
+ _freqBase2 = _channelData[_channelNum2]._freqBase;
+ _v8 = _channelData[_channelNum2]._field6;
+ }
+
+ resultCheck();
+ } else {
+ int reg = 0xA0 + _activeChannelNumber;
+ int vTimes = (_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) / 12;
+ int vOffset = (_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) % 12;
+ int val = _vList1[vOffset] + _activeChannelPtr->_field1D;
+ write2(8, reg, val & 0xFF);
+
+ reg += 0x10;
+ write2(8, reg, (_ports[reg] & 0x20) | (vTimes << 2) | (val >> 8));
+
+ write2(8, reg, _ports[reg] | 0x20);
+ }
+}
+
+static const int outputIndexes[] = {
+ 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 13, 16, 14, 17
+};
+static const int outputChannels[] = {
+ 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 0
+};
+static const int volumeList[] = {
+ 0x3F, 0x3F, 0x36, 0x31, 0x2D, 0x2A, 0x28, 0x26, 0x24, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C,
+ 0x1B, 0x1A, 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12,
+ 0x11, 0x11, 0x10, 0x10, 0x0F, 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B, 0x0A, 0x0A,
+ 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+void ASound::updateActiveChannel() {
+ int reg = 0x40 + outputChannels[outputIndexes[_activeChannelNumber * 2 + 1]];
+ int portVal = _ports[reg] & 0xFFC0;
+ int newVolume = CLIP(_activeChannelPtr->_volume + _activeChannelPtr->_field1E, 0, 63);
+
+ // Note: Original had a whole block not seeming to be used, since the initialisation
+ // sets a variable to 5660h, and doesn't change it, so the branch is never taken
+ int val = CLIP(newVolume - volumeList[_activeChannelPtr->_fieldD], 0, 63);
+ val = (63 - val) | portVal;
+
+ int val2 = CLIP(newVolume - volumeList[-(_activeChannelPtr->_fieldD - 127)], 0, 63);
+ val2 = (63 - val2) | portVal;
+ write2(0, reg, val);
+ write2(2, reg, val2);
+}
+
+void ASound::loadSample(int sampleIndex) {
+ _activeChannelReg = 0xB0 + _activeChannelNumber;
+ write2(8, _activeChannelReg, _ports[_activeChannelReg] & 0xDF);
+
+ _activeChannelReg = _activeChannelNumber;
+ _samplePtr = &_samples[sampleIndex * 2];
+ _v11 = outputChannels[outputIndexes[_activeChannelReg * 2]];
+ processSample();
+
+ AdlibChannelData &cd = _channelData[_activeChannelNumber];
+ cd._field6 = _samplePtr->_field14;
+ cd._freqBase = _samplePtr->_freqBase;
+ cd._freqMask = _samplePtr->_freqMask;
+ cd._field0 = _samplePtr->_fieldE;
+
+ _samplePtr = &_samples[sampleIndex * 2 + 1];
+ _v11 = outputChannels[outputIndexes[_activeChannelReg * 2 + 1]];
+ processSample();
+}
+
+void ASound::processSample() {
+ // Write out vib flags and split point
+ write2(8, 0x40 + _v11, 0x3F);
+ int depthRhythm = (_ports[0xBD] & 0x3F) | (_amDep ? 0x80 : 0) |
+ (_vibDep ? 0x40 : 0);
+ write2(8, 0xBD, depthRhythm);
+ write2(8, 8, _splitPoint ? 0x40 : 0);
+
+ // Write out feedback & Alg
+ int val = (_samplePtr->_feedback << 1) | (1 - _samplePtr->_alg);
+ write2(8, 0xC0 + _activeChannelReg, val);
+
+ // Write out attack/decay rate
+ val = (_samplePtr->_attackRate << 4) | (_samplePtr->_decayRate & 0xF);
+ write2(8, 0x60 + _v11, val);
+
+ // Write out sustain level/release rate
+ val = (_samplePtr->_sustainLevel << 4) | (_samplePtr->_releaseRate & 0xF);
+ write2(8, 0x80 + _v11, val);
+
+ // Write out misc flags
+ val = (_samplePtr->_ampMod ? 0x80 : 0) | (_samplePtr->_vib ? 0x40 : 0)
+ | (_samplePtr->_egTyp ? 0x20 : 0) | (_samplePtr->_ksr ? 0x10 : 0)
+ | (_samplePtr->_freqMultiple & 0xF);
+ write2(8, 0x20 + _v11, val);
+
+ // Write out waveform select
+ write2(8, 0xE0 + _v11, _samplePtr->_waveformSelect & 3);
+
+ // Write out total level & scaling level
+ val = -((_samplePtr->_totalLevel & 0x3F) - 0x3F) | (_samplePtr->_scalingLevel << 6);
+ write2(8, 0x40 + _v11, val);
+}
+
+void ASound::updateFNumber() {
+ int loReg = 0xA0 + _activeChannelNumber;
+ int hiReg = 0xB0 + _activeChannelNumber;
+ int val1 = (_ports[hiReg] & 0x1F) << 8;
+ val1 += _ports[loReg] + _activeChannelPtr->_field1;
+ write2(8, loReg, val1);
+
+ int val2 = (_ports[hiReg] & 0x20) | (val1 >> 8);
+ write2(8, hiReg, val2);
+}
+
+int ASound::readBuffer(int16 *buffer, const int numSamples) {
+ Common::StackLock slock(_driverMutex);
+
+ int32 samplesLeft = numSamples;
+ memset(buffer, 0, sizeof(int16) * numSamples);
+ while (samplesLeft) {
+ if (!_samplesTillCallback) {
+ poll();
+ flush();
+
+ _samplesTillCallback = _samplesPerCallback;
+ _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
+ if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
+ _samplesTillCallback++;
+ _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
+ }
+ }
+
+ int32 render = MIN<int>(samplesLeft, _samplesTillCallback);
+ samplesLeft -= render;
+ _samplesTillCallback -= render;
+
+ _opl->readBuffer(buffer, render);
+ buffer += render;
+ }
+ return numSamples;
+}
+
+int ASound::command0() {
+ bool isDisabled = _isDisabled;
+ _isDisabled = true;
+
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i].reset();
+
+ _v1 = 0;
+ _v2 = 0;
+ _freqMask1 = _freqMask2 = 0;
+ _freqBase1 = _freqBase2 = 0;
+ _v7 = 0;
+ _v8 = 0;
+
+ // Reset Adlib port registers
+ for (int reg = 0x4F; reg >= 0x40; --reg)
+ write2(8, reg, 0x3F);
+ for (int reg = 0xFF; reg >= 0x60; --reg)
+ write2(8, reg, 0);
+ for (int reg = 0x3F; reg > 0; --reg)
+ write2(8, reg, 0);
+ write2(8, 1, 0x20);
+
+ _isDisabled = isDisabled;
+ return 0;
+}
+
+int ASound::command1() {
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i].enable(0xFF);
+ return 0;
+}
+
+int ASound::command2() {
+ for (int i = 0; i < ADLIB_CHANNEL_MIDWAY; ++i)
+ _channels[i].setPtr2(_nullData);
+ return 0;
+}
+
+int ASound::command3() {
+ for (int i = 0; i < ADLIB_CHANNEL_MIDWAY; ++i)
+ _channels[i].enable(0xFF);
+ return 0;
+}
+
+int ASound::command4() {
+ for (int i = ADLIB_CHANNEL_MIDWAY; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i].setPtr2(_nullData);
+ return 0;
+}
+
+int ASound::command5() {
+ for (int i = 5; i < ADLIB_CHANNEL_COUNT; ++i)
+ _channels[i].enable(0xFF);
+ return 0;
+}
+
+int ASound::command6() {
+ _v9 = _v1;
+ _v1 = 0;
+ _v10 = _v2;
+ _v2 = 0;
+
+ channelOff(0x43);
+ channelOff(0x44);
+ channelOff(0x45);
+ channelOff(0x4B);
+ channelOff(0x4C);
+ channelOff(0x4D);
+ channelOff(0x53);
+ channelOff(0x54);
+ channelOff(0x55);
+
+ return 0;
+}
+
+int ASound::command7() {
+ channelOn(0x43, _channels[0]._volume);
+ channelOn(0x44, _channels[1]._volume);
+ channelOn(0x45, _channels[2]._volume);
+ channelOn(0x4B, _channels[3]._volume);
+ channelOn(0x4C, _channels[4]._volume);
+ channelOn(0x4D, _channels[5]._volume);
+
+ _v1 = _v9;
+ _v2 = _v10;
+
+ if (_v9 != _v10)
+ resultCheck();
+
+ _isDisabled = 0;
+ return _v10;
+}
+
+int ASound::command8() {
+ int result = 0;
+ for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i)
+ result |= _channels[i]._activeCount;
+
+ return result;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound1::CommandPtr ASound1::_commandList[42] = {
+ &ASound1::command0, &ASound1::command1, &ASound1::command2, &ASound1::command3,
+ &ASound1::command4, &ASound1::command5, &ASound1::command6, &ASound1::command7,
+ &ASound1::command8, &ASound1::command9, &ASound1::command10, &ASound1::command11,
+ &ASound1::command12, &ASound1::command13, &ASound1::command14, &ASound1::command15,
+ &ASound1::command16, &ASound1::command17, &ASound1::command18, &ASound1::command19,
+ &ASound1::command20, &ASound1::command21, &ASound1::command22, &ASound1::command23,
+ &ASound1::command24, &ASound1::command25, &ASound1::command26, &ASound1::command27,
+ &ASound1::command28, &ASound1::command29, &ASound1::command30, &ASound1::command31,
+ &ASound1::command32, &ASound1::command33, &ASound1::command34, &ASound1::command35,
+ &ASound1::command36, &ASound1::command37, &ASound1::command38, &ASound1::command39,
+ &ASound1::command40, &ASound1::command41
+};
+
+ASound1::ASound1(Audio::Mixer *mixer)
+ : ASound(mixer, "asound.001", 0x1520) {
+ _cmd23Toggle = false;
+
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x12C);
+ for (int i = 0; i < 98; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound1::command(int commandId, int param) {
+ if (commandId > 41)
+ return 0;
+
+ _commandParam = param;
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound1::command9() {
+ playSound(0xC68, 12);
+ return 0;
+}
+
+int ASound1::command10() {
+ byte *pData1 = loadData(0x130E, 48);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x133E, 392));
+ _channels[2].load(loadData(0x14C6, 46));
+ _channels[3].load(loadData(0x14F4, 48));
+ }
+
+ return 0;
+}
+
+int ASound1::command11() {
+ command111213();
+ _channels[0]._field1E = 0;
+ _channels[1]._field1E = 0;
+ return 0;
+}
+
+int ASound1::command12() {
+ command111213();
+ _channels[0]._field1E = 40;
+ _channels[1]._field1E = 0;
+ return 0;
+}
+
+int ASound1::command13() {
+ command111213();
+ _channels[0]._field1E = 40;
+ _channels[1]._field1E = 50;
+ return 0;
+}
+
+int ASound1::command14() {
+ playSound(0x1216, 248);
+ return 0;
+}
+
+int ASound1::command15() {
+ byte *pData1 = loadData(0x1524, 152);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[4].load(pData1);
+ _channels[5].load(loadData(0x15BC, 94));
+ _channels[6].load(loadData(0x161A, 94));
+ _channels[7].load(loadData(0x1678, 42));
+ _channels[8].load(loadData(0x16A2, 42));
+ }
+
+ return 0;
+}
+
+int ASound1::command16() {
+ playSound(0xC74, 14);
+ return 0;
+}
+
+int ASound1::command17() {
+ playSound(0xE9A, 10);
+ return 0;
+}
+
+int ASound1::command18() {
+ command1();
+ playSound(0xCA6, 20);
+ return 0;
+}
+
+int ASound1::command19() {
+ command1();
+ playSound(0xCBA, 74);
+ return 0;
+}
+
+int ASound1::command20() {
+ byte *pData = loadData(0xD18, 28);
+ if (!isSoundActive(pData))
+ playSoundData(pData);
+ return 0;
+}
+
+int ASound1::command21() {
+ playSound(0xD04, 20);
+ return 0;
+}
+
+int ASound1::command22() {
+ byte *pData = loadData(0xD34, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+
+ if (!isSoundActive(pData))
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound1::command23() {
+ _cmd23Toggle = !_cmd23Toggle;
+ playSound(_cmd23Toggle ? 0xD3E : 0xD46, 8);
+ return 0;
+}
+
+int ASound1::command24() {
+ playSound(0xD4E, 18);
+ playSound(0xD60, 20);
+ playSound(0xD74, 14);
+ return 0;
+}
+
+int ASound1::command25() {
+ byte *pData = loadData(0xD82, 16);
+ if (!isSoundActive(pData))
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound1::command26() {
+ byte *pData = loadData(0xEEC, 10);
+ pData[5] = (command2627293032() + 0x7F) & 0xFF;
+
+ if (!isSoundActive(pData))
+ _channels[6].load(pData);
+
+ return 0;
+}
+
+int ASound1::command27() {
+ byte *pData = loadData(0xEE2, 10);
+ pData[5] = (command2627293032() + 0x40) & 0xFF;
+
+ if (!isSoundActive(pData))
+ _channels[7].load(pData);
+
+ return 0;
+}
+
+int ASound1::command28() {
+ playSound(0xD92, 28);
+ return 0;
+}
+
+int ASound1::command29() {
+ byte *pData = loadData(0xC82, 36);
+ byte v = (command2627293032() + 0x40) & 0xFF;
+ pData[7] = pData[13] = pData[21] = pData[27] = v;
+
+ if (!isSoundActive(pData))
+ playSoundData(pData, 0);
+
+ return 0;
+}
+
+int ASound1::command30() {
+ byte *pData = loadData(0xEA6, 16);
+ pData[7] = (command2627293032() + 0x40) & 0xFF;
+
+ if (!isSoundActive(pData))
+ playSoundData(pData, 0);
+
+ return 0;
+}
+
+int ASound1::command31() {
+ byte *pData = loadData(0xDAE, 14);
+ if (!isSoundActive(pData))
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound1::command32() {
+ byte *pData = loadData(0xEB4, 46);
+ int v = command2627293032() + 0x40;
+ pData[9] = pData[17] = pData[25] = pData[33] = v & 0xFF;
+ pData[11] = pData[19] = pData[27] = pData[35] = v >> 8;
+
+ if (!isSoundActive(pData))
+ playSoundData(pData, 0);
+
+ return 0;
+}
+
+int ASound1::command33() {
+ playSound(0xDBC, 10);
+ playSound(0xDC6, 10);
+ return 0;
+}
+
+int ASound1::command34() {
+ int v = getRandomNumber() & 0x20;
+ if (!v)
+ v = 0x60;
+
+ byte *pData = loadData(0xDD0, 22);
+ pData[8] = pData[15] = v;
+ playSoundData(pData);
+ return 0;
+}
+
+int ASound1::command35() {
+ playSound(0xDE6, 16);
+ return 0;
+}
+
+int ASound1::command36() {
+ playSound(0xE10, 10);
+ command34();
+
+ return 0;
+}
+
+int ASound1::command37() {
+ playSound(0xE1A, 14);
+ return 0;
+}
+
+int ASound1::command38() {
+ playSound(0xE28, 114);
+ return 0;
+}
+
+int ASound1::command39() {
+ byte *pData1 = loadData(0x16CC, 82);
+ if (!isSoundActive(pData1)) {
+ _channels[5].load(pData1);
+ _channels[6].load(loadData(0x171E, 30));
+ _channels[7].load(loadData(0x173C, 40));
+ _channels[8].load(loadData(0x1764, 64));
+ }
+ return 0;
+}
+
+int ASound1::command40() {
+ playSound(0xDF6, 26);
+ return 0;
+}
+
+int ASound1::command41() {
+ playSound(0xC32, 34);
+ playSound(0xC54, 20);
+ return 0;
+}
+
+void ASound1::command111213() {
+ byte *pData1 = loadData(0xEF6, 408);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x108E, 266));
+ _channels[2].load(loadData(0x1198, 66));
+ _channels[2].load(loadData(0x11DA, 60));
+ }
+}
+
+int ASound1::command2627293032() {
+ return (_commandParam > 0x40) ? _commandParam - 0x40 : _commandParam & 0xff00;
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+const ASound2::CommandPtr ASound2::_commandList[44] = {
+ &ASound2::command0, &ASound2::command1, &ASound2::command2, &ASound2::command3,
+ &ASound2::command4, &ASound2::command5, &ASound2::command6, &ASound2::command7,
+ &ASound2::command8, &ASound2::command9, &ASound2::command10, &ASound2::command11,
+ &ASound2::command12, &ASound2::command13, &ASound2::command14, &ASound2::command15,
+ &ASound2::command16, &ASound2::command17, &ASound2::command18, &ASound2::command19,
+ &ASound2::command20, &ASound2::command21, &ASound2::command22, &ASound2::command23,
+ &ASound2::command24, &ASound2::command25, &ASound2::command26, &ASound2::command27,
+ &ASound2::command28, &ASound2::command29, &ASound2::command30, &ASound2::command31,
+ &ASound2::command32, &ASound2::command33, &ASound2::command34, &ASound2::command35,
+ &ASound2::command36, &ASound2::command37, &ASound2::command38, &ASound2::command39,
+ &ASound2::command40, &ASound2::command41, &ASound2::command42, &ASound2::command43
+};
+
+ASound2::ASound2(Audio::Mixer *mixer) : ASound(mixer, "asound.002", 0x15E0) {
+ _command12Param = 0xFD;
+
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x144);
+ for (int i = 0; i < 164; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound2::command(int commandId, int param) {
+ if (commandId > 43)
+ return 0;
+
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound2::command0() {
+ _command12Param = 0xFD;
+ return ASound::command0();
+}
+
+int ASound2::command9() {
+ byte *pData1 = loadData(0x1094, 376);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[2].load(loadData(0x123E, 130));
+
+ command9Randomize();
+ _channels[1].load(loadData(0x120C, 50));
+ }
+ return 0;
+}
+
+void ASound2::command9Randomize() {
+ // Randomization
+ int v;
+ while (((v = getRandomNumber()) & 0x3F) > 36)
+ ;
+
+ byte *pData = loadData(0x120C, 50);
+ command9Apply(pData, v + 20, -1);
+ command9Apply(pData + 1, 10 - ((v + 1) / 6), 1);
+}
+
+void ASound2::command9Apply(byte *data, int val, int incr) {
+ data += 8;
+ for (int ctr = 0; ctr < 10; ++ctr, data += 4, val += incr) {
+ *data = val;
+ }
+}
+
+int ASound2::command10() {
+ byte *pData1 = loadData(0x12C0, 60);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x12FC, 318));
+ _channels[2].load(loadData(0x143A, 110));
+ }
+
+ return 0;
+}
+
+int ASound2::command11() {
+ byte *pData = loadData(0x14A8, 170);
+ if (!isSoundActive(pData)) {
+ playSoundData(pData);
+ playSoundData(loadData(0x1552, 1802));
+ playSoundData(loadData(0x1C5C, 716));
+ playSoundData(loadData(0x1F28, 106));
+ }
+
+ return 0;
+}
+
+int ASound2::command12() {
+ _command12Param += 26;
+ byte v = _command12Param & 0x7f;
+
+ byte *pData = loadData(0x4A5E, 38);
+ pData[5] = pData[20] = v;
+ playSoundData(pData);
+
+ pData = loadData(0x4A84, 30);
+ pData[5] = pData[18] = v;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound2::command13() {
+ playSoundData(loadData(0x4AA2, 20));
+ playSoundData(loadData(0x4AB6, 20));
+
+ return 0;
+}
+
+int ASound2::command14() {
+ playSound(0x4ACA, 40);
+ playSound(0x4AF2, 42);
+
+ return 0;
+}
+
+int ASound2::command15() {
+ byte *pData1 = loadData(0x1F92, 1074);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x23C4, 1050);
+ playSound(0x27DE, 58);
+ playSound(0x2818, 712);
+ playSound(0x2AE0, 256);
+ }
+
+ return 0;
+}
+
+int ASound2::command16() {
+ byte *pData1 = loadData(0x3960, 280);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x3A78, 266);
+ playSound(0x3B72, 322);
+ playSound(0x3CC4, 488);
+ playSound(0x3EAC, 104);
+ playSound(0x3F14, 104);
+ }
+
+ return 0;
+}
+
+int ASound2::command17() {
+ byte *pData1 = loadData(0x3F7C, 432);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x412C, 422);
+ playSound(0x42D2, 424);
+ playSound(0x447A, 418);
+ }
+
+ return 0;
+}
+
+static const int command18_list[16][2] = {
+ { 0x337C, 28 }, { 0x3398, 26 }, { 0x33B2, 26 }, { 0x33CC, 26 },
+ { 0x33E6, 56 }, { 0x341E, 46 }, { 0x344C, 56 }, { 0x3484, 22 },
+ { 0x349A, 38 }, { 0x34C0, 62 }, { 0x34FE, 26 }, { 0x3518, 26 },
+ { 0x3532, 26 }, { 0x354C, 26 }, { 0x3566, 32 }, { 0x3586, 24 }
+};
+
+int ASound2::command18() {
+ if (_channels[3]._activeCount == 0) {
+ int idx = (getRandomNumber() & 0x1E) >> 1;
+ byte *pData = loadData(command18_list[idx][0], command18_list[idx][1]);
+ _channels[3].load(pData);
+ }
+
+ return 0;
+}
+
+int ASound2::command19() {
+ byte *pData1 = loadData(0x2BE0, 366);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x2D4E, 460);
+ playSound(0x2F1A, 266);
+ playSound(0x3024, 328);
+ playSound(0x316C, 162);
+ playSound(0x320E, 366);
+ }
+
+ return 0;
+}
+
+int ASound2::command20() {
+ playSound(0x4A36, 40);
+
+ return 0;
+}
+
+int ASound2::command21() {
+ playSound(0x49DE, 16);
+ playSound(0x49EE, 16);
+ playSound(0x49FF, 16);
+
+ return 0;
+}
+
+int ASound2::command22() {
+ playSound(0x4A0E, 24);
+ playSound(0x4A26, 16);
+
+ return 0;
+}
+
+int ASound2::command23() {
+ playSound(0x49B6, 16);
+
+ return 0;
+}
+
+int ASound2::command24() {
+ playSound(0x49C6, 24);
+
+ return 0;
+}
+
+int ASound2::command25() {
+ playSound(0x49AC, 10);
+
+ return 0;
+}
+
+int ASound2::command26() {
+ playSound(0x498A, 14);
+ playSound(0x4998, 20);
+
+ return 0;
+}
+
+int ASound2::command27() {
+ playSound(0x4912, 80);
+ playSound(0x4962, 40);
+
+ return 0;
+}
+
+int ASound2::command28() {
+ playSound(0x48E8, 28);
+ playSound(0x4904, 14);
+
+ return 0;
+}
+
+int ASound2::command29() {
+ playSound(0x48B2, 22);
+
+ return 0;
+}
+
+int ASound2::command30() {
+ playSound(0x4870, 22);
+ playSound(0x4886, 22);
+ playSound(0x489C, 22);
+
+ return 0;
+}
+
+int ASound2::command31() {
+ playSound(0x482E, 22);
+ playSound(0x4844, 22);
+ playSound(0x489C, 22);
+
+ return 0;
+}
+
+int ASound2::command32() {
+ playSound(0x46E8, 10);
+
+ return 0;
+}
+
+int ASound2::command33() {
+ playSound(0x46D8, 16);
+
+ return 0;
+}
+
+int ASound2::command34() {
+ playSound(0x46C8, 16);
+
+ return 0;
+}
+
+int ASound2::command35() {
+ playSound(0x46B2, 22);
+
+ return 0;
+}
+
+int ASound2::command36() {
+ playSound(0x4624, 16);
+
+ return 0;
+}
+
+int ASound2::command37() {
+ playSound(0x4674, 20);
+ playSound(0x4688, 32);
+ playSound(0x46A8, 10);
+
+ return 0;
+}
+
+int ASound2::command38() {
+ byte *pData1 = loadData(0x359E, 202);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x3668, 220);
+ playSound(0x3744, 124);
+ playSound(0x37C0, 162);
+ playSound(0x3862, 78);
+ playSound(0x38B0, 176);
+ }
+
+ return 0;
+}
+
+int ASound2::command39() {
+ byte *pData = loadData(0x466A, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound2::command40() {
+ playSound(0x4634, 34);
+ playSound(0x4656, 20);
+
+ return 0;
+}
+
+int ASound2::command41() {
+ playSound(0x48C8, 32);
+
+ return 0;
+}
+
+int ASound2::command42() {
+ playSound(0x46F2, 156);
+ playSound(0x478E, 160);
+
+ return 0;
+}
+
+int ASound2::command43() {
+ playSound(0x4B1C, 40);
+ playSound(0x4B44, 41);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound3::CommandPtr ASound3::_commandList[61] = {
+ &ASound3::command0, &ASound3::command1, &ASound3::command2, &ASound3::command3,
+ &ASound3::command4, &ASound3::command5, &ASound3::command6, &ASound3::command7,
+ &ASound3::command8, &ASound3::command9, &ASound3::command10, &ASound3::command11,
+ &ASound3::nullCommand, &ASound3::command13, &ASound3::command14, &ASound3::command15,
+ &ASound3::command16, &ASound3::command17, &ASound3::command18, &ASound3::command19,
+ &ASound3::command20, &ASound3::command21, &ASound3::command22, &ASound3::command23,
+ &ASound3::command24, &ASound3::command25, &ASound3::command26, &ASound3::command27,
+ &ASound3::command28, &ASound3::command29, &ASound3::command30, &ASound3::command31,
+ &ASound3::command32, &ASound3::command33, &ASound3::command34, &ASound3::command35,
+ &ASound3::command36, &ASound3::command37, &ASound3::command38, &ASound3::command39,
+ &ASound3::command40, &ASound3::command41, &ASound3::command42, &ASound3::command43,
+ &ASound3::command44, &ASound3::command45, &ASound3::command46, &ASound3::command47,
+ &ASound3::nullCommand, &ASound3::command49, &ASound3::command50, &ASound3::command51,
+ &ASound3::nullCommand, &ASound3::nullCommand, &ASound3::nullCommand, &ASound3::nullCommand,
+ &ASound3::nullCommand, &ASound3::command57, &ASound3::nullCommand, &ASound3::command59,
+ &ASound3::command60
+};
+
+ASound3::ASound3(Audio::Mixer *mixer) : ASound(mixer, "asound.003", 0x15B0) {
+ _command39Flag = false;
+
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x122);
+ for (int i = 0; i < 192; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound3::command(int commandId, int param) {
+ if (commandId > 60)
+ return 0;
+
+ _commandParam = param;
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound3::command9() {
+ AdlibChannel::_channelsEnabled = _commandParam != 0;
+
+ return 0;
+}
+
+int ASound3::command10() {
+ byte *pData1 = loadData(0x13EA, 254);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0X14E8, 452));
+ _channels[2].load(loadData(0x16AC, 396));
+ _channels[3].load(loadData(0x1838, 118));
+ _channels[4].load(loadData(0x18AE, 74));
+ }
+
+ return 0;
+}
+
+int ASound3::command11() {
+ byte *pData1 = loadData(0x2B84, 596);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x2DD8, 562));
+ _channels[2].load(loadData(0x300A, 1694));
+ _channels[3].load(loadData(0x36A8, 1100));
+ _channels[4].load(loadData(0x3AF4, 420));
+ _channels[5].load(loadData(0x3C98, 1516));
+ }
+
+ return 0;
+}
+
+int ASound3::command13() {
+ byte *pData1 = loadData(0x4470, 64);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x44B0, 64);
+ playSound(0x44F0, 64);
+ playSound(0x4530, 64);
+ playSound(0x4570, 64);
+ playSound(0X45b0, 64);
+ }
+
+ return 0;
+}
+
+int ASound3::command14() {
+ byte *pData1 = loadData(0X45F0, 36);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x4614, 36);
+ playSound(0x4638, 36);
+ playSound(0x465C, 32);
+ playSound(0x467C, 76);
+ playSound(0x46C8, 74);
+ }
+
+ return 0;
+}
+
+int ASound3::command15() {
+ _channels[3].load(loadData(0x36A8, 1100));
+ _channels[4].load(loadData(0x3AF4, 420));
+ _channels[5].load(loadData(0x3C98, 1516));
+
+ _channels[3]._field20 = 0xDD;
+ _channels[4]._field20 = 0xDD;
+ _channels[5]._field20 = 0xDD;
+
+ return 0;
+}
+
+int ASound3::command16() {
+ byte *pData1 = loadData(0x4712, 398);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x48A0, 354));
+ _channels[2].load(loadData(0x4A02, 410));
+ _channels[3].load(loadData(0x4B9C, 392));
+ }
+
+ return 0;
+}
+
+int ASound3::command17() {
+ byte *pData1 = loadData(0x18F8, 400);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x1A88, 680));
+ _channels[2].load(loadData(0x1D30, 478));
+ _channels[3].load(loadData(0x1F0E, 1146));
+ _channels[4].load(loadData(0x2388, 1006));
+ _channels[5].load(loadData(0x2776, 1038));
+ }
+
+ return 0;
+}
+
+int ASound3::command18() {
+ byte *pData1 = loadData(0x4284, 142);
+ if (!isSoundActive(pData1)) {
+ command1();
+ playSoundData(pData1);
+ playSound(0x4312, 172);
+ playSound(0x43BE, 88);
+ playSound(0x4416, 90);
+ }
+
+ return 0;
+}
+
+int ASound3::command19() {
+ playSound(0x4F6, 8);
+
+ return 0;
+}
+
+int ASound3::command20() {
+ playSound(0x4F1C, 10);
+
+ return 0;
+}
+
+int ASound3::command21() {
+ playSound(0x4F2E, 8);
+
+ return 0;
+}
+
+int ASound3::command22() {
+ playSound(0x4F36, 16);
+
+ return 0;
+}
+
+int ASound3::command23() {
+ playSound(0x4F50, 10);
+ playSound(0x4F46, 10);
+
+ return 0;
+}
+
+int ASound3::command24() {
+ // WORKAROUND: Original calls isSoundActive without loading data pointer
+ byte *pData = loadData(0x4EFC, 12);
+ if (!isSoundActive(pData)) {
+ int v;
+ while ((v = (getRandomNumber() & 0x3F)) > 45)
+ ;
+
+ pData[6] = v + 19;
+ playSoundData(pData);
+ }
+
+ return 0;
+}
+
+int ASound3::command25() {
+ playSound(0x4EE6, 22);
+
+ return 0;
+}
+
+int ASound3::command26() {
+ playSound(0x4F5A, 8);
+
+ return 0;
+}
+
+int ASound3::command27() {
+ playSound(0x4DA2, 34);
+ playSound(0x4DC4, 20);
+
+ return 0;
+}
+
+int ASound3::command28() {
+ playSound(0x4F72, 10);
+ playSound(0x4F72, 10);
+
+ return 0;
+}
+
+int ASound3::command29() {
+ playSound(0x4F72, 10);
+ playSound(0x4F72, 10);
+
+ return 0;
+}
+
+int ASound3::command30() {
+ playSound(0x4E5A, 22);
+ playSound(0x4E70, 22);
+ playSound(0x4E86, 22);
+
+ return 0;
+}
+
+int ASound3::command31() {
+ playSound(0x4F7C, 40);
+
+ return 0;
+}
+
+int ASound3::command32() {
+ playSound(0x4ED2, 10);
+
+ return 0;
+}
+
+int ASound3::command33() {
+ playSound(0x4EC2, 16);
+
+ return 0;
+}
+
+int ASound3::command34() {
+ playSound(0x4EB2, 16);
+
+ return 0;
+}
+
+int ASound3::command35() {
+ playSound(0x4E9C, 22);
+
+ return 0;
+}
+
+int ASound3::command36() {
+ playSound(0x4D2C, 16);
+
+ return 0;
+}
+
+int ASound3::command37() {
+ playSound(0x4E1E, 20);
+ playSound(0x4E32, 30);
+ playSound(0x4E50, 10);
+
+ return 0;
+}
+
+int ASound3::command38() {
+ playSound(0x4FAC, 10);
+
+ return 0;
+}
+
+int ASound3::command39() {
+ _command39Flag = !_command39Flag;
+ if (_command39Flag) {
+ playSound(0x4FD0, 8);
+ } else {
+ playSound(0x4FD8, 8);
+ }
+
+ return 0;
+}
+
+int ASound3::command40() {
+ _command39Flag = !_command39Flag;
+ if (_command39Flag) {
+ playSound(0x4EE0, 8);
+ } else {
+ playSound(0x4EE8, 8);
+ }
+
+ return 0;
+}
+
+int ASound3::command41() {
+ playSound(0x4F08, 20);
+
+ return 0;
+}
+
+int ASound3::command42() {
+ playSound(0x4DD8, 28);
+ playSound(0x4DF4, 42);
+
+ return 0;
+}
+
+int ASound3::command43() {
+ playSound(0x4FB6, 12);
+ playSound(0x4FC2, 14);
+
+ return 0;
+}
+
+int ASound3::command44() {
+ playSound(0x4FFE, 14);
+
+ return 0;
+}
+
+int ASound3::command45() {
+ playSound(0x500C, 14);
+
+ return 0;
+}
+
+int ASound3::command46() {
+ playSound(0x4D78, 14);
+ playSound(0x4D86, 14);
+ playSound(0x4D94, 14);
+
+ return 0;
+}
+
+int ASound3::command47() {
+ playSound(0x4D62, 8);
+ playSound(0x4D6A, 14);
+
+ return 0;
+}
+
+int ASound3::command49() {
+ playSound(0x4D62, 8);
+ playSound(0x4D6A, 14);
+
+ return 0;
+}
+
+int ASound3::command50() {
+ playSound(0x4D3C, 14);
+ playSound(0x4D4A, 14);
+ playSound(0x4D58, 10);
+
+ return 0;
+}
+
+int ASound3::command51() {
+ playSound(0x4FF0, 14);
+
+ return 0;
+}
+
+int ASound3::command57() {
+ byte *pData = loadData(0x4EDC, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound3::command59() {
+ playSound(0x4F62, 16);
+
+ return 0;
+}
+
+int ASound3::command60() {
+ playSound(0x4FA4, 8);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound4::CommandPtr ASound4::_commandList[61] = {
+ &ASound4::command0, &ASound4::command1, &ASound4::command2, &ASound4::command3,
+ &ASound4::command4, &ASound4::command5, &ASound4::command6, &ASound4::command7,
+ &ASound4::command8, &ASound4::nullCommand, &ASound4::command10, &ASound4::nullCommand,
+ &ASound4::command12, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand,
+ &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::command19,
+ &ASound4::command20, &ASound4::command21, &ASound4::nullCommand, &ASound4::nullCommand,
+ &ASound4::command24, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::command27,
+ &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::command30, &ASound4::nullCommand,
+ &ASound4::command32, &ASound4::command33, &ASound4::command34, &ASound4::command35,
+ &ASound4::command36, &ASound4::command37, &ASound4::command38, &ASound4::nullCommand,
+ &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::command43,
+ &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand,
+ &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand,
+ &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand, &ASound4::nullCommand,
+ &ASound4::nullCommand, &ASound4::command57, &ASound4::nullCommand, &ASound4::command59,
+ &ASound4::command60
+};
+
+ASound4::ASound4(Audio::Mixer *mixer) : ASound(mixer, "asound.004", 0x14F0) {
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x122);
+ for (int i = 0; i < 210; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound4::command(int commandId, int param) {
+ if (commandId > 60)
+ return 0;
+
+ _commandParam = param;
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound4::command10() {
+ byte *pData = loadData(0x22AA, 254);
+ if (!isSoundActive(pData)) {
+ command1();
+ _channels[0].load(pData);
+ _channels[1].load(loadData(0x23A8, 452));
+ _channels[2].load(loadData(0x256C, 396));
+ _channels[3].load(loadData(0x26F8, 118));
+ _channels[4].load(loadData(0x276E, 74));
+ }
+
+ return 0;
+}
+
+int ASound4::command12() {
+ byte *pData = loadData(0x16A8, 550);
+ if (!isSoundActive(pData)) {
+ command1();
+ _channels[0].load(pData);
+ _channels[1].load(loadData(0x18CE, 442));
+ _channels[2].load(loadData(0x1A88, 298));
+ _channels[3].load(loadData(0x1BB2, 354));
+ _channels[4].load(loadData(0x1D14, 572));
+ _channels[4].load(loadData(0x1F50, 560));
+ }
+
+ int v = (_commandParam > 0x40) ? _commandParam - 0x40 : 0;
+ v += 0xB5;
+ for (int channelNum = 0; channelNum < 6; ++channelNum)
+ _channels[channelNum]._field20 = v;
+
+ return 0;
+}
+
+int ASound4::command19() {
+ playSound(0x28EC, 8);
+
+ return 0;
+}
+
+int ASound4::command20() {
+ playSound(0x28E2, 10);
+
+ return 0;
+}
+
+int ASound4::command21() {
+ playSound(0x27C0, 8);
+
+ return 0;
+}
+
+int ASound4::command24() {
+ int v;
+ while ((v = (getRandomNumber() & 0x3F)) > 45)
+ ;
+
+ byte *pData = loadData(0x28D6, 12);
+ pData[6] = v + 19;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound4::command27() {
+ playSound(0x27D8, 34);
+ playSound(0x27FA, 20);
+
+ return 0;
+}
+
+int ASound4::command30() {
+ playSound(0x284A, 22);
+ playSound(0x2860, 22);
+ playSound(0x2876, 22);
+
+ return 0;
+}
+
+int ASound4::command32() {
+ playSound(0x28C2, 10);
+
+ return 0;
+}
+
+int ASound4::command33() {
+ playSound(0x28B2, 16);
+
+ return 0;
+}
+
+int ASound4::command34() {
+ playSound(0x28A2, 16);
+
+ return 0;
+}
+
+int ASound4::command35() {
+ playSound(0x288C, 22);
+
+ return 0;
+}
+
+int ASound4::command36() {
+ playSound(0x27C8, 16);
+
+ return 0;
+}
+
+int ASound4::command37() {
+ playSound(0x280E, 20);
+ playSound(0x2822, 30);
+ playSound(0x2840, 10);
+
+ return 0;
+}
+
+int ASound4::command38() {
+ playSound(0x2904, 10);
+
+ return 0;
+}
+
+int ASound4::command43() {
+ playSound(0x290E, 12);
+ playSound(0x291A, 14);
+
+ return 0;
+}
+
+int ASound4::command52() {
+ byte *pData = loadData(0x23A8, 452);
+ if (_channels[1]._ptr1 == pData) {
+ pData = loadData(0x146E, 570);
+ if (!isSoundActive(pData)) {
+ _channels[0].load(pData);
+ _channels[1]._field20 = 0xD8;
+ _channels[2]._field20 = 0xD8;
+ }
+ }
+
+ return 0;
+}
+
+int ASound4::command53() {
+ method1();
+ _channels[0]._field20 = 0;
+
+ return 0;
+}
+
+int ASound4::command54() {
+ method1();
+ _channels[1]._field20 = 0;
+ _channels[2]._field20 = 0;
+
+ return 0;
+}
+
+int ASound4::command55() {
+ method1();
+ _channels[3]._field20 = 0;
+ _channels[4]._field20 = 0;
+
+ return 0;
+}
+
+int ASound4::command56() {
+ method1();
+ _channels[5]._field20 = 0;
+
+ return 0;
+}
+
+int ASound4::command57() {
+ int v = (getRandomNumber() & 7) + 85;
+ byte *pData = loadData(0x28CC, 10);
+ pData[6] = v;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound4::command58() {
+ byte *pData = loadData(0x146E, 570);
+ if (_channels[1]._ptr1 == pData) {
+ _channels[0].load(loadData(0x22AA, 254));
+ _channels[1]._field20 = 0;
+ _channels[2]._field20 = 0;
+ }
+
+ return 0;
+}
+
+int ASound4::command59() {
+ playSound(0x28F4, 8);
+
+ return 0;
+}
+
+int ASound4::command60() {
+ playSound(0x28FC, 8);
+
+ return 0;
+}
+
+void ASound4::method1() {
+ byte *pData = loadData(0x2180, 58);
+ if (!isSoundActive(pData)) {
+ command1();
+
+ _channels[0].load(pData);
+ _channels[1].load(loadData(0x21BA, 48));
+ _channels[2].load(loadData(0x21EA, 50));
+ _channels[3].load(loadData(0x221C, 40));
+ _channels[4].load(loadData(0x2244, 28));
+ _channels[5].load(loadData(0x2260, 74));
+
+ for (int channel = 0; channel < 6; ++channel)
+ _channels[channel]._field20 = 0xB5;
+ }
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+const ASound5::CommandPtr ASound5::_commandList[42] = {
+ &ASound5::command0, &ASound5::command1, &ASound5::command2, &ASound5::command3,
+ &ASound5::command4, &ASound5::command5, &ASound5::command6, &ASound5::command7,
+ &ASound5::command8, &ASound5::command9, &ASound5::command10, &ASound5::command11,
+ &ASound5::command11, &ASound5::command13, &ASound5::command14, &ASound5::command15,
+ &ASound5::command16, &ASound5::command17, &ASound5::command18, &ASound5::command19,
+ &ASound5::command20, &ASound5::command21, &ASound5::command22, &ASound5::command23,
+ &ASound5::command11, &ASound5::command11, &ASound5::command26, &ASound5::command27,
+ &ASound5::command28, &ASound5::command29, &ASound5::command30, &ASound5::command31,
+ &ASound5::command32, &ASound5::command33, &ASound5::command34, &ASound5::command35,
+ &ASound5::command36, &ASound5::command37, &ASound5::command38, &ASound5::command39,
+ &ASound5::command40, &ASound5::command41
+};
+
+ASound5::ASound5(Audio::Mixer *mixer) : ASound(mixer, "asound.002", 0x15E0) {
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x144);
+ for (int i = 0; i < 164; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound5::command(int commandId, int param) {
+ if (commandId > 41)
+ return 0;
+
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound5::command9() {
+ byte *pData = loadData(0x2114, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound5::command10() {
+ playSound(0x211E, 10);
+
+ return 0;
+}
+
+int ASound5::command11() {
+ playSound(0x2016, 10);
+
+ return 0;
+}
+
+int ASound5::command13() {
+ playSound(0x2154, 10);
+
+ return 0;
+}
+
+int ASound5::command14() {
+ playSound(0x21DC, 22);
+
+ return 0;
+}
+
+int ASound5::command15() {
+ byte *pData = loadData(0x21DC, 22);
+ if (_channels[0]._ptr1 == pData) {
+ pData = loadData(0x1F2, 12);
+ _channels[0]._soundData = pData;
+ _channels[0]._field17 = 1;
+ _channels[0]._field19 = 1;
+ }
+
+ return 0;
+}
+
+int ASound5::command16() {
+ playSound(0x214C, 8);
+
+ return 0;
+}
+
+int ASound5::command17() {
+ playSound(0x2142, 10);
+
+ return 0;
+}
+
+int ASound5::command18() {
+ playSound(0x21A2, 22);
+
+ return 0;
+}
+
+int ASound5::command19() {
+ playSound(0x2190, 18);
+
+ return 0;
+}
+
+int ASound5::command20() {
+ playSound(0x2170, 16);
+
+ return 0;
+}
+
+int ASound5::command21() {
+ playSound(0x2180, 16);
+
+ return 0;
+}
+
+int ASound5::command22() {
+ playSound(0x2168, 8);
+
+ return 0;
+}
+
+int ASound5::command23() {
+ playSound(0x215E, 10);
+
+ return 0;
+}
+
+int ASound5::command26() {
+ playSound(0x21B8, 12);
+
+ return 0;
+}
+
+int ASound5::command27() {
+ playSound(0x21C4, 24);
+
+ return 0;
+}
+
+int ASound5::command28() {
+ playSound(0x2020, 34);
+ playSound(0x4904, 20);
+
+ return 0;
+}
+
+int ASound5::command29() {
+ byte *pData = loadData(0x17C, 312);
+ if (!isSoundActive(pData)) {
+ command1();
+ _channels[0].load(pData);
+ _channels[1].load(loadData(0x1864, 304));
+ _channels[2].load(loadData(0x1994, 222));
+ _channels[3].load(loadData(0x1864, 304));
+ _channels[4].load(loadData(0x1994, 222));
+ }
+
+ return 0;
+}
+
+int ASound5::command30() {
+ playSound(0x2092, 22);
+ playSound(0x20A8, 22);
+ playSound(0x20BE, 22);
+
+ return 0;
+}
+
+int ASound5::command31() {
+ playSound(0x2128, 22);
+ playSound(0x2134, 14);
+
+ return 0;
+}
+
+int ASound5::command32() {
+ playSound(0x210A, 10);
+
+ return 0;
+}
+
+int ASound5::command33() {
+ playSound(0x20FA, 16);
+
+ return 0;
+}
+
+int ASound5::command34() {
+ playSound(0x20EA, 16);
+
+ return 0;
+}
+
+int ASound5::command35() {
+ playSound(0x20D4, 22);
+
+ return 0;
+}
+
+int ASound5::command36() {
+ playSound(0x2006, 16);
+
+ return 0;
+}
+
+int ASound5::command37() {
+ playSound(0x2056, 20);
+ playSound(0x206A, 30);
+ playSound(0x2088, 10);
+
+ return 0;
+}
+
+int ASound5::command38() {
+ byte *pData1 = loadData(0x14F2, 570);
+ if (_channels[3]._ptr1 == pData1) {
+ _channels[3].load(loadData(0x1A72, 522));
+ _channels[3].load(loadData(0x1C7C, 874));
+ }
+
+ return 0;
+}
+
+int ASound5::command39() {
+ playSound(0x1FEE, 8);
+
+ return 0;
+}
+
+int ASound5::command40() {
+ playSound(0x1FF6, 16);
+
+ return 0;
+}
+
+int ASound5::command41() {
+ byte *pData1 = loadData(0x14F2, 570);
+ if (!isSoundActive(pData1)) {
+ byte *pData2 = loadData(0x1A72, 522);
+ if (_channels[3]._ptr1 == pData2) {
+ _channels[3].load(pData1);
+ _channels[4].load(loadData(0x1FE6, 8));
+ }
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound6::CommandPtr ASound6::_commandList[30] = {
+ &ASound6::command0, &ASound6::command1, &ASound6::command2, &ASound6::command3,
+ &ASound6::command4, &ASound6::command5, &ASound6::command6, &ASound6::command7,
+ &ASound6::command8, &ASound6::command9, &ASound6::command10, &ASound6::command11,
+ &ASound6::command11, &ASound6::command13, &ASound6::command14, &ASound6::command15,
+ &ASound6::command16, &ASound6::command17, &ASound6::command18, &ASound6::command19,
+ &ASound6::command20, &ASound6::command21, &ASound6::command22, &ASound6::command23,
+ &ASound6::command11, &ASound6::command11, &ASound6::nullCommand, &ASound6::nullCommand,
+ &ASound6::nullCommand, &ASound6::command29
+};
+
+ASound6::ASound6(Audio::Mixer *mixer) : ASound(mixer, "asound.006", 0x1390) {
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x122);
+ for (int i = 0; i < 200; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound6::command(int commandId, int param) {
+ if (commandId > 29)
+ return 0;
+
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound6::command9() {
+ byte *pData = loadData(0x2194, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound6::command10() {
+ playSound(0x2224, 24);
+
+ return 0;
+}
+
+int ASound6::command11() {
+ playSound(0x2202, 34);
+
+ return 0;
+}
+
+int ASound6::command12() {
+ playSound(0x2246, 8);
+
+ return 0;
+}
+
+int ASound6::command13() {
+ playSound(0x2298, 28);
+
+ return 0;
+}
+
+int ASound6::command14() {
+ playSound(0x22B4, 27);
+
+ return 0;
+}
+
+int ASound6::command15() {
+ playSound(0x219E, 12);
+
+ return 0;
+}
+
+int ASound6::command16() {
+ playSound(0x21AA, 22);
+ playSound(0x21C0, 12);
+
+ return 0;
+}
+
+int ASound6::command17() {
+ playSound(0x21CC, 54);
+
+ return 0;
+}
+
+int ASound6::command18() {
+ playSound(0x2270, 16);
+
+ return 0;
+}
+
+int ASound6::command19() {
+ playSound(0x2280, 16);
+
+ return 0;
+}
+
+int ASound6::command20() {
+ playSound(0x223C, 10);
+
+ return 0;
+}
+
+int ASound6::command21() {
+ playSound(0x224E, 34);
+
+ return 0;
+}
+
+int ASound6::command22() {
+ playSound(0x2290, 8);
+
+ return 0;
+}
+
+int ASound6::command23() {
+ playSound(0x215E, 34);
+ playSound(0x2180, 20);
+
+ return 0;
+}
+
+int ASound6::command24() {
+ byte *pData1 = loadData(0x1D54, 540);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x1F70, 52));
+ _channels[2].load(loadData(0x1FA4, 430));
+ }
+
+ return 0;
+}
+
+int ASound6::command25() {
+ playSound(0x2152, 12);
+
+ return 0;
+}
+
+int ASound6::command29() {
+ byte *pData1 = loadData(0x149A, 312);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x15D2, 304));
+ _channels[2].load(loadData(0x1702, 222));
+ _channels[3].load(loadData(0x17E0, 522));
+ _channels[4].load(loadData(0x19EA, 874));
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound7::CommandPtr ASound7::_commandList[38] = {
+ &ASound7::command0, &ASound7::command1, &ASound7::command2, &ASound7::command3,
+ &ASound7::command4, &ASound7::command5, &ASound7::command6, &ASound7::command7,
+ &ASound7::command8, &ASound7::command9, &ASound7::nullCommand, &ASound7::nullCommand,
+ &ASound7::nullCommand, &ASound7::nullCommand, &ASound7::nullCommand, &ASound7::command15,
+ &ASound7::command16, &ASound7::command16, &ASound7::command18, &ASound7::command19,
+ &ASound7::command20, &ASound7::command21, &ASound7::command22, &ASound7::command23,
+ &ASound7::command24, &ASound7::command25, &ASound7::command26, &ASound7::command27,
+ &ASound7::command28, &ASound7::nullCommand, &ASound7::command30, &ASound7::nullCommand,
+ &ASound7::command32, &ASound7::command33, &ASound7::command34, &ASound7::command35,
+ &ASound7::command36, &ASound7::command37
+};
+
+ASound7::ASound7(Audio::Mixer *mixer) : ASound(mixer, "asound.007", 0x1460) {
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x122);
+ for (int i = 0; i < 214; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound7::command(int commandId, int param) {
+ if (commandId > 37)
+ return 0;
+
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound7::command9() {
+ byte *pData1 = loadData(0x2992, 122);
+ if (!isSoundActive(pData1)) {
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x2A0C, 76));
+ _channels[2].load(loadData(0x2A58, 122));
+ _channels[3].load(loadData(0x2AD2, 38));
+ }
+
+ return 0;
+}
+
+int ASound7::command15() {
+ byte *pData = loadData(0x2B3E, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+
+ return 0;
+}
+
+int ASound7::command16() {
+ playSound(0x2CE2, 8);
+
+ return 0;
+}
+
+int ASound7::command18() {
+ playSound(0x2C94, 22);
+
+ return 0;
+}
+
+int ASound7::command19() {
+ byte *pData1 = loadData(0x2C94, 22);
+ byte *pData2 = loadData(0x2CAA, 16);
+ if (_channels[8]._ptr1 == pData1 || _channels[8]._ptr1 == pData2) {
+ _channels[8]._soundData = loadData(0x2CBA, 12);
+ _channels[8]._field17 = 1;
+ _channels[8]._field19 = 1;
+ }
+
+ return 0;
+}
+
+int ASound7::command20() {
+ playSound(0x2CD0, 18);
+
+ return 0;
+}
+
+int ASound7::command21() {
+ playSound(0x2CC6, 10);
+
+ return 0;
+}
+
+int ASound7::command22() {
+ playSound(0x2C08, 140);
+
+ return 0;
+}
+
+int ASound7::command23() {
+ playSound(0x2B08, 34);
+ playSound(0x2B2A, 20);
+
+ return 0;
+}
+
+int ASound7::command24() {
+ byte *pData1 = loadData(0x14C6, 144);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x1556, 146));
+ _channels[2].load(loadData(0x15E8, 138));
+ _channels[3].load(loadData(0x1672, 122));
+ _channels[4].load(loadData(0x16EC, 74));
+ }
+
+ return 0;
+}
+
+int ASound7::command25() {
+ byte *pData1 = loadData(0x1DBE, 182);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x1E74, 182));
+ _channels[2].load(loadData(0x1F2A, 186));
+ _channels[3].load(loadData(0x1FE4, 244));
+ }
+
+ return 0;
+}
+
+int ASound7::command26() {
+ byte *pData1 = loadData(0x20D8, 312);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x2210, 304));
+ _channels[2].load(loadData(0x2340, 222));
+ _channels[3].load(loadData(0x241E, 522));
+ _channels[4].load(loadData(0x2628, 874));
+ }
+
+ return 0;
+}
+
+int ASound7::command27() {
+ byte *pData1 = loadData(0x1736, 158);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x17D4, 288));
+ _channels[2].load(loadData(0x18F4, 290));
+ _channels[3].load(loadData(0x1A16, 396));
+ _channels[4].load(loadData(0x1BA2, 380));
+ _channels[5].load(loadData(0x1D1E, 160));
+ }
+
+ return 0;
+}
+
+int ASound7::command28() {
+ playSound(0x2CAA, 16);
+
+ return 0;
+}
+
+int ASound7::command30() {
+ playSound(0x2B86, 22);
+ playSound(0x2B9C, 22);
+ playSound(0x2BB2, 22);
+
+ return 0;
+}
+
+int ASound7::command32() {
+ playSound(0x2BFE, 10);
+
+ return 0;
+}
+
+int ASound7::command33() {
+ playSound(0x2BEE, 16);
+
+ return 0;
+}
+
+int ASound7::command34() {
+ playSound(0x2BDE, 16);
+
+ return 0;
+}
+
+int ASound7::command35() {
+ playSound(0x2BC8, 22);
+
+ return 0;
+}
+
+int ASound7::command36() {
+ playSound(0x2AF8, 16);
+
+ return 0;
+}
+
+int ASound7::command37() {
+ playSound(0x2B48, 20);
+ playSound(0x2B5C, 32);
+ playSound(0x2B7C, 10);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound8::CommandPtr ASound8::_commandList[38] = {
+ &ASound8::command0, &ASound8::command1, &ASound8::command2, &ASound8::command3,
+ &ASound8::command4, &ASound8::command5, &ASound8::command6, &ASound8::command7,
+ &ASound8::command8, &ASound8::command9, &ASound8::command10, &ASound8::command11,
+ &ASound8::command12, &ASound8::command13, &ASound8::command14, &ASound8::command15,
+ &ASound8::command16, &ASound8::command16, &ASound8::command18, &ASound8::command19,
+ &ASound8::command20, &ASound8::command21, &ASound8::command22, &ASound8::command23,
+ &ASound8::command24, &ASound8::command25, &ASound8::command26, &ASound8::command27,
+ &ASound8::command28, &ASound8::command29, &ASound8::command30, &ASound8::command31,
+ &ASound8::command32, &ASound8::command33, &ASound8::command34, &ASound8::command35,
+ &ASound8::command36, &ASound8::command37
+};
+
+ASound8::ASound8(Audio::Mixer *mixer) : ASound(mixer, "asound.008", 0x1490) {
+ // Load sound samples
+ _soundFile.seek(_dataOffset + 0x122);
+ for (int i = 0; i < 174; ++i)
+ _samples.push_back(AdlibSample(_soundFile));
+}
+
+int ASound8::command(int commandId, int param) {
+ if (commandId > 37)
+ return 0;
+
+ _frameCounter = 0;
+ return (this->*_commandList[commandId])();
+}
+
+int ASound8::command9() {
+ byte *pData = loadData(0x15BE, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound8::command10() {
+ byte *pData = loadData(0x2B3E, 10);
+ pData[6] = (getRandomNumber() & 7) + 85;
+ playSoundData(pData);
+
+ return 0;
+}
+
+int ASound8::command11() {
+ playSound(0x17CA, 12);
+
+ return 0;
+}
+
+int ASound8::command12() {
+ playSound(0x17D6, 12);
+
+ return 0;
+}
+
+int ASound8::command13() {
+ playSound(0x1694, 10);
+
+ return 0;
+}
+
+int ASound8::command14() {
+ playSound(0x169E, 24);
+
+ return 0;
+}
+
+int ASound8::command15() {
+ byte *pData = loadData(0x169E, 24);
+ if (_channels[8]._ptr1 == pData) {
+ _channels[8]._soundData = loadData(0x16B6, 12);
+ _channels[8]._field17 = 1;
+ _channels[8]._field19 = 1;
+ }
+
+ return 0;
+}
+
+int ASound8::command16() {
+ playSound(0x1686, 14);
+
+ return 0;
+}
+
+int ASound8::command17() {
+ playSound(0x17EC, 12);
+
+ return 0;
+}
+
+int ASound8::command18() {
+ playSound(0x17F8, 12);
+
+ return 0;
+}
+
+int ASound8::command19() {
+ playSound(0x16D8, 8);
+
+ return 0;
+}
+
+int ASound8::command20() {
+ playSound(0x16E0, 8);
+
+ return 0;
+}
+
+int ASound8::command21() {
+ playSound(0x17E2, 10);
+
+ return 0;
+}
+
+int ASound8::command22() {
+ playSound(0x178C, 14);
+ playSound(0x179A, 14);
+ playSound(0x17A8, 14);
+
+ return 0;
+}
+
+int ASound8::command23() {
+ playSound(0x2B08, 34);
+ playSound(0x2B2A, 20);
+
+ return 0;
+}
+
+int ASound8::command24() {
+ playSound(0x17B6, 8);
+
+ return 0;
+}
+
+int ASound8::command25() {
+ playSound(0x17BE, 12);
+
+ return 0;
+}
+
+int ASound8::command26() {
+ playSound(0x16C2, 22);
+
+ return 0;
+}
+
+int ASound8::command27() {
+ playSound(0x1588, 34);
+ playSound(0x15AA, 20);
+
+ return 0;
+}
+
+int ASound8::command28() {
+ byte *pData1 = loadData(0x114E, 376);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[2].load(loadData(0x12F8, 130));
+
+ byte *pData = loadData(0x12C6, 50);
+ method1(pData);
+ _channels[1].load(pData);
+ }
+
+ return 0;
+}
+
+void ASound8::method1(byte *pData) {
+ int v;
+ while ((v = (getRandomNumber() & 0x3F)) > 36)
+ ;
+
+ adjustRange(pData, v + 20, -1);
+ adjustRange(pData + 1, 10 - ((v + 1) / 6), 1);
+}
+
+void ASound8::adjustRange(byte *pData, byte v, int incr) {
+ pData += 8;
+
+ for (int i = 0; i < 10; ++i, pData += 4, v += incr) {
+ *pData = v;
+ }
+}
+
+int ASound8::command29() {
+ byte *pData1 = loadData(0x137A, 60);
+ if (!isSoundActive(pData1)) {
+ command1();
+ _channels[0].load(pData1);
+ _channels[1].load(loadData(0x13B6, 318));
+ _channels[2].load(loadData(0x14F4, 118));
+ }
+
+ return 0;
+}
+
+int ASound8::command30() {
+ playSound(0x1644, 22);
+ playSound(0x165A, 22);
+ playSound(0x1670, 22);
+
+ return 0;
+}
+
+int ASound8::command31() {
+ playSound(0x156A, 14);
+
+ return 0;
+}
+
+int ASound8::command32() {
+ playSound(0x163A, 10);
+
+ return 0;
+}
+
+int ASound8::command33() {
+ playSound(0x162A, 16);
+
+ return 0;
+}
+
+int ASound8::command34() {
+ playSound(0x161A, 16);
+
+ return 0;
+}
+
+int ASound8::command35() {
+ playSound(0x1604, 22);
+
+ return 0;
+}
+
+int ASound8::command36() {
+ playSound(0x1578, 16);
+
+ return 0;
+}
+
+int ASound8::command37() {
+ playSound(0x15C8, 20);
+ playSound(0x15DC, 30);
+ playSound(0X15FA, 10);
+
+ return 0;
+}
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h
new file mode 100644
index 0000000000..c485bd7955
--- /dev/null
+++ b/engines/mads/nebular/sound_nebular.h
@@ -0,0 +1,720 @@
+/* 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 MADS_SOUND_NEBULAR_H
+#define MADS_SOUND_NEBULAR_H
+
+#include "common/scummsys.h"
+#include "common/file.h"
+#include "common/mutex.h"
+#include "common/queue.h"
+#include "audio/audiostream.h"
+#include "audio/fmopl.h"
+#include "audio/mixer.h"
+
+namespace MADS {
+
+class SoundManager;
+
+namespace Nebular {
+
+/**
+ * Represents the data for a channel on the Adlib
+ */
+class AdlibChannel {
+public:
+ int _activeCount;
+ int _field1;
+ int _field2;
+ int _field3;
+ int _field4;
+ int _sampleIndex;
+ int _volume;
+ int _field7;
+ int _field8;
+ int _field9;
+ int _fieldA;
+ uint8 _fieldB;
+ int _fieldC;
+ int _fieldD;
+ int _fieldE;
+ byte *_ptr1;
+ byte *_pSrc;
+ byte *_ptr3;
+ byte *_ptr4;
+ int _field17;
+ int _field19;
+ byte *_soundData;
+ int _field1D;
+ int _field1E;
+ int _field1F;
+
+ // TODO: Only used by asound.003. Figure out usage
+ byte _field20;
+public:
+ static bool _channelsEnabled;
+public:
+ AdlibChannel();
+
+ void reset();
+ void enable(int flag);
+ void setPtr2(byte *pData);
+ void load(byte *pData);
+ void check(byte *nullPtr);
+};
+
+class AdlibChannelData {
+public:
+ int _field0;
+ int _freqMask;
+ int _freqBase;
+ int _field6;
+};
+
+class AdlibSample {
+public:
+ int _attackRate;
+ int _decayRate;
+ int _sustainLevel;
+ int _releaseRate;
+ bool _egTyp;
+ bool _ksr;
+ int _totalLevel;
+ int _scalingLevel;
+ int _waveformSelect;
+ int _freqMultiple;
+ int _feedback;
+ bool _ampMod;
+ int _vib;
+ int _alg;
+ int _fieldE;
+ int _freqMask;
+ int _freqBase;
+ int _field14;
+
+ AdlibSample() {}
+ AdlibSample(Common::SeekableReadStream &s);
+};
+
+struct RegisterValue {
+ uint8 _regNum;
+ uint8 _value;
+
+ RegisterValue(int regNum, int value) {
+ _regNum = regNum; _value = value;
+ }
+};
+
+#define ADLIB_CHANNEL_COUNT 9
+#define ADLIB_CHANNEL_MIDWAY 5
+#define CALLBACKS_PER_SECOND 60
+
+/**
+ * Base class for the sound player resource files
+ */
+class ASound : public Audio::AudioStream {
+private:
+ struct CachedDataEntry {
+ int _offset;
+ byte *_data;
+ };
+ Common::List<CachedDataEntry> _dataCache;
+ uint16 _randomSeed;
+
+ /**
+ * Does the initial Adlib initialisation
+ */
+ void adlibInit();
+
+ /**
+ * Does on-going processing for the Adlib sounds being played
+ */
+ void update();
+
+ /**
+ * Polls each of the channels for updates
+ */
+ void pollChannels();
+
+ /**
+ * Checks the status of the channels
+ */
+ void checkChannels();
+
+ /**
+ * Polls the currently active channel
+ */
+ void pollActiveChannel();
+
+ /**
+ * Updates the octave of the currently active channel
+ */
+ void updateOctave();
+
+ void updateChannelState();
+ void updateActiveChannel();
+
+ /**
+ * Loads up the specified sample
+ */
+ void loadSample(int sampleIndex);
+
+ /**
+ * Writes out the data of the selected sample to the Adlib
+ */
+ void processSample();
+
+ void updateFNumber();
+protected:
+ int _commandParam;
+
+ /**
+ * Queue a byte for an Adlib register
+ */
+ void write(int reg, int val);
+
+ /**
+ * Queue a byte for an Adlib register, and store it in the _ports array
+ */
+ int write2(int state, int reg, int val);
+
+ /**
+ * Flush any pending Adlib register values to the OPL driver
+ */
+ void flush();
+
+ /**
+ * Turn a channel on
+ */
+ void channelOn(int reg, int volume);
+
+ /**
+ * Turn a channel off
+ */
+ void channelOff(int reg);
+
+ /**
+ * Checks for whether a poll result needs to be set
+ */
+ void resultCheck();
+
+ /**
+ * Loads a data block from the sound file, caching the result for any future
+ * calls for the same data
+ */
+ byte *loadData(int offset, int size);
+
+ /**
+ * Play the specified sound
+ * @param offset Offset of sound data within sound player data segment
+ * @param size Size of sound data block
+ */
+ void playSound(int offset, int size);
+
+ /**
+ * Play the specified raw sound data
+ * @param pData Pointer to data block containing sound data
+ * @param startingChannel Channel to start scan from
+ */
+ void playSoundData(byte *pData, int startingChannel = ADLIB_CHANNEL_MIDWAY);
+
+ /**
+ * Checks to see whether the given block of data is already loaded into a channel.
+ */
+ bool isSoundActive(byte *pData);
+
+ /**
+ * Sets the frequency for a given channel.
+ */
+ void setFrequency(int channel, int freq);
+
+ /**
+ * Returns a 16-bit random number
+ */
+ int getRandomNumber();
+
+ virtual int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int nullCommand() { return 0; }
+public:
+ Audio::Mixer *_mixer;
+ FM_OPL *_opl;
+ Audio::SoundHandle _soundHandle;
+ AdlibChannel _channels[ADLIB_CHANNEL_COUNT];
+ AdlibChannel *_activeChannelPtr;
+ AdlibChannelData _channelData[11];
+ Common::Array<AdlibSample> _samples;
+ AdlibSample *_samplePtr;
+ Common::File _soundFile;
+ Common::Queue<RegisterValue> _queue;
+ Common::Mutex _driverMutex;
+ int _dataOffset;
+ int _frameCounter;
+ bool _isDisabled;
+ int _v1;
+ int _v2;
+ int _activeChannelNumber;
+ int _freqMask1;
+ int _freqMask2;
+ int _freqBase1;
+ int _freqBase2;
+ int _channelNum1, _channelNum2;
+ int _v7;
+ int _v8;
+ int _v9;
+ int _v10;
+ int _pollResult;
+ int _resultFlag;
+ byte _nullData[2];
+ int _ports[256];
+ bool _stateFlag;
+ int _activeChannelReg;
+ int _v11;
+ bool _amDep, _vibDep, _splitPoint;
+ int _samplesPerCallback;
+ int _samplesPerCallbackRemainder;
+ int _samplesTillCallback;
+ int _samplesTillCallbackRemainder;
+public:
+ /**
+ * Constructor
+ * @param filename Specifies the adlib sound player file to use
+ * @param dataOffset Offset in the file of the data segment
+ */
+ ASound(Audio::Mixer *mixer, const Common::String &filename, int dataOffset);
+
+ /**
+ * Destructor
+ */
+ virtual ~ASound();
+
+ /**
+ * Execute a player command. Most commands represent sounds to play, but some
+ * low number commands also provide control operations.
+ * @param commandId Player ommand to execute.
+ * @param param Optional parameter used by a few commands
+ */
+ virtual int command(int commandId, int param) = 0;
+
+ /**
+ * Stop all currently playing sounds
+ */
+ int stop();
+
+ /**
+ * Main poll method to allow sounds to progress
+ */
+ int poll();
+
+ /**
+ * General noise/note output
+ */
+ void noise();
+
+ /**
+ * Return the current frame counter
+ */
+ int getFrameCounter() { return _frameCounter; }
+
+ // AudioStream interface
+ /**
+ * Main buffer read
+ */
+ virtual int readBuffer(int16 *buffer, const int numSamples);
+
+ /**
+ * Mono sound only
+ */
+ virtual bool isStereo() const { return false; }
+
+ /**
+ * Data is continuously pushed, so definitive end
+ */
+ virtual bool endOfData() const { return false; }
+
+ /**
+ * Return sample rate
+ */
+ virtual int getRate() const { return 11025; }
+};
+
+class ASound1 : public ASound {
+private:
+ typedef int (ASound1::*CommandPtr)();
+ static const CommandPtr _commandList[42];
+ bool _cmd23Toggle;
+
+ int command9();
+ int command10();
+ int command11();
+ int command12();
+ int command13();
+ int command14();
+ int command15();
+ int command16();
+ int command17();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+ int command28();
+ int command29();
+ int command30();
+ int command31();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+ int command40();
+ int command41();
+
+ void command111213();
+ int command2627293032();
+public:
+ ASound1(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound2 : public ASound {
+private:
+ byte _command12Param;
+private:
+ typedef int (ASound2::*CommandPtr)();
+ static const CommandPtr _commandList[44];
+
+ virtual int command0();
+ int command9();
+ int command10();
+ int command11();
+ int command12();
+ int command13();
+ int command14();
+ int command15();
+ int command16();
+ int command17();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+ int command28();
+ int command29();
+ int command30();
+ int command31();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+ int command40();
+ int command41();
+ int command42();
+ int command43();
+
+ void command9Randomize();
+ void command9Apply(byte *data, int val, int incr);
+public:
+ ASound2(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound3 : public ASound {
+private:
+ bool _command39Flag;
+
+ typedef int (ASound3::*CommandPtr)();
+ static const CommandPtr _commandList[61];
+
+ int command9();
+ int command10();
+ int command11();
+ int command13();
+ int command14();
+ int command15();
+ int command16();
+ int command17();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+ int command28();
+ int command29();
+ int command30();
+ int command31();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+ int command40();
+ int command41();
+ int command42();
+ int command43();
+ int command44();
+ int command45();
+ int command46();
+ int command47();
+ int command49();
+ int command50();
+ int command51();
+ int command57();
+ int command59();
+ int command60();
+
+ void command9Randomize();
+ void command9Apply(byte *data, int val, int incr);
+public:
+ ASound3(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound4 : public ASound {
+private:
+ typedef int (ASound4::*CommandPtr)();
+ static const CommandPtr _commandList[61];
+
+ int command10();
+ int command12();
+ int command19();
+ int command20();
+ int command21();
+ int command24();
+ int command27();
+ int command30();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command43();
+ int command52();
+ int command53();
+ int command54();
+ int command55();
+ int command56();
+ int command57();
+ int command58();
+ int command59();
+ int command60();
+
+ void method1();
+public:
+ ASound4(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound5 : public ASound {
+private:
+ typedef int (ASound5::*CommandPtr)();
+ static const CommandPtr _commandList[42];
+
+ int command9();
+ int command10();
+ int command11();
+ int command12();
+ int command13();
+ int command14();
+ int command15();
+ int command16();
+ int command17();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+ int command28();
+ int command29();
+ int command30();
+ int command31();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+ int command40();
+ int command41();
+ int command42();
+ int command43();
+public:
+ ASound5(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound6 : public ASound {
+private:
+ typedef int (ASound6::*CommandPtr)();
+ static const CommandPtr _commandList[30];
+
+ int command9();
+ int command10();
+ int command11();
+ int command12();
+ int command13();
+ int command14();
+ int command15();
+ int command16();
+ int command17();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command29();
+public:
+ ASound6(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound7 : public ASound {
+private:
+ typedef int (ASound7::*CommandPtr)();
+ static const CommandPtr _commandList[38];
+
+ int command9();
+ int command15();
+ int command16();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+ int command28();
+ int command30();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+public:
+ ASound7(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+class ASound8 : public ASound {
+private:
+ typedef int (ASound8::*CommandPtr)();
+ static const CommandPtr _commandList[38];
+
+ int command9();
+ int command10();
+ int command11();
+ int command12();
+ int command13();
+ int command14();
+ int command15();
+ int command16();
+ int command17();
+ int command18();
+ int command19();
+ int command20();
+ int command21();
+ int command22();
+ int command23();
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+ int command28();
+ int command29();
+ int command30();
+ int command31();
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+
+ void method1(byte *pData);
+ void adjustRange(byte *pData, byte v, int incr);
+public:
+ ASound8(Audio::Mixer *mixer);
+
+ virtual int command(int commandId, int param);
+};
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_SOUND_NEBULAR_H */
diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp
new file mode 100644
index 0000000000..755f7bcf5c
--- /dev/null
+++ b/engines/mads/palette.cpp
@@ -0,0 +1,830 @@
+/* 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 "common/scummsys.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
+#include "mads/mads.h"
+#include "mads/msurface.h"
+#include "mads/staticres.h"
+
+namespace MADS {
+
+#define VGA_COLOR_TRANS(x) ((x) * 255 / 63)
+
+void RGB6::load(Common::SeekableReadStream *f) {
+ r = VGA_COLOR_TRANS(f->readByte());
+ g = VGA_COLOR_TRANS(f->readByte());
+ b = VGA_COLOR_TRANS(f->readByte());
+ _palIndex = f->readByte();
+ _u2 = f->readByte();
+ _flags = f->readByte();
+}
+
+/*------------------------------------------------------------------------*/
+
+PaletteUsage::PaletteUsage(MADSEngine *vm) {
+ _vm = vm;
+ _data = nullptr;
+}
+
+void PaletteUsage::load(Common::Array<UsageEntry> *data) {
+ _data = data;
+}
+
+void PaletteUsage::getKeyEntries(Common::Array<RGB6> &palette) {
+ _data->clear();
+
+ for (uint i = 0; i < palette.size(); ++i) {
+ byte *uPtr = &palette[i]._flags;
+ if ((*uPtr & 0x10) && _data->size() < 3) {
+ _data->push_back(UsageEntry(i));
+ }
+ }
+}
+
+static bool sortHelper(const PaletteUsage::UsageEntry &ue1, const PaletteUsage::UsageEntry &ue2) {
+ return ue1._sortValue < ue2._sortValue;
+}
+
+void PaletteUsage::prioritize(Common::Array<RGB6> &palette) {
+ for (uint i = 0; i < _data->size(); ++i) {
+ RGB6 &palEntry = palette[(*_data)[i]._palIndex];
+ (*_data)[i]._sortValue = _vm->_palette->rgbMerge(palEntry);
+ }
+
+ Common::sort(_data->begin(), _data->end(), sortHelper);
+}
+
+static bool rangeSorter(const PaletteUsage::UsageRange &ur1, const PaletteUsage::UsageRange &ur2) {
+ return ur1._v2 < ur2._v2;
+}
+
+int PaletteUsage::process(Common::Array<RGB6> &palette, uint flags) {
+ int palLow;
+ int palHigh = (flags & 0x800) ? 0x100 : 0xFC;
+ int palIdx;
+
+ PaletteUsage tempUsage(_vm);
+ Common::Array<UsageEntry> tempUsageData;
+ tempUsage.load(&tempUsageData);
+
+ if (flags & 0x4000) {
+ palLow = 0;
+ palIdx = palHigh;
+ } else {
+ palLow = _vm->_palette->_lowRange;
+ if ((PALETTE_COUNT - _vm->_palette->_highRange) > palHigh) {
+ palIdx = palHigh;
+ } else {
+ palIdx = PALETTE_COUNT - _vm->_palette->_highRange;
+ }
+ }
+
+ int rgbIndex = _vm->_palette->_rgbList.scan();
+ uint32 rgbMask = 1 << rgbIndex;
+ bool noUsageFlag = flags & 0x8000;
+ bool hasUsage = _data != nullptr;
+ bool flag1 = false;
+
+ if (hasUsage) {
+ if (noUsageFlag || _data->size() == 0)
+ hasUsage = false;
+
+ if (noUsageFlag && _data->size() > 0)
+ flag1 = true;
+ }
+
+ if (hasUsage) {
+ tempUsage.getKeyEntries(palette);
+ tempUsage.prioritize(palette);
+ }
+
+ int freeIndex;
+ int palCount = getGamePalFreeIndex(&freeIndex);
+ Common::Array<UsageRange> palRange;
+
+ for (uint palIndex = 0; palIndex < palette.size(); ++palIndex) {
+ byte pal2 = palIndex;
+ byte pal1 = 0;
+
+ if (!(palette[palIndex]._flags & 0x80)) {
+ pal1 = 0x40;
+ }
+ if (palette[palIndex]._flags & 0x60) {
+ pal1 |= 0x20;
+ }
+
+ palRange.push_back(UsageRange(pal1, pal2));
+ }
+
+ Common::sort(palRange.begin(), palRange.end(), rangeSorter);
+
+ int var3A = (flags & 0x4000) ? 0xffff : 0xfffe;
+
+ for (uint palIndex = 0; palIndex < palette.size(); ++palIndex) {
+ bool var48 = false;
+ int var4 = 0xffff;
+ int v1 = palRange[palIndex]._v2;
+
+ if (palette[v1]._flags & 8) {
+ var48 = true;
+ var4 = 0xFD;
+ }
+
+ if (hasUsage && palette[v1]._flags & 0x10) {
+ for (uint usageIndex = 0; usageIndex < tempUsage._data->size() && !var48; ++usageIndex) {
+ if ((*tempUsage._data)[usageIndex]._palIndex == palIndex) {
+ var48 = true;
+ int dataIndex = MIN(usageIndex, _data->size() - 1);
+ var4 = (*_data)[dataIndex]._palIndex;
+ }
+ }
+ }
+
+ if (flag1 && palette[palIndex]._flags & 0x10) {
+ for (uint usageIndex = 0; usageIndex < _data->size() && !var48; ++usageIndex) {
+ if ((*_data)[usageIndex]._palIndex == palIndex) {
+ var48 = true;
+ var4 = 0xF0 + usageIndex;
+
+ // Copy data into the high end of the main palette
+ RGB6 &pSrc = palette[palIndex];
+ byte *pDest = &_vm->_palette->_mainPalette[var4 * 3];
+ pDest[0] = pSrc.r;
+ pDest[1] = pSrc.g;
+ pDest[2] = pSrc.b;
+ }
+ }
+ }
+
+ if (!var48 && !noUsageFlag) {
+ int var2 = (palette[palIndex]._flags & 0x20) ||
+ (((flags & 0x2000) || (palette[palIndex]._flags & 0x4000)) &&
+ ((flags & 0x1000) || (palCount == 0))) ? 0x7fff : 1;
+ int var36 = (palette[palIndex]._flags & 0x80) ? 0 : 2;
+
+ for (int idx = palLow; idx < palIdx; ++idx) {
+ uint32 v = _vm->_palette->_palFlags[idx];
+ if ((v & var3A) && !(v & var36)) {
+ int var10;
+
+ if (var2 > 1) {
+ var10 = rgbFactor(&_vm->_palette->_mainPalette[idx * 3], palette[palIndex]);
+ }
+ else if (_vm->_palette->_mainPalette[idx * 3] != palette[palIndex].r ||
+ _vm->_palette->_mainPalette[idx * 3 + 1] != palette[palIndex].g ||
+ _vm->_palette->_mainPalette[idx * 3 + 2] != palette[palIndex].b) {
+ var10 = 1;
+ } else {
+ var10 = 0;
+ }
+
+ if (var2 > var10) {
+ var48 = true;
+ var4 = idx;
+ var2 = var10;
+ }
+ }
+ }
+ }
+
+ if (!var48 && (!(flags & 0x1000) || (!(palette[palIndex]._flags & 0x60) && !(flags & 0x2000)))) {
+ for (int idx = freeIndex; idx < palIdx && !var48; ++idx) {
+ if (!_vm->_palette->_palFlags[idx]) {
+ --palCount;
+ ++freeIndex;
+ var48 = true;
+ var4 = idx;
+
+ RGB6 &pSrc = palette[palIndex];
+ byte *pDest = &_vm->_palette->_mainPalette[idx * 3];
+ pDest[0] = pSrc.r;
+ pDest[1] = pSrc.g;
+ pDest[2] = pSrc.b;
+ }
+ }
+ }
+
+ assert(var48);
+ int var52 = (noUsageFlag && palette[palIndex]._u2) ? 2 : 0;
+
+ _vm->_palette->_palFlags[var4] |= var52 | rgbMask;
+ palette[palIndex]._palIndex = var4;
+ }
+
+ _vm->_palette->_rgbList[rgbIndex] = true;
+
+ return rgbIndex;
+}
+
+void PaletteUsage::transform(Common::Array<RGB6> &palette) {
+ if (!empty()) {
+ for (uint i = 0; i < _data->size(); ++i) {
+ int palIndex = (*_data)[i]._palIndex;
+ (*_data)[i]._palIndex = palette[palIndex]._palIndex;
+ }
+ }
+}
+
+void PaletteUsage::updateUsage(Common::Array<int> &usageList, int sceneUsageIndex) {
+ uint32 mask1 = 0xFFFFFFFF;
+ uint32 mask2 = 0;
+
+ for (uint idx = 0; idx < usageList.size(); ++idx) {
+ uint32 bitMask = 1 << usageList[idx];
+ mask1 ^= bitMask;
+ mask2 |= bitMask;
+ _vm->_palette->_rgbList[usageList[idx]] = false;
+ }
+
+ uint32 mask3 = 1 << sceneUsageIndex;
+
+ for (uint idx = 0; idx < PALETTE_COUNT; ++idx) {
+ uint32 mask = mask2 & _vm->_palette->_palFlags[idx];
+ if (mask) {
+ _vm->_palette->_palFlags[idx] = (_vm->_palette->_palFlags[idx] &
+ mask1) | mask3;
+ }
+ }
+
+ _vm->_palette->_rgbList[sceneUsageIndex] = true;
+}
+
+void PaletteUsage::resetPalFlags(int idx) {
+ if (idx >= 0 && idx < 32) {
+ uint32 rgbMask = ~(1 << idx);
+
+ uint32 *flagP = _vm->_palette->_palFlags;
+ for (int i = 0; i < 256; ++i, ++flagP) {
+ *flagP &= rgbMask;
+ if (*flagP == 2)
+ *flagP = 0;
+ }
+
+ _vm->_palette->_rgbList[idx] = 0;
+ }
+}
+
+int PaletteUsage::getGamePalFreeIndex(int *palIndex) {
+ *palIndex = -1;
+ int count = 0;
+
+ for (int i = 0; i < PALETTE_COUNT; ++i) {
+ if (!_vm->_palette->_palFlags[i]) {
+ ++count;
+ if (*palIndex < 0)
+ *palIndex = i;
+ }
+ }
+
+ return count;
+}
+
+int PaletteUsage::rgbFactor(byte *palEntry, RGB6 &pal6) {
+ int total = 0;
+ total += (palEntry[0] - pal6.r) * (palEntry[0] - pal6.r);
+ total += (palEntry[1] - pal6.g) * (palEntry[1] - pal6.g);
+ total += (palEntry[2] - pal6.b) * (palEntry[2] - pal6.b);
+
+ return total;
+}
+
+/*------------------------------------------------------------------------*/
+
+void RGBList::clear() {
+ for (int i = 0; i < 32; i++)
+ _data[i] = false;
+}
+
+void RGBList::reset() {
+ for (int i = 2; i < 32; i++)
+ _data[i] = false;
+}
+
+int RGBList::scan() {
+ for (int i = 0; i < 32; ++i) {
+ if (!_data[i])
+ return i;
+ }
+
+ error("RGBList was full");
+}
+
+void RGBList::copy(RGBList &src) {
+ Common::copy(&src._data[0], &src._data[32], &_data[0]);
+}
+
+/*------------------------------------------------------------------------*/
+
+Fader::Fader(MADSEngine *vm)
+ : _vm(vm) {
+ _colorFlags[0] = _colorFlags[1] = _colorFlags[2] = true;
+ _colorFlags[3] = false;
+ _colorValues[0] = _colorValues[1] = 0;
+ _colorValues[2] = _colorValues[3] = 0;
+
+ // TODO: It would be better if the fader routines could be refactored
+ // to work directly with 8-bit RGB values rather than 6-bit RGB values
+ Common::fill(&_rgb64Map[0], &_rgb64Map[PALETTE_COUNT], 0);
+ for (int i = 0; i < 64; ++i)
+ _rgb64Map[VGA_COLOR_TRANS(i)] = i;
+ byte v = 0;
+ for (int i = 0; i < PALETTE_COUNT; ++i) {
+ if (_rgb64Map[i])
+ v = _rgb64Map[i];
+ else
+ _rgb64Map[i] = v;
+ }
+}
+
+
+void Fader::setPalette(const byte *colors, uint start, uint num) {
+ g_system->getPaletteManager()->setPalette(colors, start, num);
+}
+
+void Fader::grabPalette(byte *colors, uint start, uint num) {
+ g_system->getPaletteManager()->grabPalette(colors, start, num);
+}
+
+void Fader::fadeOut(byte palette[PALETTE_SIZE], byte *paletteMap,
+ int baseColor, int numColors, int baseGrey, int numGreys,
+ int tickDelay, int steps) {
+ GreyEntry map[PALETTE_COUNT];
+ int intensity;
+ byte palIndex[PALETTE_COUNT][3];
+ int8 signs[PALETTE_COUNT][3];
+
+ mapToGreyRamp(palette, baseColor, numColors, baseGrey, numGreys, map);
+
+ for (int palCtr = baseColor; palCtr < (baseColor + numColors); ++palCtr) {
+ int index = palCtr - baseColor;
+ for (int colorCtr = 0; colorCtr < 3; ++colorCtr) {
+ if (_colorFlags[colorCtr]) {
+ int shiftSign = _colorValues[colorCtr];
+ if (shiftSign >= 0) {
+ intensity = map[index]._intensity << shiftSign;
+ } else {
+ intensity = map[index]._intensity >> ABS(shiftSign);
+ }
+ } else {
+ intensity = _colorValues[colorCtr];
+ }
+
+ int diff = intensity - _rgb64Map[palette[palCtr * 3 + colorCtr]];
+ palIndex[palCtr][colorCtr] = (byte)ABS(diff);
+ signs[palCtr][colorCtr] = (diff == 0) ? 0 : (diff < 0 ? -1 : 1);
+ }
+ }
+
+ for (int stepCtr = 0; stepCtr < steps; ++stepCtr) {
+ for (int palCtr = baseColor; palCtr < (baseColor + numColors); ++palCtr) {
+ int index = palCtr - baseColor;
+ for (int colorCtr = 0; colorCtr < 3; ++colorCtr) {
+ map[index]._accum[colorCtr] += palIndex[palCtr][colorCtr];
+ while (map[index]._accum[colorCtr] >= steps) {
+ map[index]._accum[colorCtr] -= steps;
+
+ byte rgb63 = _rgb64Map[palette[palCtr * 3 + colorCtr]] +
+ signs[palCtr][colorCtr];
+ palette[palCtr * 3 + colorCtr] = VGA_COLOR_TRANS(rgb63);
+ }
+ }
+ }
+
+ setFullPalette(palette);
+
+ _vm->_events->waitForNextFrame();
+ }
+
+ if (paletteMap != nullptr) {
+ for (int palCtr = 0; palCtr < numColors; palCtr++) {
+ paletteMap[palCtr] = map[palCtr]._mapColor;
+ }
+ }
+}
+
+void Fader::fadeIn(byte palette[PALETTE_SIZE], byte destPalette[PALETTE_SIZE],
+ int baseColor, int numColors, int baseGrey, int numGreys,
+ int tickDelay, int steps) {
+ GreyEntry map[PALETTE_COUNT];
+ byte tempPal[PALETTE_SIZE];;
+ int8 signs[PALETTE_COUNT][3];
+ byte palIndex[PALETTE_COUNT][3];
+ int intensity;
+
+ Common::copy(destPalette, destPalette + PALETTE_SIZE, tempPal);
+
+ mapToGreyRamp(tempPal, baseColor, numColors, baseGrey, numGreys, map);
+
+ for (int palCtr = baseColor; palCtr < (baseColor + numColors); ++palCtr) {
+ int index = palCtr - baseColor;
+ for (int colorCtr = 0; colorCtr < 3; ++colorCtr) {
+ if (_colorFlags[colorCtr]) {
+ int shiftSign = _colorValues[colorCtr];
+ if (shiftSign >= 0) {
+ intensity = map[index]._intensity << shiftSign;
+ }
+ else {
+ intensity = map[index]._intensity >> abs(shiftSign);
+ }
+ }
+ else {
+ intensity = _colorValues[colorCtr];
+ }
+
+ int diff = _rgb64Map[destPalette[palCtr * 3 + colorCtr]] - intensity;
+ palIndex[palCtr][colorCtr] = (byte)ABS(diff);
+ signs[palCtr][colorCtr] = (diff == 0) ? 0 : (diff < 0 ? -1 : 1);
+
+ map[index]._accum[colorCtr] = 0;
+ }
+ }
+
+ for (int stepCtr = 0; stepCtr < steps; ++stepCtr) {
+ for (int palCtr = baseColor; palCtr < (baseColor + numColors); ++palCtr) {
+ int index = palCtr - baseColor;
+ for (int colorCtr = 0; colorCtr < 3; ++colorCtr) {
+ map[index]._accum[colorCtr] += palIndex[palCtr][colorCtr];
+ while (map[index]._accum[colorCtr] >= steps) {
+ map[index]._accum[colorCtr] -= steps;
+
+ byte rgb63 = _rgb64Map[palette[palCtr * 3 + colorCtr]] +
+ signs[palCtr][colorCtr];
+ palette[palCtr * 3 + colorCtr] = VGA_COLOR_TRANS(rgb63);
+ }
+ }
+ }
+
+ setFullPalette(palette);
+
+ _vm->_events->waitForNextFrame();
+ }
+}
+
+void Fader::mapToGreyRamp(byte palette[PALETTE_SIZE], int baseColor, int numColors,
+ int baseGrey, int numGreys, GreyEntry *map) {
+ byte greyList[PALETTE_COUNT];
+ byte greyMapping[PALETTE_COUNT];
+ byte greyTable[64];
+ byte greyIntensity[64];
+ int intensity, shiftSign;
+
+ getGreyValues(palette, greyList, baseColor, numColors);
+ greyPopularity(greyList, greyTable, numColors);
+
+ for (int idx = 0; idx < numColors; ++idx) {
+ greyMapping[idx] = idx;
+ Common::fill(&map[idx]._accum[0], &map[idx]._accum[3], 0);
+ }
+
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx) {
+ map[idx]._mapColor = (byte)idx;
+ }
+
+ // Sort the mapping lists
+ insertionSort(numColors, greyList, greyMapping);
+
+ // Initialize state variables
+ int greySum = 0;
+ int greyScan = 0;
+ int greyMark = 0;
+ int greyColors = 0;
+ int greyAccum = 0;
+ int firstColor = 0;
+
+ for (int greyCtr = 0; greyCtr < 64; ++greyCtr) {
+ for (int idx = 0; idx < greyTable[greyCtr]; ++idx) {
+ greySum += greyList[greyScan++];
+ ++greyColors;
+
+ greyAccum += numGreys;
+ while (greyAccum >= numColors) {
+ greyAccum -= numColors;
+ if (greyColors > 0) {
+ greyIntensity[greyMark] = (byte)(greySum / greyColors);
+ }
+
+ for (int rescan = firstColor; rescan < greyScan; ++rescan) {
+ map[greyMapping[rescan]]._intensity = greyIntensity[greyMark];
+ map[greyMapping[rescan]]._mapColor = (byte)(greyMark + baseGrey);
+ }
+
+ firstColor = greyScan;
+ greySum = 0;
+ greyColors = 0;
+ ++greyMark;
+ }
+ }
+ }
+
+ // Set the palette range of greyscale values to be used
+ byte *palP = &palette[baseGrey * 3];
+ for (int greys = 0; greys < numGreys; ++greys) {
+ for (int color = 0; color < 3; ++color) {
+ if (_colorFlags[color]) {
+ shiftSign = (byte)_colorValues[color];
+ if (shiftSign >= 0) {
+ intensity = greyIntensity[greys] << shiftSign;
+ } else {
+ intensity = greyIntensity[greys] >> abs(shiftSign);
+ }
+ } else {
+ intensity = _colorValues[color];
+ }
+ *palP++ = VGA_COLOR_TRANS(intensity);
+ }
+ }
+}
+
+void Fader::getGreyValues(const byte palette[PALETTE_SIZE],
+ byte greyList[PALETTE_COUNT], int baseColor, int numColors) {
+ const byte *palP = &palette[baseColor * 3];
+
+ for (int i = 0; i < numColors; ++i, palP += 3) {
+ int v = rgbMerge(palP[0], palP[1], palP[2]);
+ greyList[i] = v >> 7;
+ }
+}
+
+void Fader::greyPopularity(const byte greyList[PALETTE_COUNT],
+ byte greyTable[64], int numColors) {
+ Common::fill(&greyTable[0], &greyTable[64], 0);
+ for (int i = 0; i < numColors; ++i) {
+ int idx = greyList[i];
+ ++greyTable[idx];
+ }
+}
+
+void Fader::insertionSort(int size, byte *id, byte *value) {
+ bool restartFlag;
+ int endIndex = size - 1;
+
+ do {
+ restartFlag = false;
+ if (endIndex <= 0)
+ break;
+
+ for (int arrIndex = 0; arrIndex < endIndex && !restartFlag; ++arrIndex) {
+ byte *idP = id + arrIndex;
+ byte *valueP = value + arrIndex;
+
+ // Check whether the next index is out of order with the one following it
+ if (*idP > *(idP + 1)) {
+ // Found an incorrect ordering
+ restartFlag = true;
+
+ // Save id/value at current index
+ byte savedId = *idP;
+ byte savedValue = *valueP;
+
+ int moveCount = size - arrIndex - 1;
+ if (moveCount > 0) {
+ Common::copy(idP + 1, idP + moveCount + 2, idP);
+ Common::copy(valueP + 1, valueP + moveCount + 2, valueP);
+ }
+
+ // Scan for insert spot
+ int idx = 0;
+ if (endIndex > 0) {
+ bool breakFlag = false;
+ for (; idx <= endIndex && !breakFlag; ++idx) {
+ breakFlag = savedId < id[idx];
+ }
+ }
+
+ // Set up an insert point for entry
+ moveCount = size - idx - 1;
+ if (moveCount > 0) {
+ Common::copy_backward(id + idx, id + idx + moveCount, id + idx + moveCount + 1);
+ Common::copy_backward(value + idx, value + idx + moveCount, value + idx + moveCount + 1);
+ }
+
+ // Set shifted values at the new position
+ id[idx] = savedId;
+ value[idx] = savedValue;
+ }
+ }
+ } while (restartFlag);
+}
+
+int Fader::rgbMerge(RGB6 &palEntry) {
+ return rgbMerge(palEntry.r, palEntry.g, palEntry.b);
+}
+
+int Fader::rgbMerge(byte r, byte g, byte b) {
+ return _rgb64Map[r] * 38 + _rgb64Map[g] * 76 + _rgb64Map[b] * 14;
+}
+
+/*------------------------------------------------------------------------*/
+
+Palette::Palette(MADSEngine *vm) : Fader(vm), _paletteUsage(vm) {
+ _lockFl = false;
+ _lowRange = 0;
+ _highRange = 0;
+ Common::fill(&_mainPalette[0], &_mainPalette[PALETTE_SIZE], 0);
+ Common::fill(&_palFlags[0], &_palFlags[PALETTE_COUNT], 0);
+}
+
+void Palette::setEntry(byte palIndex, byte r, byte g, byte b) {
+ _mainPalette[palIndex * 3] = VGA_COLOR_TRANS(r);
+ _mainPalette[palIndex * 3 + 1] = VGA_COLOR_TRANS(g);
+ _mainPalette[palIndex * 3 + 2] = VGA_COLOR_TRANS(b);
+
+ setPalette((const byte *)&_mainPalette[palIndex * 3], palIndex, 1);
+}
+
+uint8 Palette::palIndexFromRgb(byte r, byte g, byte b, byte *paletteData) {
+ byte index = 0;
+ int32 minDist = 0x7fffffff;
+ byte palData[PALETTE_SIZE];
+
+ if (paletteData == NULL) {
+ g_system->getPaletteManager()->grabPalette(palData, 0, PALETTE_COUNT);
+ paletteData = &palData[0];
+ }
+
+ for (int palIndex = 0; palIndex < PALETTE_COUNT; ++palIndex) {
+ int Rdiff = r - paletteData[palIndex * 3];
+ int Gdiff = g - paletteData[palIndex * 3 + 1];
+ int Bdiff = b - paletteData[palIndex * 3 + 2];
+
+ if (Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff < minDist) {
+ minDist = Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff;
+ index = (uint8)palIndex;
+ }
+ }
+
+ return (uint8)index;
+}
+
+void Palette::setGradient(byte *palette, int start, int count, int rgbValue1, int rgbValue2) {
+ int rgbCurrent = rgbValue2;
+ int rgbDiff = -(rgbValue2 - rgbValue1);
+
+ if (count > 0) {
+ byte *pDest = palette + start * 3;
+ int endVal = count - 1;
+ int numLeft = count;
+
+ int rgbCtr = 0;
+ do {
+ pDest[0] = pDest[1] = pDest[2] = rgbCurrent;
+
+ if (numLeft > 1) {
+ rgbCtr += rgbDiff;
+ if (rgbCtr >= endVal) {
+ do {
+ ++rgbCurrent;
+ rgbCtr += 1 - numLeft;
+ } while (rgbCtr >= endVal);
+ }
+ }
+
+ pDest += 3;
+ } while (--numLeft > 0);
+ }
+}
+
+void Palette::setSystemPalette() {
+ byte palData[4 * 3];
+ palData[0 * 3] = palData[0 * 3 + 1] = palData[0 * 3 + 2] = 0;
+ palData[1 * 3] = palData[1 * 3 + 1] = palData[1 * 3 + 2] = 0x54;
+ palData[2 * 3] = palData[2 * 3 + 1] = palData[2 * 3 + 2] = 0xb4;
+ palData[3 * 3] = palData[3 * 3 + 1] = palData[3 * 3 + 2] = 0xff;
+
+ setPalette(palData, 0, 4);
+}
+
+void Palette::resetGamePalette(int lowRange, int highRange) {
+ Common::fill((byte *)&_palFlags[0], (byte *)&_palFlags[PALETTE_COUNT], 0);
+ initVGAPalette(_mainPalette);
+
+ // Reserve the start of the palette for things like on-screen text
+ if (lowRange) {
+ Common::fill(&_palFlags[0], &_palFlags[lowRange], 1);
+ }
+
+ // Reserve the high end of the palette for dialog display
+ if (highRange) {
+ Common::fill(&_palFlags[256 - highRange], &_palFlags[256], 1);
+ }
+
+ _rgbList.clear();
+ _rgbList[0] = _rgbList[1] = true;
+
+ _lockFl = false;
+ _lowRange = lowRange;
+ _highRange = highRange;
+}
+
+void Palette::initPalette() {
+ uint32 palMask = 1;
+
+ if (_vm->_game->_player._spritesLoaded && _vm->_game->_player._numSprites) {
+
+ for (int idx = 0; idx < _vm->_game->_player._numSprites; ++idx) {
+ SpriteAsset *asset = _vm->_game->_scene._sprites[
+ _vm->_game->_player._spritesStart + idx];
+
+ uint32 mask = 1;
+ if (asset->_usageIndex)
+ mask <<= asset->_usageIndex;
+
+ palMask = mask;
+ }
+ }
+
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx)
+ _palFlags[idx] = palMask;
+
+ _lockFl = false;
+ _rgbList.reset();
+}
+
+void Palette::initVGAPalette(byte *palette) {
+ byte *destP = palette;
+ for (int palIndex = 0; palIndex < 16; ++palIndex) {
+ for (int byteCtr = 2; byteCtr >= 0; --byteCtr)
+ *destP++ = ((DEFAULT_VGA_LOW_PALETTE[palIndex] >> (8 * byteCtr)) & 0xff) >> 2;
+ }
+
+ destP = &palette[0xF0 * 3];
+ for (int palIndex = 0; palIndex < 16; ++palIndex) {
+ for (int byteCtr = 2; byteCtr >= 0; --byteCtr)
+ *destP++ = ((DEFAULT_VGA_HIGH_PALETTE[palIndex] >> (8 * byteCtr)) & 0xff) >> 2;
+ }
+}
+
+void Palette::setLowRange() {
+ _mainPalette[0] = _mainPalette[1] = _mainPalette[2] = VGA_COLOR_TRANS(0);
+ _mainPalette[3] = _mainPalette[4] = _mainPalette[5] = VGA_COLOR_TRANS(0x15);
+ _mainPalette[6] = _mainPalette[7] = _mainPalette[8] = VGA_COLOR_TRANS(0x2A);
+ _mainPalette[9] = _mainPalette[10] = _mainPalette[11] = VGA_COLOR_TRANS(0x3F);
+ _vm->_palette->setPalette(_mainPalette, 0, 4);
+}
+
+void Palette::setColorFlags(byte r, byte g, byte b) {
+ _colorFlags[0] = r;
+ _colorFlags[1] = g;
+ _colorFlags[2] = b;
+}
+
+void Palette::setColorValues(byte r, byte g, byte b) {
+ _colorValues[0] = r;
+ _colorValues[1] = g;
+ _colorValues[2] = b;
+}
+
+void Palette::lock() {
+ if (_rgbList[31] && !_lockFl)
+ error("Palette Lock - Unexpected values");
+
+ _lockFl = true;
+ _rgbList[31] = true;
+
+ for (int i = 0; i < 256; i++) {
+ if (_palFlags[i])
+ _palFlags[i] |= 0x80000000;
+ }
+}
+
+void Palette::unlock() {
+ if (!_lockFl)
+ return;
+
+ for (int i = 0; i < 256; i++)
+ _palFlags[i] &= 0x7FFFFFFF;
+
+ _rgbList[31] = false;
+ _lockFl = false;
+}
+
+void Palette::refreshSceneColors() {
+ int val = 18;
+ if (_vm->_game->_scene._cyclingActive)
+ val += _vm->_game->_scene._totalCycleColors;
+
+ setPalette(_mainPalette + (val * 3), val, 256 - val);
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/palette.h b/engines/mads/palette.h
new file mode 100644
index 0000000000..ff93b2f2fe
--- /dev/null
+++ b/engines/mads/palette.h
@@ -0,0 +1,330 @@
+/* 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 MADS_PALETTE_H
+#define MADS_PALETTE_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+#define PALETTE_USAGE_COUNT 4
+
+#define PALETTE_RESERVED_LOW_COUNT 18
+#define PALETTE_RESERVED_HIGH_COUNT 10
+
+#define PALETTE_COUNT 256
+#define PALETTE_SIZE (256 * 3)
+
+/**
+ * Palette mapping options
+ */
+enum {
+ PALFLAG_BACKGROUND = 0x8000, // Loading initial background
+ PALFLAG_RESERVED = 0x4000, // Enable mapping reserved colors
+ PALFLAG_ANY_TO_CLOSEST = 0x2000, // Any color can map to closest
+ PALFLAG_ALL_TO_CLOSEST = 0x1000, // Any colors that can map must map
+ PALFLAG_TOP_COLORS = 0x0800, // Allow mapping to high four colors
+ PALFLAG_DEFINE_RESERVED = 0x0400, // Define initial reserved color
+ PALFLAG_MASK = 0xfc00 // Mask for all the palette flags
+};
+
+struct PaletteCycle {
+ byte _colorCount;
+ byte _firstListColor;
+ byte _firstColorIndex;
+ byte _ticks;
+
+ PaletteCycle() { _colorCount = _firstListColor = _firstColorIndex = _ticks = 0; }
+};
+
+struct RGB6 {
+ byte r;
+ byte g;
+ byte b;
+ byte _palIndex;
+ byte _u2;
+ byte _flags;
+
+ /**
+ * Load an entry from a stream
+ */
+ void load(Common::SeekableReadStream *f);
+};
+
+class PaletteUsage {
+public:
+ struct UsageEntry {
+ uint16 _palIndex;
+ int _sortValue;
+
+ UsageEntry(int palIndex) { _palIndex = palIndex; _sortValue = -1; }
+ UsageEntry() { _palIndex = 0; _sortValue = 0; }
+ };
+ struct UsageRange {
+ byte _v1, _v2;
+
+ UsageRange(byte v1, byte v2) { _v1 = v1; _v2 = v2; }
+ };
+private:
+ MADSEngine *_vm;
+ Common::Array<UsageEntry> *_data;
+
+ int getGamePalFreeIndex(int *palIndex);
+
+ int rgbFactor(byte *palEntry, RGB6 &pal6);
+
+ Common::Array<UsageEntry> _nullUsage;
+public:
+ /**
+ * Constructor
+ */
+ PaletteUsage(MADSEngine *vm);
+
+ void load(Common::Array<UsageEntry> *data);
+
+ /**
+ * Returns whether the usage list is empty
+ */
+ bool empty() const { return _data == nullptr; }
+
+ uint16 &operator[](int index) { return (*_data)[index]._palIndex; }
+
+ /**
+ * Assigns the class to an empty usage array
+ */
+ void setEmpty() { _data = &_nullUsage; }
+
+ /**
+ * Gets key entries from the passed palette
+ * @param palette 6-bit per entry read in palette
+ */
+ void getKeyEntries(Common::Array<RGB6> &palette);
+
+ /**
+ * Prioritizes the palette index list based on the intensity of the
+ * RGB values of the palette entries that they refer to
+ */
+ void prioritize(Common::Array<RGB6> &palette);
+
+ int process(Common::Array<RGB6> &palette, uint flags);
+
+ void transform(Common::Array<RGB6> &palette);
+
+ void updateUsage(Common::Array<int> &usageList, int sceneUsageIndex);
+
+ void resetPalFlags(int idx);
+};
+
+class RGBList {
+private:
+ bool _data[32];
+public:
+ RGBList() { clear(); }
+
+ void clear();
+
+ void reset();
+
+ /**
+ * Copies the data from another instance
+ */
+ void copy(RGBList &src);
+
+ /**
+ * Scans for a free slot
+ */
+ int scan();
+
+ bool &operator[](int idx) { return _data[idx]; }
+};
+
+class Fader {
+public:
+ struct GreyEntry {
+ byte _intensity;
+ byte _mapColor;
+ uint16 _accum[3];
+ };
+private:
+ void mapToGreyRamp(byte palette[PALETTE_SIZE], int baseColor, int numColors,
+ int baseGrey, int numGreys, GreyEntry *map);
+
+ void getGreyValues(const byte palette[PALETTE_SIZE], byte greyList[PALETTE_COUNT],
+ int baseColor, int numColors);
+
+ /**
+ * Given a grey value list containing grey shades (0-63), creates a 64 byte
+ * grey table containing the number of grey values for each intensity
+ */
+ void greyPopularity(const byte greyList[PALETTE_COUNT], byte greyTable[64], int numColors);
+
+ /**
+ * Does an insertion sort of a given id/value array pair
+ */
+ void insertionSort(int size, byte *id, byte *value);
+protected:
+ MADSEngine *_vm;
+ byte _rgb64Map[PALETTE_COUNT];
+public:
+ bool _colorFlags[4];
+ int _colorValues[4];
+public:
+ /**
+ * Constructor
+ */
+ Fader(MADSEngine *vm);
+
+ /**
+ * Sets a new palette
+ */
+ void setPalette(const byte *colors, uint start, uint num);
+
+ /**
+ * Returns a subset of the currently loaded palette
+ */
+ void grabPalette(byte *colors, uint start, uint num);
+
+ /**
+ * Gets the entire palette at once
+ */
+ void getFullPalette(byte palette[PALETTE_SIZE]) {
+ grabPalette(&palette[0], 0, PALETTE_COUNT);
+ }
+
+ /**
+ * Sets the entire palette at once
+ */
+ void setFullPalette(byte palette[PALETTE_SIZE]) {
+ setPalette(&palette[0], 0, PALETTE_COUNT);
+ }
+
+ /**
+ * Calculates a merge/hash for a given palette entry
+ */
+ int rgbMerge(byte r, byte g, byte b);
+
+ /**
+ * Calculates a merge/hash for a given palette entry
+ */
+ int rgbMerge(RGB6 &palEntry);
+
+ /**
+ * Fades the given palette out to black or grey
+ */
+ void fadeOut(byte palette[PALETTE_SIZE], byte *paletteMap,
+ int baseColor, int numColors, int baseGrey, int numGreys,
+ int tickDelay, int steps);
+
+ /**
+ * Fade into the given palette
+ */
+ void fadeIn(byte palette[PALETTE_SIZE], byte destPalette[PALETTE_SIZE],
+ int baseColor, int numColors, int baseGrey, int numGreys,
+ int tickDelay, int steps);
+};
+
+class Palette : public Fader {
+private:
+ /**
+ * Initializes the first 16 palette indexes with the equivalent
+ * standard VGA palette
+ */
+ void initVGAPalette(byte *palette);
+public:
+ byte _mainPalette[PALETTE_SIZE];
+ byte _cyclingPalette[PALETTE_SIZE];
+ uint32 _palFlags[PALETTE_COUNT];
+ PaletteUsage _paletteUsage;
+ RGBList _rgbList;
+ bool _lockFl;
+ int _lowRange;
+ int _highRange;
+public:
+ /**
+ * Constructor
+ */
+ Palette(MADSEngine *vm);
+
+ /**
+ * Destructor
+ */
+ virtual ~Palette() {}
+
+ /**
+ * Set a palette entry
+ */
+ void setEntry(byte palIndex, byte r, byte g, byte b);
+
+ /**
+ * Returns the palette index in the palette that most closely matches the
+ * specified RGB pair
+ */
+ uint8 palIndexFromRgb(byte r, byte g, byte b, byte *paletteData = nullptr);
+
+ /**
+ * Sets a small set of system/core colors needed by the game
+ */
+ void setSystemPalette();
+
+ /**
+ * Update a range of an arbitrary palette
+ */
+ static void setGradient(byte *palette, int start, int count, int rgbValue1, int rgbValue2);
+
+ /**
+ * Resets the game palette
+ */
+ void resetGamePalette(int v1, int v2);
+
+ /**
+ * Initializes the main palette
+ */
+ void initPalette();
+
+ /**
+ * Set the first four palette entries with preset values
+ */
+ void setLowRange();
+
+ /**
+ * Set up the palette as the game ends
+ */
+ void close() {
+ warning("TODO: Palette::close");
+ }
+
+ void setColorFlags(byte r, byte g, byte b);
+ void setColorValues(byte r, byte g, byte b);
+
+ void lock();
+ void unlock();
+
+ void refreshSceneColors();
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_PALETTE_H */
diff --git a/engines/mads/phantom/game_phantom.cpp b/engines/mads/phantom/game_phantom.cpp
new file mode 100644
index 0000000000..15ac241d8c
--- /dev/null
+++ b/engines/mads/phantom/game_phantom.cpp
@@ -0,0 +1,161 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/game.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/phantom/game_phantom.h"
+//#include "mads/nebular/dialogs_nebular.h"
+//#include "mads/nebular/globals_nebular.h"
+#include "mads/phantom/phantom_scenes.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+GamePhantom::GamePhantom(MADSEngine *vm)
+ : Game(vm) {
+ _surface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+ _storyMode = STORYMODE_NAUGHTY;
+}
+
+ProtectionResult GamePhantom::checkCopyProtection() {
+ /*
+ // DEBUG: Flag copy protection failure
+ _globals[5] = -1;
+
+ if (!ConfMan.getBool("copy_protection"))
+ return true;
+
+ * DEBUG: Disabled for now
+ CopyProtectionDialog *dlg = new CopyProtectionDialog(_vm, false);
+ dlg->show();
+ delete dlg;
+ */
+
+ // DEBUG: Return that copy protection failed
+ return PROTECTION_SUCCEED;
+}
+
+void GamePhantom::initializeGlobals() {
+ //int count, count2;
+ //int bad;
+
+ _globals.reset();
+ //_globals[kTalkInanimateCount] = 8;
+
+ /* Section #1 variables */
+ // TODO
+
+ /* Section #2 variables */
+ // TODO
+
+ /* Section #3 variables */
+ // TODO
+
+ /* Section #4 variables */
+ // TODO
+
+ /* Section #5 variables */
+ // TODO
+
+ /* Section #9 variables */
+ // TODO
+
+ _player._facing = FACING_NORTH;
+ _player._turnToFacing = FACING_NORTH;
+
+ //Player::preloadSequences("RXM", 1);
+ //Player::preloadSequences("ROX", 1);
+}
+
+void GamePhantom::setSectionHandler() {
+ delete _sectionHandler;
+
+ switch (_sectionNumber) {
+ case 1:
+ _sectionHandler = new Section1Handler(_vm);
+ break;
+ case 2:
+ _sectionHandler = new Section2Handler(_vm);
+ break;
+ case 3:
+ _sectionHandler = new Section3Handler(_vm);
+ break;
+ case 4:
+ _sectionHandler = new Section4Handler(_vm);
+ break;
+ case 5:
+ _sectionHandler = new Section5Handler(_vm);
+ break;
+ default:
+ break;
+ }
+}
+
+void GamePhantom::checkShowDialog() {
+ // TODO: Copied from Nebular
+ if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[5]) {
+ _player.releasePlayerSprites();
+ _vm->_dialogs->showDialog();
+ _vm->_dialogs->_pendingDialog = DIALOG_NONE;
+ }
+}
+
+void GamePhantom::doObjectAction() {
+ // TODO: Copied from Nebular
+ //Scene &scene = _scene;
+ MADSAction &action = _scene._action;
+ //Dialogs &dialogs = *_vm->_dialogs;
+ //int id;
+
+ action._inProgress = false;
+}
+
+void GamePhantom::unhandledAction() {
+ // TODO
+}
+
+void GamePhantom::step() {
+ if (_player._visible && _player._stepEnabled && !_player._moving &&
+ (_player._facing == _player._turnToFacing)) {
+
+ // TODO
+ }
+
+}
+
+void GamePhantom::synchronize(Common::Serializer &s, bool phase1) {
+ Game::synchronize(s, phase1);
+
+ // TODO: Copied from Nebular
+ if (!phase1) {
+ _globals.synchronize(s);
+ }
+}
+
+} // End of namespace Phantom
+
+} // End of namespace MADS
diff --git a/engines/mads/phantom/game_phantom.h b/engines/mads/phantom/game_phantom.h
new file mode 100644
index 0000000000..7a84ee1c72
--- /dev/null
+++ b/engines/mads/phantom/game_phantom.h
@@ -0,0 +1,124 @@
+/* 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 MADS_GAME_PHANTOM_H
+#define MADS_GAME_PHANTOM_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/globals.h"
+//#include "mads/nebular/globals_nebular.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+// TODO: Adapt for Phantom's difficulty setting
+enum StoryMode { STORYMODE_NAUGHTY = 1, STORYMODE_NICE = 2 };
+
+enum InventoryObject {
+ OBJ_NONE = -1,
+ OBJ_KEY = 0,
+ OBJ_LANTERN = 1,
+ OBJ_RED_FRAME = 2,
+ OBJ_SANDBAG = 3,
+ OBJ_YELLOW_FRAME = 4,
+ OBJ_FIRE_AXE = 5,
+ OBJ_SMALL_NOTE = 6,
+ OBJ_ROPE = 7,
+ OBJ_SWORD = 8,
+ OBJ_ENVELOPE = 9,
+ OBJ_TICKET = 10,
+ OBJ_PIECE_OF_PAPER = 11,
+ OBJ_PARCHMENT = 12,
+ OBJ_LETTER = 13,
+ OBJ_NOTICE = 14,
+ OBJ_BOOK = 15,
+ OBJ_CRUMPLED_NOTE = 16,
+ OBJ_BLUE_FRAME = 17,
+ OBJ_LARGE_NOTE = 18,
+ OBJ_GREEN_FRAME = 19,
+ OBJ_MUSIC_SCORE = 20,
+ OBJ_WEDDING_RING = 21,
+ OBJ_CABLE_HOOK = 22,
+ OBJ_ROPE_WITH_HOOK = 23,
+ OBJ_OAR = 24
+};
+
+// HACK: A stub for now, remove from here once it's implemented properly
+class PhantomGlobals : public Globals {
+public:
+ PhantomGlobals() {
+ resize(210); // Rex has 210 globals
+ }
+ virtual ~PhantomGlobals() {}
+};
+
+class GamePhantom : public Game {
+ friend class Game;
+protected:
+ GamePhantom(MADSEngine *vm);
+
+ virtual ProtectionResult checkCopyProtection();
+
+ virtual void initializeGlobals();
+
+ virtual void setSectionHandler();
+
+ virtual void checkShowDialog();
+public:
+ PhantomGlobals _globals;
+ StoryMode _storyMode;
+
+ virtual Globals &globals() { return _globals; }
+
+ virtual void doObjectAction();
+
+ virtual void unhandledAction();
+
+ virtual void step();
+
+ virtual void synchronize(Common::Serializer &s, bool phase1);
+};
+
+
+class Section1Handler : public SectionHandler {
+public:
+ Section1Handler(MADSEngine *vm) : SectionHandler(vm) {}
+
+ // TODO: Properly implement handler methods
+ virtual void preLoadSection() {}
+ virtual void sectionPtr2() {}
+ virtual void postLoadSection() {}
+};
+
+// TODO: Properly implement handler classes
+typedef Section1Handler Section2Handler;
+typedef Section1Handler Section3Handler;
+typedef Section1Handler Section4Handler;
+typedef Section1Handler Section5Handler;
+
+} // End of namespace Nebular
+
+} // End of namespace MADS
+
+#endif /* MADS_GAME_PHANTOM_H */
diff --git a/engines/mads/phantom/phantom_scenes.cpp b/engines/mads/phantom/phantom_scenes.cpp
new file mode 100644
index 0000000000..dbce014525
--- /dev/null
+++ b/engines/mads/phantom/phantom_scenes.cpp
@@ -0,0 +1,204 @@
+/* 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 "common/scummsys.h"
+#include "common/config-manager.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/resources.h"
+#include "mads/scene.h"
+#include "mads/phantom/game_phantom.h"
+#include "mads/phantom/phantom_scenes.h"
+
+namespace MADS {
+
+namespace Phantom {
+
+SceneLogic *SceneFactory::createScene(MADSEngine *vm) {
+ Scene &scene = vm->_game->_scene;
+
+ // TODO
+ //scene.addActiveVocab(NOUN_DROP);
+
+ switch (scene._nextSceneId) {
+ // Scene group #1 (theater, stage and dressing rooms)
+ case 101: // seats
+ return new DummyScene(vm); // TODO
+ case 102: // music stands
+ return new DummyScene(vm); // TODO
+ case 103: // below stage
+ return new DummyScene(vm); // TODO
+ case 104: // stage
+ return new DummyScene(vm); // TODO
+ case 105: // ground floor, storage room
+ return new DummyScene(vm); // TODO
+ case 106: // behind stage
+ return new DummyScene(vm); // TODO
+ case 107: // stage right wing
+ return new DummyScene(vm); // TODO
+ case 108: // stage left wing
+ return new DummyScene(vm); // TODO
+ case 109: // upper floor, staircase
+ return new DummyScene(vm); // TODO
+ case 110: // outside dressing rooms 1
+ return new DummyScene(vm); // TODO
+ case 111: // outside dressing rooms 2
+ return new DummyScene(vm); // TODO
+ case 112: // inside dressing room 1
+ return new DummyScene(vm); // TODO
+ case 113: // inside dressing room 2
+ return new DummyScene(vm); // TODO
+ case 114: // lower floor, storage room
+ return new DummyScene(vm); // TODO
+ case 150: // cutscene
+ return new DummyScene(vm); // TODO
+
+ // Scene group #2 (theater entrance, offices, balcony)
+ case 201: // entrance / ticket office
+ return new DummyScene(vm); // TODO
+ case 202: // outside offices / paintings room
+ return new DummyScene(vm); // TODO
+ case 203: // office
+ return new DummyScene(vm); // TODO
+ case 204: // library
+ return new DummyScene(vm); // TODO
+ case 205: // upper floor, outside balcony boxes
+ return new DummyScene(vm); // TODO
+ case 206: // balcony box #1
+ return new DummyScene(vm); // TODO
+ case 207: // balcony box #2
+ return new DummyScene(vm); // TODO
+ case 208: // stage and balcony view
+ return new DummyScene(vm); // TODO
+ case 250: // cutscene
+ return new DummyScene(vm); // TODO
+
+ // Scene group #3 (catwalks, chandelier, lake / catacombs entrance)
+ case 301: // catwalk #1 above stage
+ return new DummyScene(vm); // TODO
+ case 302: // catwalk #2 above stage
+ return new DummyScene(vm); // TODO
+ case 303: // above chandelier
+ return new DummyScene(vm); // TODO
+ case 304: // chandelier
+ return new DummyScene(vm); // TODO
+ case 305: // chandelier fight, phantom closeup
+ return new DummyScene(vm); // TODO
+ case 306: // chandelier #2
+ return new DummyScene(vm); // TODO
+ case 307: // catwalk #3 above stage
+ return new DummyScene(vm); // TODO
+ case 308: // hidden staircase behind balcony box
+ return new DummyScene(vm); // TODO
+ case 309: // lake and archway
+ return new DummyScene(vm); // TODO
+ case 310: // lake
+ return new DummyScene(vm); // TODO
+
+ // Scene group #4 (labyrinth)
+ case 401: // labyrinth room, 3 exits
+ return new DummyScene(vm); // TODO
+ case 403: // labyrinth room (big), 4 exits + 1 bricked door, left
+ return new DummyScene(vm); // TODO
+ case 404: // labyrinth room, 3 exits
+ return new DummyScene(vm); // TODO
+ case 406: // labyrinth room, 2 exits
+ return new DummyScene(vm); // TODO
+ case 407: // catacomb room / lake
+ return new DummyScene(vm); // TODO
+ case 408: // catacomb corridor
+ return new DummyScene(vm); // TODO
+ case 409: // catacomb room, door with switch panel
+ return new DummyScene(vm); // TODO
+ case 410: // skull switch panel
+ return new DummyScene(vm); // TODO
+ case 453: // Labyrinth room (big), 4 exits + 1 bricked door, right
+ return new DummyScene(vm); // TODO
+ case 456: // Labyrinth room, 2 exits
+ return new DummyScene(vm); // TODO
+
+ // Scene group #5 (Phantom's hideout)
+ case 501: // catacombs, outside phantom's hideout, lake and boat
+ return new DummyScene(vm); // TODO
+ case 502: // push panel trap
+ return new DummyScene(vm); // TODO
+ case 504: // Phantom's hideout, church organ
+ return new DummyScene(vm); // TODO
+ case 505: // Phantom's hideout, sarcophagus
+ return new DummyScene(vm); // TODO
+ case 506: // catacomb room with ramp
+ return new DummyScene(vm); // TODO
+
+ default:
+ error("Invalid scene %d called", scene._nextSceneId);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+PhantomScene::PhantomScene(MADSEngine *vm) : SceneLogic(vm),
+ _globals(static_cast<GamePhantom *>(vm->_game)->_globals),
+ _game(*static_cast<GamePhantom *>(vm->_game)),
+ _action(vm->_game->_scene._action) {
+}
+
+Common::String PhantomScene::formAnimName(char sepChar, int suffixNum) {
+ return Resources::formatName(_scene->_currentSceneId, sepChar, suffixNum,
+ EXT_NONE, "");
+}
+
+/*------------------------------------------------------------------------*/
+
+void SceneInfoPhantom::loadCodes(MSurface &depthSurface, int variant) {
+ File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT"));
+ MadsPack codesPack(&f);
+ Common::SeekableReadStream *stream = codesPack.getItemStream(variant + 1);
+
+ loadCodes(depthSurface, stream);
+
+ delete stream;
+ f.close();
+}
+
+void SceneInfoPhantom::loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) {
+ byte *destP = depthSurface.getData();
+ byte *endP = depthSurface.getBasePtr(0, depthSurface.h);
+
+ byte runLength = stream->readByte();
+ while (destP < endP && runLength > 0) {
+ byte runValue = stream->readByte();
+
+ // Write out the run length
+ Common::fill(destP, destP + runLength, runValue);
+ destP += runLength;
+
+ // Get the next run length
+ runLength = stream->readByte();
+ }
+
+ if (destP < endP)
+ Common::fill(destP, endP, 0);
+}
+
+} // End of namespace Phantom
+
+} // End of namespace MADS
diff --git a/engines/mads/phantom/phantom_scenes.h b/engines/mads/phantom/phantom_scenes.h
new file mode 100644
index 0000000000..cd295a28b6
--- /dev/null
+++ b/engines/mads/phantom/phantom_scenes.h
@@ -0,0 +1,521 @@
+/* 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 MADS_PHANTOM_SCENES_H
+#define MADS_PHANTOM_SCENES_H
+
+#include "common/scummsys.h"
+#include "mads/game.h"
+#include "mads/scene.h"
+#include "mads/phantom/game_phantom.h"
+//#include "mads/phantom/globals_phantom.h"
+
+
+namespace MADS {
+
+namespace Phantom {
+
+enum Noun {
+ NOUN_GAME = 0x1,
+ NOUN_QSAVE = 0x2,
+ NOUN_LOOK = 0x3,
+ NOUN_TAKE = 0x4,
+ NOUN_PUSH = 0x5,
+ NOUN_OPEN = 0x6,
+ NOUN_PUT = 0x7,
+ NOUN_TALK_TO = 0x8,
+ NOUN_GIVE = 0x9,
+ NOUN_PULL = 0xA,
+ NOUN_CLOSE = 0xB,
+ NOUN_THROW = 0xC,
+ NOUN_WALK_TO = 0xD,
+ NOUN_ = 0xE,
+ NOUN_IN_ONE = 0xF,
+ NOUN_IN_TWO = 0x10,
+ NOUN_ACT_CURTAIN = 0x11,
+ NOUN_AISLE = 0x12,
+ NOUN_APRON = 0x13,
+ NOUN_ATTACK = 0x14,
+ NOUN_BACKSTAGE = 0x15,
+ NOUN_BEAR_PROP = 0x16,
+ NOUN_BLUE_FRAME = 0x17,
+ NOUN_BOOK = 0x18,
+ NOUN_BUST = 0x19,
+ NOUN_CABLE = 0x1A,
+ NOUN_CARPET = 0x1B,
+ NOUN_CARTON = 0x1C,
+ NOUN_CARTONS = 0x1D,
+ NOUN_CEILING = 0x1E,
+ NOUN_CHAIR = 0x1F,
+ NOUN_CIRCULAR_STAIRCASE = 0x20,
+ NOUN_CLIMB_DOWN = 0x21,
+ NOUN_CLIMB_INTO = 0x22,
+ NOUN_CLIMB_THROUGH = 0x23,
+ NOUN_COLUMN_PROP = 0x24,
+ NOUN_CONDUCTORS_STAND = 0x25,
+ NOUN_CORRIDOR = 0x26,
+ NOUN_COUCH = 0x27,
+ NOUN_COUNTERWEIGHT_SYSTEM = 0x28,
+ NOUN_CRATE = 0x29,
+ NOUN_CRATES = 0x2A,
+ NOUN_CRUMPLED_NOTE = 0x2B,
+ NOUN_CYCLORAMA = 0x2C,
+ NOUN_CYLINDER = 0x2D,
+ NOUN_DOOR = 0x2E,
+ NOUN_DRESSING_ROOM_DOOR = 0x2F,
+ NOUN_DRESSING_SCREEN = 0x30,
+ NOUN_DRESSING_TABLE = 0x31,
+ NOUN_ELEPHANT_PROP = 0x32,
+ NOUN_ENVELOPE = 0x33,
+ NOUN_EXIT = 0x34,
+ NOUN_EXIT_DOWN = 0x35,
+ NOUN_EXIT_SIGN = 0x36,
+ NOUN_EXIT_TO = 0x37,
+ NOUN_EXIT_TO_BACKSTAGE = 0x38,
+ NOUN_EXIT_TO_CELLAR = 0x39,
+ NOUN_EXIT_TO_CORRIDOR = 0x3A,
+ NOUN_EXIT_TO_DRESSING_RMS = 0x3B,
+ NOUN_EXIT_TO_LEFT_WING = 0x3C,
+ NOUN_EXIT_TO_PIT = 0x3D,
+ NOUN_EXIT_TO_RIGHT_WING = 0x3E,
+ NOUN_EXIT_TO_STAGE = 0x3F,
+ NOUN_EXIT_TO_STAIRWELL = 0x40,
+ NOUN_EXIT_TO_TRAP_ROOM = 0x41,
+ NOUN_EXIT_UP = 0x42,
+ NOUN_EXPOSED_BRICK = 0x43,
+ NOUN_FAN = 0x44,
+ NOUN_FIRE_AXE = 0x45,
+ NOUN_FL = 0x46,
+ NOUN_FLAT = 0x47,
+ NOUN_FLATS = 0x48,
+ NOUN_FLOOR = 0x49,
+ NOUN_FOLDING_CHAIRS = 0x4A,
+ NOUN_GARBAGE_CAN = 0x4B,
+ NOUN_GRAFFITI = 0x4C,
+ NOUN_GREEN_FRAME = 0x4D,
+ NOUN_HEMP = 0x4E,
+ NOUN_HOLE = 0x4F,
+ NOUN_HOUSE = 0x50,
+ NOUN_IN_ONE2 = 0x51,
+ NOUN_IN_TWO2 = 0x52,
+ NOUN_JUMP_INTO = 0x53,
+ NOUN_JUNK = 0x54,
+ NOUN_KEY = 0x55,
+ NOUN_LAMP = 0x56,
+ NOUN_LANTERN = 0x57,
+ NOUN_LARGE_NOTE = 0x58,
+ NOUN_LASSO = 0x59,
+ NOUN_LEG = 0x5A,
+ NOUN_LETTER = 0x5B,
+ NOUN_LIGHT_FIXTURE = 0x5C,
+ NOUN_LOCK = 0x5D,
+ NOUN_LOCKING_RAIL = 0x5E,
+ NOUN_LOCKRAIL = 0x5F,
+ NOUN_LOOK_AT = 0x60,
+ NOUN_LOOK_THROUGH = 0x61,
+ NOUN_MANNEQUINS = 0x62,
+ NOUN_MIRROR = 0x63,
+ NOUN_MUMMY_PROP = 0x64,
+ NOUN_MURAL = 0x65,
+ NOUN_MUSIC_SCORE = 0x66,
+ NOUN_MUSIC_STAND = 0x67,
+ NOUN_MUSIC_STANDS = 0x68,
+ NOUN_NOTHING = 0x69,
+ NOUN_NOTICE = 0x6A,
+ NOUN_ORCHESTRA_DOOR = 0x6B,
+ NOUN_ORCHESTRA_PIT = 0x6C,
+ NOUN_PAINTING = 0x6D,
+ NOUN_PARCHMENT = 0x6E,
+ NOUN_PIECE_OF_PAPER = 0x6F,
+ NOUN_PIPE = 0x70,
+ NOUN_PIT = 0x71,
+ NOUN_PLANT = 0x72,
+ NOUN_POSTER = 0x73,
+ NOUN_PROMPTERS_BOX = 0x74,
+ NOUN_PROP_TABLE = 0x75,
+ NOUN_PROPS = 0x76,
+ NOUN_PROSCENIUM_ARCH = 0x77,
+ NOUN_PURCHASE_LINES = 0x78,
+ NOUN_RAILING = 0x79,
+ NOUN_READ = 0x7A,
+ NOUN_RED_FRAME = 0x7B,
+ NOUN_REMOVE = 0x7C,
+ NOUN_ROPE = 0x7D,
+ NOUN_RUG = 0x7E,
+ NOUN_SANDBAG = 0x7F,
+ NOUN_SCAFFOLDING = 0x80,
+ NOUN_SEATS = 0x81,
+ NOUN_SIDE_WALL = 0x82,
+ NOUN_SMALL_NOTE = 0x83,
+ NOUN_STAGE = 0x84,
+ NOUN_STAGE_EXIT = 0x85,
+ NOUN_STAGE_LEFT = 0x86,
+ NOUN_STAGE_RIGHT = 0x87,
+ NOUN_STAGEMANAGERS_POST = 0x88,
+ NOUN_STAIR_UNIT = 0x89,
+ NOUN_STAIRCASE = 0x8A,
+ NOUN_STAIRWELL = 0x8B,
+ NOUN_STOOL = 0x8C,
+ NOUN_STRIKE = 0x8D,
+ NOUN_SWORD = 0x8E,
+ NOUN_TABLE = 0x8F,
+ NOUN_THE_HOUSE = 0x90,
+ NOUN_THUNDER_MACHINE = 0x91,
+ NOUN_TICKET = 0x92,
+ NOUN_TRAP_CEILING = 0x93,
+ NOUN_TRAP_DOOR = 0x94,
+ NOUN_TURN_OFF = 0x95,
+ NOUN_TURN_ON = 0x96,
+ NOUN_UNLOCK = 0x97,
+ NOUN_URN = 0x98,
+ NOUN_WALK_ACROSS = 0x99,
+ NOUN_WALK_DOWN = 0x9A,
+ NOUN_WALK_THROUGH = 0x9B,
+ NOUN_WALK_UP = 0x9C,
+ NOUN_WALL = 0x9D,
+ NOUN_WARDROBE = 0x9E,
+ NOUN_WASTE_BASKET = 0x9F,
+ NOUN_WATER_PIPE = 0xA0,
+ NOUN_WEAR = 0xA1,
+ NOUN_WEDDING_RING = 0xA2,
+ NOUN_YELLOW_FRAME = 0xA3,
+ NOUN_PROP = 0xA4,
+ NOUN_CLIMB_UP = 0xA5,
+ NOUN_WALK_ONTO = 0xA6,
+ NOUN_WALK = 0xA7,
+ NOUN_LEFT_DOOR = 0xA8,
+ NOUN_RIGHT_DOOR = 0xA9,
+ NOUN_DOOR_TO_PIT = 0xAA,
+ NOUN_HEADPHONES = 0xAB,
+ NOUN_BOXES = 0xAC,
+ NOUN_MUG = 0xAD,
+ NOUN_DINETTE_SET = 0xAE,
+ NOUN_BOX = 0xAF,
+ NOUN_CASES = 0xB0,
+ NOUN_TRASH_BUCKET = 0xB1,
+ NOUN_CORK_BOARD = 0xB2,
+ NOUN_HEADSET = 0xB3,
+ NOUN_GRAND_FOYER = 0xB4,
+ NOUN_BACK_WALL = 0xB5,
+ NOUN_BALLET_BAR = 0xB6,
+ NOUN_THROW_RUGS = 0xB7,
+ NOUN_COSTUME_RACK = 0xB8,
+ NOUN_COAT_RACK = 0xB9,
+ NOUN_PAINTINGS = 0xBA,
+ NOUN_UMBRELLA = 0xBB,
+ NOUN_SHELF = 0xBC,
+ NOUN_CONTAINER = 0xBD,
+ NOUN_TORN_POSTER = 0xBE,
+ NOUN_REVIEW = 0xBF,
+ NOUN_REVIEWS = 0xC0,
+ NOUN_STAGE_RIGHT_WING = 0xC1,
+ NOUN_STAGE_LEFT_WING = 0xC2,
+ NOUN_PEDESTAL = 0xC3,
+ NOUN_PLANT_PROP = 0xC4,
+ NOUN_STATUE = 0xC5,
+ NOUN_BATTEN = 0xC6,
+ NOUN_BIG_PROP = 0xC7,
+ NOUN_VENTILATION_DUCT = 0xC8,
+ NOUN_CHANDELIER = 0xC9,
+ NOUN_BARRIER = 0xCA,
+ NOUN_PLACARD = 0xCB,
+ NOUN_TICKET_WINDOW = 0xCC,
+ NOUN_ARCHWAY = 0xCD,
+ NOUN_COLUMN = 0xCE,
+ NOUN_RAIL = 0xCF,
+ NOUN_SEAT = 0xD0,
+ NOUN_LOGE_CORRIDOR = 0xD1,
+ NOUN_HOUSE_LIGHT = 0xD2,
+ NOUN_FLOV = 0xD3,
+ NOUN_LEFT_COLUMN = 0xD4,
+ NOUN_RIGHT_COLUMN = 0xD5,
+ NOUN_BOOKCASE = 0xD6,
+ NOUN_DOORWAY = 0xD7,
+ NOUN_COMFY_CHAIR = 0xD8,
+ NOUN_DESK = 0xD9,
+ NOUN_MANAGERS_CHAIR = 0xDA,
+ NOUN_DESK_LAMP = 0xDB,
+ NOUN_WINDOW = 0xDC,
+ NOUN_SHEERS = 0xDD,
+ NOUN_TAPESTRY = 0xDE,
+ NOUN_OVERDOOR_MEDALLION = 0xDF,
+ NOUN_LATTICEWORK = 0xE0,
+ NOUN_DECORATIVE_MOLDING = 0xE1,
+ NOUN_LEFT_DOORWAY = 0xE2,
+ NOUN_LEFT_ARCHWAY = 0xE3,
+ NOUN_RIGHT_DOORWAY = 0xE4,
+ NOUN_RIGHT_ARCHWAY = 0xE5,
+ NOUN_SOFA = 0xE6,
+ NOUN_END_TABLE = 0xE7,
+ NOUN_COFFEE_TABLE = 0xE8,
+ NOUN_DECORATIVE_VASE = 0xE9,
+ NOUN_MARBLE_COLUMN = 0xEA,
+ NOUN_BOX_FIVE = 0xEB,
+ NOUN_ENTER = 0xEC,
+ NOUN_BOX_SIX = 0xED,
+ NOUN_BOX_SEVEN = 0xEE,
+ NOUN_BOX_EIGHT = 0xEF,
+ NOUN_BOX_NINE = 0xF0,
+ NOUN_STEP = 0xF1,
+ NOUN_PANEL = 0xF2,
+ NOUN_WALK_BEHIND = 0xF3,
+ NOUN_MIDDLE_DOORWAY = 0xF4,
+ NOUN_LIGHT = 0xF5,
+ NOUN_CANDLE = 0xF6,
+ NOUN_CASE = 0xF7,
+ NOUN_HANDLE = 0xF8,
+ NOUN_AXE = 0xF9,
+ NOUN_DOOR_CHUNKS = 0xFA,
+ NOUN_FLO = 0xFB,
+ NOUN_BULLETIN_BOARD = 0xFC,
+ NOUN_JULIE = 0xFD,
+ NOUN_GLASS_CASE = 0xFE,
+ NOUN_KEYHOLE = 0xFF,
+ NOUN_MIDDLE_DOOR = 0x100,
+ NOUN_DRESSING_GOWN = 0x101,
+ NOUN_MONSIEUR_BRIE = 0x102,
+ NOUN_CATWALK = 0x103,
+ NOUN_GRID = 0x104,
+ NOUN_GIRDER = 0x105,
+ NOUN_GRIDWORK = 0x106,
+ NOUN_DUCTWORK = 0x107,
+ NOUN_OPENING = 0x108,
+ NOUN_DOME = 0x109,
+ NOUN_ALCOVE = 0x10A,
+ NOUN_CHRISTINE_DAAE = 0x10B,
+ NOUN_CHRISTINE = 0x10C,
+ NOUN_WOMAN = 0x10D,
+ NOUN_PROMPTERS_STAND = 0x10E,
+ NOUN_SUPPORT = 0x10F,
+ NOUN_OTHER_CATWALK = 0x110,
+ NOUN_SLOT = 0x111,
+ NOUN_BEAM_POSITION = 0x112,
+ NOUN_LIGHTING_INSTRUMENT = 0x113,
+ NOUN_TARP = 0x114,
+ NOUN_FACE = 0x115,
+ NOUN_CATWALK_OVER_HOUSE = 0x116,
+ NOUN_STAIRCASE_POST = 0x117,
+ NOUN_JACQUES = 0x118,
+ NOUN_GENTLEMAN = 0x119,
+ NOUN_BODY = 0x11A,
+ NOUN_HOLLOW_COLUMN = 0x11B,
+ NOUN_UPPER_LEVEL = 0x11C,
+ NOUN_MIDDLE_LEVEL = 0x11D,
+ NOUN_LOWER_LEVEL = 0x11E,
+ NOUN_LADDER = 0x11F,
+ NOUN_CLIMB = 0x120,
+ NOUN_CHANDELIER_TRAP = 0x121,
+ NOUN_PIECE_OF_WOOD = 0x122,
+ NOUN_CUT_HEMP = 0x123,
+ NOUN_STONE_WALL = 0x124,
+ NOUN_LAKE = 0x125,
+ NOUN_STONE_COLUMN = 0x126,
+ NOUN_EXIT_THROUGH = 0x127,
+ NOUN_STONE_FLOOR = 0x128,
+ NOUN_STONE_ARCHWAY = 0x129,
+ NOUN_CHARLES = 0x12A,
+ NOUN_SWITCH = 0x12B,
+ NOUN_PROMPTERS_SEAT = 0x12C,
+ NOUN_LEVER = 0x12D,
+ NOUN_MONSIEUR_RICHARD = 0x12E,
+ NOUN_JULIE2 = 0x12F,
+ NOUN_CABLE_HOOK = 0x130,
+ NOUN_ATTACH = 0x131,
+ NOUN_ROPE_WITH_HOOK = 0x132,
+ NOUN_GRAPPLE = 0x133,
+ NOUN_OAR = 0x134,
+ NOUN_ORGAN = 0x135,
+ NOUN_SIT_AT = 0x136,
+ NOUN_ORGAN_BENCH = 0x137,
+ NOUN_SIT_ON = 0x138,
+ NOUN_LARGE_CHAIR = 0x139,
+ NOUN_SIT_IN = 0x13A,
+ NOUN_SARCOPHAGUS = 0x13B,
+ NOUN_SKULL = 0x13C,
+ NOUN_SKULLS = 0x13D,
+ NOUN_TOTEM = 0x13E,
+ NOUN_POLE = 0x13F,
+ NOUN_CURTAIN = 0x140,
+ NOUN_TORCH = 0x141,
+ NOUN_RAMP = 0x142,
+ NOUN_MADAME_GIRY = 0x143,
+ NOUN_PANELS = 0x144,
+ NOUN_MORE_CATACOMBS = 0x145,
+ NOUN_BLOCKED_ARCHWAY = 0x146,
+ NOUN_GRATE = 0x147,
+ NOUN_CATACOMBS = 0x148,
+ NOUN_TICKET_SELLER = 0x149,
+ NOUN_USHER = 0x14A,
+ NOUN_UNLUCKY_ADVENTURER = 0x14B,
+ NOUN_SWITCH_PANEL = 0x14C,
+ NOUN_SKULL_SWITCH = 0x14D,
+ NOUN_TOGGLE = 0x14E,
+ NOUN_CATACOMB_ROOM = 0x14F,
+ NOUN_BOX_TEN = 0x150,
+ NOUN_FOYER = 0x151,
+ NOUN_WALK_DOWN_STAIRCASE = 0x152,
+ NOUN_WALK_DOWN_STAIRS_TO = 0x153,
+ NOUN_HAT_RACK = 0x154,
+ NOUN_VASE = 0x155,
+ NOUN_CLOTHES_DUMMY = 0x156,
+ NOUN_NOTICES = 0x157,
+ NOUN_ARCHWAY_TO_NORTH = 0x158,
+ NOUN_ARCHWAY_TO_WEST = 0x159,
+ NOUN_ARCHWAY_TO_EAST = 0x15A,
+ NOUN_GATE = 0x15B,
+ NOUN_NEST = 0x15C,
+ NOUN_POT = 0x15D,
+ NOUN_PUDDLE = 0x15E,
+ NOUN_WEB = 0x15F,
+ NOUN_PLANK = 0x160,
+ NOUN_BLOCK = 0x161,
+ NOUN_RATS_NEST = 0x162,
+ NOUN_BROKEN_POT = 0x163,
+ NOUN_STONE = 0x164,
+ NOUN_DRAIN = 0x165,
+ NOUN_FATE = 0x166,
+ NOUN_SKULL_SWITCH_1 = 0x167,
+ NOUN_SKULL_SWITCH_2 = 0x168,
+ NOUN_SKULL_SWITCH_3 = 0x169,
+ NOUN_SKULL_SWITCH_4 = 0x16A,
+ NOUN_SKULL_SWITCH_5 = 0x16B,
+ NOUN_SKULL_SWITCH_6 = 0x16C,
+ NOUN_SKULL_SWITCH_7 = 0x16D,
+ NOUN_SKULL_SWITCH_8 = 0x16E,
+ NOUN_SKULL_SWITCH_9 = 0x16F,
+ NOUN_SKULL_SWITCH_10 = 0x170,
+ NOUN_SKULL_SWITCH_11 = 0x171,
+ NOUN_SKULL_SWITCH_12 = 0x172,
+ NOUN_SKULL_SWITCH_13 = 0x173,
+ NOUN_SKULL_SWITCH_14 = 0x174,
+ NOUN_SKULL_SWITCH_15 = 0x175,
+ NOUN_SKULL_SWITCH_16 = 0x176,
+ NOUN_SKULL_SWITCH_17 = 0x177,
+ NOUN_SKULL_SWITCH_18 = 0x178,
+ NOUN_SKULL_SWITCH_19 = 0x179,
+ NOUN_SKULL_SWITCH_20 = 0x17A,
+ NOUN_SKULL_SWITCH_21 = 0x17B,
+ NOUN_SKULL_SWITCH_22 = 0x17C,
+ NOUN_SKULL_SWITCH_23 = 0x17D,
+ NOUN_SKULL_SWITCH_24 = 0x17E,
+ NOUN_SKULL_SWITCH_25 = 0x17F,
+ NOUN_SKULL_SWITCH_26 = 0x180,
+ NOUN_EDGAR_DEGAS = 0x181,
+ NOUN_CHANDELIER_CABLE = 0x182,
+ NOUN_COB_WEB = 0x183,
+ NOUN_SKULL_FACE = 0x184,
+ NOUN_BOAT = 0x185,
+ NOUN_HOOK = 0x186,
+ NOUN_AROUND = 0x187,
+ NOUN_CANE = 0x188,
+ NOUN_MASK = 0x189,
+ NOUN_COVER = 0x18A,
+ NOUN_PADLOCK = 0x18B,
+ NOUN_LID = 0x18C,
+ NOUN_COBWEB = 0x18D,
+ NOUN_PHANTOM = 0x18E,
+ NOUN_PAPER = 0x18F
+};
+
+class SceneFactory {
+public:
+ static SceneLogic *createScene(MADSEngine *vm);
+};
+
+/**
+ * Specialized base class for Dragonsphere game scenes
+ */
+class PhantomScene : public SceneLogic {
+protected:
+ PhantomGlobals &_globals;
+ GamePhantom &_game;
+ MADSAction &_action;
+
+ /**
+ * Forms an animation resource name
+ */
+ Common::String formAnimName(char sepChar, int suffixNum);
+
+ /**
+ * Plays appropriate sound for entering varous rooms
+ */
+ void lowRoomsEntrySound();
+public:
+ /**
+ * Constructor
+ */
+ PhantomScene(MADSEngine *vm);
+
+ void sub7178C();
+};
+
+class SceneInfoPhantom : public SceneInfo {
+ friend class SceneInfo;
+protected:
+ virtual void loadCodes(MSurface &depthSurface, int variant);
+
+ virtual void loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream);
+
+ /**
+ * Constructor
+ */
+ SceneInfoPhantom(MADSEngine *vm) : SceneInfo(vm) {}
+};
+
+// TODO: Temporary, remove once implemented properly
+class Scene1xx : public PhantomScene {
+protected:
+ /**
+ * Plays an appropriate sound when entering a scene
+ */
+ void sceneEntrySound() {}
+
+ /**
+ *Sets the AA file to use for the scene
+ */
+ void setAAName() {}
+
+ /**
+ * Updates the prefix used for getting player sprites for the scene
+ */
+ void setPlayerSpritesPrefix() {}
+public:
+ Scene1xx(MADSEngine *vm) : PhantomScene(vm) {}
+};
+
+// TODO: Temporary, remove once implemented properly
+class DummyScene : public PhantomScene {
+public:
+ DummyScene(MADSEngine *vm) : PhantomScene(vm) {
+ warning("Unimplemented scene");
+ }
+
+ virtual void setup() {}
+ virtual void enter() {}
+ virtual void actions() {}
+};
+
+} // End of namespace Phantom
+
+} // End of namespace MADS
+
+#endif /* MADS_PHANTOM_SCENES_H */
diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp
new file mode 100644
index 0000000000..ed585cf636
--- /dev/null
+++ b/engines/mads/player.cpp
@@ -0,0 +1,794 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/player.h"
+
+namespace MADS {
+
+#define PLAYER_SEQ_INDEX -2
+
+const int Player::_directionListIndexes[32] = {
+ 0, 7, 4, 3, 6, 0, 2, 5, 0, 1, 9, 4, 1, 2, 7, 9, 3, 8, 9, 6, 7, 2, 3, 6, 1, 7, 9, 4, 7, 8, 0, 0
+};
+
+Player::Player(MADSEngine *vm)
+ : _vm(vm) {
+ _action = nullptr;
+ _facing = FACING_NORTH;
+ _turnToFacing = FACING_NORTH;
+ _targetFacing = FACING_NORTH;
+ _prepareWalkFacing = FACING_NONE;
+ _mirror = false;
+ _spritesLoaded = false;
+ _spritesStart = 0;
+ _spritesIdx = 0;
+ _numSprites = 0;
+ _stepEnabled = false;
+ _visible = false;
+ _priorVisible = false;
+ _needToWalk = false;
+ _readyToWalk = false;
+ _beenVisible = false;
+ _loadsFirst = false;
+ _loadedFirst = false;
+ _walkAnywhere = false;
+ _special = 0;
+ _ticksAmount = 0;
+ _priorTimer = 0;
+ _trigger = 0;
+ _scalingVelocity = false;
+ _spritesChanged = false;
+ _forceRefresh = false;
+ _highSprites = false;
+ _currentDepth = 0;
+ _currentScale = 0;
+ _frameNumber = 0;
+ _centerOfGravity = 0;
+ _frameCount = 0;
+ _velocity = 0;
+ _upcomingTrigger = 0;
+ _trigger = 0;
+ _frameListIndex = 0;
+ _stopWalkerIndex = 0;
+ _totalDistance = 0;
+ _distAccum = 0;
+ _pixelAccum = 0;
+ _deltaDistance = 0;
+ _xDirection = 0;
+ _yDirection = 0;
+ _moving = false;
+ _walkOffScreen = 0;
+ _walkOffScreenSceneId = -1;
+
+ Common::fill(&_stopWalkerList[0], &_stopWalkerList[12], 0);
+ Common::fill(&_stopWalkerTrigger[0], &_stopWalkerTrigger[12], 0);
+ Common::fill(&_spriteSetsPresent[0], &_spriteSetsPresent[PLAYER_SPRITES_FILE_COUNT], false);
+}
+
+void Player::cancelWalk() {
+ Scene &scene = _vm->_game->_scene;
+ _action = &scene._action;
+ _targetPos = _playerPos;
+ _targetFacing = FACING_NONE;
+ _turnToFacing = _facing;
+ _moving = false;
+ _walkOffScreen = _walkOffScreenSceneId = 0;
+ scene._rails.resetRoute();
+ _walkAnywhere = false;
+
+ _needToWalk = false;
+ _readyToWalk = false;
+}
+
+bool Player::loadSprites(const Common::String &prefix) {
+ Common::String suffixList = "89632741";
+
+ Common::String newPrefix;
+ if (prefix.empty()) {
+ newPrefix = _spritesPrefix;
+ } else {
+ _spritesPrefix = prefix;
+ newPrefix = prefix;
+ }
+
+ _numSprites = 0;
+ if (!_spritesPrefix.empty()) {
+ for (int fileIndex = 0; fileIndex < PLAYER_SPRITES_FILE_COUNT; ++fileIndex) {
+ Common::String setName = Common::String::format("*%s_%c.SS",
+ newPrefix.c_str(), suffixList[fileIndex]);
+ if (fileIndex >= 5)
+ _highSprites = true;
+
+ _spriteSetsPresent[fileIndex] = true;
+
+ int setIndex = -1;
+ if (Common::File::exists(setName)) {
+ setIndex = _vm->_game->_scene._sprites.addSprites(setName, 4);
+ ++_numSprites;
+ } else if (fileIndex < 5) {
+ _highSprites = 0;
+ return true;
+ } else {
+ _spriteSetsPresent[fileIndex] = false;
+ }
+
+ if (fileIndex == 0)
+ _spritesStart = setIndex;
+ }
+
+ _spritesLoaded = true;
+ _spritesChanged = false;
+ _highSprites = false;
+ return false;
+ } else {
+ Common::fill(&_spriteSetsPresent[0], &_spriteSetsPresent[PLAYER_SPRITES_FILE_COUNT], false);
+ _highSprites = false;
+ return false;
+ }
+}
+
+void Player::setFinalFacing() {
+ if (_targetFacing != FACING_NONE)
+ _turnToFacing = _targetFacing;
+}
+
+void Player::changeFacing() {
+ int dirIndex = 0, dirIndex2 = 0;
+ int newDir = 0, newDir2 = 0;
+
+ if (_facing != _turnToFacing) {
+ // Find the index for the given direction in the player direction list
+ int tempDir = _facing;
+ do {
+ ++dirIndex;
+ newDir += tempDir;
+ tempDir = _directionListIndexes[tempDir + 10];
+ } while (tempDir != _turnToFacing);
+ }
+
+
+ if (_facing != _turnToFacing) {
+ // Find the index for the given direction in the player direction list
+ int tempDir = _facing;
+ do {
+ ++dirIndex2;
+ newDir2 += tempDir;
+ tempDir = _directionListIndexes[tempDir + 20];
+ } while (tempDir != _turnToFacing);
+ }
+
+ int diff = dirIndex - dirIndex2;
+ if (diff == 0)
+ diff = newDir - newDir2;
+
+ _facing = (diff >= 0) ? (Facing)_directionListIndexes[_facing + 20] :
+ (Facing)_directionListIndexes[_facing + 10];
+ selectSeries();
+
+ if ((_facing == _turnToFacing) && !_moving)
+ updateFrame();
+
+ _priorTimer += 1;
+}
+
+void Player::cancelCommand() {
+ cancelWalk();
+ _action->_inProgress = false;
+}
+
+void Player::selectSeries() {
+ Scene &scene = _vm->_game->_scene;
+
+ clearStopList();
+ _mirror = false;
+
+ _spritesIdx = _directionListIndexes[_facing];
+ if (!_spriteSetsPresent[_spritesIdx]) {
+ // Direction isn't present, so use alternate direction, with entries flipped
+ _spritesIdx -= 4;
+ _mirror = true;
+ }
+
+ // If the user isn't to be present (such as for a cutscene), exit immediately
+ // WORKAROUND: Original didn't do a secondary check for the sprite set being
+ // present, but it's needed to prevent invalid reads during cutscenes
+ if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesIdx])
+ return;
+
+ SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
+ assert(spriteSet._charInfo);
+ _velocity = MAX(spriteSet._charInfo->_velocity, 100);
+ setBaseFrameRate();
+
+ _frameCount = spriteSet._charInfo->_totalFrames;
+ if (_frameCount == 0)
+ _frameCount = spriteSet.getCount();
+
+ _centerOfGravity = spriteSet._charInfo->_centerOfGravity;
+
+ if ((_frameNumber <= 0) || (_frameNumber > _frameCount))
+ _frameNumber = 1;
+
+ _forceRefresh = true;
+}
+
+void Player::updateFrame() {
+ // WORKAROUND: Prevent character info being referenced when not present
+ if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesStart + _spritesIdx])
+ return;
+
+ Scene &scene = _vm->_game->_scene;
+ SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
+ assert(spriteSet._charInfo);
+
+ if (!spriteSet._charInfo->_numEntries) {
+ _frameNumber = 1;
+ } else {
+ _frameListIndex = _stopWalkerList[_stopWalkerIndex];
+
+ if (!_visible) {
+ _upcomingTrigger = 0;
+ } else {
+ _upcomingTrigger = _stopWalkerTrigger[_stopWalkerIndex];
+
+ if (_stopWalkerIndex > 0)
+ --_stopWalkerIndex;
+ }
+
+ // Set the player frame number
+ int listIndex = ABS(_frameListIndex);
+ _frameNumber = (_frameListIndex >= 0) ? spriteSet._charInfo->_startFrames[listIndex] :
+ spriteSet._charInfo->_stopFrames[listIndex];
+
+ // Set next waiting period in ticks
+ if (listIndex == 0) {
+ setBaseFrameRate();
+ } else {
+ _ticksAmount = spriteSet._charInfo->_ticksList[listIndex];
+ }
+ }
+
+ _forceRefresh = true;
+}
+
+void Player::update() {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_forceRefresh || (_visible != _priorVisible)) {
+ int slotIndex = getSpriteSlot();
+ if (slotIndex >= 0)
+ scene._spriteSlots[slotIndex]._flags = IMG_ERASE;
+
+ int newDepth = 1;
+ int yp = MIN(_playerPos.y, (int16)(MADS_SCENE_HEIGHT - 1));
+
+ for (int idx = 1; idx < 15; ++idx) {
+ if (scene._sceneInfo->_depthList[newDepth] >= yp)
+ newDepth = idx + 1;
+ }
+ _currentDepth = newDepth;
+
+ // Get the scale
+ int newScale = getScale(_playerPos.y);
+ _currentScale = MIN(newScale, 100);
+
+ if (_visible) {
+ // Player sprite needs to be rendered
+ SpriteSlot slot;
+ slot._flags = IMG_UPDATE;
+ slot._seqIndex = PLAYER_SEQ_INDEX;
+ slot._spritesIndex = _spritesStart + _spritesIdx;
+ slot._frameNumber = _mirror ? -_frameNumber : _frameNumber;
+ slot._position.x = _playerPos.x;
+ slot._position.y = _playerPos.y + (_centerOfGravity * newScale) / 100;
+ slot._depth = newDepth;
+ slot._scale = newScale;
+
+ if (slotIndex >= 0) {
+ // Check if the existing player slot has the same details, and can be re-used
+ SpriteSlot &s2 = scene._spriteSlots[slotIndex];
+ bool equal = (s2._seqIndex == slot._seqIndex)
+ && (s2._spritesIndex == slot._spritesIndex)
+ && (s2._frameNumber == slot._frameNumber)
+ && (s2._position == slot._position)
+ && (s2._depth == slot._depth)
+ && (s2._scale == slot._scale);
+
+ if (equal)
+ // Undo the prior expiry of the player sprite
+ s2._flags = IMG_STATIC;
+ else
+ slotIndex = -1;
+ }
+
+ if (slotIndex < 0) {
+ // New slot needed, so allocate one and copy the slot data
+ slotIndex = scene._spriteSlots.add();
+ scene._spriteSlots[slotIndex] = slot;
+ }
+
+ // If changing a scene, check to change the scene when the player
+ // has moved off-screen
+ if (_walkOffScreen) {
+ SpriteAsset *asset = scene._sprites[slot._spritesIndex];
+ MSprite *frame = asset->getFrame(_frameNumber - 1);
+ int xScale = frame->w * newScale / 200;
+ int yScale = frame->h * newScale / 100;
+ int playerX = slot._position.x;
+ int playerY = slot._position.y;
+
+ if ((playerX + xScale) < 0 || (playerX + xScale) >= MADS_SCREEN_WIDTH ||
+ playerY < 0 || (playerY + yScale) >= MADS_SCENE_HEIGHT) {
+ scene._nextSceneId = _walkOffScreen;
+ _walkOffScreen = 0;
+ _walkAnywhere = false;
+ }
+ }
+
+ }
+ }
+
+ _beenVisible |= _visible;
+ _priorVisible = _visible;
+ _forceRefresh = false;
+}
+
+void Player::clearStopList() {
+ _stopWalkerList[0] = 0;
+ _stopWalkerTrigger[0] = 0;
+ _stopWalkerIndex = 0;
+ _upcomingTrigger = 0;
+ _trigger = 0;
+}
+
+void Player::startWalking(const Common::Point &pt, Facing facing) {
+ Scene &scene = _vm->_game->_scene;
+
+ clearStopList();
+ setBaseFrameRate();
+ _moving = true;
+ _targetFacing = facing;
+
+ bool v = scene._depthSurface.getDepthHighBit(pt);
+
+ scene._rails.setupRoute(v, _playerPos, pt);
+}
+
+void Player::walk(const Common::Point &pos, Facing facing) {
+ cancelWalk();
+ _needToWalk = true;
+ _readyToWalk = true;
+ _prepareWalkPos = pos;
+ _prepareWalkFacing = facing;
+}
+
+void Player::nextFrame() {
+ Scene &scene = _vm->_game->_scene;
+
+ uint32 newTime = _priorTimer + _ticksAmount;
+ if (scene._frameStartTime >= newTime) {
+ _priorTimer = scene._frameStartTime;
+ if (_moving) {
+ move();
+ } else {
+ idle();
+ }
+
+ setFrame();
+ update();
+ }
+}
+
+void Player::move() {
+ Scene &scene = _vm->_game->_scene;
+ Rails &rails = scene._rails;
+ bool newFacing = false;
+
+ if (_moving) {
+ while (!_walkOffScreen && _playerPos == _targetPos) {
+ bool isRouteEmpty = rails.empty();
+ if (!isRouteEmpty) {
+ const WalkNode &node = rails.popNode();
+
+ _targetPos = node._walkPos;
+ newFacing = true;
+ } else if (!_walkOffScreenSceneId) {
+ // End of walking path
+ rails.resetRoute();
+ _moving = false;
+ setFinalFacing();
+ newFacing = true;
+ } else {
+ _walkOffScreen = _walkOffScreenSceneId;
+ _walkAnywhere = true;
+ _walkOffScreenSceneId = 0;
+ _stepEnabled = false;
+ newFacing = false;
+ }
+
+ if (!_moving)
+ break;
+ }
+ }
+
+ if (newFacing && _moving)
+ startMovement();
+
+ if (_turnToFacing != _facing)
+ changeFacing();
+ else if (!_moving)
+ updateFrame();
+
+ int velocity = _velocity;
+ if (_scalingVelocity && (_totalDistance > 0)) {
+ int angleRange = 100 - _currentScale;
+ int angleScale = angleRange * (_posDiff.x - 1) / _totalDistance + _currentScale;
+ velocity = MAX(1L, (angleScale * _currentScale * velocity) / 10000L);
+ }
+
+ if (!_moving || (_facing != _turnToFacing))
+ return;
+
+ Common::Point newPos = _playerPos;
+ newFacing = false;
+ _special = 0;
+
+ if (_distAccum < velocity) {
+ do {
+ if (_pixelAccum < _posDiff.x)
+ _pixelAccum += _posDiff.y;
+ if (_pixelAccum >= _posDiff.x) {
+ if ((_posChange.y > 0) || _walkOffScreen)
+ newPos.y += _yDirection;
+ --_posChange.y;
+ _pixelAccum -= _posDiff.x;
+ }
+
+ if (_pixelAccum < _posDiff.x) {
+ if ((_posChange.x > 0) || _walkOffScreen)
+ newPos.x += _xDirection;
+ --_posChange.x;
+ }
+
+ if (!_walkAnywhere && !_walkOffScreen && (_walkOffScreenSceneId == 0)) {
+ newFacing = scene._depthSurface.getDepthHighBit(newPos);
+
+ if (_special == 0)
+ _special = scene.getDepthHighBits(newPos);
+ }
+
+ _distAccum += _deltaDistance;
+
+ } while ((_distAccum < velocity) && !newFacing && ((_posChange.x > 0) || (_posChange.y > 0) || (_walkOffScreen != 0)));
+ }
+
+ _distAccum -= velocity;
+
+ if (newFacing) {
+ cancelCommand();
+ } else {
+ if (!_walkOffScreen) {
+ // If the move is complete, make sure the position is exactly on the given destination
+ if (_posChange.x == 0)
+ newPos.x = _targetPos.x;
+ if (_posChange.y == 0)
+ newPos.y = _targetPos.y;
+ }
+
+ _playerPos = newPos;
+ }
+}
+
+void Player::idle() {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_facing != _turnToFacing) {
+ // The direction has changed, so reset for new direction
+ changeFacing();
+ return;
+ }
+
+ if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesStart + _spritesIdx])
+ return;
+
+ SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
+ assert(spriteSet._charInfo);
+ if (spriteSet._charInfo->_numEntries == 0)
+ // No entries, so exit immediately
+ return;
+
+ int frameIndex = ABS(_frameListIndex);
+ int direction = (_frameListIndex < 0) ? -1 : 1;
+
+ if (frameIndex >= spriteSet._charInfo->_numEntries) {
+ // Reset back to the start of the list
+ _frameListIndex = 0;
+ } else {
+ _frameNumber += direction;
+ _forceRefresh = true;
+
+ if (spriteSet._charInfo->_stopFrames[frameIndex] < _frameNumber) {
+ _trigger = _upcomingTrigger;
+ updateFrame();
+ }
+ if (spriteSet._charInfo->_startFrames[frameIndex] < _frameNumber) {
+ _trigger = _upcomingTrigger;
+ updateFrame();
+ }
+ }
+}
+
+void Player::setFrame() {
+ if (_moving) {
+ if (++_frameNumber > _frameCount)
+ _frameNumber = 1;
+ _forceRefresh = true;
+ } else {
+ if (!_forceRefresh)
+ idle();
+ }
+}
+
+int Player::getSpriteSlot() {
+ SpriteSlots &spriteSlots = _vm->_game->_scene._spriteSlots;
+
+ for (uint idx = 0; idx < spriteSlots.size(); ++idx) {
+ if (spriteSlots[idx]._seqIndex == PLAYER_SEQ_INDEX &&
+ spriteSlots[idx]._flags >= IMG_STATIC)
+ return idx;
+ }
+
+ return - 1;
+}
+
+int Player::getScale(int yp) {
+ Scene &scene = _vm->_game->_scene;
+
+ int scale = (scene._bandsRange == 0) ? scene._sceneInfo->_maxScale :
+ (yp - scene._sceneInfo->_yBandsStart) * scene._scaleRange / scene._bandsRange +
+ scene._sceneInfo->_minScale;
+
+ return MIN(scale, 100);
+}
+
+void Player::setBaseFrameRate() {
+ Scene &scene = _vm->_game->_scene;
+
+ SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
+ assert(spriteSet._charInfo);
+
+ _ticksAmount = spriteSet._charInfo->_ticksAmount;
+ if (_ticksAmount == 0)
+ _ticksAmount = 6;
+}
+
+void Player::startMovement() {
+ int xDiff = _targetPos.x - _playerPos.x;
+ int yDiff = _targetPos.y - _playerPos.y;
+ int srcScale = getScale(_playerPos.y);
+ int destScale = getScale(_targetPos.y);
+
+ // Sets the X direction
+ if (xDiff > 0)
+ _xDirection = 1;
+ else if (xDiff < 0)
+ _xDirection = -1;
+ else
+ _xDirection = 0;
+
+ // Sets the Y direction
+ if (yDiff > 0)
+ _yDirection = 1;
+ else if (yDiff < 0)
+ _yDirection = -1;
+ else
+ _yDirection = 0;
+
+ xDiff = ABS(xDiff);
+ yDiff = ABS(yDiff);
+ int scaleDiff = ABS(srcScale - destScale);
+
+ int xAmt100 = xDiff * 100;
+ int yAmt100 = yDiff * 100;
+ int xAmt33 = xDiff * 33;
+
+ int scaleAmount = (_scalingVelocity ? scaleDiff * 3 : 0) + 100 * yDiff / 100;
+ int scaleAmount100 = scaleAmount * 100;
+
+ // Figure out direction that will need to be moved in
+ int majorDir;
+ if (xDiff == 0) {
+ majorDir = 1;
+ } else if (yDiff == 0) {
+ majorDir = 3;
+ } else {
+ if ((scaleAmount < xDiff) && ((xAmt33 / scaleAmount) >= 141))
+ majorDir = 3;
+ else if (yDiff <= xDiff)
+ majorDir = 2;
+ else if ((scaleAmount100 / xDiff) >= 141)
+ majorDir = 1;
+ else
+ majorDir = 2;
+ }
+
+ switch (majorDir) {
+ case 1:
+ _turnToFacing = (_yDirection <= 0) ? FACING_NORTH : FACING_SOUTH;
+ break;
+ case 2: {
+ _turnToFacing = (Facing)(((_yDirection <= 0) ? 9 : 3) - ((_xDirection <= 0) ? 2 : 0));
+ break;
+ }
+ case 3:
+ _turnToFacing = (_xDirection <= 0) ? FACING_WEST : FACING_EAST;
+ break;
+ default:
+ break;
+ }
+
+ _totalDistance = sqrt((double)(xAmt100 * xAmt100 + yAmt100 * yAmt100));
+ _posDiff.x = xDiff + 1;
+ _posDiff.y = yDiff + 1;
+ _posChange.x = xDiff;
+ _posChange.y = yDiff;
+
+ int majorChange = MAX(xDiff, yDiff);
+ _deltaDistance = (majorChange == 0) ? 0 : _totalDistance / majorChange;
+
+ if (_playerPos.x > _targetPos.x)
+ _pixelAccum = MAX(_posChange.x, _posChange.y);
+ else
+ _pixelAccum = 0;
+
+ _totalDistance /= 100;
+ _distAccum = -_deltaDistance;
+}
+
+void Player::newWalk() {
+ if (_needToWalk && _readyToWalk) {
+ startWalking(_prepareWalkPos, _prepareWalkFacing);
+ _needToWalk = false;
+ }
+}
+
+void Player::addWalker(int walker, int trigger) {
+ Scene &scene = _vm->_game->_scene;
+ SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx];
+ assert(spriteSet._charInfo);
+
+ if (walker < spriteSet._charInfo->_numEntries && _stopWalkerIndex < 11) {
+ ++_stopWalkerIndex;
+ _stopWalkerList[_stopWalkerIndex] = walker;
+ _stopWalkerTrigger[_stopWalkerIndex] = trigger;
+ }
+}
+
+
+/**
+* Releases any sprites used by the player
+*/
+void Player::releasePlayerSprites() {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_spritesLoaded && _numSprites > 0) {
+ int spriteEnd = _spritesStart + _numSprites - 1;
+ do {
+ scene._sprites.remove(spriteEnd);
+ } while (--spriteEnd >= _spritesStart);
+ }
+
+ _numSprites = 0;
+ _spritesLoaded = false;
+ _spritesChanged = true;
+
+ if (scene._sprites._assetCount > 0) {
+ warning("Player::releasePlayerSprites(): leftover sprites remain, clearing list");
+ scene._sprites.clear();
+ }
+}
+
+void Player::synchronize(Common::Serializer &s) {
+ s.syncAsByte(_moving);
+ s.syncAsSint16LE(_playerPos.x);
+ s.syncAsSint16LE(_playerPos.y);
+ s.syncAsSint16LE(_targetPos.x);
+ s.syncAsSint16LE(_targetPos.y);
+ s.syncAsSint16LE(_xDirection);
+ s.syncAsSint16LE(_yDirection);
+ s.syncAsSint16LE(_posDiff.x);
+ s.syncAsSint16LE(_posDiff.y);
+ s.syncAsSint16LE(_posChange.x);
+ s.syncAsSint16LE(_posChange.y);
+ s.syncAsUint16LE(_targetFacing);
+ s.syncAsSint16LE(_special);
+ s.syncAsByte(_forceRefresh);
+ s.syncAsSint16LE(_ticksAmount);
+ s.syncAsByte(_walkAnywhere);
+ s.syncAsUint16LE(_walkOffScreenSceneId);
+ s.syncAsByte(_walkOffScreen);
+ s.syncAsByte(_needToWalk);
+ s.syncAsByte(_readyToWalk);
+ s.syncAsUint16LE(_prepareWalkFacing);
+ s.syncAsSint16LE(_prepareWalkPos.x);
+ s.syncAsSint16LE(_prepareWalkPos.y);
+ s.syncAsByte(_stepEnabled);
+ s.syncAsByte(_visible);
+ s.syncAsByte(_priorVisible);
+
+ for (int i = 0; i < 8; ++i)
+ s.syncAsByte(_spriteSetsPresent[i]);
+
+ s.syncAsByte(_facing);
+ s.syncAsByte(_turnToFacing);
+ s.syncAsSint16LE(_spritesIdx);
+ s.syncAsSint16LE(_frameNumber);
+ s.syncAsSint16LE(_currentDepth);
+ s.syncAsSint16LE(_currentScale);
+ s.syncAsSint16LE(_frameListIndex);
+
+ for (int i = 0; i < 12; ++i) {
+ s.syncAsSint16LE(_stopWalkerList[i]);
+ s.syncAsSint16LE(_stopWalkerTrigger[i]);
+ }
+
+ s.syncAsSint16LE(_stopWalkerIndex);
+ s.syncAsSint16LE(_upcomingTrigger);
+ s.syncAsSint16LE(_trigger);
+ s.syncAsSint16LE(_scalingVelocity);
+ s.syncAsSint16LE(_pixelAccum);
+ s.syncAsSint16LE(_distAccum);
+ s.syncAsSint16LE(_deltaDistance);
+ s.syncAsSint16LE(_totalDistance);
+ s.syncAsSint16LE(_velocity);
+ s.syncAsUint16LE(_frameCount);
+ s.syncString(_spritesPrefix);
+ s.syncAsUint32LE(_priorTimer);
+ s.syncAsByte(_loadsFirst);
+ s.syncAsByte(_loadedFirst);
+ s.syncAsByte(_spritesLoaded);
+ s.syncAsByte(_spritesChanged);
+ s.syncAsByte(_beenVisible);
+ s.syncAsSint16LE(_centerOfGravity);
+ s.syncAsByte(_mirror);
+}
+
+void Player::removePlayerSprites() {
+ Scene &scene = _vm->_game->_scene;
+ int heroSpriteId = _spritesStart;
+ for (int i = 0; i < 8; i++) {
+ if (_spriteSetsPresent[i]) {
+ scene._sprites.remove(heroSpriteId++);
+ _spriteSetsPresent[i] = false;
+ }
+ }
+
+ if (scene._activeAnimation != nullptr)
+ scene._activeAnimation->resetSpriteSetsCount();
+
+ scene._spriteSlots.fullRefresh();
+ _visible = false;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/player.h b/engines/mads/player.h
new file mode 100644
index 0000000000..671ac9d16e
--- /dev/null
+++ b/engines/mads/player.h
@@ -0,0 +1,228 @@
+/* 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 MADS_PLAYER_H
+#define MADS_PLAYER_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/serializer.h"
+
+namespace MADS {
+
+class MADSEngine;
+class MADSAction;
+
+#define PLAYER_SPRITES_FILE_COUNT 8
+#define MAX_ROUTE_NODES 22
+
+/**
+ * Player facings
+ */
+enum Facing {
+ FACING_NORTH = 8, FACING_SOUTH = 2, FACING_EAST = 6, FACING_WEST = 4,
+ FACING_NORTHEAST = 9, FACING_SOUTHEAST = 3,
+ FACING_SOUTHWEST = 1, FACING_NORTHWEST = 7,
+ FACING_NONE = 5, FACING_DUMMY = 0
+};
+
+class Player {
+private:
+ static const int _directionListIndexes[32];
+private:
+ MADSEngine *_vm;
+ bool _highSprites;
+ bool _spriteSetsPresent[PLAYER_SPRITES_FILE_COUNT];
+ bool _mirror;
+ int _frameCount;
+ int _frameListIndex;
+ int _distAccum;
+ int _pixelAccum;
+ int _deltaDistance;
+ int _stopWalkerList[12];
+ int _stopWalkerTrigger[12];
+ int _totalDistance;
+
+ void clearStopList();
+
+ /**
+ * If the player is moving, handles figuring out the correct motion
+ */
+ void move();
+
+ /**
+ * Update the player's frame number
+ */
+ void setFrame();
+
+ /**
+ * Get the sprite slot index for the player
+ */
+ int getSpriteSlot();
+
+ /**
+ * Get the scale for the player at the given Y position
+ */
+ int getScale(int yp);
+
+ /**
+ * Sets the frame rate for the current sprite set
+ */
+ void setBaseFrameRate();
+
+ /**
+ * Starts a player moving to a given destination
+ */
+ void startMovement();
+
+ void changeFacing();
+public:
+ MADSAction *_action;
+
+ Facing _facing;
+ Facing _turnToFacing;
+ Facing _prepareWalkFacing;
+ int _xDirection, _yDirection;
+ Facing _targetFacing;
+ bool _spritesLoaded;
+ int _spritesStart;
+ int _spritesIdx;
+ int _numSprites;
+ bool _stepEnabled;
+ bool _spritesChanged;
+ bool _visible;
+ bool _priorVisible;
+ bool _beenVisible;
+ bool _walkAnywhere;
+ int _frameNumber;
+ bool _loadsFirst;
+ bool _loadedFirst;
+ Common::Point _playerPos;
+ Common::Point _targetPos;
+ Common::Point _posChange;
+ Common::Point _posDiff;
+ Common::Point _prepareWalkPos;
+ bool _moving;
+ int _walkOffScreen, _walkOffScreenSceneId;
+ int _special;
+ int _ticksAmount;
+ uint32 _priorTimer;
+ int _velocity;
+ int _upcomingTrigger;
+ int _trigger;
+ bool _scalingVelocity;
+ bool _forceRefresh;
+ bool _needToWalk;
+ bool _readyToWalk;
+ int _stopWalkerIndex;
+ int _centerOfGravity;
+ int _currentDepth;
+ int _currentScale;
+ Common::String _spritesPrefix;
+public:
+ Player(MADSEngine *vm);
+
+ /**
+ * Load sprites for the player
+ */
+ bool loadSprites(const Common::String &prefix);
+
+ /**
+ * Called when the player has reached the given destination, start him
+ * turning to the specified facing
+ */
+ void setFinalFacing();
+
+ /**
+ * Stops the player walking
+ */
+ void cancelWalk();
+
+ /**
+ * Cancels any oustanding player action
+ */
+ void cancelCommand();
+
+ /**
+ * Set up control parameters for the current active series (the
+ * direction which the player is facing in) */
+ void selectSeries();
+
+ /*
+ * Moves to the next frame for the currently active player sprite set
+ */
+ void updateFrame();
+
+ void update();
+
+ /**
+ * Handler method for when the player is not moving
+ */
+ void idle();
+
+ /**
+ * Starts the player walking towards a given point and direction facing
+ * @param pos Destination location
+ * @param facing Direction to face once the destination is reached
+ */
+ void startWalking(const Common::Point &pt, Facing facing);
+
+ /**
+ * Used by the game scripst to make the player walk to a given destination.
+ * The difference from startWalking is that this contains several extra
+ * layers of checking that startWalking bypasses.
+ */
+ void walk(const Common::Point &pos, Facing facing);
+
+ /**
+ * If a new walk sequence is pending, and has been okayed by the preparser,
+ * start the actual walking
+ */
+ void newWalk();
+
+ void nextFrame();
+
+ /**
+ * Add a walker to the current queue
+ */
+ void addWalker(int walker, int trigger);
+
+ /**
+ * Delete any sprites used by the player
+ */
+ void releasePlayerSprites();
+
+ /**
+ * Serialize the data of the player
+ */
+ void synchronize(Common::Serializer &s);
+
+ static void preloadSequences(const Common::String &prefix, int level) {
+ // No implementation in ScummVM
+ }
+
+ void removePlayerSprites();
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_PLAYER_H */
diff --git a/engines/mads/rails.cpp b/engines/mads/rails.cpp
new file mode 100644
index 0000000000..7f8a56d21b
--- /dev/null
+++ b/engines/mads/rails.cpp
@@ -0,0 +1,277 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/rails.h"
+
+namespace MADS {
+
+WalkNode::WalkNode() {
+ _active = false;
+ Common::fill(&_distances[0], &_distances[MAX_ROUTE_NODES], 0);
+}
+
+void WalkNode::load(Common::SeekableReadStream *f) {
+ _walkPos.x = f->readSint16LE();
+ _walkPos.y = f->readSint16LE();
+ for (int i = 0; i < MAX_ROUTE_NODES; ++i)
+ _distances[i] = f->readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+Rails::Rails() {
+ _depthSurface = nullptr;
+ _routeLength = 0;
+ _depthStyle = 0;
+ _next = 0;
+}
+
+void Rails::load(const WalkNodeList &nodes, DepthSurface *depthSurface, int depthStyle) {
+ // Store the depth surface and depth style to use
+ _depthSurface = depthSurface;
+ _depthStyle = depthStyle;
+
+ // Load the passed node list
+ _nodes.clear();
+
+ for (uint i = 0; i < nodes.size(); ++i)
+ _nodes.push_back(nodes[i]);
+
+ // Add two more empty nodes for the start and end points of any walk sequence
+ _nodes.push_back(WalkNode());
+ _nodes.push_back(WalkNode());
+}
+
+
+void Rails::setupRoute(bool bitFlag, const Common::Point &srcPos, const Common::Point &destPos) {
+ // Reset the nodes in as being inactive
+ for (uint i = 0; i < _nodes.size(); ++i)
+ _nodes[i]._active = false;
+
+ // Set the two extra walk nodes to the start and destination positions
+ setNodePosition(_nodes.size() - 2, srcPos);
+ setNodePosition(_nodes.size() - 1, destPos);
+
+ // Start constructing route node list
+ _routeLength = 0x3FFF;
+ _routeIndexes.clear();
+
+ // Recursively form a route from the destination walk node back to the player's position
+ setupRouteNode(&_tempRoute[0], _nodes.size() - 1, bitFlag ? 0xC000 : 0x8000, 0);
+
+ _next = 0;
+ if (_routeIndexes.size() > 0) {
+ Common::Point currPos = srcPos;
+ for (int routeCtr = size() - 1; (routeCtr >= 0) && !_next; --routeCtr) {
+ int idx = _routeIndexes[routeCtr];
+ const Common::Point &pt = _nodes[idx]._walkPos;
+
+ _next = scanPath(currPos, pt);
+ currPos = pt;
+ }
+ }
+}
+
+void Rails::setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength) {
+ WalkNode &currentNode = _nodes[nodeIndex];
+ currentNode._active = true;
+
+ *routeIndexP++ = nodeIndex;
+
+ // Get the index of the ultimate source position (the player)
+ int subIndex = _nodes.size() - 2;
+
+ int distanceVal = _nodes[nodeIndex]._distances[subIndex];
+ if (distanceVal & flags) {
+ routeLength += distanceVal & 0x3FFF;
+ if (routeLength < _routeLength) {
+ // Found a new shorter route to destination, so set up the route with the found one
+ _routeIndexes.clear();
+ for (int i = 0; routeIndexP != &_tempRoute[i]; ++i)
+ _routeIndexes.push(_tempRoute[i]);
+ _routeLength = routeLength;
+ }
+ } else {
+ for (int idx = _nodes.size() - 2; idx > 0; --idx) {
+ int nodePos = idx - 1;
+ if (!_nodes[nodePos]._active && ((currentNode._distances[nodePos] & flags) != 0))
+ setupRouteNode(routeIndexP, nodePos, 0x8000, routeLength + (distanceVal & 0x3fff));
+ }
+ }
+
+ currentNode._active = false;
+}
+
+
+int Rails::scanPath(const Common::Point &srcPos, const Common::Point &destPos) {
+ // For compressed depth surfaces, always return 0
+ if (_depthStyle == 2)
+ return 0;
+
+ int yDiff = destPos.y - srcPos.y;
+ int yAmount = MADS_SCREEN_WIDTH;
+
+ if (yDiff < 0) {
+ yDiff = -yDiff;
+ yAmount = -yAmount;
+ }
+
+ int xDiff = destPos.x - srcPos.x;
+ int xDirection = 1;
+ int xAmount = 0;
+ if (xDiff < 0) {
+ xDiff = -xDiff;
+ xDirection = -xDirection;
+ xAmount = MIN(yDiff, xDiff);
+ }
+
+ ++xDiff;
+ ++yDiff;
+
+ const byte *srcP = _depthSurface->getBasePtr(srcPos.x, srcPos.y);
+ int index = xAmount;
+
+ // Outer loop
+ for (int xCtr = 0; xCtr < xDiff; ++xCtr, srcP += xDirection) {
+ index += yDiff;
+ int v = (*srcP & 0x7F) >> 4;
+ if (v)
+ return v;
+
+ // Inner loop for handling vertical movement
+ while (index >= xDiff) {
+ index -= xDiff;
+
+ v = (*srcP & 0x7F) >> 4;
+ if (v)
+ return v;
+
+ srcP += yAmount;
+ }
+ }
+
+ return 0;
+}
+
+void Rails::resetRoute() {
+ _routeIndexes.clear();
+ _next = 0;
+}
+
+const WalkNode &Rails::popNode() {
+ assert(!_routeIndexes.empty());
+
+ return _nodes[_routeIndexes.pop()];
+}
+
+void Rails::setNodePosition(int nodeIndex, const Common::Point &pt) {
+ int flags, hypotenuse;
+
+ _nodes[nodeIndex]._walkPos = pt;
+
+ // Recalculate inter-node lengths
+ for (uint idx = 0; idx < _nodes.size(); ++idx) {
+ int entry;
+ if (idx == (uint)nodeIndex) {
+ entry = 0x3FFF;
+ } else {
+ // Process the node
+ flags = getRouteFlags(pt, _nodes[idx]._walkPos);
+
+ int xDiff = ABS(_nodes[idx]._walkPos.x - pt.x);
+ int yDiff = ABS(_nodes[idx]._walkPos.y - pt.y);
+ hypotenuse = sqrt((double)(xDiff * xDiff + yDiff * yDiff));
+
+ if (hypotenuse >= 0x3FFF)
+ // Shouldn't ever be this large
+ hypotenuse = 0x3FFF;
+
+ entry = hypotenuse | flags;
+ }
+
+ _nodes[idx]._distances[nodeIndex] = entry;
+ _nodes[nodeIndex]._distances[idx] = entry;
+ }
+}
+
+int Rails::getRouteFlags(const Common::Point &src, const Common::Point &dest) {
+ int result = 0x8000;
+ bool flag = false;
+
+ int xDiff = ABS(dest.x - src.x);
+ int yDiff = ABS(dest.y - src.y);
+ int xDirection = dest.x >= src.x ? 1 : -1;
+ int yDirection = dest.y >= src.y ? _depthSurface->w : -_depthSurface->w;
+ int minorDiff = 0;
+ if (dest.x < src.x)
+ minorDiff = MIN(xDiff, yDiff);
+ ++xDiff;
+ ++yDiff;
+
+ byte *srcP = _depthSurface->getBasePtr(src.x, src.y);
+
+ int totalCtr = minorDiff;
+ for (int xCtr = 0; xCtr < xDiff; ++xCtr, srcP += xDirection) {
+ totalCtr += yDiff;
+
+ if ((*srcP & 0x80) == 0)
+ flag = false;
+ else if (!flag) {
+ flag = true;
+ result -= 0x4000;
+ if (result == 0)
+ break;
+ }
+
+ while (totalCtr >= xDiff) {
+ totalCtr -= xDiff;
+
+ if ((*srcP & 0x80) == 0)
+ flag = false;
+ else if (!flag) {
+ flag = true;
+ result -= 0x4000;
+ if (result == 0)
+ break;
+ }
+
+ srcP += yDirection;
+ }
+ if (result == 0)
+ break;
+ }
+
+ return result;
+}
+
+void Rails::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_routeLength);
+ s.syncAsSint16LE(_next);
+
+ if (s.isLoading()) {
+ _routeIndexes.clear();
+ }
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/rails.h b/engines/mads/rails.h
new file mode 100644
index 0000000000..e6cab08f85
--- /dev/null
+++ b/engines/mads/rails.h
@@ -0,0 +1,134 @@
+/* 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 MADS_RAILS_H
+#define MADS_RAILS_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/serializer.h"
+#include "common/stack.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+class WalkNode {
+public:
+ Common::Point _walkPos;
+ uint16 _distances[MAX_ROUTE_NODES];
+ bool _active;
+
+ /**
+ * Constructor
+ */
+ WalkNode();
+
+ /**
+ * Loads the scene node
+ */
+ void load(Common::SeekableReadStream *f);
+};
+typedef Common::Array<WalkNode> WalkNodeList;
+
+/**
+ * This class handles storing the intermediate walk node points for a
+ * given scene, and calculating walking routes between any two positions.
+ */
+class Rails {
+private:
+ WalkNodeList _nodes;
+ DepthSurface *_depthSurface;
+ int _depthStyle;
+ int _routeLength;
+ int _next;
+ int _tempRoute[MAX_ROUTE_NODES];
+ Common::Stack<int> _routeIndexes;
+private:
+ /**
+ * Change the position of a walking node. Doing so causes a recalculation of the
+ * distance between it and every other node, and vice versa
+ */
+ void setNodePosition(int nodeIndex, const Common::Point &pt);
+
+ int getRouteFlags(const Common::Point &src, const Common::Point &dest);
+public:
+ /**
+ * Constructor
+ */
+ Rails();
+
+ /**
+ * Loads the scene data for the list of intermediate walk nodes and the
+ * depth surface to use.
+ * @param nodes Intermediate walk-points
+ * @param depthSurface Depth surface to use
+ */
+ void load(const WalkNodeList &nodes, DepthSurface *depthSurface, int depthStyle);
+
+ /**
+ * Set up a route between two points in a scene
+ */
+ void setupRoute(bool bitFlag, const Common::Point &srcPos, const Common::Point &destPos);
+
+ void setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength);
+
+ /**
+ * Resets any currently running route
+ */
+ void resetRoute();
+
+ /**
+ * Scans along an edge connecting two points within the depths/walk surface, and returns the information of the first
+ * pixel high nibble encountered with a non-zero value
+ */
+ int scanPath(const Common::Point &srcPos, const Common::Point &destPos);
+
+ /*
+ * Return the number of walk nodes in the calculated route
+ */
+ int size() const { return _routeIndexes.size(); }
+
+ /**
+ * Returns true if the current calculated walk route is empty
+ */
+ bool empty() const { return _routeIndexes.empty(); }
+
+ /**
+ * Returns the data for a given walk node
+ */
+ const WalkNode &operator[](int idx) { return _nodes[_routeIndexes[idx]]; }
+
+ const WalkNode &popNode();
+
+ void resetNext() { _next = 0; }
+ int getNext() { return _next; }
+
+ /**
+ * Synchronize the data for the route
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_RAILS_H */
diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp
new file mode 100644
index 0000000000..1fb75e6ba2
--- /dev/null
+++ b/engines/mads/resources.cpp
@@ -0,0 +1,417 @@
+/* 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 "common/scummsys.h"
+#include "common/archive.h"
+#include "common/textconsole.h"
+#include "mads/mads.h"
+#include "mads/resources.h"
+
+namespace MADS {
+
+enum ResourceType {RESTYPE_ROOM, RESTYPE_SC, RESTYPE_TEXT, RESTYPE_QUO, RESTYPE_I,
+ RESTYPE_OB, RESTYPE_FONT, RESTYPE_SOUND, RESTYPE_SPEECH, RESTYPE_HAS_EXT, RESTYPE_NO_EXT};
+
+/**
+ * HAG Archives implementation
+ */
+class HagArchive : public Common::Archive {
+private:
+ /**
+ * Details of a single entry in a HAG file index
+ */
+ struct HagEntry {
+ Common::String _resourceName;
+ uint32 _offset;
+ uint32 _size;
+
+ HagEntry() : _offset(0), _size(0) {}
+ HagEntry(Common::String resourceName, uint32 offset, uint32 size)
+ : _resourceName(resourceName), _offset(offset), _size(size) {
+ }
+ };
+
+ class HagIndex {
+ public:
+ Common::List<HagEntry> _entries;
+ Common::String _filename;
+ };
+
+ Common::Array<HagIndex> _index;
+
+ /**
+ * Load the index of all the game's HAG files
+ */
+ void loadIndex(MADSEngine *vm);
+
+ /**
+ * Given a resource name, opens up the correct HAG file and returns whether
+ * an entry with the given name exists.
+ */
+ bool getHeaderEntry(const Common::String &resourceName, HagIndex &hagIndex, HagEntry &hagEntry) const;
+
+ /**
+ * Returns the HAG resource filename that will contain a given resource
+ */
+ Common::String getResourceFilename(const Common::String &resourceName) const;
+
+ /**
+ * Return a resource type given a resource name
+ */
+ ResourceType getResourceType(const Common::String &resourceName) const;
+public:
+ HagArchive(MADSEngine *vm);
+ virtual ~HagArchive();
+
+ // 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;
+};
+
+const char *const MADSCONCAT_STRING = "MADSCONCAT";
+
+HagArchive::HagArchive(MADSEngine *vm) {
+ loadIndex(vm);
+}
+
+HagArchive::~HagArchive() {
+}
+
+// Archive implementation
+bool HagArchive::hasFile(const Common::String &name) const {
+ HagIndex hagIndex;
+ HagEntry hagEntry;
+ return getHeaderEntry(name, hagIndex, hagEntry);
+}
+
+int HagArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int members = 0;
+
+ for (uint hagCtr = 0; hagCtr < _index.size(); ++hagCtr) {
+ HagIndex hagIndex = _index[hagCtr];
+ Common::List<HagEntry>::iterator i;
+
+ for (i = hagIndex._entries.begin(); i != hagIndex._entries.end(); ++i) {
+ list.push_back(Common::ArchiveMemberList::value_type(
+ new Common::GenericArchiveMember((*i)._resourceName, this)));
+ ++members;
+ }
+ }
+
+ return members;
+}
+
+const Common::ArchiveMemberPtr HagArchive::getMember(const Common::String &name) const {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *HagArchive::createReadStreamForMember(const Common::String &name) const {
+ HagIndex hagIndex;
+ HagEntry hagEntry;
+
+ if (getHeaderEntry(name, hagIndex, hagEntry)) {
+ // Entry found. If the correct file is not already open, open it
+ Common::File f;
+ if (!f.open(hagIndex._filename))
+ error("Could not open HAG file");
+
+ // Return a new stream for the specific resource
+ f.seek(hagEntry._offset);
+ return f.readStream(hagEntry._size);
+ }
+
+ return nullptr;
+}
+
+void HagArchive::loadIndex(MADSEngine *vm) {
+ Common::File hagFile;
+
+ for (int sectionIndex = -1; sectionIndex < 11; ++sectionIndex) {
+ if (sectionIndex == 0)
+ continue;
+
+ // Dragonsphere does not have some sections - skip them
+ if (vm->getGameID() == GType_Dragonsphere) {
+ if (sectionIndex == 7 || sectionIndex == 8)
+ continue;
+ }
+
+ // Phantom does not have some sections - skip them
+ if (vm->getGameID() == GType_Phantom) {
+ if (sectionIndex == 6 || sectionIndex == 7 || sectionIndex == 8)
+ continue;
+ }
+
+ Common::String filename = (sectionIndex == -1) ? "GLOBAL.HAG" :
+ Common::String::format("SECTION%d.HAG", sectionIndex);
+ if (sectionIndex == 10) {
+ // Speech
+ if (!Common::File::exists("SPEECH.HAG"))
+ break;
+ else
+ filename = "SPEECH.HAG";
+ }
+ if (!hagFile.open(filename))
+ error("Could not locate HAG file - %s", filename.c_str());
+
+ // Check for header
+ char headerBuffer[16];
+ if ((hagFile.read(headerBuffer, 16) != 16) ||
+ (strncmp(headerBuffer, MADSCONCAT_STRING, 10) != 0))
+ error("Invalid HAG file opened");
+
+ // Scan through the HAG index
+ int numEntries = hagFile.readUint16LE();
+
+ HagIndex hagIndex;
+ hagIndex._filename = filename;
+
+ for (int idx = 0; idx < numEntries; ++idx) {
+ // Read in the details of the next resource
+ char resourceBuffer[14];
+ uint32 offset = hagFile.readUint32LE();
+ uint32 size = hagFile.readUint32LE();
+ hagFile.read(resourceBuffer, 14);
+
+ hagIndex._entries.push_back(HagEntry(resourceBuffer, offset, size));
+ }
+
+ hagFile.close();
+ _index.push_back(hagIndex);
+ }
+}
+
+bool HagArchive::getHeaderEntry(const Common::String &resourceName,
+ HagIndex &hagIndex, HagEntry &hagEntry) const {
+ Common::String resName = resourceName;
+ resName.toUppercase();
+ if (resName[0] == '*')
+ resName.deleteChar(0);
+
+ Common::String hagFilename = getResourceFilename(resName);
+
+ // Find the index for the given file
+ for (uint hagCtr = 0; hagCtr < _index.size(); ++hagCtr) {
+ hagIndex = _index[hagCtr];
+
+ if (hagIndex._filename == hagFilename) {
+ Common::List<HagEntry>::iterator ei;
+ for (ei = hagIndex._entries.begin(); ei != hagIndex._entries.end(); ++ei) {
+ hagEntry = *ei;
+ if (hagEntry._resourceName.compareToIgnoreCase(resName) == 0)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+Common::String HagArchive::getResourceFilename(const Common::String &resourceName) const {
+ ResourceType resType = getResourceType(resourceName);
+ Common::String outputFilename = "GLOBAL.HAG";
+
+ if ((resType == RESTYPE_ROOM) || (resType == RESTYPE_SC)) {
+ int value = atoi(resourceName.c_str() + 2);
+ int hagFileNum = (resType == RESTYPE_ROOM) ? value / 100 : value;
+
+ if (hagFileNum > 0)
+ outputFilename = Common::String::format("SECTION%d.HAG", hagFileNum);
+ }
+
+ if (resType == RESTYPE_SPEECH)
+ outputFilename = "SPEECH.HAG";
+
+ return outputFilename;
+}
+
+ResourceType HagArchive::getResourceType(const Common::String &resourceName) const {
+ if (resourceName.hasPrefix("RM")) {
+ // Room resource
+ return RESTYPE_ROOM;
+ } else if (resourceName.hasPrefix("SC")) {
+ // SC resource
+ return RESTYPE_SC;
+ } else if (resourceName.hasSuffix(".TXT")) {
+ // Text resource
+ return RESTYPE_TEXT;
+ } else if (resourceName.hasSuffix(".QUO")) {
+ // QUO resource
+ return RESTYPE_QUO;
+ } else if (resourceName.hasPrefix("I")) {
+ // I resource
+ return RESTYPE_I;
+ } else if (resourceName.hasPrefix("OB")) {
+ // OB resource
+ return RESTYPE_OB;
+ } else if (resourceName.hasPrefix("FONT")) {
+ // FONT resource
+ return RESTYPE_FONT;
+ } else if (resourceName.hasPrefix("SOUND")) {
+ // SOUND resource
+ return RESTYPE_SOUND;
+ } else if (resourceName.hasPrefix("SPCHC")) {
+ // SPEECH resource
+ return RESTYPE_SPEECH;
+ }
+
+ // Check for a known extension
+ const char *extPos = strchr(resourceName.c_str(), '.');
+ if (extPos) {
+ ++extPos;
+ if (!strcmp(extPos, "FL") || !strcmp(extPos, "LBM") || !strcmp(extPos, "ANM") ||
+ !strcmp(extPos, "AA") || !strcmp(extPos, "SS")) {
+ return RESTYPE_HAS_EXT;
+ }
+ }
+
+ return RESTYPE_NO_EXT;
+}
+
+/*------------------------------------------------------------------------*/
+
+void Resources::init(MADSEngine *vm) {
+ SearchMan.add("HAG", new HagArchive(vm));
+}
+
+Common::String Resources::formatName(RESPREFIX resType, int id, const Common::String &ext) {
+ Common::String result = "*";
+
+ if (resType == 3 && !id) {
+ id = id / 100;
+ }
+
+ if (!ext.empty()) {
+ switch (resType) {
+ case RESPREFIX_GL:
+ result += "GL000";
+ break;
+ case RESPREFIX_SC:
+ result += Common::String::format("SC%.3d", id);
+ break;
+ case RESPREFIX_RM:
+ result += Common::String::format("RM%.3d", id);
+ break;
+ default:
+ break;
+ }
+
+ result += ext;
+ }
+
+ return result;
+}
+
+Common::String Resources::formatName(int prefix, char asciiCh, int id, EXTTYPE extType,
+ const Common::String &suffix) {
+ Common::String result;
+ if (prefix <= 0) {
+ result = "*";
+ } else {
+ result = Common::String::format("%s%.3d",
+ (prefix < 100) ? "*SC" : "*RM", prefix);
+ }
+
+ result += Common::String::format("%c", asciiCh);
+ if (id >= 0)
+ result += Common::String::format("%d", id);
+ if (!suffix.empty())
+ result += suffix;
+
+ switch (extType) {
+ case EXT_SS:
+ result += ".SS";
+ break;
+ case EXT_AA:
+ result += ".AA";
+ break;
+ case EXT_DAT:
+ result += ".DAT";
+ break;
+ case EXT_HH:
+ result += ".HH";
+ break;
+ case EXT_ART:
+ result += ".ART";
+ break;
+ case EXT_INT:
+ result += ".INT";
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+Common::String Resources::formatResource(const Common::String &resName,
+ const Common::String &hagFilename) {
+// int v1 = 0, v2 = 0;
+
+ if (resName.hasPrefix("*")) {
+ // Resource file specified
+ error("TODO: formatResource");
+ } else {
+ // File outside of hag file
+ return resName;
+ }
+}
+
+Common::String Resources::formatAAName(int idx) {
+ return formatName(0, 'I', idx, EXT_AA, "");
+}
+
+/*------------------------------------------------------------------------*/
+
+void File::openFile(const Common::String &filename) {
+ if (!Common::File::open(filename))
+ error("Could not open file - %s", filename.c_str());
+}
+
+/*------------------------------------------------------------------------*/
+
+void SynchronizedList::synchronize(Common::Serializer &s) {
+ int v = 0;
+ int count = size();
+ s.syncAsUint16LE(count);
+
+ if (s.isSaving()) {
+ for (int idx = 0; idx < count; ++idx) {
+ v = (*this)[idx];
+ s.syncAsSint32LE(v);
+ }
+ } else {
+ clear();
+ reserve(count);
+ for (int idx = 0; idx < count; ++idx) {
+ s.syncAsSint32LE(v);
+ push_back(v);
+ }
+ }
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/resources.h b/engines/mads/resources.h
new file mode 100644
index 0000000000..8d9ab1e39f
--- /dev/null
+++ b/engines/mads/resources.h
@@ -0,0 +1,89 @@
+/* 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 MADS_RESOURCES_H
+#define MADS_RESOURCES_H
+
+#include "common/scummsys.h"
+#include "common/file.h"
+#include "common/serializer.h"
+#include "common/str.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+enum RESPREFIX {
+ RESPREFIX_GL = 1, RESPREFIX_SC = 2, RESPREFIX_RM = 3
+};
+
+enum EXTTYPE {
+ EXT_NONE = -1, EXT_SS = 1, EXT_AA = 2, EXT_DAT = 3, EXT_HH = 4,
+ EXT_ART = 5, EXT_INT = 6
+};
+
+class Resources {
+public:
+ /**
+ * Instantiates the resource manager
+ */
+ static void init(MADSEngine *vm);
+
+ static Common::String formatName(RESPREFIX resType, int id, const Common::String &ext);
+ static Common::String formatName(int prefix, char asciiCh, int id,
+ EXTTYPE extType, const Common::String &suffix);
+ static Common::String formatResource(const Common::String &resName, const Common::String &hagFilename);
+ static Common::String formatAAName(int idx);
+};
+
+/**
+ * Derived file class
+ */
+class File : public Common::File {
+public:
+ /**
+ * Constructor
+ */
+ File() : Common::File() {}
+
+ /**
+ * Constructor
+ */
+ File(const Common::String &filename) { openFile(filename); }
+
+ /**
+ * Opens the given file, throwing an error if it can't be opened
+ */
+ void openFile(const Common::String &filename);
+};
+
+class SynchronizedList : public Common::Array<int> {
+public:
+ /**
+ * Synchronize the list
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_RESOURCES_H */
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
new file mode 100644
index 0000000000..e98648f009
--- /dev/null
+++ b/engines/mads/scene.cpp
@@ -0,0 +1,719 @@
+/* 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 "common/scummsys.h"
+#include "mads/scene.h"
+#include "mads/compression.h"
+#include "mads/mads.h"
+#include "mads/dragonsphere/dragonsphere_scenes.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/phantom/phantom_scenes.h"
+
+namespace MADS {
+
+Scene::Scene(MADSEngine *vm)
+ : _vm(vm), _action(_vm), _depthSurface(vm),
+ _dirtyAreas(_vm), _dynamicHotspots(vm), _hotspots(vm),
+ _kernelMessages(vm), _sequences(vm), _sprites(vm), _spriteSlots(vm),
+ _textDisplay(vm), _userInterface(vm) {
+ _priorSceneId = 0;
+ _nextSceneId = 0;
+ _currentSceneId = 0;
+ _sceneLogic = nullptr;
+ _sceneInfo = nullptr;
+ _cyclingActive = false;
+ _cyclingThreshold = 0;
+ _cyclingDelay = 0;
+ _totalCycleColors = 0;
+ _depthStyle = 0;
+ _roomChanged = false;
+ _reloadSceneFlag = false;
+ _freeAnimationFlag = false;
+ _animationData = nullptr;
+ _activeAnimation = nullptr;
+ _textSpacing = -1;
+ _frameStartTime = 0;
+ _layer = LAYER_GUI;
+ _lookFlag = false;
+ _bandsRange = 0;
+ _scaleRange = 0;
+ _interfaceY = 0;
+ _spritesCount = 0;
+ _variant = 0;
+
+ _paletteUsageF.push_back(PaletteUsage::UsageEntry(0xF));
+
+ // Set up a scene surface that maps to our physical screen drawing surface
+ _sceneSurface.init(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
+ _vm->_screen.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
+
+ // Set up the verb list
+ _verbList.push_back(VerbInit(VERB_LOOK, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_TAKE, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_PUSH, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_OPEN, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_PUT, VERB_THIS, PREP_RELATIONAL));
+ _verbList.push_back(VerbInit(VERB_TALKTO, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_GIVE, VERB_THIS, PREP_TO));
+ _verbList.push_back(VerbInit(VERB_PULL, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_CLOSE, VERB_THAT, PREP_NONE));
+ _verbList.push_back(VerbInit(VERB_THROW, VERB_THIS, PREP_TO));
+}
+
+Scene::~Scene() {
+ delete _sceneLogic;
+ delete _sceneInfo;
+}
+
+void Scene::clearVocab() {
+ _activeVocabs.clear();
+}
+
+void Scene::addActiveVocab(int vocabId) {
+ if (activeVocabIndexOf(vocabId) == -1) {
+ assert(_activeVocabs.size() < 200);
+ _activeVocabs.push_back(vocabId);
+ }
+}
+
+int Scene::activeVocabIndexOf(int vocabId) {
+ for (uint i = 0; i < _activeVocabs.size(); ++i) {
+ if (_activeVocabs[i] == vocabId)
+ return i;
+ }
+
+ return -1;
+}
+
+void Scene::clearSequenceList() {
+ _sequences.clear();
+}
+
+void Scene::clearMessageList() {
+ _kernelMessages.clear();
+ _talkFont = FONT_CONVERSATION;
+ _textSpacing = -1;
+}
+
+void Scene::loadSceneLogic() {
+ delete _sceneLogic;
+
+ switch (_vm->getGameID()) {
+ case GType_RexNebular:
+ _sceneLogic = Nebular::SceneFactory::createScene(_vm);
+ break;
+ case GType_Dragonsphere:
+ _sceneLogic = Dragonsphere::SceneFactory::createScene(_vm);
+ break;
+ case GType_Phantom:
+ _sceneLogic = Phantom::SceneFactory::createScene(_vm);
+ break;
+ default:
+ error("Scene logic: Unknown game");
+ }
+}
+
+void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) {
+ // Store the previously active scene number and set the new one
+ _priorSceneId = _currentSceneId;
+ _currentSceneId = sceneId;
+
+ _variant = 0;
+ if (palFlag)
+ _vm->_palette->resetGamePalette(18, 10);
+
+ _spriteSlots.reset(false);
+ _sequences.clear();
+ _kernelMessages.clear();
+ _vm->_palette->_paletteUsage.load(&_scenePaletteUsage);
+
+ int flags = SCENEFLAG_LOAD_SHADOW;
+ if (_vm->_dithering)
+ flags |= SCENEFLAG_DITHER;
+
+ _sceneInfo = SceneInfo::init(_vm);
+ _sceneInfo->load(_currentSceneId, _variant, Common::String(), flags,
+ _depthSurface, _backgroundSurface);
+
+ // Initialize palette animation for the scene
+ initPaletteAnimation(_sceneInfo->_paletteCycles, false);
+
+ // Copy over nodes
+ _rails.load(_sceneInfo->_nodes, &_depthSurface, _sceneInfo->_depthStyle);
+
+ // Load hotspots
+ loadHotspots();
+
+ // Load vocab
+ loadVocab();
+
+ // Load palette usage
+ _vm->_palette->_paletteUsage.load(&_paletteUsageF);
+
+ // Load interface
+ flags = PALFLAG_RESERVED | ANIMFLAG_LOAD_BACKGROUND;
+ if (_vm->_dithering)
+ flags |= ANIMFLAG_DITHER;
+ if (_vm->_textWindowStill)
+ flags |= ANIMFLAG_LOAD_BACKGROUND_ONLY;
+
+ _animationData = Animation::init(_vm, this);
+ DepthSurface depthSurface(_vm);
+ _animationData->load(_userInterface, depthSurface, prefix, flags, nullptr, nullptr);
+
+ _vm->_palette->_paletteUsage.load(&_scenePaletteUsage);
+
+ _bandsRange = _sceneInfo->_yBandsEnd - _sceneInfo->_yBandsStart;
+ _scaleRange = _sceneInfo->_maxScale - _sceneInfo->_minScale;
+
+ _spriteSlots.reset(false);
+ _interfaceY = MADS_SCENE_HEIGHT;
+ _spritesCount = _sprites.size();
+
+ _userInterface.setup(_vm->_game->_screenObjects._inputMode);
+
+ _vm->_game->_screenObjects._category = CAT_NONE;
+ _vm->_events->showCursor();
+}
+
+void Scene::loadHotspots() {
+ File f(Resources::formatName(RESPREFIX_RM, _currentSceneId, ".HH"));
+ MadsPack madsPack(&f);
+ bool isV2 = (_vm->getGameID() != GType_RexNebular);
+
+ Common::SeekableReadStream *stream = madsPack.getItemStream(0);
+ int count = stream->readUint16LE();
+ delete stream;
+
+ stream = madsPack.getItemStream(1);
+ _hotspots.clear();
+ for (int i = 0; i < count; ++i)
+ _hotspots.push_back(Hotspot(*stream, isV2));
+
+ delete stream;
+ f.close();
+}
+
+void Scene::loadVocab() {
+ // Add all the verbs to the active vocab list
+ for (uint i = 0; i < _verbList.size(); ++i)
+ addActiveVocab(_verbList[i]._id);
+
+ // Load the vocabs for any object descriptions and custom actions
+ for (uint objIndex = 0; objIndex < _vm->_game->_objects.size(); ++objIndex) {
+ InventoryObject &io = _vm->_game->_objects[objIndex];
+ addActiveVocab(io._descId);
+
+ for (int vocabIndex = 0; vocabIndex <io._vocabCount; ++vocabIndex) {
+ addActiveVocab(io._vocabList[vocabIndex]._vocabId);
+ }
+ }
+
+ // Load scene hotspot list vocabs and verbs
+ for (uint i = 0; i < _hotspots.size(); ++i) {
+ addActiveVocab(_hotspots[i]._vocabId);
+ if (_hotspots[i]._verbId)
+ addActiveVocab(_hotspots[i]._verbId);
+ }
+
+ loadVocabStrings();
+}
+
+void Scene::loadVocabStrings() {
+ _vocabStrings.clear();
+ File f("*VOCAB.DAT");
+ Common::String msg;
+
+ for (;;) {
+ char c = (char)f.readByte();
+ if (f.eos()) break;
+
+ if (c == '\0') {
+ _vocabStrings.push_back(msg);
+ msg = "";
+ } else {
+ msg += c;
+ }
+ }
+
+ f.close();
+}
+
+uint32 Scene::getVocabStringsCount() const {
+ return _vocabStrings.size();
+}
+
+void Scene::initPaletteAnimation(Common::Array<PaletteCycle> &palCycles, bool animFlag) {
+ // Initialize the animation palette and ticks list
+ _cycleTicks.clear();
+ _paletteCycles.clear();
+
+ for (uint i = 0; i < palCycles.size(); ++i) {
+ _cycleTicks.push_back(_vm->_events->getFrameCounter());
+ _paletteCycles.push_back(palCycles[i]);
+ }
+
+ // Save the initial starting palette
+ Common::copy(&_vm->_palette->_mainPalette[0], &_vm->_palette->_mainPalette[PALETTE_SIZE],
+ &_vm->_palette->_cyclingPalette[0]);
+
+ // Calculate total
+ _totalCycleColors = 0;
+ for (uint i = 0; i < _paletteCycles.size(); ++i)
+ _totalCycleColors += _paletteCycles[i]._colorCount;
+
+ _cyclingThreshold = (_totalCycleColors > 16) ? 3 : 0;
+ _cyclingActive = animFlag;
+}
+
+void Scene::animatePalette() {
+ byte rgb[3];
+
+ if (_cyclingActive) {
+ Scene::_cyclingDelay++;
+ if (_cyclingDelay >= _cyclingThreshold) {
+ uint32 frameCounter = _vm->_events->getFrameCounter();
+ bool changesFlag = false;
+ for (uint16 idx = 0; idx < _paletteCycles.size(); idx++) {
+ if (frameCounter >= (_cycleTicks[idx] + _paletteCycles[idx]._ticks)) {
+ _cycleTicks[idx] = frameCounter;
+ int count = _paletteCycles[idx]._colorCount;
+ int first = _paletteCycles[idx]._firstColorIndex;
+ int listIndex = _paletteCycles[idx]._firstListColor;
+ changesFlag = true;
+
+ if (count > 1) {
+ // Make a copy of the last color
+ byte *pSrc = &_vm->_palette->_cyclingPalette[first * 3];
+ byte *pEnd = pSrc + count * 3;
+ Common::copy(pEnd - 3, pEnd, &rgb[0]);
+
+ // Shift the cycle palette forward one entry
+ Common::copy_backward(pSrc, pEnd - 3, pEnd);
+
+ // Move the saved color to the start of the cycle
+ Common::copy(&rgb[0], &rgb[3], pSrc);
+
+ if (++listIndex >= count)
+ listIndex = 0;
+ }
+
+ _paletteCycles[idx]._firstListColor = listIndex;
+ }
+ }
+
+ if (changesFlag) {
+ int firstColor = _paletteCycles[0]._firstColorIndex;
+ byte *pSrc = &_vm->_palette->_cyclingPalette[firstColor * 3];
+ _vm->_palette->setPalette(pSrc, firstColor, _totalCycleColors);
+ }
+
+ _cyclingDelay = 0;
+ }
+ }
+}
+
+bool Scene::getDepthHighBits(const Common::Point &pt) {
+ if (_sceneInfo->_depthStyle == 2) {
+ return 0;
+ } else {
+ const byte *p = _depthSurface.getBasePtr(pt.x, pt.y);
+ return (*p & 0x70) >> 4;
+ }
+}
+
+void Scene::loop() {
+ while (!_vm->shouldQuit() && !_reloadSceneFlag && (_nextSceneId == _currentSceneId)) {
+ // Handle drawing a game frame
+ doFrame();
+
+ // TODO: Verify correctness of frame wait
+ _vm->_events->waitForNextFrame();
+
+ if (_vm->_dialogs->_pendingDialog != DIALOG_NONE && !_vm->_game->_trigger
+ && _vm->_game->_player._stepEnabled)
+ _reloadSceneFlag = true;
+ }
+}
+
+void Scene::doFrame() {
+ Player &player = _vm->_game->_player;
+ bool flag = false;
+
+ if (_action._selectedAction || !player._stepEnabled) {
+ _action.clear();
+ _action._selectedAction = 0;
+ }
+
+ if (!_vm->_game->_trigger && !player._trigger) {
+ // Refresh the dynamic hotspots if they've changed
+ if (_dynamicHotspots._changed)
+ _dynamicHotspots.refresh();
+
+ // Check all on-screen visual objects
+ _vm->_game->_screenObjects.check(player._stepEnabled && !player._needToWalk &&
+ !_vm->_game->_fx);
+ }
+
+ if (_action._selectedAction && player._stepEnabled && !player._needToWalk &&
+ !_vm->_game->_trigger && !player._trigger) {
+ _action.startAction();
+ if (_action._activeAction._verbId == Nebular::VERB_LOOK_AT) {
+ _action._activeAction._verbId = VERB_LOOK;
+ _action._savedFields._command = false;
+ }
+
+ flag = true;
+ }
+
+ if (flag || (_vm->_game->_trigger && _vm->_game->_triggerMode == SEQUENCE_TRIGGER_PREPARE)) {
+ doPreactions();
+ }
+
+ player.newWalk();
+ if (!_vm->_game->_fx)
+ _frameStartTime = _vm->_events->getFrameCounter();
+
+ // Handle parser actions as well as game triggers
+ if ((_action._inProgress && !player._moving && !player._needToWalk &&
+ (player._facing == player._turnToFacing) && !_vm->_game->_trigger) ||
+ (_vm->_game->_trigger && (_vm->_game->_triggerMode == SEQUENCE_TRIGGER_PARSER))) {
+ doAction();
+ }
+
+ if (_currentSceneId != _nextSceneId) {
+ _freeAnimationFlag = true;
+ } else {
+ doSceneStep();
+ checkKeyboard();
+
+ if (_currentSceneId != _nextSceneId) {
+ _freeAnimationFlag = true;
+ } else {
+ player.nextFrame();
+
+ // Cursor update code
+ updateCursor();
+
+ if (!_vm->_game->_trigger) {
+ // Handle any active sequences
+ _sequences.tick();
+
+ // Handle any active animation
+ if (_activeAnimation)
+ _activeAnimation->update();
+ }
+
+ // If the debugget flag is set, show the mouse position
+ int mouseTextIndex = 0;
+ if (_vm->_debugger->_showMousePos) {
+ Common::Point pt = _vm->_events->mousePos();
+ Common::String msg = Common::String::format("(%d,%d)", pt.x, pt.y);
+ mouseTextIndex = _kernelMessages.add(Common::Point(5, 5),
+ 0x203, 0, 0, 1, msg);
+ }
+
+ if (!_vm->_game->_trigger) {
+ if (_reloadSceneFlag || _currentSceneId != _nextSceneId)
+ _kernelMessages.reset();
+ _kernelMessages.update();
+ }
+
+ _userInterface._uiSlots.draw(!_vm->_game->_fx, _vm->_game->_fx);
+
+ // Write any text needed by the interface
+ if (_vm->_game->_fx)
+ _userInterface.drawTextElements();
+
+ // Draw any elements
+ drawElements((ScreenTransition)_vm->_game->_fx, _vm->_game->_fx);
+
+ // Handle message updates
+ if (_vm->_game->_fx) {
+ uint32 priorTime = _vm->_game->_priorFrameTimer;
+ uint32 newTime = _vm->_events->getFrameCounter();
+ _sequences.delay(newTime, priorTime);
+ _kernelMessages.delay(newTime, priorTime);
+ }
+
+ if (_vm->_debugger->_showMousePos)
+ // Mouse position display isn't persistent, so remove it
+ _kernelMessages.remove(mouseTextIndex);
+
+ // Original had a debugger check/call here to allow pausing after
+ // drawing each frame. Not implemented under ScummVM
+ }
+ }
+
+ if (_vm->_game->_fx)
+ _cyclingActive = true;
+ _vm->_game->_fx = kTransitionNone;
+
+ if (_freeAnimationFlag)
+ freeAnimation();
+}
+
+void Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
+ // Draw any sprite backgrounds
+ _spriteSlots.drawBackground();
+
+ // Set up dirty areas for any text display
+ _textDisplay.setDirtyAreas();
+
+ // Merge any identified dirty areas
+ _dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
+
+ // Copy background for the dirty areas to the screen
+ _dirtyAreas.copy(&_backgroundSurface, &_vm->_screen, _posAdjust);
+
+ // Handle dirty areas for foreground objects
+ if (_vm->getGameID() == GType_RexNebular) // TODO: Implement for V2 games
+ _spriteSlots.setDirtyAreas();
+ _textDisplay.setDirtyAreas2();
+ _dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
+
+ // Draw sprites that have changed
+ if (_vm->getGameID() == GType_RexNebular) // TODO: Implement for V2 games
+ _spriteSlots.drawSprites(&_sceneSurface);
+
+ // Draw text elements onto the view
+ _textDisplay.draw(&_vm->_screen);
+
+ if (transitionType) {
+ // Fading in the screen
+ _vm->_screen.transition(transitionType, surfaceFlag);
+ _vm->_sound->startQueuedCommands();
+ } else {
+ // Copy dirty areas to the screen
+ _dirtyAreas.copyToScreen(_vm->_screen._offset);
+ }
+
+ _spriteSlots.cleanUp();
+ _textDisplay.cleanUp();
+}
+
+void Scene::doPreactions() {
+ if (_vm->_game->_screenObjects._inputMode == kInputBuildingSentences ||
+ _vm->_game->_screenObjects._inputMode == kInputLimitedSentences) {
+ _vm->_game->_triggerSetupMode = SEQUENCE_TRIGGER_PREPARE;
+ _action.checkAction();
+ _sceneLogic->preActions();
+
+ if (_vm->_game->_triggerMode == SEQUENCE_TRIGGER_PREPARE)
+ _vm->_game->_trigger = 0;
+ }
+}
+
+void Scene::doAction() {
+ bool flag = false;
+
+ _vm->_game->_triggerSetupMode = SEQUENCE_TRIGGER_PARSER;
+ if ((_action._inProgress || _vm->_game->_trigger) && !_action._savedFields._commandError) {
+ _sceneLogic->actions();
+ flag = !_action._inProgress;
+ }
+
+ if (_vm->_game->_screenObjects._inputMode == kInputConversation) {
+ _action._inProgress = false;
+ } else {
+ if ((_action._inProgress || _vm->_game->_trigger) ||
+ (!flag && _action._savedFields._commandError == flag)) {
+ _vm->_game->_sectionHandler->sectionPtr2();
+ flag = !_action._inProgress;
+ }
+
+ if ((_action._inProgress || _vm->_game->_trigger) &&
+ (!flag || _action._savedFields._commandError == flag)) {
+ _vm->_game->doObjectAction();
+ }
+
+ if (!_action._savedFields._lookFlag) {
+ if (_action._inProgress) {
+ _action._savedFields._commandError = true;
+ _sceneLogic->postActions();
+ }
+
+ if (_action._inProgress) {
+ _action._savedFields._commandError = true;
+ _sceneLogic->unhandledAction();
+ }
+
+ if (_action._inProgress)
+ _vm->_game->unhandledAction();
+ }
+ }
+
+ _action._inProgress = false;
+ if (_vm->_game->_triggerMode == SEQUENCE_TRIGGER_PARSER)
+ _vm->_game->_trigger = 0;
+}
+
+void Scene::doSceneStep() {
+ _vm->_game->_triggerSetupMode = SEQUENCE_TRIGGER_DAEMON;
+ _sceneLogic->step();
+ _vm->_game->_sectionHandler->step();
+ _vm->_game->step();
+
+ if (_vm->_game->_triggerMode == SEQUENCE_TRIGGER_DAEMON)
+ _vm->_game->_trigger = 0;
+}
+
+void Scene::checkKeyboard() {
+ if (_vm->_events->isKeyPressed()) {
+ Common::Event evt = _vm->_events->_pendingKeys.pop();
+ _vm->_game->handleKeypress(evt);
+ }
+
+ if ((_vm->_events->_mouseStatus & 3) == 3 && _vm->_game->_player._stepEnabled) {
+ _reloadSceneFlag = true;
+ _vm->_dialogs->_pendingDialog = DIALOG_GAME_MENU;
+ _action.clear();
+ _action._selectedAction = 0;
+ }
+}
+
+void Scene::loadAnimation(const Common::String &resName, int trigger) {
+ // WORKAROUND: If there's already a previous active animation used by the
+ // scene, then free it before we create the new one
+ if (_activeAnimation)
+ freeAnimation();
+
+ DepthSurface depthSurface(_vm);
+ UserInterface interfaceSurface(_vm);
+
+ _activeAnimation = Animation::init(_vm, this);
+ _activeAnimation->load(interfaceSurface, depthSurface, resName,
+ _vm->_dithering ? ANIMFLAG_DITHER : 0, nullptr, nullptr);
+ _activeAnimation->startAnimation(trigger);
+}
+
+void Scene::updateCursor() {
+ Player &player = _vm->_game->_player;
+
+ CursorType cursorId = CURSOR_ARROW;
+ if (_action._interAwaiting == AWAITING_COMMAND && !_vm->_events->_rightMousePressed &&
+ _vm->_game->_screenObjects._category == CAT_HOTSPOT) {
+ int idx = _vm->_game->_screenObjects._selectedObject -
+ _userInterface._categoryIndexes[CAT_HOTSPOT - 1];
+ assert(idx >= 0);
+
+ if (idx >= (int)_hotspots.size()) {
+ idx -= _hotspots.size();
+ _vm->_events->_newCursorId = _dynamicHotspots[idx]._cursor;
+ } else {
+ idx = _hotspots.size() - idx - 1;
+ _vm->_events->_newCursorId = _hotspots[idx]._cursor;
+ }
+
+ cursorId = _vm->_events->_newCursorId == CURSOR_NONE ?
+ CURSOR_ARROW : _vm->_events->_newCursorId;
+ }
+
+ if (!player._stepEnabled)
+ cursorId = CURSOR_WAIT;
+ if (cursorId >= _vm->_events->_cursorSprites->getCount())
+ cursorId = (CursorType)_vm->_events->_cursorSprites->getCount();
+ _vm->_events->_newCursorId = cursorId;
+
+ if (cursorId != _vm->_events->_cursorId) {
+ _vm->_events->setCursor(cursorId);
+ }
+}
+
+void Scene::freeCurrentScene() {
+ if (_animationData) {
+ delete _animationData;
+ _animationData = nullptr;
+ }
+ if (_activeAnimation) {
+ delete _activeAnimation;
+ _activeAnimation = nullptr;
+ }
+
+ _vm->_palette->_paletteUsage.load(nullptr);
+ _hotspots.clear();
+ _backgroundSurface.free();
+ _depthSurface.free();
+
+ delete _sceneInfo;
+ _sceneInfo = nullptr;
+}
+
+void Scene::removeSprites() {
+ for (int idx = _sprites.size() - 1; idx >= _spritesCount; --idx)
+ _sprites.remove(idx);
+}
+
+void Scene::changeVariant(int variant) {
+ _variant = variant;
+ _sceneInfo->loadCodes(_depthSurface, variant);
+ _spriteSlots.fullRefresh();
+}
+
+void Scene::resetScene() {
+ _vm->_game->clearQuotes();
+ _spriteSlots.fullRefresh(true);
+ _sequences.clear();
+}
+
+void Scene::freeAnimation() {
+ if (_activeAnimation) {
+ Player &player = _vm->_game->_player;
+
+ if (!_freeAnimationFlag) {
+ _spriteSlots.fullRefresh(true);
+ _sequences.scan();
+ }
+
+ // Refresh the player
+ if (player._visible) {
+ player._forceRefresh = true;
+ player.update();
+ }
+
+ // Remove any kernel messages in use by the animation
+ for (uint i = 0; i < _activeAnimation->_messages.size(); ++i) {
+ int msgIndex = _activeAnimation->_messages[i]._kernelMsgIndex;
+ if (msgIndex >= 0)
+ _kernelMessages.remove(msgIndex);
+ }
+
+ // Delete the animation
+ delete _activeAnimation;
+ _activeAnimation = nullptr;
+ }
+
+ _freeAnimationFlag = false;
+}
+
+void Scene::synchronize(Common::Serializer &s) {
+ _action.synchronize(s);
+ _rails.synchronize(s);
+ _userInterface.synchronize(s);
+ s.syncAsByte(_reloadSceneFlag);
+ s.syncAsByte(_roomChanged);
+ s.syncAsUint16LE(_nextSceneId);
+ s.syncAsUint16LE(_priorSceneId);
+ _dynamicHotspots.synchronize(s);
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
new file mode 100644
index 0000000000..407d70dc85
--- /dev/null
+++ b/engines/mads/scene.h
@@ -0,0 +1,251 @@
+/* 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 MADS_SCENE_H
+#define MADS_SCENE_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "mads/assets.h"
+#include "mads/screen.h"
+#include "mads/hotspots.h"
+#include "mads/messages.h"
+#include "mads/msurface.h"
+#include "mads/scene_data.h"
+#include "mads/animation.h"
+#include "mads/rails.h"
+#include "mads/sequence.h"
+#include "mads/sprites.h"
+#include "mads/user_interface.h"
+
+namespace MADS {
+
+class Scene {
+private:
+ /**
+ * Return the index of a given Vocab in the active vocab list
+ */
+ int activeVocabIndexOf(int vocabId);
+
+ /**
+ * Secondary loading vocab list
+ */
+ void loadVocabStrings();
+
+ /*
+ * Initializes the data for palette animation within the scene
+ */
+ void initPaletteAnimation(Common::Array<PaletteCycle> &palCycles, bool animFlag);
+
+ /**
+ * Handles a single frame within the game scene
+ */
+ void doFrame();
+
+ void doPreactions();
+
+ void doAction();
+
+ /**
+ * Calls all the necessary step handlers for the current frame
+ */
+ void doSceneStep();
+
+ /**
+ * Checks whether there's a pending keypress, and if so handles it.
+ */
+ void checkKeyboard();
+
+ /**
+ * Checks for a highlighted hotspot, and updates the cursor accordingly
+ */
+ void updateCursor();
+protected:
+ MADSEngine *_vm;
+public:
+ SceneLogic *_sceneLogic;
+ MSurface _sceneSurface;
+ int _priorSceneId;
+ int _nextSceneId;
+ int _currentSceneId;
+ Common::Array<VerbInit> _verbList;
+ TextDisplayList _textDisplay;
+ SpriteSlots _spriteSlots;
+ SpriteSets _sprites;
+ DynamicHotspots _dynamicHotspots;
+ Common::Array<int> _activeVocabs;
+ SequenceList _sequences;
+ KernelMessages _kernelMessages;
+ Rails _rails;
+ Common::String _talkFont;
+ int _textSpacing;
+ Hotspots _hotspots;
+ DirtyAreas _dirtyAreas;
+ int _variant;
+ SceneInfo *_sceneInfo;
+ MSurface _backgroundSurface;
+ DepthSurface _depthSurface;
+ UserInterface _userInterface;
+ bool _cyclingActive;
+ int _cyclingThreshold;
+ int _cyclingDelay;
+ int _totalCycleColors;
+ Common::Array<uint32> _cycleTicks;
+ Common::Array<PaletteCycle> _paletteCycles;
+ Common::StringArray _vocabStrings;
+ Animation *_animationData;
+ Animation *_activeAnimation;
+ bool _freeAnimationFlag;
+ int _depthStyle;
+ int _bandsRange;
+ int _scaleRange;
+ int _interfaceY;
+ int _spritesCount;
+ MADSAction _action;
+ bool _roomChanged;
+ bool _reloadSceneFlag;
+ Common::Point _posAdjust;
+ uint32 _frameStartTime;
+ Layer _layer;
+ bool _lookFlag;
+ Common::Point _customDest;
+ Common::Array<PaletteUsage::UsageEntry> _paletteUsageF;
+ Common::Array<PaletteUsage::UsageEntry> _scenePaletteUsage;
+
+ /**
+ * Constructor
+ */
+ Scene(MADSEngine *vm);
+
+ /**
+ * Destructor
+ */
+ ~Scene();
+
+ /**
+ * Clear the vocabulary list
+ */
+ void clearVocab();
+
+ /**
+ * Add a given vocab entry to the active list
+ */
+ void addActiveVocab(int vocabId);
+
+ /**
+ * Get the number of entries in the game's vocabulary
+ */
+ uint32 getVocabStringsCount() const;
+
+ /**
+ * Clear the sequence list
+ */
+ void clearSequenceList();
+
+ /**
+ * Clear the message list
+ */
+ void clearMessageList();
+
+ /**
+ * Loads the scene logic for a given scene
+ */
+ void loadSceneLogic();
+
+ /**
+ * Loads the resources associated with the given scene
+ * @param sceneId Scene to load
+ * @param prefix Prefix to use for retrieving animation data
+ * @param palFlag Flag for whether to reset the high/lo palette areas
+ */
+ void loadScene(int sceneId, const Common::String &prefix, bool palFlag);
+
+ /**
+ * Loads the hotstpots for the scene
+ */
+ void loadHotspots();
+
+ /**
+ * Loads the vocab list
+ */
+ void loadVocab();
+
+ bool getDepthHighBits(const Common::Point &pt);
+
+ /**
+ * Main scene loop
+ */
+ void loop();
+
+ /**
+ * Draw all the elements onto the scene
+ */
+ void drawElements(ScreenTransition transitionType, bool surfaceFlag);
+
+ /**
+ * Handles cycling palette colors for the scene
+ */
+ void animatePalette();
+
+ /**
+ * Load an animation
+ */
+ void loadAnimation(const Common::String &resName, int trigger = 0);
+
+ /**
+ * Returns a vocab entry
+ */
+ Common::String getVocab(int vocabId) { return _vocabStrings[vocabId - 1]; }
+
+ /**
+ * Clear the data for the currently loaded scene
+ */
+ void freeCurrentScene();
+
+ /**
+ * Set the walk surface for a scene to a different variant
+ */
+ void changeVariant(int variant);
+
+ void resetScene();
+
+ /**
+ * Removes all the scene specific sprites fromt the sprites list,
+ * leaving any player sprites list in place at the start of the list.
+ */
+ void removeSprites();
+
+ /**
+ * Frees any currently active animation for the scene
+ */
+ void freeAnimation();
+
+ /**
+ * Synchronize the game
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_SCENE_H */
diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp
new file mode 100644
index 0000000000..d53a668fd3
--- /dev/null
+++ b/engines/mads/scene_data.cpp
@@ -0,0 +1,463 @@
+/* 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 "common/scummsys.h"
+#include "mads/scene_data.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/screen.h"
+#include "mads/resources.h"
+#include "mads/dragonsphere/dragonsphere_scenes.h"
+#include "mads/nebular/nebular_scenes.h"
+#include "mads/phantom/phantom_scenes.h"
+
+namespace MADS {
+
+KernelMessage::KernelMessage() {
+ _flags = 0;
+ _sequenceIndex = 0;
+ _color1 = 0;
+ _color2 = 0;
+ _msgOffset = 0;
+ _numTicks = 0;
+ _frameTimer2 = 0;
+ _frameTimer = 0;
+ _timeout = 0;
+ _trigger = 0;
+ _abortMode = SEQUENCE_TRIGGER_PARSER;
+ _actionDetails._verbId = VERB_NONE;
+ _actionDetails._objectNameId = 0;
+ _actionDetails._indirectObjectId = 0;
+ _textDisplayIndex = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+void ARTHeader::load(Common::SeekableReadStream *f, bool isV2) {
+ if (!isV2) {
+ // Read in dimensions of image
+ _width = f->readUint16LE();
+ _height = f->readUint16LE();
+ }
+
+ // Read in palette information
+ int palCount = f->readUint16LE();
+ for (int i = 0; i < palCount; ++i) {
+ RGB6 rgb;
+ rgb.load(f);
+ _palette.push_back(rgb);
+ }
+ f->skip(6 * (256 - palCount));
+
+ // Read palette animations
+ int cycleCount = f->readUint16LE();
+ for (int i = 0; i < cycleCount; ++i) {
+ PaletteCycle cycle;
+ cycle._colorCount = f->readByte();
+ cycle._firstListColor = f->readByte();
+ cycle._firstColorIndex = f->readByte();
+ cycle._ticks = f->readByte();
+
+ _paletteCycles.push_back(cycle);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+void SceneInfo::SpriteInfo::load(Common::SeekableReadStream *f) {
+ f->skip(3);
+ _spriteSetIndex = f->readByte();
+ f->skip(2);
+ _position.x = f->readSint16LE();
+ _position.y = f->readSint16LE();
+ _depth = f->readByte();
+ _scale = f->readByte();
+}
+
+/*------------------------------------------------------------------------*/
+
+SceneInfo::SceneInfo(MADSEngine *vm) : _vm(vm) {
+ _sceneId = 0;
+ _artFileNum = 0;
+ _depthStyle = 0;
+ _width = 0;
+ _height = 0;
+ _yBandsEnd = 0;
+ _yBandsStart = 0;
+ _maxScale = 0;
+ _minScale = 0;
+ _field4A = 0;
+ _usageIndex = 0;
+ for (int i = 0; i < 15; ++i)
+ _depthList[i] = 0;
+}
+
+SceneInfo *SceneInfo::init(MADSEngine *vm) {
+ switch (vm->getGameID()) {
+ case GType_RexNebular:
+ return new Nebular::SceneInfoNebular(vm);
+ case GType_Dragonsphere:
+ return new Dragonsphere::SceneInfoDragonsphere(vm);
+ case GType_Phantom:
+ return new Phantom::SceneInfoPhantom(vm);
+ default:
+ error("SceneInfo: Unknown game");
+ }
+
+ return nullptr;
+}
+
+void SceneInfo::load(int sceneId, int variant, const Common::String &resName,
+ int flags, DepthSurface &depthSurface, MSurface &bgSurface) {
+ bool sceneFlag = sceneId >= 0;
+
+ // Figure out the resource to use
+ Common::String resourceName;
+ if (sceneFlag) {
+ resourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".DAT");
+ } else {
+ resourceName = "*" + Resources::formatResource(resName, resName);
+ }
+
+ // Open the scene info resource for access
+ File infoFile(resourceName);
+ MadsPack infoPack(&infoFile);
+
+ // Read in basic data
+ Common::SeekableReadStream *infoStream = infoPack.getItemStream(0);
+ if (_vm->getGameID() == GType_RexNebular) {
+ _sceneId = infoStream->readUint16LE();
+ } else {
+ infoStream->skip(6); // actual scene ID (string)
+ _sceneId = sceneId;
+ }
+
+ // TODO: The following isn't quite right for V2 games (it's all 0)
+ _artFileNum = infoStream->readUint16LE();
+ _depthStyle = infoStream->readUint16LE();
+ _width = infoStream->readUint16LE();
+ _height = infoStream->readUint16LE();
+
+ // HACK for V2 games (for now)
+ if (_vm->getGameID() != GType_RexNebular) {
+ _width = 320;
+ _height = 156;
+ }
+
+ infoStream->skip(24);
+
+ int nodeCount = infoStream->readUint16LE();
+ _yBandsEnd = infoStream->readUint16LE();
+ _yBandsStart = infoStream->readUint16LE();
+ _maxScale = infoStream->readUint16LE();
+ _minScale = infoStream->readUint16LE();
+ for (int i = 0; i < DEPTH_BANDS_SIZE; ++i)
+ _depthList[i] = infoStream->readUint16LE();
+ _field4A = infoStream->readUint16LE();
+
+ // Load the set of objects that are associated with the scene
+ for (int i = 0; i < 20; ++i) {
+ WalkNode node;
+ node.load(infoStream);
+
+ if (i < nodeCount)
+ _nodes.push_back(node);
+ }
+
+ int spriteSetsCount = infoStream->readUint16LE();
+ int spriteInfoCount = infoStream->readUint16LE();
+
+ // Load in sprite sets
+ Common::StringArray setNames;
+ for (int i = 0; i < 10; ++i) {
+ char name[64];
+ infoStream->read(name, 64);
+
+ if (i < spriteSetsCount)
+ setNames.push_back(Common::String(name));
+ }
+
+ // Load in sprite draw information
+ Common::Array<SpriteInfo> spriteInfo;
+ // TODO: The following isn't quite right for V2 games
+ if (_vm->getGameID() == GType_RexNebular) {
+ for (int i = 0; i < 50; ++i) {
+ SpriteInfo info;
+ info.load(infoStream);
+
+ if (i < spriteInfoCount)
+ spriteInfo.push_back(info);
+ }
+ }
+ delete infoStream;
+
+ int width = _width;
+ int height = _height;
+
+ if (!bgSurface.getPixels()) {
+ bgSurface.setSize(width, height);
+ }
+
+ if (_depthStyle == 2)
+ width >>= 2;
+ if (!depthSurface.getPixels()) {
+ depthSurface.setSize(width, height);
+ }
+
+ if (_vm->getGameID() == GType_RexNebular) {
+ // Load the depth surface with the scene codes
+ Common::SeekableReadStream *depthStream = infoPack.getItemStream(variant + 1);
+ loadCodes(depthSurface, depthStream);
+ delete depthStream;
+ }
+
+ infoFile.close();
+
+ if (_vm->getGameID() == GType_RexNebular) {
+ loadMadsV1Background(sceneId, resName, flags, bgSurface);
+ loadPalette(sceneId, _artFileNum, resName, flags, bgSurface);
+ } else {
+ loadMadsV2Background(sceneId, resName, flags, bgSurface);
+ loadPalette(sceneId, sceneId, resName, flags, bgSurface);
+ }
+
+ Common::Array<SpriteAsset *> spriteSets;
+ Common::Array<int> usageList;
+
+ // TODO: The following isn't quite right for V2 games
+ if (_vm->getGameID() == GType_RexNebular) {
+ for (uint i = 0; i < setNames.size(); ++i) {
+ Common::String setResName;
+ if (sceneFlag || resName.hasPrefix("*"))
+ setResName += "*";
+ setResName += setNames[i];
+
+ SpriteAsset *sprites = new SpriteAsset(_vm, setResName, flags);
+ spriteSets.push_back(sprites);
+ usageList.push_back(sprites->_usageIndex);
+ }
+ }
+
+ _vm->_palette->_paletteUsage.updateUsage(usageList, _usageIndex);
+
+ for (uint i = 0; i < spriteInfo.size(); ++i) {
+ SpriteInfo &si = spriteInfo[i];
+ SpriteAsset *asset = spriteSets[si._spriteSetIndex];
+ assert(asset && _depthStyle != 2);
+
+ MSprite *spr = asset->getFrame(asset->getCount() - 1);
+ bgSurface.copyFromScaled(spr, si._position, si._depth, &depthSurface,
+ si._scale, spr->getTransparencyIndex());
+ }
+
+ // Free the sprite sets
+ for (int i = (int)spriteSets.size() - 1; i >= 0; --i) {
+ _vm->_palette->_paletteUsage.resetPalFlags(spriteSets[i]->_usageIndex);
+ delete spriteSets[i];
+ }
+}
+
+void SceneInfo::loadPalette(int sceneId, int artFileNum, const Common::String &resName, int flags, MSurface &bgSurface) {
+ bool sceneFlag = sceneId >= 0;
+ Common::String resourceName;
+ bool isV2 = (_vm->getGameID() != GType_RexNebular);
+ Common::String extension = !isV2 ? ".ART" : ".TT";
+ int paletteStream = !isV2 ? 0 : 2;
+
+ // Get the ART resource
+ if (sceneFlag) {
+ resourceName = Resources::formatName(RESPREFIX_RM, artFileNum, extension);
+ } else {
+ resourceName = "*" + Resources::formatResource(resName, resName);
+ }
+
+ // Load in the ART header and palette
+ File artFile(resourceName);
+ MadsPack artResource(&artFile);
+ Common::SeekableReadStream *stream = artResource.getItemStream(paletteStream);
+
+ ARTHeader artHeader;
+ artHeader.load(stream, isV2);
+ delete stream;
+
+ // Copy out the palette animation data
+ for (uint i = 0; i < artHeader._paletteCycles.size(); ++i)
+ _paletteCycles.push_back(artHeader._paletteCycles[i]);
+
+ if (!(flags & 1)) {
+ if (!_vm->_palette->_paletteUsage.empty()) {
+ _vm->_palette->_paletteUsage.getKeyEntries(artHeader._palette);
+ _vm->_palette->_paletteUsage.prioritize(artHeader._palette);
+ }
+
+ _usageIndex = _vm->_palette->_paletteUsage.process(artHeader._palette,
+ (flags & 0xF800) | 0x8000);
+ if (_usageIndex > 0) {
+ _vm->_palette->_paletteUsage.transform(artHeader._palette);
+
+ for (uint i = 0; i < _paletteCycles.size(); ++i) {
+ byte listColor = _paletteCycles[i]._firstListColor;
+ _paletteCycles[i]._firstColorIndex = artHeader._palette[listColor]._palIndex;
+ }
+ }
+ }
+
+ if (!(flags & 1)) {
+ // Translate the background to use the correct palette indexes
+ bgSurface.translate(artHeader._palette);
+ }
+}
+
+void SceneInfo::loadMadsV1Background(int sceneId, const Common::String &resName, int flags, MSurface &bgSurface) {
+ bool sceneFlag = sceneId >= 0;
+ Common::String resourceName;
+ Common::SeekableReadStream *stream;
+
+ // Get the ART resource
+ if (sceneFlag) {
+ resourceName = Resources::formatName(RESPREFIX_RM, _artFileNum, ".ART");
+ } else {
+ resourceName = "*" + Resources::formatResource(resName, resName);
+ }
+
+ // Load in the ART data
+ File artFile(resourceName);
+ MadsPack artResource(&artFile);
+
+ // Read in the background surface data
+ assert(_width == bgSurface.w && _height == bgSurface.h);
+ stream = artResource.getItemStream(1);
+ stream->read(bgSurface.getPixels(), bgSurface.w * bgSurface.h);
+
+ // Close the ART file
+ delete stream;
+ artFile.close();
+}
+
+void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName, int flags, MSurface &bgSurface) {
+ Common::String tileMapResourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".MM");
+ File tileMapFile(tileMapResourceName);
+ MadsPack tileMapPack(&tileMapFile);
+ Common::SeekableReadStream *mapStream = tileMapPack.getItemStream(0);
+
+ // Get the details of the tiles and map
+ mapStream->readUint32LE();
+ int tileCountX = mapStream->readUint16LE();
+ int tileCountY = mapStream->readUint16LE();
+ int tileWidthMap = mapStream->readUint16LE();
+ int tileHeightMap = mapStream->readUint16LE();
+ int screenWidth = mapStream->readUint16LE();
+ int screenHeight = mapStream->readUint16LE();
+ int tileCountMap = tileCountX * tileCountY;
+ delete mapStream;
+
+ // Obtain tile map information
+ typedef Common::List<Common::SharedPtr<MSurface> > TileSetList;
+ typedef TileSetList::iterator TileSetIterator;
+ TileSetList tileSet;
+ uint16 *tileMap = new uint16[tileCountMap];
+ mapStream = tileMapPack.getItemStream(1);
+ for (int i = 0; i < tileCountMap; ++i)
+ tileMap[i] = mapStream->readUint16LE();
+ delete mapStream;
+ tileMapFile.close();
+
+ // --------------------------------------------------------------------------------
+
+ // Tile data, which needs to be kept compressed, as the tile map offsets refer to
+ // the compressed data. Each tile is then uncompressed separately
+ Common::String tileDataResourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".TT");
+ File tileDataFile(tileDataResourceName);
+ MadsPack tileDataPack(&tileDataFile);
+ Common::SeekableReadStream *tileDataUncomp = tileDataPack.getItemStream(0);
+
+ // Validate that the data matches between the tiles and tile map file and is valid
+ int tileCount = tileDataUncomp->readUint16LE();
+ int tileWidth = tileDataUncomp->readUint16LE();
+ int tileHeight = tileDataUncomp->readUint16LE();
+ delete tileDataUncomp;
+ assert(tileCountMap == tileCount);
+ assert(tileWidth == tileWidthMap);
+ assert(tileHeight == tileHeightMap);
+ assert(screenWidth == _width);
+ assert(screenHeight <= _height);
+
+ // --------------------------------------------------------------------------------
+
+ // Get tile data
+
+ tileDataUncomp = tileDataPack.getItemStream(1);
+ FabDecompressor fab;
+ uint32 compressedTileDataSize = 0;
+
+ for (int i = 0; i < tileCount; i++) {
+ tileDataUncomp->seek(i * 4, SEEK_SET);
+ uint32 tileOfs = tileDataUncomp->readUint32LE();
+ MSurface* newTile = new MSurface(tileWidth, tileHeight);
+
+ if (i == tileCount - 1)
+ compressedTileDataSize = tileDataFile.size() - tileOfs;
+ else
+ compressedTileDataSize = tileDataUncomp->readUint32LE() - tileOfs;
+
+ //debugCN(kDebugGraphics, "Tile: %i, compressed size: %i\n", i, compressedTileDataSize);
+
+ newTile->empty();
+
+ byte *compressedTileData = new byte[compressedTileDataSize];
+
+ tileDataFile.seek(tileDataPack.getDataOffset() + tileOfs, SEEK_SET);
+ tileDataFile.read(compressedTileData, compressedTileDataSize);
+
+ fab.decompress(compressedTileData, compressedTileDataSize, (byte*)newTile->getPixels(), tileWidth * tileHeight);
+ tileSet.push_back(TileSetList::value_type(newTile));
+ delete[] compressedTileData;
+ }
+
+ delete tileDataUncomp;
+
+ // --------------------------------------------------------------------------------
+
+ // Loop through the mapping data to place the tiles on the screen
+
+ uint16 *tIndex = &tileMap[0];
+ for (int y = 0; y < tileCountY; y++) {
+ for (int x = 0; x < tileCountX; x++) {
+ int tileIndex = *tIndex++;
+ assert(tileIndex < tileCount);
+ TileSetIterator tile = tileSet.begin();
+ for (int i = 0; i < tileIndex; i++)
+ ++tile;
+ ((*tile).get())->copyTo(&bgSurface, Common::Point(x * tileWidth, y * tileHeight));
+ }
+ }
+ tileSet.clear();
+ tileDataFile.close();
+}
+
+/*------------------------------------------------------------------------*/
+
+SceneLogic::SceneLogic(MADSEngine *vm) : _vm(vm) {
+ _scene = &_vm->_game->_scene;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h
new file mode 100644
index 0000000000..783a9ab8a9
--- /dev/null
+++ b/engines/mads/scene_data.h
@@ -0,0 +1,224 @@
+/* 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 MADS_SCENE_DATA_H
+#define MADS_SCENE_DATA_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/serializer.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "common/rect.h"
+#include "mads/action.h"
+#include "mads/assets.h"
+#include "mads/events.h"
+#include "mads/game_data.h"
+#include "mads/hotspots.h"
+#include "mads/messages.h"
+#include "mads/rails.h"
+#include "mads/user_interface.h"
+
+namespace MADS {
+
+class MADSEngine;
+class Scene;
+class SpriteSlot;
+
+#define MADS_INTERFACE_HEIGHT 44
+#define MADS_SCENE_HEIGHT 156
+
+#define DEPTH_BANDS_SIZE 15
+
+#define SPRITE_SLOTS_MAX_SIZE 50
+#define TEXT_DISPLAY_MAX_SIZE 40
+#define DIRTY_AREAS_SIZE (SPRITE_SLOTS_MAX_SIZE + TEXT_DISPLAY_MAX_SIZE)
+
+enum {
+ SCENEFLAG_DITHER = 0x01, // Dither to 16 colors
+ SCENEFLAG_LOAD_SHADOW = 0x10 // Load hard shadows
+};
+
+class VerbInit {
+public:
+ int _id;
+ VerbType _verbType;
+ PrepType _prepType;
+
+ VerbInit() {}
+ VerbInit(int id, VerbType verbType, PrepType prepType)
+ : _id(id), _verbType(verbType), _prepType(prepType) {
+ }
+};
+
+class SceneLogic {
+protected:
+ MADSEngine *_vm;
+ Scene *_scene;
+public:
+ /**
+ * Constructor
+ */
+ SceneLogic(MADSEngine *vm);
+
+ /**
+ * Destructor
+ */
+ virtual ~SceneLogic() {}
+
+ /**
+ * Called to initially setup a scene
+ */
+ virtual void setup() = 0;
+
+ /**
+ * Called as the scene is entered (made active)
+ */
+ virtual void enter() = 0;
+
+ /**
+ * Called one per frame
+ */
+ virtual void step() {}
+
+ /**
+ * Called before an action is started
+ */
+ virtual void preActions() {}
+
+ /**
+ * Handles scene actions
+ */
+ virtual void actions() = 0;
+
+ /**
+ * Post-action handling
+ */
+ virtual void postActions() {}
+
+ /**
+ * Unhandled action handling
+ */
+ virtual void unhandledAction() {}
+
+ /**
+ * Synchronize any local data for the scene
+ */
+ virtual void synchronize(Common::Serializer &s) {}
+};
+
+struct ARTHeader {
+ int _width;
+ int _height;
+ Common::Array<RGB6> _palette;
+ Common::Array<PaletteCycle> _paletteCycles;
+
+ void load(Common::SeekableReadStream *f, bool isV2);
+};
+
+/**
+ * Handles general data for a given scene
+ */
+class SceneInfo {
+ class SpriteInfo {
+ public:
+ int _spriteSetIndex;
+ Common::Point _position;
+ int _depth;
+ int _scale;
+
+ void load(Common::SeekableReadStream *f);
+ };
+protected:
+ MADSEngine *_vm;
+
+ /**
+ * Constructor
+ */
+ SceneInfo(MADSEngine *vm);
+public:
+ int _sceneId;
+ int _artFileNum;
+ int _depthStyle;
+ int _width;
+ int _height;
+
+ int _yBandsEnd;
+ int _yBandsStart;
+ int _maxScale;
+ int _minScale;
+ int _depthList[DEPTH_BANDS_SIZE];
+ int _field4A; // Useless field ?
+
+ int _usageIndex;
+ Common::Array<PaletteCycle> _paletteCycles;
+ WalkNodeList _nodes;
+public:
+ /**
+ * Destructor
+ */
+ virtual ~SceneInfo() {}
+
+ /**
+ * Instantiates the class
+ */
+ static SceneInfo *init(MADSEngine *vm);
+
+ /**
+ * loads the data
+ */
+ void load(int sceneId, int variant, const Common::String &resName, int flags,
+ DepthSurface &depthSurface, MSurface &bgSurface);
+
+ /**
+ * Loads the palette for a scene
+ */
+ void loadPalette(int sceneId, int artFileNum, const Common::String &resName, int flags, MSurface &bgSurface);
+
+ /**
+ * Loads a V1 game background
+ */
+ void loadMadsV1Background(int sceneId, const Common::String &resName, int flags, MSurface &bgSurface);
+
+ /**
+ * Loads a V2 game background
+ */
+ void loadMadsV2Background(int sceneId, const Common::String &resName, int flags, MSurface &bgSurface);
+
+ /**
+ * Loads the given surface with depth information of a given scene
+ * @param depthSurface Depth/walk surface
+ * @param variant Variant number to load
+ */
+ virtual void loadCodes(MSurface &depthSurface, int variant) = 0;
+
+ /**
+ * Loads the given surface with depth information of a given scene
+ * @param depthSurface Depth/walk surface
+ * @param stream Stream to load the data from
+ */
+ virtual void loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) = 0;
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_SCENE_DATA_H */
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
new file mode 100644
index 0000000000..91aa3abdb0
--- /dev/null
+++ b/engines/mads/screen.cpp
@@ -0,0 +1,642 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/game.h"
+#include "mads/screen.h"
+#include "mads/palette.h"
+#include "mads/user_interface.h"
+
+namespace MADS {
+
+MADSEngine *DirtyArea::_vm = nullptr;
+
+DirtyArea::DirtyArea() {
+ _active = false;
+ _textActive = false;
+ _mergedArea = nullptr;
+}
+
+void DirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) {
+ if (_bounds.left % 2) {
+ --_bounds.left;
+ ++width;
+ }
+
+ if (_bounds.left < 0)
+ _bounds.left = 0;
+ else if (_bounds.left > maxWidth)
+ _bounds.left = maxWidth;
+ int right = _bounds.left + width;
+ if (right < 0)
+ right = 0;
+ if (right > maxWidth)
+ right = maxWidth;
+
+ _bounds.right = right;
+
+ if (_bounds.top < 0)
+ _bounds.top = 0;
+ else if (_bounds.top > maxHeight)
+ _bounds.top = maxHeight;
+ int bottom = _bounds.top + height;
+ if (bottom < 0)
+ bottom = 0;
+ if (bottom > maxHeight)
+ bottom = maxHeight;
+
+ _bounds.bottom = bottom;
+ _active = true;
+}
+
+
+void DirtyArea::setSpriteSlot(const SpriteSlot *spriteSlot) {
+ int width, height;
+ Scene &scene = _vm->_game->_scene;
+
+ if (spriteSlot->_flags == IMG_REFRESH) {
+ // Special entry to refresh the entire screen
+ _bounds.left = 0;
+ _bounds.top = 0;
+ width = MADS_SCREEN_WIDTH;
+ height = MADS_SCENE_HEIGHT;
+ } else {
+ // Standard sprite slots
+ _bounds.left = spriteSlot->_position.x - scene._posAdjust.x;
+ _bounds.top = spriteSlot->_position.y - scene._posAdjust.y;
+
+ SpriteAsset &spriteSet = *scene._sprites[spriteSlot->_spritesIndex];
+ MSprite *frame = spriteSet.getFrame(ABS(spriteSlot->_frameNumber) - 1);
+
+ if (spriteSlot->_scale == -1) {
+ width = frame->w;
+ height = frame->h;
+ } else {
+ width = frame->w * spriteSlot->_scale / 100;
+ height = frame->h * spriteSlot->_scale / 100;
+
+ _bounds.left -= width / 2;
+ _bounds.top += -(height - 1);
+ }
+ }
+
+ setArea(width, height, MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+}
+
+void DirtyArea::setTextDisplay(const TextDisplay *textDisplay) {
+ _bounds.left = textDisplay->_bounds.left;
+ _bounds.top = textDisplay->_bounds.top;
+
+ setArea(textDisplay->_bounds.width(), textDisplay->_bounds.height(),
+ MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+}
+
+void DirtyArea::setUISlot(const UISlot *slot) {
+ int type = slot->_flags;
+ if (type <= IMG_UPDATE_ONLY)
+ type += -IMG_UPDATE_ONLY;
+ if (type >= 0x40)
+ type &= ~0x40;
+
+ MSurface &intSurface = _vm->_game->_scene._userInterface;
+ switch (type) {
+ case IMG_REFRESH:
+ _bounds.left = 0;
+ _bounds.top = 0;
+ setArea(intSurface.w, intSurface.h, intSurface.w, intSurface.h);
+ break;
+
+ case IMG_OVERPRINT:
+ _bounds.left = slot->_position.x;
+ _bounds.top = slot->_position.y;
+ _bounds.setWidth(slot->_width);
+ _bounds.setHeight(slot->_height);
+ setArea(slot->_width, slot->_height, intSurface.w, intSurface.h);
+ break;
+
+ default: {
+ SpriteAsset *asset = _vm->_game->_scene._sprites[slot->_spritesIndex];
+ MSprite *frame = asset->getFrame(slot->_frameNumber - 1);
+ int w = frame->w;
+ int h = frame->h;
+
+ if (slot->_segmentId == IMG_SPINNING_OBJECT) {
+ _bounds.left = slot->_position.x;
+ _bounds.top = slot->_position.y;
+ } else {
+ _bounds.left = slot->_position.x + w / 2;
+ _bounds.top = slot->_position.y - h + 1;
+ }
+
+ setArea(w, h, intSurface.w, intSurface.h);
+ break;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+DirtyAreas::DirtyAreas(MADSEngine *vm) : _vm(vm) {
+ DirtyArea::_vm = vm;
+
+ for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) {
+ DirtyArea rec;
+ rec._active = false;
+ push_back(rec);
+ }
+}
+
+void DirtyAreas::merge(int startIndex, int count) {
+ if (startIndex >= count)
+ return;
+
+ for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) {
+ if (!(*this)[outerCtr]._active)
+ continue;
+
+ for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) {
+ if (!(*this)[innerCtr]._active || !intersects(outerCtr, innerCtr))
+ continue;
+
+ if ((*this)[outerCtr]._textActive && (*this)[innerCtr]._textActive)
+ mergeAreas(innerCtr, outerCtr);
+ }
+ }
+}
+
+/**
+* Returns true if two dirty areas intersect
+*/
+bool DirtyAreas::intersects(int idx1, int idx2) {
+ return (*this)[idx1]._bounds.intersects((*this)[idx2]._bounds);
+}
+
+void DirtyAreas::mergeAreas(int idx1, int idx2) {
+ DirtyArea &da1 = (*this)[idx1];
+ DirtyArea &da2 = (*this)[idx2];
+
+ da1._bounds.extend(da2._bounds);
+
+ da2._active = false;
+ da2._mergedArea = &da1;
+ da1._textActive = true;
+}
+
+void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust) {
+ for (uint i = 0; i < size(); ++i) {
+ const Common::Rect &srcBounds = (*this)[i]._bounds;
+
+ // Check if this is a sane rectangle before attempting to create it
+ if (srcBounds.left >= srcBounds.right || srcBounds.top >= srcBounds.bottom)
+ continue;
+
+ Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
+ srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
+
+ if ((*this)[i]._active && bounds.isValidRect()) {
+ srcSurface->copyTo(destSurface, bounds, Common::Point(bounds.left, bounds.top));
+ }
+ }
+}
+
+void DirtyAreas::copyToScreen(const Common::Point &posAdjust) {
+ for (uint i = 0; i < size(); ++i) {
+ const Common::Rect &srcBounds = (*this)[i]._bounds;
+
+ // Check if this is a sane rectangle before attempting to create it
+ if (srcBounds.left >= srcBounds.right || srcBounds.top >= srcBounds.bottom)
+ continue;
+
+ Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
+ srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
+
+ if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) {
+ _vm->_screen.copyRectToScreen(bounds);
+ }
+ }
+}
+
+void DirtyAreas::reset() {
+ for (uint i = 0; i < size(); ++i)
+ (*this)[i]._active = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+ScreenObject::ScreenObject() {
+ _category = CAT_NONE;
+ _descId = 0;
+ _layer = 0;
+ _active = false;
+}
+
+/*------------------------------------------------------------------------*/
+
+ScreenObjects::ScreenObjects(MADSEngine *vm) : _vm(vm) {
+ _objectY = -1;
+ _forceRescan = false;
+ _inputMode = kInputBuildingSentences;
+ _v7FED6 = 0;
+ _v8332A = 0;
+ _category = CAT_NONE;
+ _spotId = 0;
+ _released = false;
+ _uiCount = 0;
+ _selectedObject = -1;
+ _eventFlag = false;
+ _baseTime = 0;
+}
+
+void ScreenObjects::add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId) {
+ //assert(size() < 100);
+
+ ScreenObject so;
+ so._bounds = bounds;
+ so._category = category;
+ so._descId = descId;
+ so._layer = layer;
+ so._active = true;
+
+ push_back(so);
+}
+
+void ScreenObjects::check(bool scanFlag) {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+
+ if (!_vm->_events->_mouseButtons || _inputMode != kInputBuildingSentences)
+ _vm->_events->_rightMousePressed = false;
+
+ if ((_vm->_events->_mouseMoved || userInterface._scrollbarActive
+ || _v8332A || _forceRescan) && scanFlag) {
+ _category = CAT_NONE;
+ _selectedObject = scanBackwards(_vm->_events->currentPos(), LAYER_GUI);
+ if (_selectedObject > 0) {
+ ScreenObject &scrObject = (*this)[_selectedObject];
+ _category = (ScrCategory)(scrObject._category & 7);
+ _spotId = scrObject._descId;
+ }
+
+ // Handling for easy mouse
+ ScrCategory category = scene._userInterface._category;
+ if (_vm->_easyMouse && _vm->_events->_mouseButtons && category != _category
+ && scene._userInterface._category != CAT_NONE) {
+ _released = true;
+ if (category >= CAT_COMMAND && category <= CAT_TALK_ENTRY) {
+ elementHighlighted();
+ }
+
+ scene._action.checkActionAtMousePos();
+ }
+
+ //_released = _vm->_events->_mouseReleased;
+ if (_vm->_events->_vD2 || (_vm->_easyMouse && !_vm->_events->_mouseStatusCopy))
+ scene._userInterface._category = _category;
+
+ if (!_vm->_events->_mouseButtons || _vm->_easyMouse) {
+ if (userInterface._category >= CAT_COMMAND && userInterface._category <= CAT_TALK_ENTRY) {
+ elementHighlighted();
+ }
+ }
+
+ if (_vm->_events->_mouseButtons || (_vm->_easyMouse && scene._action._interAwaiting > AWAITING_COMMAND
+ && scene._userInterface._category == CAT_INV_LIST) ||
+ (_vm->_easyMouse && scene._userInterface._category == CAT_HOTSPOT)) {
+ scene._action.checkActionAtMousePos();
+ }
+
+ if (_vm->_events->_mouseReleased) {
+ scene._action.leftClick();
+ scene._userInterface._category = CAT_NONE;
+ }
+
+ if (_vm->_events->_mouseButtons || _vm->_easyMouse || userInterface._scrollbarActive)
+ scene._userInterface.updateInventoryScroller();
+
+ if (_vm->_events->_mouseButtons || _vm->_easyMouse)
+ scene._action.set();
+
+ _forceRescan = false;
+ }
+
+ scene._action.refresh();
+
+ uint32 currentTicks = _vm->_events->getFrameCounter();
+ if (currentTicks >= _baseTime) {
+ // Check the user interface slots to see if there's any slots that need to be expired
+ UISlots &uiSlots = userInterface._uiSlots;
+ for (uint idx = 0; idx < uiSlots.size(); ++idx) {
+ UISlot &slot = uiSlots[idx];
+
+ if (slot._flags != IMG_REFRESH && slot._flags > IMG_UPDATE_ONLY
+ && slot._segmentId != IMG_SPINNING_OBJECT)
+ slot._flags = IMG_ERASE;
+ }
+
+ // Any background animation in the user interface
+ userInterface.doBackgroundAnimation();
+
+ // Handle animating the selected inventory item
+ userInterface.inventoryAnim();
+
+ // Set the base time
+ _baseTime = currentTicks + 6;
+ }
+}
+
+int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) {
+ for (int i = (int)size(); i >= 1; --i) {
+ ScreenObject &sObj = (*this)[i];
+ if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer)
+ return i;
+ }
+
+ // Entry not found
+ return 0;
+}
+
+void ScreenObjects::elementHighlighted() {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+ Common::Array<int> &invList = _vm->_game->_objects._inventoryList;
+ MADSAction &action = scene._action;
+ int varA;
+ int topIndex;
+ int *idxP;
+ int var4;
+ int index;
+ int indexEnd = -1;
+ int var8 = 0;
+ int uiCount;
+
+ switch (userInterface._category) {
+ case CAT_COMMAND:
+ index = 10;
+ indexEnd = 9;
+ varA = 5;
+ topIndex = 0;
+ idxP = !_vm->_events->_rightMousePressed ? &userInterface._highlightedCommandIndex :
+ &userInterface._selectedActionIndex;
+
+ if (_vm->_events->_rightMousePressed && userInterface._selectedItemVocabIdx >= 0)
+ userInterface.updateSelection(CAT_INV_VOCAB, -1, &userInterface._selectedItemVocabIdx);
+
+ var4 = _released && !_vm->_events->_rightMousePressed ? 1 : 0;
+ break;
+
+ case CAT_INV_LIST:
+ userInterface.scrollInventory();
+
+ index = MIN((int)invList.size() - userInterface._inventoryTopIndex, 5);
+ indexEnd = invList.size() - 1;
+ varA = 0;
+ topIndex = userInterface._inventoryTopIndex;
+ idxP = &userInterface._highlightedInvIndex;
+ var4 = (!_released || (_vm->_events->_mouseButtons && action._interAwaiting == 1)) ? 0 : 1;
+ break;
+
+ case CAT_INV_VOCAB:
+ if (userInterface._selectedInvIndex >= 0) {
+ InventoryObject &invObject = _vm->_game->_objects.getItem(
+ userInterface._selectedInvIndex);
+ index = invObject._vocabCount;
+ indexEnd = index - 1;
+ } else {
+ index = 0;
+ }
+
+ varA = 0;
+ topIndex = 0;
+ idxP = _vm->_events->_rightMousePressed ? &userInterface._selectedItemVocabIdx : &userInterface._highlightedItemVocabIndex;
+
+ if (_vm->_events->_rightMousePressed && userInterface._selectedActionIndex >= 0)
+ userInterface.updateSelection(CAT_COMMAND, -1, &userInterface._selectedActionIndex);
+
+ var4 = _released && !_vm->_events->_rightMousePressed ? 1 : 0;
+ break;
+
+ case CAT_INV_ANIM:
+ index = 1;
+ indexEnd = invList.size() - 1;
+ varA = 0;
+ topIndex = userInterface._selectedInvIndex;
+ idxP = &var8;
+ var4 = -1;
+ break;
+
+ case CAT_TALK_ENTRY:
+ index = userInterface._talkStrings.size();
+ indexEnd = index - 1;
+ varA = 0;
+ topIndex = 0;
+ idxP = &userInterface._highlightedCommandIndex;
+ var4 = -1;
+ break;
+
+ default:
+ uiCount = size() - _uiCount;
+ index = uiCount + scene._hotspots.size();
+ indexEnd = index - 1;
+ varA = 0;
+ topIndex = 0;
+ idxP = &var8;
+ var4 = -1;
+ break;
+ }
+
+ int newIndex = -1;
+ int catIndex = userInterface._categoryIndexes[userInterface._category - 1];
+ int newX = 0, newY = 0;
+ Common::Point currentPos = _vm->_events->currentPos();
+
+ for (int idx = 0; idx < index && newIndex < 0; ++idx) {
+ int scrObjIndex = (_category == CAT_HOTSPOT) ? catIndex - idx + index - 1 :
+ catIndex + idx;
+
+ ScreenObject &scrObject = (*this)[scrObjIndex];
+ if (!scrObject._active)
+ continue;
+
+ const Common::Rect &bounds = scrObject._bounds;
+ newY = MAX((int)bounds.bottom, newY);
+ newX = MAX((int)bounds.left, newX);
+
+ if (currentPos.y >= bounds.top && currentPos.y < bounds.bottom) {
+ if (var4) {
+ if (currentPos.x >= bounds.left && currentPos.x < bounds.right) {
+ // Cursor is inside hotspot bounds
+ newIndex = scrObjIndex - catIndex;
+ if (_category == CAT_HOTSPOT && newIndex < (int)scene._hotspots.size())
+ newIndex = scene._hotspots.size() - newIndex - 1;
+ }
+ } else if (!varA) {
+ newIndex = idx;
+ } else if (varA <= idx) {
+ if (currentPos.x > bounds.left)
+ newIndex = idx;
+ } else {
+ if (currentPos.x < bounds.right)
+ newIndex = idx;
+ }
+ }
+ }
+
+ if (newIndex == -1 && index > 0 && !var4) {
+ if (_vm->_events->currentPos().y <= newY) {
+ newIndex = 0;
+ if (varA && _vm->_events->currentPos().x >= newX)
+ newIndex = varA;
+ } else {
+ newIndex = index - 1;
+ }
+ }
+
+ if (newIndex >= 0)
+ newIndex = MIN(newIndex + topIndex, indexEnd);
+
+ action._pickedWord = newIndex;
+
+ if (_category == CAT_INV_LIST || _category == CAT_INV_ANIM) {
+ if (action._interAwaiting == 1 && newIndex >= 0 && _released &&
+ (!_vm->_events->_mouseReleased || !_vm->_easyMouse))
+ newIndex = -1;
+ }
+
+ if (_released && !_vm->_events->_rightMousePressed &&
+ (_vm->_events->_mouseReleased || !_vm->_easyMouse))
+ newIndex = -1;
+
+ if (_category != CAT_HOTSPOT && _category != CAT_INV_ANIM)
+ userInterface.updateSelection(_category, newIndex, idxP);
+}
+
+void ScreenObjects::setActive(ScrCategory category, int descId, bool active) {
+ for (uint idx = 1; idx < size(); ++idx) {
+ ScreenObject &sObj = (*this)[idx];
+ if (sObj._category == category && sObj._descId == descId)
+ sObj._active = active;
+ }
+}
+
+void ScreenObjects::synchronize(Common::Serializer &s) {
+ s.syncAsSint16LE(_selectedObject);
+ s.syncAsSint16LE(_category);
+}
+
+/*------------------------------------------------------------------------*/
+
+ScreenSurface::ScreenSurface() {
+ _shakeCountdown = -1;
+ _random = 0x4D2;
+}
+
+void ScreenSurface::init() {
+ setSize(g_system->getWidth(), g_system->getHeight());
+}
+
+void ScreenSurface::copyRectToScreen(const Common::Point &destPos,
+ const Common::Rect &bounds) {
+ const byte *buf = getBasePtr(destPos.x, destPos.y);
+
+ if (bounds.width() != 0 && bounds.height() != 0)
+ g_system->copyRectToScreen(buf, this->pitch, bounds.left, bounds.top,
+ bounds.width(), bounds.height());
+}
+
+void ScreenSurface::copyRectToScreen(const Common::Rect &bounds) {
+ copyRectToScreen(Common::Point(bounds.left, bounds.top), bounds);
+}
+
+void ScreenSurface::updateScreen() {
+ if (_shakeCountdown >= 0) {
+ _random = _random * 5 + 1;
+ int offset = (_random >> 8) & 3;
+ if (_shakeCountdown-- <= 0)
+ offset = 0;
+
+ // Copy the screen with the left hand hide side of the screen of a given
+ // offset width shown at the very right. The offset changes to give
+ // an effect of shaking the screen
+ offset *= 4;
+ const byte *buf = getBasePtr(offset, 0);
+ g_system->copyRectToScreen(buf, this->pitch, 0, 0,
+ this->pitch - offset, this->h);
+ if (offset > 0)
+ g_system->copyRectToScreen(this->pixels, this->pitch,
+ this->pitch - offset, 0, offset, this->h);
+ }
+
+ g_system->updateScreen();
+}
+
+void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag) {
+ Palette &pal = *_vm->_palette;
+ byte palData[PALETTE_SIZE];
+
+ switch (transitionType) {
+ case kTransitionFadeIn:
+ case kTransitionFadeOutIn:
+ Common::fill(&pal._colorValues[0], &pal._colorValues[3], 0);
+ Common::fill(&pal._colorFlags[0], &pal._colorFlags[3], false);
+
+ if (transitionType == kTransitionFadeOutIn) {
+ // Fade out
+ pal.getFullPalette(palData);
+ pal.fadeOut(palData, nullptr, 0, PALETTE_COUNT, 0, 0, 1, 16);
+ }
+
+ // Reset palette to black
+ Common::fill(&palData[0], &palData[PALETTE_SIZE], 0);
+ pal.setFullPalette(palData);
+
+ copyRectToScreen(getBounds());
+ pal.fadeIn(palData, pal._mainPalette, 0, 256, 0, 1, 1, 16);
+ break;
+
+ case kTransitionBoxInBottomLeft:
+ case kTransitionBoxInBottomRight:
+ case kTransitionBoxInTopLeft:
+ case kTransitionBoxInTopRight:
+ error("TODO: transition");
+ break;
+
+ case kTransitionPanLeftToRight:
+ case kTransitionPanRightToLeft:
+ error("TODO: transition");
+
+ case kTransitionCircleIn1:
+ case kTransitionCircleIn2:
+ case kTransitionCircleIn3:
+ case kTransitionCircleIn4:
+ error("TODO circle transition");
+
+ case kCenterVertTransition:
+ error("TODO: center vert transition");
+
+ default:
+ // Quick transitions
+ break;
+ }
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
new file mode 100644
index 0000000000..a3653d6d62
--- /dev/null
+++ b/engines/mads/screen.h
@@ -0,0 +1,240 @@
+/* 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 MADS_SCREEN_H
+#define MADS_SCREEN_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/msurface.h"
+#include "mads/action.h"
+
+namespace MADS {
+
+#define MADS_SCREEN_WIDTH 320
+#define MADS_SCREEN_HEIGHT 200
+
+enum Layer {
+ LAYER_GUI = 19
+};
+
+enum ScreenTransition {
+ kTransitionNone = 0,
+ kTransitionFadeIn, kTransitionFadeOutIn,
+ kTransitionBoxInBottomLeft, kTransitionBoxInBottomRight,
+ kTransitionBoxInTopLeft, kTransitionBoxInTopRight,
+ kTransitionPanLeftToRight, kTransitionPanRightToLeft,
+ kTransitionCircleIn1, kTransitionCircleIn2,
+ kTransitionCircleIn3, kTransitionCircleIn4,
+ kVertTransition1, kVertTransition2, kVertTransition3,
+ kVertTransition4, kVertTransition5, kVertTransition6,
+ kVertTransition7, kCenterVertTransition
+};
+
+enum InputMode {
+ kInputBuildingSentences = 0, // Normal sentence building
+ kInputConversation = 1, // Conversation mode
+ kInputLimitedSentences = 2 // Use only scene hotspots
+};
+
+class SpriteSlot;
+class TextDisplay;
+class UISlot;
+
+class DirtyArea {
+private:
+ static MADSEngine *_vm;
+ friend class DirtyAreas;
+public:
+ Common::Rect _bounds;
+ bool _textActive;
+ bool _active;
+ DirtyArea *_mergedArea;
+
+ DirtyArea();
+
+ void setArea(int width, int height, int maxWidth, int maxHeight);
+
+ /**
+ * Set up a dirty area for a sprite slot
+ */
+ void setSpriteSlot(const SpriteSlot *spriteSlot);
+
+ /**
+ * Set up a dirty area for a text display
+ */
+ void setTextDisplay(const TextDisplay *textDisplay);
+
+ /**
+ * Set up a dirty area for a UI slot
+ */
+ void setUISlot(const UISlot *slot);
+};
+
+class DirtyAreas : public Common::Array<DirtyArea> {
+private:
+ MADSEngine *_vm;
+public:
+ DirtyAreas(MADSEngine *vm);
+
+ /**
+ * Merge together any designated dirty areas that overlap
+ * @param startIndex 1-based starting dirty area starting index
+ * @param count Number of entries to process
+ */
+ void merge(int startIndex, int count);
+
+ bool intersects(int idx1, int idx2);
+ void mergeAreas(int idx1, int idx2);
+
+ /**
+ * Copy the data specified by the dirty rect list between surfaces
+ * @param srcSurface Source surface
+ * @param destSurface Dest surface
+ * @param posAdjust Position adjustment
+ */
+ void copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust);
+
+ /**
+ * Use the lsit of dirty areas to copy areas of the screen surface to
+ * the physical screen
+ * @param posAdjust Position adjustment */
+ void copyToScreen(const Common::Point &posAdjust);
+
+ void reset();
+};
+
+
+class ScreenObject {
+public:
+ bool _active;
+ Common::Rect _bounds;
+ ScrCategory _category;
+ int _descId;
+ int _layer;
+
+ ScreenObject();
+};
+
+class ScreenObjects : public Common::Array<ScreenObject> {
+private:
+ MADSEngine *_vm;
+ int _objectY;
+
+ int scanBackwards(const Common::Point &pt, int layer);
+public:
+ InputMode _inputMode;
+ int _v7FED6;
+ int _v8332A;
+ int _forceRescan;
+ int _selectedObject;
+ ScrCategory _category;
+ bool _released;
+ int _uiCount;
+ bool _eventFlag;
+ uint32 _baseTime;
+ int _spotId;
+
+ /*
+ * Constructor
+ */
+ ScreenObjects(MADSEngine *vm);
+
+ /**
+ * Add a new item to the list
+ */
+ void add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId);
+
+ /**
+ */
+ void check(bool scanFlag);
+
+ /**
+ * Handle an element being highlighted on the screen, and make it active.
+ */
+ void elementHighlighted();
+
+ /**
+ * Retrieve a ScreenObject from the list
+ * @remarks This array is 1-based indexed by the game
+ */
+ ScreenObject &operator[](int idx) {
+ assert(idx > 0);
+ return Common::Array<ScreenObject>::operator[](idx - 1);
+ }
+
+ /**
+ * Sets an item identified by category and Desc Id as active or not
+ * @param category Screen category
+ * @param descId Description for item
+ * @param active Whether to set item as active or not
+ */
+ void setActive(ScrCategory category, int descId, bool active);
+
+ /**
+ * Synchronize the data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+class ScreenSurface : public MSurface {
+private:
+ uint16 _random;
+public:
+ Common::Point _offset;
+ int _shakeCountdown;
+public:
+ /**
+ * Constructor
+ */
+ ScreenSurface();
+
+ /**
+ * Initialize the surface
+ */
+ void init();
+
+ /**
+ * Copys an area of the screen surface to a given destination position on
+ * the ScummVM physical screen buffer
+ * @param destPos Destination position
+ * @param bounds Area of screen surface to copy
+ */
+ void copyRectToScreen(const Common::Point &destPos, const Common::Rect &bounds);
+
+ /**
+ * Copys an area of the screen surface to the ScmmVM physical screen buffer
+ * @param bounds Area of screen surface to copy
+ */
+ void copyRectToScreen(const Common::Rect &bounds);
+
+ /**
+ * Updates the screen with the contents of the surface
+ */
+ void updateScreen();
+
+ void transition(ScreenTransition transitionType, bool surfaceFlag);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_SCREEN_H */
diff --git a/engines/mads/sequence.cpp b/engines/mads/sequence.cpp
new file mode 100644
index 0000000000..f987595f05
--- /dev/null
+++ b/engines/mads/sequence.cpp
@@ -0,0 +1,541 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/assets.h"
+#include "mads/sequence.h"
+#include "mads/scene.h"
+
+namespace MADS {
+
+SequenceEntry::SequenceEntry() {
+ _spritesIndex = 0;
+ _flipped = 0;
+ _frameIndex = 0;
+ _frameStart = 0;
+ _numSprites = 0;
+ _animType = ANIMTYPE_NONE;
+ _frameInc = 0;
+ _depth = 0;
+ _scale = 0;
+ _dynamicHotspotIndex = -1;
+ _triggerCountdown = 0;
+ _doneFlag = 0;
+ _triggerMode = SEQUENCE_TRIGGER_DAEMON;
+ _numTicks = 0;
+ _extraTicks = 0;
+ _timeout = 0;
+ _active = false;
+ _nonFixed = false;
+ _flags = 0;
+ for (int i = 0; i < 5; ++i)
+ _entries._mode[i] = SEQUENCE_TRIGGER_EXPIRE;
+
+ _entries._count = 0;
+ _actionNouns._verbId = VERB_NONE;
+ _actionNouns._objectNameId = -1;
+ _actionNouns._indirectObjectId = -1;
+
+ Common::fill(&_entries._frameIndex[0], &_entries._frameIndex[SEQUENCE_ENTRY_SUBSET_MAX], 0);
+ Common::fill(&_entries._trigger[0], &_entries._trigger[SEQUENCE_ENTRY_SUBSET_MAX], 0);
+}
+
+/*------------------------------------------------------------------------*/
+
+#define SEQUENCE_LIST_SIZE 30
+
+SequenceList::SequenceList(MADSEngine *vm) : _vm(vm) {
+ // IMPORTANT: Preallocate timer slots. Note that sprite slots refer to entries
+ // in this list by index, so we can't just add or delete entries later
+ for (int i = 0; i < SEQUENCE_LIST_SIZE; ++i) {
+ SequenceEntry rec;
+ rec._active = false;
+ rec._dynamicHotspotIndex = -1;
+ _entries.push_back(rec);
+ }
+}
+
+void SequenceList::clear() {
+ for (uint i = 0; i < _entries.size(); ++i) {
+ _entries[i]._active = false;
+ _entries[i]._dynamicHotspotIndex = -1;
+ }
+}
+
+bool SequenceList::addSubEntry(int index, SequenceTrigger mode, int frameIndex, int trigger) {
+ if (_entries[index]._entries._count >= SEQUENCE_ENTRY_SUBSET_MAX)
+ return true;
+
+ int subIndex = _entries[index]._entries._count++;
+ _entries[index]._entries._mode[subIndex] = mode;
+ _entries[index]._entries._frameIndex[subIndex] = frameIndex;
+ _entries[index]._entries._trigger[subIndex] = trigger;
+
+ return false;
+}
+
+int SequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks,
+ int msgX, int msgY, bool nonFixed, int scale, int depth, int frameInc, SpriteAnimType animType, int numSprites,
+ int frameStart) {
+ Scene &scene = _vm->_game->_scene;
+
+ // Find a free slot
+ uint seqIndex = 0;
+ while ((seqIndex < _entries.size()) && _entries[seqIndex]._active)
+ ++seqIndex;
+ if (seqIndex == _entries.size())
+ error("TimerList full");
+
+ if (frameStart <= 0)
+ frameStart = 1;
+ if (numSprites == 0)
+ numSprites = scene._sprites[spriteListIndex]->getCount();
+ if (frameStart == numSprites)
+ frameInc = 0;
+
+ // Set the list entry fields
+ _entries[seqIndex]._active = true;
+ _entries[seqIndex]._spritesIndex = spriteListIndex;
+ _entries[seqIndex]._flipped = flipped;
+ _entries[seqIndex]._frameIndex = frameIndex;
+ _entries[seqIndex]._frameStart = frameStart;
+ _entries[seqIndex]._numSprites = numSprites;
+ _entries[seqIndex]._animType = animType;
+ _entries[seqIndex]._frameInc = frameInc;
+ _entries[seqIndex]._depth = depth;
+ _entries[seqIndex]._scale = scale;
+ _entries[seqIndex]._nonFixed = nonFixed;
+ _entries[seqIndex]._position.x = msgX;
+ _entries[seqIndex]._position.y = msgY;
+ _entries[seqIndex]._numTicks = numTicks;
+ _entries[seqIndex]._extraTicks = extraTicks;
+
+ _entries[seqIndex]._timeout = scene._frameStartTime + delayTicks;
+
+ _entries[seqIndex]._triggerCountdown = triggerCountdown;
+ _entries[seqIndex]._doneFlag = false;
+ _entries[seqIndex]._flags = 0;
+ _entries[seqIndex]._dynamicHotspotIndex = -1;
+ _entries[seqIndex]._entries._count = 0;
+ _entries[seqIndex]._triggerMode = _vm->_game->_triggerSetupMode;
+
+ _entries[seqIndex]._actionNouns = _vm->_game->_scene._action._activeAction;
+
+ return seqIndex;
+}
+
+int SequenceList::addTimer(int timeout, int abortVal) {
+ Scene &scene = _vm->_game->_scene;
+ uint seqIndex;
+ for (seqIndex = 0; seqIndex < _entries.size(); ++seqIndex) {
+ if (!_entries[seqIndex]._active)
+ break;
+ }
+ assert(seqIndex < _entries.size());
+
+ SequenceEntry &se = _entries[seqIndex];
+ se._active = true;
+ se._spritesIndex = -1;
+ se._numTicks = timeout;
+ se._extraTicks = 0;
+ se._timeout = scene._frameStartTime + timeout;
+ se._triggerCountdown = true;
+ se._doneFlag = false;
+ se._entries._count = 0;
+ se._triggerMode = _vm->_game->_triggerSetupMode;
+ se._actionNouns = _vm->_game->_scene._action._activeAction;
+ addSubEntry(seqIndex, SEQUENCE_TRIGGER_EXPIRE, 0, abortVal);
+
+ return seqIndex;
+}
+
+void SequenceList::remove(int seqIndex) {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_entries[seqIndex]._active) {
+ if (_entries[seqIndex]._dynamicHotspotIndex >= 0)
+ scene._dynamicHotspots.remove(_entries[seqIndex]._dynamicHotspotIndex);
+ }
+
+ _entries[seqIndex]._active = false;
+ scene._spriteSlots.deleteTimer(seqIndex);
+}
+
+void SequenceList::setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot) {
+ Scene &scene = _vm->_game->_scene;
+ SequenceEntry &timerEntry = _entries[seqIndex];
+ SpriteAsset &spriteSet = *scene._sprites[timerEntry._spritesIndex];
+
+ spriteSlot._flags = spriteSet.isBackground() ? IMG_DELTA : IMG_UPDATE;
+ spriteSlot._seqIndex = seqIndex;
+ spriteSlot._spritesIndex = timerEntry._spritesIndex;
+ spriteSlot._frameNumber = timerEntry._flipped ? -timerEntry._frameIndex : timerEntry._frameIndex;
+ spriteSlot._depth = timerEntry._depth;
+ spriteSlot._scale = timerEntry._scale;
+
+ if (!timerEntry._nonFixed) {
+ spriteSlot._position = timerEntry._position;
+ } else {
+ MSprite *sprite = spriteSet.getFrame(timerEntry._frameIndex - 1);
+ spriteSlot._position = sprite->_offset;
+ }
+}
+
+bool SequenceList::loadSprites(int seqIndex) {
+ Scene &scene = _vm->_game->_scene;
+ SequenceEntry &seqEntry = _entries[seqIndex];
+ int slotIndex;
+ bool result = false;
+ int idx = -1;
+
+ scene._spriteSlots.deleteTimer(seqIndex);
+ if (seqEntry._doneFlag) {
+ remove(seqIndex);
+ return false;
+ }
+
+ if (seqEntry._spritesIndex == -1) {
+ // Doesn't have an associated sprite anymore, so mark as done
+ seqEntry._doneFlag = true;
+ } else if ((slotIndex = scene._spriteSlots.add()) >= 0) {
+ SpriteSlot &spriteSlot = scene._spriteSlots[slotIndex];
+ setSpriteSlot(seqIndex, spriteSlot);
+
+ if ((seqEntry._flags != 0) || (seqEntry._dynamicHotspotIndex >= 0)) {
+ SpriteAsset &spriteSet = *scene._sprites[seqEntry._spritesIndex];
+ MSprite *frame = spriteSet.getFrame(seqEntry._frameIndex - 1);
+ int width = frame->getWidth() * seqEntry._scale / 200;
+ int height = frame->getHeight() * seqEntry._scale / 100;
+ Common::Point pt = spriteSlot._position;
+
+ // Handle sprite movement, if present
+ if (seqEntry._flags & 1) {
+ seqEntry._posAccum.x += seqEntry._posDiff.x;
+ if (seqEntry._posAccum.x >= 100) {
+ int v = seqEntry._posAccum.x / 100;
+ seqEntry._position.x += v * seqEntry._posSign.x;
+ seqEntry._posAccum.x -= v * 100;
+ }
+
+ seqEntry._posAccum.y += seqEntry._posDiff.y;
+ if (seqEntry._posAccum.y >= 100) {
+ int v = seqEntry._posAccum.y / 100;
+ seqEntry._position.y += v * seqEntry._posSign.y;
+ seqEntry._posAccum.y -= v * 100;
+ }
+ }
+
+ if (seqEntry._flags & 2) {
+ // Check for object having moved off-scren
+ if ((pt.x + width) < 0 || (pt.x + width) >= MADS_SCREEN_WIDTH ||
+ pt.y < 0 || (pt.y - height) >= MADS_SCENE_HEIGHT) {
+ result = true;
+ seqEntry._doneFlag = true;
+ }
+ }
+
+ if (seqEntry._dynamicHotspotIndex >= 0) {
+ DynamicHotspot &dynHotspot = scene._dynamicHotspots[seqEntry._dynamicHotspotIndex];
+
+ dynHotspot._bounds.left = MAX(pt.x - width, 0);
+ dynHotspot._bounds.top = MAX(pt.y - height, 0);
+ dynHotspot._bounds.right = dynHotspot._bounds.left + width;
+ dynHotspot._bounds.bottom = dynHotspot._bounds.top + height;
+
+ scene._dynamicHotspots._changed = true;
+ }
+ }
+
+ // Frame adjustments
+ if (seqEntry._frameStart != seqEntry._numSprites)
+ seqEntry._frameIndex += seqEntry._frameInc;
+
+ if (seqEntry._frameIndex >= seqEntry._frameStart) {
+ if (seqEntry._frameIndex > seqEntry._numSprites) {
+ result = true;
+ if (seqEntry._animType == ANIMTYPE_CYCLED) {
+ // back to the starting frame (cyclic)
+ seqEntry._frameIndex = seqEntry._frameStart;
+ } else {
+ // Switch into reverse mode
+ seqEntry._frameIndex = seqEntry._numSprites - 1;
+ seqEntry._frameInc = -1;
+ }
+ }
+ } else {
+ // Currently in reverse mode and moved past starting frame
+ result = true;
+
+ if (seqEntry._animType == ANIMTYPE_CYCLED)
+ {
+ // Switch back to forward direction again
+ seqEntry._frameIndex = seqEntry._frameStart + 1;
+ seqEntry._frameInc = 1;
+ } else {
+ // Otherwise reset back to last sprite for further reverse animating
+ seqEntry._frameIndex = seqEntry._numSprites;
+ }
+ }
+
+ if (result && (seqEntry._triggerCountdown != 0)) {
+ if (--seqEntry._triggerCountdown == 0)
+ seqEntry._doneFlag = true;
+ }
+ } else {
+ // Out of sprite display slots, so mark entry as done
+ seqEntry._doneFlag = true;
+ }
+
+ for (int i = 0; i < seqEntry._entries._count; ++i) {
+ switch (seqEntry._entries._mode[i]) {
+ case SEQUENCE_TRIGGER_EXPIRE:
+ case SEQUENCE_TRIGGER_LOOP:
+ if (((seqEntry._entries._mode[i] == SEQUENCE_TRIGGER_EXPIRE) && seqEntry._doneFlag) ||
+ ((seqEntry._entries._mode[i] == SEQUENCE_TRIGGER_LOOP) && result))
+ idx = i;
+ break;
+
+ case SEQUENCE_TRIGGER_SPRITE: {
+ int v = seqEntry._entries._frameIndex[i];
+ if ((v == seqEntry._frameIndex) || (v == 0))
+ idx = i;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if (idx >= 0) {
+ _vm->_game->_trigger = seqEntry._entries._trigger[idx];
+ _vm->_game->_triggerMode = seqEntry._triggerMode;
+
+ if (seqEntry._triggerMode != SEQUENCE_TRIGGER_DAEMON)
+ scene._action._activeAction = seqEntry._actionNouns;
+ }
+
+ return result;
+}
+
+/**
+* Handles counting down entries in the timer list for action
+*/
+void SequenceList::tick() {
+ Scene &scene = _vm->_game->_scene;
+ for (uint idx = 0; idx < _entries.size(); ++idx) {
+ if ((_vm->_game->_fx == 0) && (_vm->_game->_trigger != 0))
+ break;
+
+ SequenceEntry &seqEntry = _entries[idx];
+ uint32 currentTimer = scene._frameStartTime;
+
+ if (!seqEntry._active || (currentTimer < seqEntry._timeout))
+ continue;
+
+ // Set the next timeout for the timer entry
+ seqEntry._timeout = currentTimer + seqEntry._numTicks;
+
+ // Action the sprite
+ if (loadSprites(idx)) {
+ seqEntry._timeout += seqEntry._extraTicks;
+ }
+ }
+}
+
+void SequenceList::delay(uint32 priorFrameTime, uint32 currentTime) {
+ for (uint idx = 0; idx < _entries.size(); ++idx) {
+ if (_entries[idx]._active) {
+ _entries[idx]._timeout += currentTime - priorFrameTime;
+ }
+ }
+}
+
+void SequenceList::setAnimRange(int seqIndex, int startVal, int endVal) {
+ Scene &scene = _vm->_game->_scene;
+ SequenceEntry &seqEntry = _entries[seqIndex];
+ SpriteAsset &spriteSet = *scene._sprites[seqEntry._spritesIndex];
+ int numSprites = spriteSet.getCount();
+ int tempStart, tempEnd;
+
+ switch (startVal) {
+ case -2:
+ tempStart = numSprites;
+ break;
+ case -1:
+ tempStart = 1;
+ break;
+ default:
+ tempStart = startVal;
+ break;
+ }
+
+ switch (endVal) {
+ case -2:
+ case 0:
+ tempEnd = numSprites;
+ break;
+ case -1:
+ tempEnd = 1;
+ break;
+ default:
+ tempEnd = endVal;
+ break;
+ }
+
+ seqEntry._frameStart = tempStart;
+ seqEntry._numSprites = tempEnd;
+
+ seqEntry._frameIndex = (seqEntry._frameInc >= 0) ? tempStart : tempEnd;
+}
+
+void SequenceList::scan() {
+ Scene &scene = _vm->_game->_scene;
+
+ for (uint i = 0; i < _entries.size(); ++i) {
+ if (_entries[i]._active && (_entries[i]._spritesIndex != -1)) {
+ int idx = scene._spriteSlots.add();
+ setSpriteSlot(i, scene._spriteSlots[idx]);
+ }
+ }
+}
+
+/**
+* Sets the depth of the specified entry in the sequence list
+*/
+void SequenceList::setDepth(int seqIndex, int depth) {
+ _entries[seqIndex]._depth = depth;
+}
+
+void SequenceList::setPosition(int seqIndex, const Common::Point &pt) {
+ _entries[seqIndex]._position = pt;
+ _entries[seqIndex]._nonFixed = false;
+}
+
+int SequenceList::addSpriteCycle(int srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
+ Scene &scene = _vm->_game->_scene;
+ MSprite *spriteFrame = scene._sprites[srcSpriteIdx]->getFrame(0);
+ int depth = scene._depthSurface.getDepth(Common::Point(
+ spriteFrame->_offset.x + (spriteFrame->w / 2),
+ spriteFrame->_offset.y + (spriteFrame->h / 2)));
+
+ return add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
+ true, 100, depth - 1, 1, ANIMTYPE_CYCLED, 0, 0);
+}
+
+int SequenceList::addReverseSpriteCycle(int srcSpriteIdx, bool flipped, int numTicks,
+ int triggerCountdown, int timeoutTicks, int extraTicks) {
+ Scene &scene = _vm->_game->_scene;
+
+ SpriteAsset *asset = scene._sprites[srcSpriteIdx];
+ MSprite *spriteFrame = asset->getFrame(0);
+ int depth = scene._depthSurface.getDepth(Common::Point(
+ spriteFrame->_offset.x + (spriteFrame->w / 2),
+ spriteFrame->_offset.y + (spriteFrame->h / 2)));
+
+ return add(srcSpriteIdx, flipped, asset->getCount(), triggerCountdown, timeoutTicks, extraTicks,
+ numTicks, 0, 0, true, 100, depth - 1, -1, ANIMTYPE_CYCLED, 0, 0);
+}
+
+
+int SequenceList::startCycle(int srcSpriteIndex, bool flipped, int cycleIndex) {
+ int result = addSpriteCycle(srcSpriteIndex, flipped, INDEFINITE_TIMEOUT, 0, 0, 0);
+ if (result >= 0)
+ setAnimRange(result, cycleIndex, cycleIndex);
+
+ return result;
+}
+
+int SequenceList::startReverseCycle(int srcSpriteIndex, bool flipped, int numTicks,
+ int triggerCountdown, int timeoutTicks, int extraTicks) {
+ SpriteAsset *sprites = _vm->_game->_scene._sprites[srcSpriteIndex];
+ MSprite *frame = sprites->getFrame(0);
+ int depth = _vm->_game->_scene._depthSurface.getDepth(Common::Point(
+ frame->_offset.x + frame->w / 2, frame->_offset.y + frame->h / 2));
+
+ return add(srcSpriteIndex, flipped, 1, triggerCountdown, timeoutTicks, extraTicks,
+ numTicks, 0, 0, true, 100, depth - 1, 1, ANIMTYPE_REVERSIBLE, 0, 0);
+}
+
+void SequenceList::updateTimeout(int spriteIdx, int seqIndex) {
+ Player &player = _vm->_game->_player;
+ int timeout;
+
+ if (spriteIdx >= 0)
+ timeout = _entries[spriteIdx]._timeout;
+ else
+ timeout = player._priorTimer + player._ticksAmount;
+
+ if (seqIndex >= 0)
+ _entries[seqIndex]._timeout = timeout;
+ else
+ player._priorTimer = timeout - player._ticksAmount;
+
+}
+
+void SequenceList::setScale(int spriteIdx, int scale) {
+ _entries[spriteIdx]._scale = scale;
+}
+
+void SequenceList::setMsgLayout(int seqIndex) {
+ Player &player = _vm->_game->_player;
+ int yp = player._playerPos.y + (player._centerOfGravity * player._currentScale) / 100;
+ setPosition(seqIndex, Common::Point(player._playerPos.x, yp));
+ setDepth(seqIndex, player._currentDepth);
+ setScale(seqIndex, player._currentScale);
+ updateTimeout(-1, seqIndex);
+}
+
+void SequenceList::setDone(int seqIndex) {
+ _entries[seqIndex]._doneFlag = true;
+ _entries[seqIndex]._timeout = _vm->_game->_player._priorTimer;
+}
+
+void SequenceList::setMotion(int seqIndex, int flags, int deltaX, int deltaY) {
+ SequenceEntry &se = _entries[seqIndex];
+ se._flags = flags | 1;
+
+ // Set the direction sign for movement
+ if (deltaX > 0) {
+ se._posSign.x = 1;
+ } else if (deltaX < 0) {
+ se._posSign.x = -1;
+ } else {
+ se._posSign.x = 0;
+ }
+
+ if (deltaY > 0) {
+ se._posSign.y = 1;
+ }
+ else if (deltaY < 0) {
+ se._posSign.y = -1;
+ } else {
+ se._posSign.y = 0;
+ }
+
+ se._posDiff.x = ABS(deltaX);
+ se._posDiff.y = ABS(deltaY);
+ se._posAccum.x = se._posAccum.y = 0;
+}
+
+} // End of namespace
diff --git a/engines/mads/sequence.h b/engines/mads/sequence.h
new file mode 100644
index 0000000000..ee587ff02d
--- /dev/null
+++ b/engines/mads/sequence.h
@@ -0,0 +1,131 @@
+/* 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 MADS_SEQUENCE_H
+#define MADS_SEQUENCE_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "mads/action.h"
+
+namespace MADS {
+
+class SpriteSlot;
+
+enum SequenceTrigger {
+ SEQUENCE_TRIGGER_EXPIRE = 0, // Trigger when the sequence finishes
+ SEQUENCE_TRIGGER_LOOP = 1, // Trigger when the sequence loops
+ SEQUENCE_TRIGGER_SPRITE = 2 // Trigger when sequence reaches specific sprite
+};
+
+enum SpriteAnimType { ANIMTYPE_NONE = 0, ANIMTYPE_CYCLED = 1, ANIMTYPE_REVERSIBLE = 2 };
+
+#define SEQUENCE_ENTRY_SUBSET_MAX 5
+
+struct SequenceSubEntries {
+ int _count;
+ SequenceTrigger _mode[SEQUENCE_ENTRY_SUBSET_MAX];
+ int _frameIndex[SEQUENCE_ENTRY_SUBSET_MAX];
+ int _trigger[SEQUENCE_ENTRY_SUBSET_MAX];
+};
+
+struct SequenceEntry {
+ bool _active;
+ int8 _spritesIndex;
+ bool _flipped;
+
+ int _frameIndex;
+ int _frameStart;
+ int _numSprites;
+
+ SpriteAnimType _animType;
+ int _frameInc;
+
+ int _depth;
+ int _scale;
+ int _dynamicHotspotIndex;
+
+ bool _nonFixed;
+ uint32 _flags;
+
+ Common::Point _position;
+ Common::Point _posDiff;
+ Common::Point _posSign;
+ Common::Point _posAccum;
+ int _triggerCountdown;
+ bool _doneFlag;
+ SequenceSubEntries _entries;
+ TriggerMode _triggerMode;
+
+ ActionDetails _actionNouns;
+ int _numTicks;
+ int _extraTicks;
+ uint32 _timeout;
+
+ SequenceEntry();
+};
+
+class MADSEngine;
+
+class SequenceList {
+private:
+ MADSEngine *_vm;
+ Common::Array<SequenceEntry> _entries;
+public:
+ SequenceList(MADSEngine *vm);
+
+ SequenceEntry &operator[](int index) { return _entries[index]; }
+ void clear();
+ bool addSubEntry(int index, SequenceTrigger mode, int frameIndex, int trigger);
+ int add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks,
+ int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, int scale, int depth,
+ int frameInc, SpriteAnimType animType, int numSprites, int frameStart);
+
+ int addTimer(int timeout, int abortVal);
+ void remove(int seqIndex);
+ void setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot);
+ bool loadSprites(int seqIndex);
+ void tick();
+ void delay(uint32 priorFrameTime, uint32 currentTime);
+ void setAnimRange(int seqIndex, int startVal, int endVal);
+ void scan();
+ void setDepth(int seqIndex, int depth);
+ void setPosition(int seqIndex, const Common::Point &pt);
+ int addSpriteCycle(int srcSpriteIdx, bool flipped, int numTicks,
+ int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0);
+ int addReverseSpriteCycle(int srcSpriteIdx, bool flipped, int numTicks,
+ int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0);
+
+ int startCycle(int srcSpriteIdx, bool flipped, int cycleIndex);
+ int startReverseCycle(int srcSpriteIndex, bool flipped, int numTicks,
+ int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0);
+ void updateTimeout(int spriteIdx, int seqIndex);
+ void setScale(int spriteIdx, int scale);
+ void setMsgLayout(int seqIndex);
+ void setDone(int seqIndex);
+ void setMotion(int seqIndex, int flags, int deltaX, int deltaY);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_SEQUENCE_H */
diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp
new file mode 100644
index 0000000000..bd99aed2f4
--- /dev/null
+++ b/engines/mads/sound.cpp
@@ -0,0 +1,142 @@
+/* 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 "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+#include "common/memstream.h"
+#include "mads/sound.h"
+#include "mads/mads.h"
+#include "mads/nebular/sound_nebular.h"
+
+namespace MADS {
+
+SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) {
+ _vm = vm;
+ _mixer = mixer;
+ _driver = nullptr;
+ _pollSoundEnabled = false;
+ _soundPollFlag = false;
+ _newSoundsPaused = false;
+}
+
+SoundManager::~SoundManager() {
+ delete _driver;
+}
+
+void SoundManager::init(int sectionNumber) {
+ assert(sectionNumber > 0 && sectionNumber < 10);
+
+ switch (_vm->getGameID()) {
+ case GType_RexNebular:
+ switch (sectionNumber) {
+ case 1:
+ _driver = new Nebular::ASound1(_mixer);
+ break;
+ case 2:
+ _driver = new Nebular::ASound2(_mixer);
+ break;
+ case 3:
+ _driver = new Nebular::ASound3(_mixer);
+ break;
+ case 4:
+ _driver = new Nebular::ASound4(_mixer);
+ break;
+ case 5:
+ _driver = new Nebular::ASound5(_mixer);
+ break;
+ case 6:
+ _driver = new Nebular::ASound6(_mixer);
+ break;
+ case 7:
+ _driver = new Nebular::ASound7(_mixer);
+ break;
+ case 8:
+ _driver = new Nebular::ASound8(_mixer);
+ break;
+ case 9:
+ error("Sound driver 9 not implemented");
+ default:
+ _driver = nullptr;
+ break;
+ }
+ break;
+
+ default:
+ warning("SoundManager: Unknown game");
+ _driver = nullptr;
+ break;
+ }
+}
+
+void SoundManager::closeDriver() {
+ if (_driver) {
+ command(0);
+ setEnabled(false);
+ stop();
+
+ removeDriver();
+ }
+}
+
+void SoundManager::removeDriver() {
+ delete _driver;
+ _driver = nullptr;
+}
+
+void SoundManager::setEnabled(bool flag) {
+ _pollSoundEnabled = flag;
+ _soundPollFlag = false;
+}
+
+void SoundManager::pauseNewCommands() {
+ _newSoundsPaused = true;
+}
+
+void SoundManager::startQueuedCommands() {
+ _newSoundsPaused = false;
+
+ while (!_queuedCommands.empty()) {
+ int commandId = _queuedCommands.pop();
+ command(commandId);
+ }
+}
+
+void SoundManager::command(int commandId, int param) {
+ if (_newSoundsPaused) {
+ if (_queuedCommands.size() < 8)
+ _queuedCommands.push(commandId);
+ } else if (_driver) {
+ _driver->command(commandId, param);
+ }
+}
+
+void SoundManager::stop() {
+ if (_driver)
+ _driver->stop();
+}
+
+void SoundManager::noise() {
+ if (_driver)
+ _driver->noise();
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/sound.h b/engines/mads/sound.h
new file mode 100644
index 0000000000..9a251f9dd0
--- /dev/null
+++ b/engines/mads/sound.h
@@ -0,0 +1,103 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_SOUND_H
+#define MADS_SOUND_H
+
+#include "common/scummsys.h"
+#include "common/queue.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "mads/nebular/sound_nebular.h"
+
+namespace MADS {
+
+class MADSEngine;
+
+class SoundManager {
+private:
+ MADSEngine *_vm;
+ Audio::Mixer *_mixer;
+ Nebular::ASound *_driver;
+ bool _pollSoundEnabled;
+ bool _soundPollFlag;
+ bool _newSoundsPaused;
+ Common::Queue<int> _queuedCommands;
+public:
+ SoundManager(MADSEngine *vm, Audio::Mixer *mixer);
+ ~SoundManager();
+
+ /**
+ * Initializes the sound driver for a given game section
+ */
+ void init(int sectionNumber);
+
+ /**
+ * Stop any currently active sound and remove the driver
+ */
+ void closeDriver();
+
+ /**
+ * Remove the driver
+ */
+ void removeDriver();
+
+ /**
+ * Sets the enabled status of the sound
+ * @flag True if sound should be enabled
+ */
+ void setEnabled(bool flag);
+
+ /**
+ * Temporarily pause the playback of any new sound commands
+ */
+ void pauseNewCommands();
+
+ /**
+ * Stop queueing sound commands, and execute any previously queued ones
+ */
+ void startQueuedCommands();
+
+ //@{
+ /**
+ * Executes a command on the sound driver
+ * @param commandid Command Id to execute
+ * @param param Optional paramater specific to a few commands
+ */
+ void command(int commandId, int param = 0);
+
+ /**
+ * Stops any currently playing sound
+ */
+ void stop();
+
+ /**
+ * Noise
+ * Some sort of random noise generation?
+ */
+ void noise();
+ //@}
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_SOUND_H */
diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp
new file mode 100644
index 0000000000..a229fccb89
--- /dev/null
+++ b/engines/mads/sprites.cpp
@@ -0,0 +1,417 @@
+/* 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 "common/scummsys.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
+#include "mads/mads.h"
+#include "mads/screen.h"
+#include "mads/msurface.h"
+#include "mads/sprites.h"
+
+namespace MADS {
+
+enum {
+ kEndOfLine = 0,
+ kEndOfSprite = 1,
+ kMarker = 2
+};
+
+#define TRANSPARENT_COLOR_INDEX 0xFF
+
+class DepthEntry {
+public:
+ int depth;
+ int index;
+
+ DepthEntry(int depthAmt, int indexVal) { depth = depthAmt; index = indexVal; }
+};
+
+bool sortHelper(const DepthEntry &entry1, const DepthEntry &entry2) {
+ return entry1.depth < entry2.depth;
+}
+
+typedef Common::List<DepthEntry> DepthList;
+
+/*------------------------------------------------------------------------*/
+
+MSprite::MSprite()
+ : MSurface() {
+}
+
+MSprite::MSprite(Common::SeekableReadStream *source, const Common::Array<RGB6> &palette,
+ const Common::Rect &bounds)
+ : MSurface(bounds.width(), bounds.height()),
+ _offset(Common::Point(bounds.left, bounds.top)) {
+ // Load the sprite data
+ loadSprite(source, palette);
+}
+
+MSprite::~MSprite() {
+}
+
+void MSprite::loadSprite(Common::SeekableReadStream *source,
+ const Common::Array<RGB6> &palette) {
+ byte *outp, *lineStart;
+ bool newLine = false;
+
+ outp = getData();
+ lineStart = getData();
+ int spriteSize = this->w * this->h;
+ byte transIndex = getTransparencyIndex();
+ Common::fill(outp, outp + spriteSize, transIndex);
+
+ for (;;) {
+ byte cmd1, cmd2, count, pixel;
+
+ if (newLine) {
+ outp = lineStart + getWidth();
+ lineStart = outp;
+ newLine = false;
+ }
+
+ cmd1 = source->readByte();
+
+ if (cmd1 == 0xFC)
+ break;
+ else if (cmd1 == 0xFF)
+ newLine = true;
+ else if (cmd1 == 0xFD) {
+ while (!newLine) {
+ count = source->readByte();
+ if (count == 0xFF) {
+ newLine = true;
+ } else {
+ pixel = source->readByte();
+ while (count--)
+ *outp++ = (pixel == 0xFD) ? getTransparencyIndex() : pixel;
+ }
+ }
+ } else {
+ while (!newLine) {
+ cmd2 = source->readByte();
+ if (cmd2 == 0xFF) {
+ newLine = true;
+ } else if (cmd2 == 0xFE) {
+ count = source->readByte();
+ pixel = source->readByte();
+ while (count--)
+ *outp++ = (pixel == 0xFD) ? getTransparencyIndex() : pixel;
+ } else {
+ *outp++ = (cmd2 == 0xFD) ? getTransparencyIndex() : cmd2;
+ }
+ }
+ }
+ }
+
+ // Do a final iteration over the sprite to convert it's pixels to
+ // the final positions in the main palette
+ for (outp = getData(); spriteSize > 0; --spriteSize, ++outp) {
+ if (*outp != transIndex)
+ *outp = palette[*outp]._palIndex;
+ }
+}
+
+byte MSprite::getTransparencyIndex() const {
+ return TRANSPARENT_COLOR_INDEX;
+}
+
+/*------------------------------------------------------------------------*/
+
+MADSEngine *SpriteSlot::_vm = nullptr;
+
+SpriteSlot::SpriteSlot() {
+ _flags = IMG_STATIC;
+ _seqIndex = 0;
+ _spritesIndex = 0;
+ _frameNumber = 0;
+ _depth = 0;
+ _scale = 0;
+}
+
+SpriteSlot::SpriteSlot(SpriteFlags type, int seqIndex) {
+ _flags = type;
+ _seqIndex = seqIndex;
+ _spritesIndex = 0;
+ _frameNumber = 0;
+ _depth = 0;
+ _scale = 0;
+}
+
+bool SpriteSlot::operator==(const SpriteSlotSubset &other) const {
+ return (_spritesIndex == other._spritesIndex) && (_frameNumber == other._frameNumber) &&
+ (_position == other._position) && (_depth == other._depth) &&
+ (_scale == other._scale);
+}
+
+void SpriteSlot::copy(const SpriteSlotSubset &other) {
+ _spritesIndex = other._spritesIndex;
+ _frameNumber = other._frameNumber;
+ _position = other._position;
+ _depth = other._depth;
+ _scale = other._scale;
+}
+
+/*------------------------------------------------------------------------*/
+
+SpriteSlots::SpriteSlots(MADSEngine *vm) : _vm(vm) {
+ SpriteSlot::_vm = vm;
+}
+
+void SpriteSlots::reset(bool flag) {
+ _vm->_game->_scene._textDisplay.reset();
+
+ if (flag)
+ _vm->_game->_scene._sprites.clear();
+
+ Common::Array<SpriteSlot>::clear();
+ push_back(SpriteSlot(IMG_REFRESH, -1));
+}
+
+void SpriteSlots::deleteEntry(int index) {
+ remove_at(index);
+}
+
+void SpriteSlots::setDirtyAreas() {
+ Scene &scene = _vm->_game->_scene;
+
+ for (uint i = 0; i < size(); ++i) {
+ if ((*this)[i]._flags >= IMG_STATIC) {
+ scene._dirtyAreas[i].setSpriteSlot(&(*this)[i]);
+
+ scene._dirtyAreas[i]._textActive = ((*this)[i]._flags <= IMG_STATIC) ? 0 : 1;
+ (*this)[i]._flags = IMG_STATIC;
+ }
+ }
+}
+
+void SpriteSlots::fullRefresh(bool clearAll) {
+ if (clearAll)
+ Common::Array<SpriteSlot>::clear();
+
+ push_back(SpriteSlot(IMG_REFRESH, -1));
+}
+
+void SpriteSlots::deleteTimer(int seqIndex) {
+ for (uint idx = 0; idx < size(); ++idx) {
+ SpriteSlot &slot = (*this)[idx];
+ if (slot._seqIndex == seqIndex) {
+ slot._flags = IMG_ERASE;
+ return;
+ }
+ }
+}
+
+int SpriteSlots::add() {
+ SpriteSlot ss;
+ push_back(ss);
+ return size() - 1;
+}
+
+void SpriteSlots::drawBackground() {
+ Scene &scene = _vm->_game->_scene;
+
+ // Initial draw loop for any active sprites in the background
+ for (uint i = 0; i < size(); ++i) {
+ SpriteSlot &spriteSlot = (*this)[i];
+ DirtyArea &dirtyArea = scene._dirtyAreas[i];
+
+ if (spriteSlot._flags >= IMG_STATIC) {
+ // Foreground sprite, so we can ignore it
+ dirtyArea._active = false;
+ } else {
+ dirtyArea._active = true;
+ dirtyArea.setSpriteSlot(&spriteSlot);
+
+ if (spriteSlot._flags == IMG_DELTA) {
+ // Background object, so need to draw it
+ assert(spriteSlot._frameNumber > 0);
+ SpriteAsset *asset = scene._sprites[spriteSlot._spritesIndex];
+ MSprite *frame = asset->getFrame(spriteSlot._frameNumber - 1);
+
+ Common::Point pt = spriteSlot._position;
+ if (spriteSlot._scale != -1) {
+ // Adjust the drawing position
+ pt.x -= frame->w / 2;
+ pt.y -= frame->h / 2;
+ }
+
+
+ if (spriteSlot._depth <= 1) {
+ frame->copyTo(&scene._backgroundSurface, pt, frame->getTransparencyIndex());
+ } else if (scene._depthStyle == 0) {
+ scene._backgroundSurface.copyFrom(frame, pt, spriteSlot._depth, &scene._depthSurface,
+ 100, frame->getTransparencyIndex());
+ } else {
+ error("Unsupported depth style");
+ }
+ }
+ }
+ }
+
+ // Mark any remaning sprite slot dirty areas as inactive
+ for (uint i = size(); i < SPRITE_SLOTS_MAX_SIZE; ++i)
+ scene._dirtyAreas[i]._active = false;
+
+ // Flag any active text display
+ for (uint i = 0; i < scene._textDisplay.size(); ++i) {
+ TextDisplay &textDisplay = scene._textDisplay[i];
+ DirtyArea &dirtyArea = scene._dirtyAreas[i + SPRITE_SLOTS_MAX_SIZE];
+
+ if (textDisplay._expire >= 0 || !textDisplay._active) {
+ dirtyArea._active = false;
+ } else {
+ dirtyArea._active = true;
+ dirtyArea.setTextDisplay(&textDisplay);
+ }
+ }
+}
+
+void SpriteSlots::drawSprites(MSurface *s) {
+ DepthList depthList;
+ Scene &scene = _vm->_game->_scene;
+
+ // Get a list of sprite object depths for active objects
+ for (uint i = 0; i < size(); ++i) {
+ SpriteSlot &spriteSlot = (*this)[i];
+ if (spriteSlot._flags >= IMG_STATIC) {
+ DepthEntry rec(16 - spriteSlot._depth, i);
+ depthList.push_back(rec);
+ }
+ }
+
+ // Sort the list in order of the depth
+ Common::sort(depthList.begin(), depthList.end(), sortHelper);
+
+ // Loop through each of the objects
+ DepthList::iterator i;
+ for (i = depthList.begin(); i != depthList.end(); ++i) {
+ DepthEntry &de = *i;
+ SpriteSlot &slot = (*this)[de.index];
+ assert(slot._spritesIndex < (int)scene._sprites.size());
+ SpriteAsset &spriteSet = *scene._sprites[slot._spritesIndex];
+
+ // Get the sprite frame
+ int frameNumber = ABS(slot._frameNumber);
+ bool flipped = slot._frameNumber < 0;
+
+ assert(frameNumber > 0);
+ MSprite *sprite = spriteSet.getFrame(frameNumber - 1);
+
+ MSurface *spr = sprite;
+ if (flipped) {
+ // Create a flipped copy of the sprite temporarily
+ spr = sprite->flipHorizontal();
+ }
+
+ if ((slot._scale < 100) && (slot._scale != -1)) {
+ // Minimalized drawing
+ s->copyFrom(spr, slot._position, slot._depth, &scene._depthSurface,
+ slot._scale, sprite->getTransparencyIndex());
+ } else {
+ int xp, yp;
+
+ if (slot._scale == -1) {
+ xp = slot._position.x - scene._posAdjust.x;
+ yp = slot._position.y - scene._posAdjust.y;
+ } else {
+ xp = slot._position.x - (spr->w / 2) - scene._posAdjust.x;
+ yp = slot._position.y - spr->h - scene._posAdjust.y + 1;
+ }
+
+ if (slot._depth > 1) {
+ // Draw the frame with depth processing
+ s->copyFrom(spr, Common::Point(xp, yp), slot._depth, &scene._depthSurface,
+ 100, sprite->getTransparencyIndex());
+ } else {
+ // No depth, so simply draw the image
+ spr->copyTo(s, Common::Point(xp, yp), sprite->getTransparencyIndex());
+ }
+ }
+
+ // Free sprite if it was a flipped one
+ if (flipped)
+ delete spr;
+ }
+}
+
+void SpriteSlots::cleanUp() {
+ for (int i = (int)size() - 1; i >= 0; --i) {
+ if ((*this)[i]._flags < IMG_STATIC)
+ remove_at(i);
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+SpriteSets::~SpriteSets() {
+ clear();
+}
+
+int SpriteSets::add(SpriteAsset *asset, int idx) {
+ if (idx)
+ idx = idx + 49;
+ else
+ idx = size();
+
+ if (idx >= (int)size())
+ resize(idx + 1);
+
+ if ((*this)[idx]) {
+ delete (*this)[idx];
+ } else {
+ ++_assetCount;
+ }
+
+ (*this)[idx] = asset;
+ return idx;
+}
+
+int SpriteSets::addSprites(const Common::String &resName, int flags) {
+ return add(new SpriteAsset(_vm, resName, flags));
+}
+
+void SpriteSets::clear() {
+ for (uint i = 0; i < size(); ++i)
+ delete (*this)[i];
+
+ _assetCount = 0;
+ Common::Array<SpriteAsset *>::clear();
+}
+
+void SpriteSets::remove(int idx) {
+ if (idx >= 0) {
+ if (idx < ((int)size() - 1)) {
+ delete (*this)[idx];
+ (*this)[idx] = nullptr;
+ } else {
+ while (size() > 0 && (*this)[size() - 1] == nullptr) {
+ remove_at(size() - 1);
+ }
+ }
+
+ if (_assetCount > 0)
+ --_assetCount;
+ }
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/sprites.h b/engines/mads/sprites.h
new file mode 100644
index 0000000000..324122e348
--- /dev/null
+++ b/engines/mads/sprites.h
@@ -0,0 +1,239 @@
+/* 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 MADS_SPRITES_H
+#define MADS_SPRITES_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "mads/assets.h"
+#include "mads/msurface.h"
+
+namespace MADS {
+
+enum SpriteFlags {
+ IMG_STATIC = 0, // Item should remain fixed on the screen
+ IMG_UPDATE = 1, // Item needs to be redrawn
+ IMG_ERASE = -1, // Erase image and remove it
+ IMG_REFRESH = -2, // Full refresh
+ IMG_OVERPRINT = -3, // Interface overprint
+ IMG_DELTA = -4, // Delta change
+ IMG_FULL_UPDATE = -5, // Interface refresh
+ IMG_UPDATE_ONLY = -20 // Update the active screen area only
+};
+
+class MADSEngine;
+
+struct BGR8 {
+ uint8 b, g, r;
+};
+
+typedef struct {
+ int32 x; // x position relative to GrBuff(0, 0)
+ int32 y; // y position relative to GrBuff(0, 0)
+ int32 scale_x; // x scale factor (can be negative for reverse draw)
+ int32 scale_y; // y scale factor (can't be negative)
+ uint8* depth_map; // depth code array for destination (doesn't care if srcDepth is 0)
+ BGR8* Pal; // palette for shadow draw (doesn't care if SHADOW bit is not set in Src.encoding)
+ uint8* ICT; // Inverse Color Table (doesn't care if SHADOW bit is not set in Src.encoding)
+ uint8 depth; // depth code for source (0 if no depth processing)
+} DrawRequestX;
+
+typedef struct {
+ uint32 Pack;
+ uint32 Stream;
+ long hot_x;
+ long hot_y;
+ uint32 Width;
+ uint32 Height;
+ uint32 Comp;
+ uint32 Reserved[8];
+ uint8* data;
+} RendCell;
+
+#define SS_HEADER_NUM_FIELDS 14
+struct SpriteSeriesHeader {
+ uint32 header;
+ uint32 size;
+ uint32 packing;
+ uint32 frameRate;
+ uint32 pixSpeed;
+ uint32 maxWidth;
+ uint32 maxHeight;
+ uint32 reserved3;
+ uint32 reserved4;
+ uint32 reserved5;
+ uint32 reserved6;
+ uint32 reserved7;
+ uint32 reserved8;
+ uint32 count;
+};
+
+#define SF_HEADER_NUM_FIELDS 15
+struct SpriteFrameHeader {
+ uint32 pack;
+ uint32 stream;
+ uint32 x;
+ uint32 y;
+ uint32 width;
+ uint32 height;
+ uint32 comp;
+ uint32 reserved1;
+ uint32 reserved2;
+ uint32 reserved3;
+ uint32 reserved4;
+ uint32 reserved5;
+ uint32 reserved6;
+ uint32 reserved7;
+ uint32 reserved8;
+};
+
+class MSprite : public MSurface {
+private:
+ void loadSprite(Common::SeekableReadStream *source, const Common::Array<RGB6> &palette);
+public:
+ MSprite();
+ MSprite(Common::SeekableReadStream *source, const Common::Array<RGB6> &palette,
+ const Common::Rect &bounds);
+ virtual ~MSprite();
+
+ Common::Point _offset;
+
+ byte getTransparencyIndex() const;
+};
+
+class SpriteSlotSubset {
+public:
+ int _spritesIndex;
+ int _frameNumber;
+ Common::Point _position;
+ int _depth;
+ int _scale;
+};
+
+class SpriteSlot : public SpriteSlotSubset {
+private:
+ static MADSEngine *_vm;
+ friend class SpriteSlots;
+public:
+ SpriteFlags _flags;
+ int _seqIndex;
+public:
+ SpriteSlot();
+ SpriteSlot(SpriteFlags type, int seqIndex);
+
+ void setup(int dirtyAreaIndex);
+ bool operator==(const SpriteSlotSubset &other) const;
+ void copy(const SpriteSlotSubset &other);
+};
+
+class SpriteSlots : public Common::Array<SpriteSlot> {
+private:
+ MADSEngine *_vm;
+public:
+ SpriteSlots(MADSEngine *vm);
+
+ /**
+ * Clears any pending slot data and schedules a full screen refresh.
+ * @param flag Also reset sprite list
+ */
+ void reset(bool flag = true);
+
+ /**
+ * Delete a sprite entry
+ * @param index Specifies the index in the array
+ */
+ void deleteEntry(int index);
+
+ /**
+ * Setup dirty areas for the sprite slots
+ */
+ void setDirtyAreas();
+
+ /**
+ * Adds a full screen refresh to the sprite slots
+ */
+ void fullRefresh(bool clearAll = false);
+
+ /**
+ * Delete a timer entry with the given Id
+ */
+ void deleteTimer(int seqIndex);
+
+ /**
+ * Add a new slot entry and return it's index
+ */
+ int add();
+
+ /**
+ * Draw any sprites into the background of the scene
+ */
+ void drawBackground();
+
+ /**
+ * Draw any sprites into the foreground of the scene
+ */
+ void drawSprites(MSurface *s);
+
+ void cleanUp();
+};
+
+class SpriteSets : public Common::Array<SpriteAsset *> {
+private:
+ MADSEngine *_vm;
+public:
+ int _assetCount;
+
+ /**
+ * Constructor
+ */
+ SpriteSets(MADSEngine *vm) : _vm(vm), _assetCount(0) {}
+
+ /**
+ * Destructor
+ */
+ ~SpriteSets();
+
+ /**
+ * Clears the current list, freeing any laoded assets
+ */
+ void clear();
+
+ /**
+ * Add a sprite asset to the list
+ */
+ int add(SpriteAsset *asset, int idx = 0);
+
+ /**
+ * Adds a sprite asset to the list by name
+ */
+ int addSprites(const Common::String &resName, int flags = 0);
+
+ /**
+ * Remove an asset from the list
+ */
+ void remove(int idx);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_SPRITES_H */
diff --git a/engines/mads/staticres.cpp b/engines/mads/staticres.cpp
new file mode 100644
index 0000000000..189e5f72e7
--- /dev/null
+++ b/engines/mads/staticres.cpp
@@ -0,0 +1,58 @@
+/* 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 "common/scummsys.h"
+#include "mads/staticres.h"
+
+namespace MADS {
+
+const char *const kArticleList[9] = {
+ nullptr, "with", "to", "at", "from", "on", "in", "under", "behind"
+};
+
+const char *const kCheatingEnabledDesc[3] = {
+ "CHEATING ENABLED",
+ "(For your convenience).",
+ nullptr
+};
+
+const char *const kLookAroundStr = "Look around";
+const char *const kToStr = "to ";
+const char *const kUseStr = "Use ";
+const char *const kWalkToStr = "Walk to ";
+const char *const kFenceStr = "fence";
+const char *const kOverStr = "over";
+
+const char *const kGameReleaseInfoStr = "ScummVM rev: 8.43 14-Sept-92";
+const char *const kGameReleaseTitleStr = "GAME RELASE VERSION INFO";
+
+const uint32 DEFAULT_VGA_LOW_PALETTE[16] = {
+ 0x000000, 0x0000a8, 0x00a800, 0x00a8a8, 0xa80000, 0xa800a8, 0xa85400, 0xa8a8a8,
+ 0x545454, 0x5454fc, 0x54fc54, 0x54fcfc, 0xfc5454, 0xfc54fc, 0xfcfc54, 0xfcfcfc
+};
+
+const uint32 DEFAULT_VGA_HIGH_PALETTE[16] = {
+ 0x2c402c, 0x2c4030, 0x2c4034, 0x2c403c, 0x2c4040, 0x2c3c40, 0x2c3440, 0x2c3040,
+ 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000
+};
+
+} // End of namespace MADS
diff --git a/engines/mads/staticres.h b/engines/mads/staticres.h
new file mode 100644
index 0000000000..560fd12e67
--- /dev/null
+++ b/engines/mads/staticres.h
@@ -0,0 +1,47 @@
+/* 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 MADS_STATICRES_H
+#define MADS_STATICRES_H
+
+namespace MADS {
+
+extern const char *const kArticleList[9];
+
+extern const char *const kCheatingEnabledDesc[3];
+
+extern const char *const kLookAroundStr;
+extern const char *const kToStr;
+extern const char *const kUseStr;
+extern const char *const kWalkToStr;
+extern const char *const kFenceStr;
+extern const char *const kOverStr;
+
+extern const char *const kGameReleaseInfoStr;
+extern const char *const kGameReleaseTitleStr;
+
+extern const uint32 DEFAULT_VGA_LOW_PALETTE[16];
+extern const uint32 DEFAULT_VGA_HIGH_PALETTE[16];
+
+} // End of namespace MADS
+
+#endif /* MADS_STATICRES_H */
diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp
new file mode 100644
index 0000000000..e410d173d7
--- /dev/null
+++ b/engines/mads/user_interface.cpp
@@ -0,0 +1,1096 @@
+/* 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 "common/scummsys.h"
+#include "mads/mads.h"
+#include "mads/compression.h"
+#include "mads/user_interface.h"
+#include "mads/nebular/game_nebular.h"
+
+namespace MADS {
+
+UISlot::UISlot() {
+ _flags = IMG_STATIC;
+ _segmentId = 0;
+ _spritesIndex = 0;
+ _frameNumber = 0;
+ _width = _height = 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+void UISlots::fullRefresh() {
+ UISlot slot;
+ slot._flags = IMG_REFRESH;
+ slot._segmentId = -1;
+
+ push_back(slot);
+}
+
+void UISlots::add(const Common::Rect &bounds) {
+ assert(size() < 50);
+
+ UISlot ie;
+ ie._flags = IMG_OVERPRINT;
+ ie._segmentId = IMG_TEXT_UPDATE;
+ ie._position = Common::Point(bounds.left, bounds.top);
+ ie._width = bounds.width();
+ ie._height = bounds.height();
+
+ push_back(ie);
+}
+
+void UISlots::add(const AnimFrameEntry &frameEntry) {
+ assert(size() < 50);
+
+ UISlot ie;
+ ie._flags = IMG_UPDATE;
+ ie._segmentId = frameEntry._seqIndex;
+ ie._spritesIndex = frameEntry._spriteSlot._spritesIndex;
+ ie._frameNumber = frameEntry._spriteSlot._frameNumber;
+ ie._position = frameEntry._spriteSlot._position;
+
+ push_back(ie);
+}
+
+void UISlots::draw(bool updateFlag, bool delFlag) {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+ DirtyArea *dirtyAreaPtr = nullptr;
+
+ // Loop through setting up the dirty areas
+ for (uint idx = 0; idx < size(); ++idx) {
+ DirtyArea &dirtyArea = userInterface._dirtyAreas[idx];
+ UISlot &slot = (*this)[idx];
+
+ if (slot._flags >= IMG_STATIC) {
+ dirtyArea._active = false;
+ } else {
+ dirtyArea.setUISlot(&slot);
+ dirtyArea._textActive = true;
+ if (slot._segmentId == IMG_SPINNING_OBJECT && slot._flags == IMG_FULL_UPDATE) {
+ dirtyArea._active = false;
+ dirtyAreaPtr = &dirtyArea;
+ }
+ }
+ }
+
+ userInterface._dirtyAreas.merge(1, userInterface._uiSlots.size());
+ if (dirtyAreaPtr)
+ dirtyAreaPtr->_active = true;
+
+ // Copy parts of the user interface background that need to be erased
+ for (uint idx = 0; idx < size(); ++idx) {
+ DirtyArea &dirtyArea = userInterface._dirtyAreas[idx];
+ UISlot &slot = (*this)[idx];
+
+ if (dirtyArea._active && dirtyArea._bounds.width() > 0
+ && dirtyArea._bounds.height() > 0 && slot._flags > -20) {
+
+ if (slot._flags >= IMG_ERASE) {
+ // Merge area
+ userInterface.mergeFrom(&userInterface._surface, dirtyArea._bounds,
+ Common::Point(dirtyArea._bounds.left, dirtyArea._bounds.top));
+ } else {
+ // Copy area
+ userInterface._surface.copyTo(&userInterface, dirtyArea._bounds,
+ Common::Point(dirtyArea._bounds.left, dirtyArea._bounds.top));
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < size(); ++idx) {
+ DirtyArea &dirtyArea = userInterface._dirtyAreas[idx];
+ UISlot &slot = (*this)[idx];
+
+ int slotType = slot._flags;
+ if (slotType >= IMG_STATIC) {
+ dirtyArea.setUISlot(&slot);
+ if (!updateFlag)
+ slotType &= ~0x40;
+
+ dirtyArea._textActive = slotType > 0;
+ slot._flags &= 0x40;
+ }
+ }
+
+ userInterface._dirtyAreas.merge(1, userInterface._uiSlots.size());
+
+ for (uint idx = 0; idx < size(); ++idx) {
+ DirtyArea *dirtyArea = &userInterface._dirtyAreas[idx];
+ UISlot &slot = (*this)[idx];
+
+ if (slot._flags >= IMG_STATIC && !(slot._flags & 0x40)) {
+ if (!dirtyArea->_active) {
+ do {
+ dirtyArea = dirtyArea->_mergedArea;
+ } while (!dirtyArea->_active);
+ }
+
+ if (dirtyArea->_textActive) {
+ SpriteAsset *asset = scene._sprites[slot._spritesIndex];
+
+ // Get the frame details
+ int frameNumber = ABS(slot._frameNumber);
+ bool flipped = slot._frameNumber < 0;
+
+ if (slot._segmentId == IMG_SPINNING_OBJECT) {
+ MSprite *sprite = asset->getFrame(frameNumber);
+ sprite->copyTo(&userInterface, slot._position,
+ sprite->getTransparencyIndex());
+ } else {
+ MSprite *sprite = asset->getFrame(frameNumber - 1);
+
+ if (flipped) {
+ MSurface *spr = sprite->flipHorizontal();
+ userInterface.mergeFrom(spr, spr->getBounds(), slot._position,
+ sprite->getTransparencyIndex());
+ delete spr;
+ } else {
+ userInterface.mergeFrom(sprite, sprite->getBounds(), slot._position,
+ sprite->getTransparencyIndex());
+ }
+ }
+ }
+ }
+ }
+
+ // Mark areas of the screen surface for updating
+ if (updateFlag) {
+ for (uint idx = 0; idx < size(); ++idx) {
+ DirtyArea &dirtyArea = userInterface._dirtyAreas[idx];
+
+ if (dirtyArea._active && dirtyArea._textActive &&
+ dirtyArea._bounds.width() > 0 && dirtyArea._bounds.height() > 0) {
+ // Flag area of screen as needing update
+ Common::Rect r = dirtyArea._bounds;
+ r.translate(0, scene._interfaceY);
+ _vm->_screen.copyRectToScreen(r);
+ }
+ }
+ }
+
+ // Post-processing to remove slots no longer needed
+ for (int idx = (int)size() - 1; idx >= 0; --idx) {
+ UISlot &slot = (*this)[idx];
+
+ if (slot._flags < IMG_STATIC) {
+ if (delFlag || updateFlag)
+ remove_at(idx);
+ else if (slot._flags > -20)
+ slot._flags -= 20;
+ } else {
+ if (updateFlag)
+ slot._flags &= ~0x40;
+ else
+ slot._flags |= 0x40;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+MADSEngine *Conversation::_vm;
+
+void Conversation::init(MADSEngine *vm) {
+ _vm = vm;
+}
+
+void Conversation::setup(int globalId, ...) {
+ va_list va;
+ va_start(va, globalId);
+
+ // Load the list of conversation quotes
+ _quotes.clear();
+ int quoteId = va_arg(va, int);
+ while (quoteId > 0) {
+ _quotes.push_back(quoteId);
+ quoteId = va_arg(va, int);
+ }
+ va_end(va);
+
+ if (quoteId < 0) {
+ // For an ending value of -1, also initial the bitflags for the global
+ // associated with the conversation entry, which enables all the quote Ids
+ _vm->_game->globals()[globalId] = (int16)0xffff;
+ }
+
+ _globalId = globalId;
+}
+
+void Conversation::set(int quoteId, ...) {
+ _vm->_game->globals()[_globalId] = 0;
+
+ va_list va;
+ va_start(va, quoteId);
+
+ // Loop through handling each quote
+ while (quoteId > 0) {
+ for (uint idx = 0; idx < _quotes.size(); ++idx) {
+ if (_quotes[idx] == quoteId) {
+ // Found index, so set that bit in the global keeping track of conversation state
+ _vm->_game->globals()[_globalId] |= 1 << idx;
+ break;
+ }
+ }
+
+ quoteId = va_arg(va, int);
+ }
+ va_end(va);
+}
+
+int Conversation::read(int quoteId) {
+ uint16 flags = _vm->_game->globals()[_globalId];
+ int count = 0;
+
+ for (uint idx = 0; idx < _quotes.size(); ++idx) {
+ if (flags & (1 << idx))
+ ++count;
+
+ if (_quotes[idx] == quoteId)
+ return flags & (1 << idx);
+ }
+
+ // Could not find it, simply return number of active quotes
+ return count;
+}
+
+void Conversation::write(int quoteId, bool flag) {
+ for (uint idx = 0; idx < _quotes.size(); ++idx) {
+ if (_quotes[idx] == quoteId) {
+ // Found index, so set or clear the flag
+ if (flag) {
+ // Set bit
+ _vm->_game->globals()[_globalId] |= 1 << idx;
+ } else {
+ // Clear bit
+ _vm->_game->globals()[_globalId] &= ~(1 << idx);
+ }
+ return;
+ }
+ }
+}
+
+void Conversation::start() {
+ UserInterface &userInterface = _vm->_game->_scene._userInterface;
+ userInterface.emptyConversationList();
+
+ // Loop through each of the quotes loaded into the conversation
+ for (uint idx = 0; idx < _quotes.size(); ++idx) {
+ // Check whether the given quote is enabled or not
+ if (_vm->_game->globals()[_globalId] & (1 << idx)) {
+ // Quote enabled, so add it to the list of talk selections
+ Common::String msg = _vm->_game->getQuote(_quotes[idx]);
+ userInterface.addConversationMessage(_quotes[idx], msg);
+ }
+ }
+
+ userInterface.setup(kInputConversation);
+}
+
+/*------------------------------------------------------------------------*/
+
+UserInterface::UserInterface(MADSEngine *vm) : _vm(vm), _dirtyAreas(vm),
+ _uiSlots(vm) {
+ _invSpritesIndex = -1;
+ _invFrameNumber = 1;
+ _scrollMilli = 0;
+ _scrollFlag = false;
+ _category = CAT_NONE;
+ _inventoryTopIndex = 0;
+ _selectedInvIndex = -1;
+ _selectedActionIndex = 0;
+ _selectedItemVocabIdx = -1;
+ _scrollbarActive = SCROLLBAR_NONE;
+ _scrollbarOldActive = SCROLLBAR_NONE;
+ _scrollbarStrokeType = SCROLLBAR_NONE;
+ _scrollbarQuickly = false;
+ _scrollbarMilliTime = 0;
+ _scrollbarElevator = _scrollbarOldElevator = 0;
+ _highlightedCommandIndex = -1;
+ _highlightedInvIndex = -1;
+ _highlightedItemVocabIndex = -1;
+ _dirtyAreas.resize(50);
+ _inventoryChanged = false;
+ _noSegmentsActive = 0;
+ _someSegmentsActive = 0;
+ _rectP = nullptr;
+
+ Common::fill(&_categoryIndexes[0], &_categoryIndexes[7], 0);
+
+ // Map the user interface to the bottom of the game's screen surface
+ byte *pData = _vm->_screen.getBasePtr(0, MADS_SCENE_HEIGHT);
+ setPixels(pData, MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
+
+ _surface.setSize(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
+}
+
+void UserInterface::load(const Common::String &resName) {
+ File f(resName);
+ MadsPack madsPack(&f);
+
+ // Load in the palette
+ Common::SeekableReadStream *palStream = madsPack.getItemStream(0);
+
+ uint32 *gamePalP = &_vm->_palette->_palFlags[0];
+ byte *palP = &_vm->_palette->_mainPalette[0];
+
+ for (int i = 0; i < 16; ++i, gamePalP++, palP += 3) {
+ RGB6 rgb;
+ rgb.load(palStream);
+ palP[0] = rgb.r;
+ palP[1] = rgb.g;
+ palP[2] = rgb.b;
+ *gamePalP |= 1;
+ }
+ delete palStream;
+
+ // Read in the surface data
+ Common::SeekableReadStream *pixelsStream = madsPack.getItemStream(1);
+ pixelsStream->read(_surface.getData(), MADS_SCREEN_WIDTH * MADS_INTERFACE_HEIGHT);
+ delete pixelsStream;
+}
+
+void UserInterface::setup(InputMode inputMode) {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_vm->_game->_screenObjects._inputMode != inputMode) {
+ Common::String resName = _vm->_game->_aaName;
+
+ // Strip off any extension
+ const char *p = strchr(resName.c_str(), '.');
+ if (p) {
+ resName = Common::String(resName.c_str(), p);
+ }
+
+ // Add on suffix if necessary
+ if (inputMode != kInputBuildingSentences)
+ resName += "A";
+
+ resName += ".INT";
+
+ load(resName);
+ _surface.copyTo(this);
+ }
+ _vm->_game->_screenObjects._inputMode = inputMode;
+
+ scene._userInterface._uiSlots.clear();
+ scene._userInterface._uiSlots.fullRefresh();
+ _vm->_game->_screenObjects._baseTime = _vm->_events->getFrameCounter();
+ _highlightedCommandIndex = -1;
+ _highlightedItemVocabIndex = -1;
+ _highlightedInvIndex = -1;
+
+ if (_vm->_game->_kernelMode == KERNEL_ACTIVE_CODE)
+ scene._userInterface._uiSlots.draw(false, false);
+
+ scene._action.clear();
+ drawTextElements();
+ loadElements();
+ scene._dynamicHotspots.refresh();
+}
+
+void UserInterface::drawTextElements() {
+ if (_vm->_game->_screenObjects._inputMode) {
+ drawConversationList();
+ } else {
+ // Draw the actions
+ drawActions();
+ drawInventoryList();
+ drawItemVocabList();
+ }
+}
+
+void UserInterface::mergeFrom(MSurface *src, const Common::Rect &srcBounds,
+ const Common::Point &destPos, int transparencyIndex) {
+ // Validation of the rectangle and position
+ int destX = destPos.x, destY = destPos.y;
+ if ((destX >= w) || (destY >= h))
+ return;
+
+ Common::Rect copyRect = srcBounds;
+ if (destX < 0) {
+ copyRect.left += -destX;
+ destX = 0;
+ } else if (destX + copyRect.width() > w) {
+ copyRect.right -= destX + copyRect.width() - w;
+ }
+ if (destY < 0) {
+ copyRect.top += -destY;
+ destY = 0;
+ } else if (destY + copyRect.height() > h) {
+ copyRect.bottom -= destY + copyRect.height() - h;
+ }
+
+ if (!copyRect.isValidRect())
+ return;
+
+ // Copy the specified area
+
+ byte *data = src->getData();
+ byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
+ byte *destPtr = (byte *)this->pixels + (destY * getWidth()) + destX;
+
+ for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
+ // Process each line of the area
+ for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr) {
+ // Check for the range used for the user interface background,
+ // which are the only pixels that can be replaced
+ if ((destPtr[xCtr] >= 8 && destPtr[xCtr] <= 15) && (int)srcPtr[xCtr] != transparencyIndex)
+ destPtr[xCtr] = srcPtr[xCtr];
+ }
+
+ srcPtr += src->getWidth();
+ destPtr += getWidth();
+ }
+}
+
+void UserInterface::drawActions() {
+ for (int idx = 0; idx < 10; ++idx) {
+ writeVocab(CAT_COMMAND, idx);
+ }
+}
+
+void UserInterface::drawInventoryList() {
+ int endIndex = MIN((int)_vm->_game->_objects._inventoryList.size(), _inventoryTopIndex + 5);
+ for (int idx = _inventoryTopIndex; idx < endIndex; ++idx) {
+ writeVocab(CAT_INV_LIST, idx);
+ }
+}
+
+void UserInterface::drawItemVocabList() {
+ if (_selectedInvIndex >= 0) {
+ InventoryObject &io = _vm->_game->_objects[
+ _vm->_game->_objects._inventoryList[_selectedInvIndex]];
+ for (int idx = 0; idx < io._vocabCount; ++idx) {
+ writeVocab(CAT_INV_VOCAB, idx);
+ }
+ }
+}
+
+void UserInterface::drawScrolller() {
+ if (_scrollbarActive)
+ writeVocab(CAT_INV_SCROLLER, _scrollbarActive);
+ writeVocab(CAT_INV_SCROLLER, 4);
+}
+
+void UserInterface::updateInventoryScroller() {
+ ScreenObjects &screenObjects = _vm->_game->_screenObjects;
+ Common::Array<int> &inventoryList = _vm->_game->_objects._inventoryList;
+
+ if (screenObjects._inputMode != kInputBuildingSentences)
+ return;
+
+ _scrollbarActive = SCROLLBAR_NONE;
+
+ if ((screenObjects._category == CAT_INV_SCROLLER) || (screenObjects._category != CAT_INV_SCROLLER
+ && _scrollbarOldActive == SCROLLBAR_ELEVATOR && _vm->_events->_mouseStatusCopy)) {
+ if (_vm->_events->_mouseStatusCopy || _vm->_easyMouse) {
+ if ((_vm->_events->_mouseClicked || (_vm->_easyMouse && !_vm->_events->_mouseStatusCopy))
+ && (screenObjects._category == CAT_INV_SCROLLER))
+ _scrollbarStrokeType = (ScrollbarActive)screenObjects._spotId;
+
+ if (screenObjects._spotId == _scrollbarStrokeType || _scrollbarOldActive == SCROLLBAR_ELEVATOR) {
+ _scrollbarActive = _scrollbarStrokeType;
+ uint32 currentMilli = g_system->getMillis();
+ uint32 timeInc = _scrollbarQuickly ? 100 : 380;
+
+ if (_vm->_events->_mouseStatus && (_scrollbarMilliTime + timeInc) <= currentMilli) {
+ _scrollbarQuickly = _vm->_events->_vD2 < 1;
+ _scrollbarMilliTime = currentMilli;
+
+ switch (_scrollbarStrokeType) {
+ case SCROLLBAR_UP:
+ // Scroll up
+ if (_inventoryTopIndex > 0 && inventoryList.size() > 0) {
+ --_inventoryTopIndex;
+ _inventoryChanged = true;
+ }
+ break;
+
+ case SCROLLBAR_DOWN:
+ // Scroll down
+ if (_inventoryTopIndex < ((int)inventoryList.size() - 1) && inventoryList.size() > 1) {
+ ++_inventoryTopIndex;
+ _inventoryChanged = true;
+ }
+ break;
+
+ case SCROLLBAR_ELEVATOR: {
+ // Inventory slider
+ int newIndex = CLIP((int)_vm->_events->currentPos().y - 170, 0, 17)
+ * inventoryList.size() / 10;
+ if (newIndex >= (int)inventoryList.size())
+ newIndex = inventoryList.size() - 1;
+
+ if (inventoryList.size() > 0) {
+ _inventoryChanged = newIndex != _inventoryTopIndex;
+ _inventoryTopIndex = newIndex;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (_inventoryChanged) {
+ int dummy;
+ updateSelection(CAT_INV_LIST, 0, &dummy);
+ }
+ }
+ }
+ }
+ }
+
+ if (_scrollbarActive != _scrollbarOldActive || _scrollbarElevator != _scrollbarOldElevator)
+ scrollbarChanged();
+
+ _scrollbarOldActive = _scrollbarActive;
+ _scrollbarOldElevator = _scrollbarElevator;
+}
+
+void UserInterface::scrollbarChanged() {
+ Common::Rect r(73, 4, 73 + 9, 4 + 38);
+ _uiSlots.add(r);
+ _uiSlots.draw(false, false);
+ drawScrolller();
+ updateRect(r);
+}
+
+void UserInterface::writeVocab(ScrCategory category, int id) {
+ Common::Rect bounds;
+ if (!getBounds(category, id, bounds))
+ return;
+
+ Scene &scene = _vm->_game->_scene;
+ Font *font = nullptr;
+
+ int vocabId;
+ Common::String vocabStr;
+ switch (category) {
+ case CAT_COMMAND:
+ font = _vm->_font->getFont(FONT_INTERFACE);
+ vocabId = scene._verbList[id]._id;
+ if (id == _highlightedCommandIndex) {
+ _vm->_font->setColorMode(SELMODE_HIGHLIGHTED);
+ } else {
+ _vm->_font->setColorMode(id == _selectedActionIndex ? SELMODE_SELECTED : SELMODE_UNSELECTED);
+ }
+ vocabStr = scene.getVocab(vocabId);
+ vocabStr.setChar(toupper(vocabStr[0]), 0);
+ font->writeString(this, vocabStr, Common::Point(bounds.left, bounds.top));
+ break;
+
+ case CAT_INV_LIST:
+ font = _vm->_font->getFont(FONT_INTERFACE);
+ vocabId = _vm->_game->_objects.getItem(id)._descId;
+ if (id == _highlightedInvIndex) {
+ _vm->_font->setColorMode(SELMODE_HIGHLIGHTED);
+ } else {
+ _vm->_font->setColorMode(id == _selectedInvIndex ? SELMODE_SELECTED : SELMODE_UNSELECTED);
+ }
+
+ vocabStr = scene.getVocab(vocabId);
+ vocabStr.setChar(toupper(vocabStr[0]), 0);
+ font->writeString(this, vocabStr, Common::Point(bounds.left, bounds.top));
+ break;
+
+ case CAT_TALK_ENTRY:
+ font = _vm->_font->getFont(FONT_INTERFACE);
+ font->setColorMode(id == _highlightedCommandIndex ? SELMODE_HIGHLIGHTED : SELMODE_UNSELECTED);
+ font->writeString(this, _talkStrings[id], Common::Point(bounds.left, bounds.top));
+ break;
+
+ case CAT_INV_SCROLLER:
+ font = _vm->_font->getFont(FONT_MISC);
+
+ switch (id) {
+ case 1:
+ vocabStr = "a";
+ break;
+ case 2:
+ vocabStr = "b";
+ break;
+ case 3:
+ vocabStr = "d";
+ break;
+ case 4:
+ vocabStr = "c";
+ break;
+ default:
+ break;
+ }
+
+ font->setColorMode((id == 4) || (_scrollbarActive == SCROLLBAR_ELEVATOR) ?
+ SELMODE_HIGHLIGHTED : SELMODE_UNSELECTED);
+ font->writeString(this, vocabStr, Common::Point(bounds.left, bounds.top));
+ break;
+ default:
+ // Item specific verbs
+ font = _vm->_font->getFont(FONT_INTERFACE);
+ vocabId = _vm->_game->_objects.getItem(_selectedInvIndex)._vocabList[id]._vocabId;
+ if (id == _highlightedItemVocabIndex) {
+ _vm->_font->setColorMode(SELMODE_HIGHLIGHTED);
+ } else {
+ _vm->_font->setColorMode(id == _selectedInvIndex ? SELMODE_SELECTED : SELMODE_UNSELECTED);
+ vocabStr = scene.getVocab(vocabId);
+ vocabStr.setChar(toupper(vocabStr[0]), 0);
+ font->writeString(this, vocabStr, Common::Point(bounds.left, bounds.top));
+ break;
+ }
+ break;
+ }
+}
+
+void UserInterface::loadElements() {
+ Scene &scene = _vm->_game->_scene;
+ Common::Rect bounds;
+ _vm->_game->_screenObjects.clear();
+
+ if (_vm->_game->_screenObjects._inputMode == kInputBuildingSentences) {
+ // Set up screen objects for the inventory scroller
+ for (int idx = 1; idx <= 3; ++idx) {
+ getBounds(CAT_INV_SCROLLER, idx, bounds);
+ moveRect(bounds);
+
+ _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_SCROLLER, idx);
+ }
+
+ // Set up actions
+ _categoryIndexes[CAT_COMMAND - 1] = _vm->_game->_screenObjects.size() + 1;
+ for (int idx = 0; idx < 10; ++idx) {
+ getBounds(CAT_COMMAND, idx, bounds);
+ moveRect(bounds);
+
+ _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_COMMAND, idx);
+ }
+
+ // Set up inventory list
+ _categoryIndexes[CAT_INV_LIST - 1] = _vm->_game->_screenObjects.size() + 1;
+ for (int idx = 0; idx < 5; ++idx) {
+ getBounds(CAT_INV_LIST, idx, bounds);
+ moveRect(bounds);
+
+ _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_LIST, idx);
+ }
+
+ // Set up the inventory vocab list
+ _categoryIndexes[CAT_INV_VOCAB - 1] = _vm->_game->_screenObjects.size() + 1;
+ for (int idx = 0; idx < 5; ++idx) {
+ getBounds(CAT_INV_VOCAB, idx, bounds);
+ moveRect(bounds);
+
+ _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_VOCAB, idx);
+ }
+
+ // Set up the inventory item picture
+ _categoryIndexes[CAT_INV_ANIM - 1] = _vm->_game->_screenObjects.size() + 1;
+ _vm->_game->_screenObjects.add(Common::Rect(160, 159, 231, 194), LAYER_GUI,
+ CAT_INV_ANIM, 0);
+ }
+
+ if (_vm->_game->_screenObjects._inputMode == kInputBuildingSentences ||
+ _vm->_game->_screenObjects._inputMode == kInputLimitedSentences) {
+ _categoryIndexes[CAT_HOTSPOT - 1] = _vm->_game->_screenObjects.size() + 1;
+ for (int hotspotIdx = scene._hotspots.size() - 1; hotspotIdx >= 0; --hotspotIdx) {
+ Hotspot &hs = scene._hotspots[hotspotIdx];
+ _vm->_game->_screenObjects.add(hs._bounds, LAYER_GUI, CAT_HOTSPOT, hotspotIdx);
+ }
+ }
+
+ if (_vm->_game->_screenObjects._inputMode == kInputConversation) {
+ // setup areas for talk entries
+ _categoryIndexes[CAT_TALK_ENTRY - 1] = _vm->_game->_screenObjects.size() + 1;
+ for (int idx = 0; idx < 5; ++idx) {
+ getBounds(CAT_TALK_ENTRY, idx, bounds);
+ moveRect(bounds);
+
+ _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_TALK_ENTRY, idx);
+ }
+ }
+
+ // Store the number of UI elements loaded for easy nuking/refreshing hotspots added later
+ _vm->_game->_screenObjects._uiCount = _vm->_game->_screenObjects.size();
+}
+
+bool UserInterface::getBounds(ScrCategory category, int v, Common::Rect &bounds) {
+ int heightMultiplier, widthMultiplier;
+ int leftStart, yOffset, widthAmt;
+
+ switch (category) {
+ case CAT_COMMAND:
+ heightMultiplier = v % 5;
+ widthMultiplier = v / 5;
+ leftStart = 2;
+ yOffset = 3;
+ widthAmt = 32;
+ break;
+
+ case CAT_INV_LIST:
+ if (v < _inventoryTopIndex || v >= (_inventoryTopIndex + 5))
+ return false;
+
+ heightMultiplier = v - _inventoryTopIndex;
+ widthMultiplier = 0;
+ leftStart = 90;
+ yOffset = 3;
+ widthAmt = 69;
+ break;
+
+ case CAT_TALK_ENTRY:
+ heightMultiplier = v;
+ widthMultiplier = 0;
+ leftStart = 2;
+ yOffset = 3;
+ widthAmt = 310;
+ break;
+
+ case CAT_INV_SCROLLER:
+ heightMultiplier = 0;
+ widthMultiplier = 0;
+ yOffset = 0;
+ widthAmt = 9;
+ leftStart = (v != 73) ? 73 : 75;
+ break;
+
+ default:
+ heightMultiplier = v;
+ widthMultiplier = 0;
+ leftStart = 240;
+ yOffset = 3;
+ widthAmt = 80;
+ break;
+ }
+
+ bounds.left = (widthMultiplier > 0) ? widthMultiplier * widthAmt + leftStart : leftStart;
+ bounds.setWidth(widthAmt);
+ bounds.top = heightMultiplier * 8 + yOffset;
+ bounds.setHeight(8);
+
+ if (category == CAT_INV_SCROLLER) {
+ switch (v) {
+ case SCROLLBAR_UP:
+ // Arrow up
+ bounds.top = 4;
+ bounds.setHeight(7);
+ break;
+ case SCROLLBAR_DOWN:
+ // Arrow down
+ bounds.top = 35;
+ bounds.setHeight(7);
+ break;
+ case SCROLLBAR_ELEVATOR:
+ // Scroller
+ bounds.top = 12;
+ bounds.setHeight(22);
+ break;
+ case SCROLLBAR_THUMB:
+ // Thumb
+ bounds.top = _scrollbarElevator + 14;
+ bounds.setHeight(1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+void UserInterface::moveRect(Common::Rect &bounds) {
+ bounds.translate(0, MADS_SCENE_HEIGHT);
+}
+
+void UserInterface::drawConversationList() {
+ for (uint idx = 0; idx < _talkStrings.size(); ++idx) {
+ writeVocab(CAT_TALK_ENTRY, idx);
+ }
+}
+
+void UserInterface::emptyConversationList() {
+ _talkStrings.clear();
+ _talkIds.clear();
+}
+
+void UserInterface::addConversationMessage(int vocabId, const Common::String &msg) {
+ assert(_talkStrings.size() < 5);
+
+ _talkStrings.push_back(msg);
+ _talkIds.push_back(vocabId);
+}
+
+void UserInterface::loadInventoryAnim(int objectId) {
+ Scene &scene = _vm->_game->_scene;
+ noInventoryAnim();
+
+ if (_vm->_invObjectsAnimated) {
+ Common::String resName = Common::String::format("*OB%.3dI", objectId);
+ SpriteAsset *asset = new SpriteAsset(_vm, resName, 8);
+ _invSpritesIndex = scene._sprites.add(asset, 1);
+ if (_invSpritesIndex >= 0) {
+ _invFrameNumber = 1;
+ }
+ }
+}
+
+void UserInterface::noInventoryAnim() {
+ Scene &scene = _vm->_game->_scene;
+
+ if (_invSpritesIndex >= 0) {
+ scene._sprites.remove(_invSpritesIndex);
+ _vm->_game->_screenObjects._baseTime = _vm->_events->getFrameCounter();
+ _invSpritesIndex = -1;
+ }
+
+ if (_vm->_game->_screenObjects._inputMode == kInputBuildingSentences)
+ refresh();
+}
+
+void UserInterface::refresh() {
+ _uiSlots.clear();
+ _uiSlots.fullRefresh();
+ _uiSlots.draw(false, false);
+
+ drawTextElements();
+}
+
+void UserInterface::inventoryAnim() {
+ Scene &scene = _vm->_game->_scene;
+ if (_vm->_game->_screenObjects._inputMode == kInputConversation ||
+ _vm->_game->_screenObjects._inputMode == kInputLimitedSentences ||
+ _invSpritesIndex < 0)
+ return;
+
+ // Move to the next frame number in the sequence, resetting if at the end
+ SpriteAsset *asset = scene._sprites[_invSpritesIndex];
+ if (++_invFrameNumber > asset->getCount())
+ _invFrameNumber = 1;
+
+ // Loop through the slots list for inventory animation entry
+ for (uint i = 0; i < _uiSlots.size(); ++i) {
+ if (_uiSlots[i]._segmentId == IMG_SPINNING_OBJECT)
+ _uiSlots[i]._flags = IMG_FULL_UPDATE;
+ }
+
+ // Add a new slot entry for the inventory animation
+ UISlot slot;
+ slot._flags = IMG_UPDATE;
+ slot._segmentId = IMG_SPINNING_OBJECT;
+ slot._frameNumber = _invFrameNumber;
+ slot._spritesIndex = _invSpritesIndex;
+ slot._position = Common::Point(160, 3);
+
+ _uiSlots.push_back(slot);
+}
+
+void UserInterface::doBackgroundAnimation() {
+ Scene &scene = _vm->_game->_scene;
+ Common::Array<AnimUIEntry> &uiEntries = scene._animationData->_uiEntries;
+ Common::Array<AnimFrameEntry> &frameEntries = scene._animationData->_frameEntries;
+
+ _noSegmentsActive = !_someSegmentsActive;
+ _someSegmentsActive = false;
+
+ for (int idx = 0; idx < (int)uiEntries.size(); ++idx) {
+ AnimUIEntry &uiEntry = uiEntries[idx];
+
+ if (uiEntry._counter < 0) {
+ if (uiEntry._counter == -1) {
+ int probabilityRandom = _vm->getRandomNumber(1, 30000);
+ int probability = uiEntry._probability;
+ if (uiEntry._probability > 30000) {
+ if (_noSegmentsActive) {
+ probability -= 30000;
+ } else {
+ probability = -1;
+ }
+ }
+ if (probabilityRandom <= probability) {
+ uiEntry._counter = uiEntry._firstImage;
+ _someSegmentsActive = true;
+ }
+ } else {
+ uiEntry._counter = uiEntry._firstImage;
+ _someSegmentsActive = true;
+ }
+ } else {
+ for (int idx2 = 0; idx2 < ANIM_SPAWN_COUNT; idx2++) {
+ if (uiEntry._spawnFrame[idx2] == (uiEntry._counter - uiEntry._firstImage)) {
+ int tempIndex = uiEntry._spawn[idx2];
+ if (idx >= tempIndex) {
+ uiEntries[tempIndex]._counter = uiEntries[tempIndex]._firstImage;
+ } else {
+ uiEntries[tempIndex]._counter = -2;
+ }
+ _someSegmentsActive = true;
+ }
+ }
+
+ ++uiEntry._counter;
+ if (uiEntry._counter > uiEntry._lastImage) {
+ uiEntry._counter = -1;
+ } else {
+ _someSegmentsActive = true;
+ }
+ }
+ }
+
+ for (uint idx = 0; idx < uiEntries.size(); ++idx) {
+ int imgScan = uiEntries[idx]._counter;
+ if (imgScan >= 0) {
+ _uiSlots.add(frameEntries[imgScan]);
+ }
+ }
+}
+
+void UserInterface::categoryChanged() {
+ _highlightedInvIndex = -1;
+ _vm->_events->initVars();
+ _category = CAT_NONE;
+}
+
+void UserInterface::selectObject(int invIndex) {
+ if (_selectedInvIndex != invIndex || _inventoryChanged) {
+ int oldVocabCount = _selectedInvIndex < 0 ? 0 : _vm->_game->_objects.getItem(_selectedInvIndex)._vocabCount;
+ int newVocabCount = invIndex < 0 ? 0 : _vm->_game->_objects.getItem(invIndex)._vocabCount;
+ int maxVocab = MAX(oldVocabCount, newVocabCount);
+
+ updateSelection(CAT_INV_LIST, invIndex, &_selectedInvIndex);
+ _highlightedItemVocabIndex = -1;
+ _selectedItemVocabIdx = -1;
+
+ if (maxVocab) {
+ assert(_uiSlots.size() < 50);
+ int vocabHeight = maxVocab * 8;
+
+ Common::Rect bounds(240, 3, 240 + 80, 3 + vocabHeight);
+ _uiSlots.add(bounds);
+ _uiSlots.draw(false, false);
+ drawItemVocabList();
+ updateRect(bounds);
+ }
+ }
+
+ if (invIndex == -1) {
+ noInventoryAnim();
+ } else {
+ loadInventoryAnim(_vm->_game->_objects._inventoryList[invIndex]);
+ _vm->_palette->setPalette(_vm->_palette->_mainPalette, 7, 1);
+ _vm->_palette->setPalette(_vm->_palette->_mainPalette, 246, 2);
+ }
+}
+
+void UserInterface::updateSelection(ScrCategory category, int newIndex, int *idx) {
+ Game &game = *_vm->_game;
+ Common::Array<int> &invList = game._objects._inventoryList;
+ Common::Rect bounds;
+
+ if (category == CAT_INV_LIST && _inventoryChanged) {
+ *idx = newIndex;
+ bounds = Common::Rect(90, 3, 90 + 69, 3 + 40);
+ _uiSlots.add(bounds);
+ _uiSlots.draw(false, false);
+ drawInventoryList();
+ updateRect(bounds);
+ _inventoryChanged = false;
+
+ if (invList.size() < 2) {
+ _scrollbarElevator = 0;
+ } else {
+ int v = _inventoryTopIndex * 18 / (invList.size() - 1);
+ _scrollbarElevator = MIN(v, 17);
+ }
+ } else {
+ int oldIndex = *idx;
+ *idx = newIndex;
+
+ if (oldIndex >= 0) {
+ writeVocab(category, oldIndex);
+
+ if (getBounds(category, oldIndex, bounds))
+ updateRect(bounds);
+ }
+
+ if (newIndex >= 0) {
+ writeVocab(category, newIndex);
+
+ if (getBounds(category, newIndex, bounds))
+ updateRect(bounds);
+ }
+ }
+}
+
+void UserInterface::updateRect(const Common::Rect &bounds) {
+ Common::Rect r = bounds;
+ r.translate(0, MADS_SCENE_HEIGHT);
+ _vm->_screen.copyRectToScreen(r);
+}
+
+void UserInterface::scrollerChanged() {
+ warning("TODO: scrollerChanged");
+}
+
+void UserInterface::scrollInventory() {
+ Common::Array<int> &invList = _vm->_game->_objects._inventoryList;
+
+ if (_vm->_events->_mouseButtons) {
+ int yp = _vm->_events->currentPos().y;
+ if (yp < MADS_SCENE_HEIGHT || yp == (MADS_SCREEN_HEIGHT - 1)) {
+ uint32 timeDiff = _scrollFlag ? 100 : 380;
+ uint32 currentMilli = g_system->getMillis();
+ _vm->_game->_screenObjects._v8332A = -1;
+
+ if (currentMilli >= (_scrollMilli + timeDiff)) {
+ _scrollMilli = currentMilli;
+ _scrollFlag = true;
+
+ if (yp == (MADS_SCREEN_HEIGHT - 1)) {
+ if (_inventoryTopIndex < ((int)invList.size() - 1)) {
+ ++_inventoryTopIndex;
+ _inventoryChanged = true;
+ }
+ } else {
+ if (_inventoryTopIndex > 0) {
+ --_inventoryTopIndex;
+ _inventoryChanged = true;
+ }
+ }
+ }
+ }
+ }
+
+ _vm->_game->_screenObjects._v8332A = 0;
+}
+
+void UserInterface::synchronize(Common::Serializer &s) {
+ InventoryObjects &invObjects = _vm->_game->_objects;
+
+ if (s.isLoading()) {
+ _selectedInvIndex = invObjects._inventoryList.empty() ? -1 : 0;
+ }
+
+ for (int i = 0; i < 8; ++i)
+ s.syncAsSint16LE(_categoryIndexes[i]);
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h
new file mode 100644
index 0000000000..827fa3041f
--- /dev/null
+++ b/engines/mads/user_interface.h
@@ -0,0 +1,306 @@
+/* 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 MADS_USER_INTERFACE_H
+#define MADS_USER_INTERFACE_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+#include "common/str.h"
+#include "mads/msurface.h"
+#include "mads/screen.h"
+
+namespace MADS {
+
+enum { IMG_SPINNING_OBJECT = 200, IMG_TEXT_UPDATE = 201 };
+
+enum ScrollbarActive {
+ SCROLLBAR_NONE = 0, // No state
+ SCROLLBAR_UP = 1, // Up butotn
+ SCROLLBAR_DOWN = 2, // Down button
+ SCROLLBAR_ELEVATOR = 3, // Elevator bar
+ SCROLLBAR_THUMB = 4 // Scrollbar thumb
+};
+
+class AnimFrameEntry;
+class MADSEngine;
+
+class UISlot {
+public:
+ int _flags;
+ int _segmentId;
+ int _spritesIndex;
+ int _frameNumber;
+ Common::Point _position;
+
+ // Only used for IMG_OVERPRINT
+ int _width;
+ int _height;
+
+ UISlot();
+};
+
+/**
+ * Sprite list for the user interface
+ */
+class UISlots : public Common::Array<UISlot> {
+private:
+ MADSEngine *_vm;
+public:
+ /**
+ * Constructor
+ */
+ UISlots(MADSEngine *vm) : _vm(vm) {}
+
+ /**
+ * Add an overprint (text) entry to the list
+ */
+ void add(const Common::Rect &bounds);
+
+ /**
+ * Loads the data from an aimation frame entry
+ */
+ void add(const AnimFrameEntry &frameEntry);
+
+ /**
+ * Adds a special entry for full refresh of the user interface
+ */
+ void fullRefresh();
+
+ /**
+ * Draw all the sprites in the list on the user interface.
+ * @param updateFlag Flag drawn areas to be updated on physical screen
+ * @param delFlag Controls how used slots are deleted after drawing
+ */
+ void draw(bool updateFlag, bool delFlag);
+};
+
+class Conversation {
+private:
+ static MADSEngine *_vm;
+public:
+ static void init(MADSEngine *vm);
+public:
+ int _globalId;
+ Common::Array<int> _quotes;
+
+ /**
+ * Set up a conversation sequence
+ */
+ void setup(int globalId, ...);
+
+ /**
+ * Activates the passed set of quotes in the given conversation node
+ */
+ void set(int quoteId, ...);
+
+ /**
+ * Returns the bit for a given quote to indicate whether it's active or not or,
+ * if 0 is passed, returns the number of currently active quotes
+ */
+ int read(int quoteId);
+
+ /**
+ * Activates or deactivates the specified quote in the given conversation node
+ */
+ void write(int quoteId, bool flag);
+
+ /**
+ * Starts the conversation
+ */
+ void start();
+};
+
+class UserInterface : public MSurface {
+ friend class UISlots;
+private:
+ MADSEngine *_vm;
+ int _invSpritesIndex;
+ int _invFrameNumber;
+ uint32 _scrollMilli;
+ bool _scrollFlag;
+ int _noSegmentsActive;
+ int _someSegmentsActive;
+ ScrollbarActive _scrollbarStrokeType;
+
+ /**
+ * Loads the elements of the user interface
+ */
+ void loadElements();
+
+ /**
+ * Returns the area within the user interface a given element falls
+ */
+ bool getBounds(ScrCategory category, int invIndex, Common::Rect &bounds);
+
+ /**
+ * Reposition a bounding rectangle to physical co-ordinates
+ */
+ void moveRect(Common::Rect &bounds);
+
+ /**
+ * Draw options during a conversation.
+ */
+ void drawConversationList();
+
+ /**
+ * Draw the action list
+ */
+ void drawActions();
+
+ /**
+ * Draw the inventory list
+ */
+ void drawInventoryList();
+
+ /**
+ * Draw the inventory item vocab list
+ */
+ void drawItemVocabList();
+
+ /**
+ * Draw the inventory scroller
+ */
+ void drawScrolller();
+
+ /**
+ * Called when the inventory scrollbar has changed
+ */
+ void scrollbarChanged();
+
+ /**
+ * Draw a UI textual element
+ */
+ void writeVocab(ScrCategory category, int id);
+
+ void refresh();
+
+ void updateRect(const Common::Rect &bounds);
+public:
+ MSurface _surface;
+ UISlots _uiSlots;
+ DirtyAreas _dirtyAreas;
+ ScrCategory _category;
+ Common::Rect *_rectP;
+ int _inventoryTopIndex;
+ int _selectedInvIndex;
+ int _selectedActionIndex;
+ int _selectedItemVocabIdx;
+ ScrollbarActive _scrollbarActive, _scrollbarOldActive;
+ int _highlightedCommandIndex;
+ int _highlightedInvIndex;
+ int _highlightedItemVocabIndex;
+ bool _inventoryChanged;
+ int _categoryIndexes[8];
+ Common::StringArray _talkStrings;
+ Common::Array<int> _talkIds;
+ bool _scrollbarQuickly;
+ uint32 _scrollbarMilliTime;
+ int _scrollbarElevator, _scrollbarOldElevator;
+public:
+ /**
+ * Constructor
+ */
+ UserInterface(MADSEngine *vm);
+
+ /**
+ * Loads an interface from a specified resource
+ */
+ void load(const Common::String &resName);
+
+ /**
+ * Set up the interface
+ */
+ void setup(InputMode inputMode);
+
+ void drawTextElements();
+
+ /**
+ * Merges a sub-section of another surface into the user interface without
+ * destroying any on-screen text
+ * @param src Source surface
+ * @param srcBounds Area to copy/merge from
+ * @param destPos Destination position to draw in current surface
+ * @param transparencyIndex Transparency color
+ */
+ void mergeFrom(MSurface *src, const Common::Rect &srcBounds, const Common::Point &destPos,
+ int transparencyIndex = -1);
+
+ /**
+ * Loads the animation sprite data for a given inventory object
+ */
+ void loadInventoryAnim(int objectId);
+
+ /**
+ * Resets the inventory animation when no inventory item is selected
+ */
+ void noInventoryAnim();
+
+ /**
+ * Handles any animation that occurs in the background of the user interface
+ */
+ void doBackgroundAnimation();
+
+ /**
+ * Handles queuing a new frame of an inventory animation for drawing
+ */
+ void inventoryAnim();
+
+ void categoryChanged();
+
+ /**
+ * Select an item from the inventory list
+ * @param invIndex Index in the inventory list of the item to select
+ */
+ void selectObject(int invIndex);
+
+ void updateSelection(ScrCategory category, int newIndex, int *idx);
+
+ void scrollerChanged();
+
+ void scrollInventory();
+
+ /**
+ * Checks for the mouse being on the user interface inventory scroller,
+ * and update the scroller highlight and selected inventory object as necessary
+ */
+ void updateInventoryScroller();
+
+ /**
+ * Empties the current conversation talk list
+ */
+ void emptyConversationList();
+
+ /**
+ * Add a msesage to the list of conversation items to select from
+ */
+ void addConversationMessage(int vocabId, const Common::String &msg);
+
+ /**
+ * Synchronize the data
+ */
+ void synchronize(Common::Serializer &s);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_USER_INTERFACE_H */
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 2e83eb3328..d49f3e8637 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -49,20 +49,20 @@ namespace Mohawk {
#ifdef ENABLE_MYST
MystConsole::MystConsole(MohawkEngine_Myst *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("changeCard", WRAP_METHOD(MystConsole, Cmd_ChangeCard));
- DCmd_Register("curCard", WRAP_METHOD(MystConsole, Cmd_CurCard));
- DCmd_Register("var", WRAP_METHOD(MystConsole, Cmd_Var));
- DCmd_Register("curStack", WRAP_METHOD(MystConsole, Cmd_CurStack));
- DCmd_Register("changeStack", WRAP_METHOD(MystConsole, Cmd_ChangeStack));
- DCmd_Register("drawImage", WRAP_METHOD(MystConsole, Cmd_DrawImage));
- DCmd_Register("drawRect", WRAP_METHOD(MystConsole, Cmd_DrawRect));
- DCmd_Register("setResourceEnable", WRAP_METHOD(MystConsole, Cmd_SetResourceEnable));
- DCmd_Register("playSound", WRAP_METHOD(MystConsole, Cmd_PlaySound));
- DCmd_Register("stopSound", WRAP_METHOD(MystConsole, Cmd_StopSound));
- DCmd_Register("playMovie", WRAP_METHOD(MystConsole, Cmd_PlayMovie));
- DCmd_Register("disableInitOpcodes", WRAP_METHOD(MystConsole, Cmd_DisableInitOpcodes));
- DCmd_Register("cache", WRAP_METHOD(MystConsole, Cmd_Cache));
- DCmd_Register("resources", WRAP_METHOD(MystConsole, Cmd_Resources));
+ registerCmd("changeCard", WRAP_METHOD(MystConsole, Cmd_ChangeCard));
+ registerCmd("curCard", WRAP_METHOD(MystConsole, Cmd_CurCard));
+ registerCmd("var", WRAP_METHOD(MystConsole, Cmd_Var));
+ registerCmd("curStack", WRAP_METHOD(MystConsole, Cmd_CurStack));
+ registerCmd("changeStack", WRAP_METHOD(MystConsole, Cmd_ChangeStack));
+ registerCmd("drawImage", WRAP_METHOD(MystConsole, Cmd_DrawImage));
+ registerCmd("drawRect", WRAP_METHOD(MystConsole, Cmd_DrawRect));
+ registerCmd("setResourceEnable", WRAP_METHOD(MystConsole, Cmd_SetResourceEnable));
+ registerCmd("playSound", WRAP_METHOD(MystConsole, Cmd_PlaySound));
+ registerCmd("stopSound", WRAP_METHOD(MystConsole, Cmd_StopSound));
+ registerCmd("playMovie", WRAP_METHOD(MystConsole, Cmd_PlayMovie));
+ registerCmd("disableInitOpcodes", WRAP_METHOD(MystConsole, Cmd_DisableInitOpcodes));
+ registerCmd("cache", WRAP_METHOD(MystConsole, Cmd_Cache));
+ registerCmd("resources", WRAP_METHOD(MystConsole, Cmd_Resources));
}
MystConsole::~MystConsole() {
@@ -70,7 +70,7 @@ MystConsole::~MystConsole() {
bool MystConsole::Cmd_ChangeCard(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: changeCard <card>\n");
+ debugPrintf("Usage: changeCard <card>\n");
return true;
}
@@ -81,20 +81,20 @@ bool MystConsole::Cmd_ChangeCard(int argc, const char **argv) {
}
bool MystConsole::Cmd_CurCard(int argc, const char **argv) {
- DebugPrintf("Current Card: %d\n", _vm->getCurCard());
+ debugPrintf("Current Card: %d\n", _vm->getCurCard());
return true;
}
bool MystConsole::Cmd_Var(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: var <var> (<value>)\n");
+ debugPrintf("Usage: var <var> (<value>)\n");
return true;
}
if (argc > 2)
_vm->_scriptParser->setVarValue((uint16)atoi(argv[1]), (uint16)atoi(argv[2]));
- DebugPrintf("%d = %d\n", (uint16)atoi(argv[1]), _vm->_scriptParser->getVar((uint16)atoi(argv[1])));
+ debugPrintf("%d = %d\n", (uint16)atoi(argv[1]), _vm->_scriptParser->getVar((uint16)atoi(argv[1])));
return true;
}
@@ -130,19 +130,19 @@ static const uint16 default_start_card[12] = {
};
bool MystConsole::Cmd_CurStack(int argc, const char **argv) {
- DebugPrintf("Current Stack: %s\n", mystStackNames[_vm->getCurStack()]);
+ debugPrintf("Current Stack: %s\n", mystStackNames[_vm->getCurStack()]);
return true;
}
bool MystConsole::Cmd_ChangeStack(int argc, const char **argv) {
if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: changeStack <stack> [<card>]\n\n");
- DebugPrintf("Stacks:\n=======\n");
+ debugPrintf("Usage: changeStack <stack> [<card>]\n\n");
+ debugPrintf("Stacks:\n=======\n");
for (byte i = 0; i < ARRAYSIZE(mystStackNames); i++)
- DebugPrintf(" %s\n", mystStackNames[i]);
+ debugPrintf(" %s\n", mystStackNames[i]);
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
@@ -156,7 +156,7 @@ bool MystConsole::Cmd_ChangeStack(int argc, const char **argv) {
}
if (!stackNum) {
- DebugPrintf("\'%s\' is not a stack name!\n", argv[1]);
+ debugPrintf("\'%s\' is not a stack name!\n", argv[1]);
return true;
}
@@ -177,7 +177,7 @@ bool MystConsole::Cmd_ChangeStack(int argc, const char **argv) {
bool MystConsole::Cmd_DrawImage(int argc, const char **argv) {
if (argc != 2 && argc != 6) {
- DebugPrintf("Usage: drawImage <image> [<left> <top> <right> <bottom>]\n");
+ debugPrintf("Usage: drawImage <image> [<left> <top> <right> <bottom>]\n");
return true;
}
@@ -195,8 +195,8 @@ bool MystConsole::Cmd_DrawImage(int argc, const char **argv) {
bool MystConsole::Cmd_DrawRect(int argc, const char **argv) {
if (argc != 5 && argc != 2) {
- DebugPrintf("Usage: drawRect <left> <top> <right> <bottom>\n");
- DebugPrintf("Usage: drawRect <resource id>\n");
+ debugPrintf("Usage: drawRect <left> <top> <right> <bottom>\n");
+ debugPrintf("Usage: drawRect <resource id>\n");
return true;
}
@@ -213,7 +213,7 @@ bool MystConsole::Cmd_DrawRect(int argc, const char **argv) {
bool MystConsole::Cmd_SetResourceEnable(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Usage: setResourceEnable <resource id> <bool>\n");
+ debugPrintf("Usage: setResourceEnable <resource id> <bool>\n");
return true;
}
@@ -223,7 +223,7 @@ bool MystConsole::Cmd_SetResourceEnable(int argc, const char **argv) {
bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: playSound <value>\n");
+ debugPrintf("Usage: playSound <value>\n");
return true;
}
@@ -234,7 +234,7 @@ bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
}
bool MystConsole::Cmd_StopSound(int argc, const char **argv) {
- DebugPrintf("Stopping Sound\n");
+ debugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
@@ -243,8 +243,8 @@ bool MystConsole::Cmd_StopSound(int argc, const char **argv) {
bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: playMovie <name> [<stack>] [<left> <top>]\n");
- DebugPrintf("NOTE: The movie will play *once* in the background.\n");
+ debugPrintf("Usage: playMovie <name> [<stack>] [<left> <top>]\n");
+ debugPrintf("NOTE: The movie will play *once* in the background.\n");
return true;
}
@@ -258,7 +258,7 @@ bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
}
if (!stackNum) {
- DebugPrintf("\'%s\' is not a stack name!\n", argv[2]);
+ debugPrintf("\'%s\' is not a stack name!\n", argv[2]);
return true;
}
}
@@ -277,7 +277,7 @@ bool MystConsole::Cmd_PlayMovie(int argc, const char **argv) {
bool MystConsole::Cmd_DisableInitOpcodes(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: disableInitOpcodes\n");
+ debugPrintf("Usage: disableInitOpcodes\n");
return true;
}
@@ -289,7 +289,7 @@ bool MystConsole::Cmd_DisableInitOpcodes(int argc, const char **argv) {
bool MystConsole::Cmd_Cache(int argc, const char **argv) {
if (argc > 2) {
- DebugPrintf("Usage: cache on/off - Omit parameter to get current state\n");
+ debugPrintf("Usage: cache on/off - Omit parameter to get current state\n");
return true;
}
@@ -304,15 +304,15 @@ bool MystConsole::Cmd_Cache(int argc, const char **argv) {
_vm->setCacheState(state);
}
- DebugPrintf("Cache: %s\n", state ? "Enabled" : "Disabled");
+ debugPrintf("Cache: %s\n", state ? "Enabled" : "Disabled");
return true;
}
bool MystConsole::Cmd_Resources(int argc, const char **argv) {
- DebugPrintf("Resources in card %d:\n", _vm->getCurCard());
+ debugPrintf("Resources in card %d:\n", _vm->getCurCard());
for (uint i = 0; i < _vm->_resources.size(); i++) {
- DebugPrintf("#%2d %s\n", i, _vm->_resources[i]->describe().c_str());
+ debugPrintf("#%2d %s\n", i, _vm->_resources[i]->describe().c_str());
}
return true;
@@ -323,21 +323,21 @@ bool MystConsole::Cmd_Resources(int argc, const char **argv) {
#ifdef ENABLE_RIVEN
RivenConsole::RivenConsole(MohawkEngine_Riven *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("changeCard", WRAP_METHOD(RivenConsole, Cmd_ChangeCard));
- DCmd_Register("curCard", WRAP_METHOD(RivenConsole, Cmd_CurCard));
- DCmd_Register("var", WRAP_METHOD(RivenConsole, Cmd_Var));
- DCmd_Register("playSound", WRAP_METHOD(RivenConsole, Cmd_PlaySound));
- DCmd_Register("playSLST", WRAP_METHOD(RivenConsole, Cmd_PlaySLST));
- DCmd_Register("stopSound", WRAP_METHOD(RivenConsole, Cmd_StopSound));
- DCmd_Register("curStack", WRAP_METHOD(RivenConsole, Cmd_CurStack));
- DCmd_Register("changeStack", WRAP_METHOD(RivenConsole, Cmd_ChangeStack));
- DCmd_Register("hotspots", WRAP_METHOD(RivenConsole, Cmd_Hotspots));
- DCmd_Register("zipMode", WRAP_METHOD(RivenConsole, Cmd_ZipMode));
- DCmd_Register("dumpScript", WRAP_METHOD(RivenConsole, Cmd_DumpScript));
- DCmd_Register("listZipCards", WRAP_METHOD(RivenConsole, Cmd_ListZipCards));
- DCmd_Register("getRMAP", WRAP_METHOD(RivenConsole, Cmd_GetRMAP));
- DCmd_Register("combos", WRAP_METHOD(RivenConsole, Cmd_Combos));
- DCmd_Register("sliderState", WRAP_METHOD(RivenConsole, Cmd_SliderState));
+ registerCmd("changeCard", WRAP_METHOD(RivenConsole, Cmd_ChangeCard));
+ registerCmd("curCard", WRAP_METHOD(RivenConsole, Cmd_CurCard));
+ registerCmd("var", WRAP_METHOD(RivenConsole, Cmd_Var));
+ registerCmd("playSound", WRAP_METHOD(RivenConsole, Cmd_PlaySound));
+ registerCmd("playSLST", WRAP_METHOD(RivenConsole, Cmd_PlaySLST));
+ registerCmd("stopSound", WRAP_METHOD(RivenConsole, Cmd_StopSound));
+ registerCmd("curStack", WRAP_METHOD(RivenConsole, Cmd_CurStack));
+ registerCmd("changeStack", WRAP_METHOD(RivenConsole, Cmd_ChangeStack));
+ registerCmd("hotspots", WRAP_METHOD(RivenConsole, Cmd_Hotspots));
+ registerCmd("zipMode", WRAP_METHOD(RivenConsole, Cmd_ZipMode));
+ registerCmd("dumpScript", WRAP_METHOD(RivenConsole, Cmd_DumpScript));
+ registerCmd("listZipCards", WRAP_METHOD(RivenConsole, Cmd_ListZipCards));
+ registerCmd("getRMAP", WRAP_METHOD(RivenConsole, Cmd_GetRMAP));
+ registerCmd("combos", WRAP_METHOD(RivenConsole, Cmd_Combos));
+ registerCmd("sliderState", WRAP_METHOD(RivenConsole, Cmd_SliderState));
}
RivenConsole::~RivenConsole() {
@@ -346,7 +346,7 @@ RivenConsole::~RivenConsole() {
bool RivenConsole::Cmd_ChangeCard(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: changeCard <card>\n");
+ debugPrintf("Usage: changeCard <card>\n");
return true;
}
@@ -358,19 +358,19 @@ bool RivenConsole::Cmd_ChangeCard(int argc, const char **argv) {
}
bool RivenConsole::Cmd_CurCard(int argc, const char **argv) {
- DebugPrintf("Current Card: %d\n", _vm->getCurCard());
+ debugPrintf("Current Card: %d\n", _vm->getCurCard());
return true;
}
bool RivenConsole::Cmd_Var(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: var <var name> (<value>)\n");
+ debugPrintf("Usage: var <var name> (<value>)\n");
return true;
}
if (!_vm->_vars.contains(argv[1])) {
- DebugPrintf("Unknown variable '%s'\n", argv[1]);
+ debugPrintf("Unknown variable '%s'\n", argv[1]);
return true;
}
@@ -379,13 +379,13 @@ bool RivenConsole::Cmd_Var(int argc, const char **argv) {
if (argc > 2)
var = (uint32)atoi(argv[2]);
- DebugPrintf("%s = %d\n", argv[1], var);
+ debugPrintf("%s = %d\n", argv[1], var);
return true;
}
bool RivenConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: playSound <value>\n");
+ debugPrintf("Usage: playSound <value>\n");
return true;
}
@@ -397,7 +397,7 @@ bool RivenConsole::Cmd_PlaySound(int argc, const char **argv) {
bool RivenConsole::Cmd_PlaySLST(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: playSLST <slst index> <card, default = current>\n");
+ debugPrintf("Usage: playSLST <slst index> <card, default = current>\n");
return true;
}
@@ -412,7 +412,7 @@ bool RivenConsole::Cmd_PlaySLST(int argc, const char **argv) {
}
bool RivenConsole::Cmd_StopSound(int argc, const char **argv) {
- DebugPrintf("Stopping Sound\n");
+ debugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
_vm->_sound->stopAllSLST();
@@ -420,58 +420,57 @@ bool RivenConsole::Cmd_StopSound(int argc, const char **argv) {
}
bool RivenConsole::Cmd_CurStack(int argc, const char **argv) {
- DebugPrintf("Current Stack: %s\n", _vm->getStackName(_vm->getCurStack()).c_str());
+ debugPrintf("Current Stack: %s\n", _vm->getStackName(_vm->getCurStack()).c_str());
return true;
}
bool RivenConsole::Cmd_ChangeStack(int argc, const char **argv) {
- byte i;
-
if (argc < 3) {
- DebugPrintf("Usage: changeStack <stack> <card>\n\n");
- DebugPrintf("Stacks:\n=======\n");
+ debugPrintf("Usage: changeStack <stack> <card>\n\n");
+ debugPrintf("Stacks:\n=======\n");
- for (i = 0; i <= tspit; i++)
- DebugPrintf(" %s\n", _vm->getStackName(i).c_str());
+ for (uint i = kStackFirst; i <= kStackLast; i++)
+ debugPrintf(" %s\n", _vm->getStackName(i).c_str());
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
- byte stackNum = 0;
+ uint stack = kStackUnknown;
- for (i = 1; i <= tspit + 1; i++)
- if (!scumm_stricmp(argv[1], _vm->getStackName(i - 1).c_str())) {
- stackNum = i;
+ for (uint i = kStackFirst; i <= kStackLast; i++) {
+ if (!scumm_stricmp(argv[1], _vm->getStackName(i).c_str())) {
+ stack = i;
break;
}
+ }
- if (!stackNum) {
- DebugPrintf("\'%s\' is not a stack name!\n", argv[1]);
+ if (stack == kStackUnknown) {
+ debugPrintf("\'%s\' is not a stack name!\n", argv[1]);
return true;
}
- _vm->changeToStack(stackNum - 1);
+ _vm->changeToStack(stack);
_vm->changeToCard((uint16)atoi(argv[2]));
return false;
}
bool RivenConsole::Cmd_Hotspots(int argc, const char **argv) {
- DebugPrintf("Current card (%d) has %d hotspots:\n", _vm->getCurCard(), _vm->getHotspotCount());
+ debugPrintf("Current card (%d) has %d hotspots:\n", _vm->getCurCard(), _vm->getHotspotCount());
for (uint16 i = 0; i < _vm->getHotspotCount(); i++) {
- DebugPrintf("Hotspot %d, index %d, BLST ID %d (", i, _vm->_hotspots[i].index, _vm->_hotspots[i].blstID);
+ debugPrintf("Hotspot %d, index %d, BLST ID %d (", i, _vm->_hotspots[i].index, _vm->_hotspots[i].blstID);
if (_vm->_hotspots[i].enabled)
- DebugPrintf("enabled");
+ debugPrintf("enabled");
else
- DebugPrintf("disabled");
+ debugPrintf("disabled");
- DebugPrintf(") - (%d, %d, %d, %d)\n", _vm->_hotspots[i].rect.left, _vm->_hotspots[i].rect.top, _vm->_hotspots[i].rect.right, _vm->_hotspots[i].rect.bottom);
- DebugPrintf(" Name = %s\n", _vm->getHotspotName(i).c_str());
+ debugPrintf(") - (%d, %d, %d, %d)\n", _vm->_hotspots[i].rect.left, _vm->_hotspots[i].rect.top, _vm->_hotspots[i].rect.right, _vm->_hotspots[i].rect.bottom);
+ debugPrintf(" Name = %s\n", _vm->getHotspotName(i).c_str());
}
return true;
@@ -481,34 +480,33 @@ bool RivenConsole::Cmd_ZipMode(int argc, const char **argv) {
uint32 &zipModeActive = _vm->_vars["azip"];
zipModeActive = !zipModeActive;
- DebugPrintf("Zip Mode is ");
- DebugPrintf(zipModeActive ? "Enabled" : "Disabled");
- DebugPrintf("\n");
+ debugPrintf("Zip Mode is ");
+ debugPrintf(zipModeActive ? "Enabled" : "Disabled");
+ debugPrintf("\n");
return true;
}
bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
if (argc < 4) {
- DebugPrintf("Usage: dumpScript <stack> <CARD or HSPT> <card>\n");
+ debugPrintf("Usage: dumpScript <stack> <CARD or HSPT> <card>\n");
return true;
}
uint16 oldStack = _vm->getCurStack();
+ uint newStack = kStackUnknown;
- byte newStack = 0;
-
- for (byte i = 1; i <= tspit + 1; i++)
- if (!scumm_stricmp(argv[1], _vm->getStackName(i - 1).c_str())) {
+ for (uint i = kStackFirst; i <= kStackLast; i++) {
+ if (!scumm_stricmp(argv[1], _vm->getStackName(i).c_str())) {
newStack = i;
break;
}
+ }
- if (!newStack) {
- DebugPrintf("\'%s\' is not a stack name!\n", argv[1]);
+ if (newStack == kStackUnknown) {
+ debugPrintf("\'%s\' is not a stack name!\n", argv[1]);
return true;
}
- newStack--;
_vm->changeToStack(newStack);
// Load in Variable Names
@@ -594,7 +592,7 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
delete hsptStream;
} else {
- DebugPrintf("%s doesn't have any scripts!\n", argv[2]);
+ debugPrintf("%s doesn't have any scripts!\n", argv[2]);
}
// See above for why this is printed via debugN
@@ -602,18 +600,18 @@ bool RivenConsole::Cmd_DumpScript(int argc, const char **argv) {
_vm->changeToStack(oldStack);
- DebugPrintf("Script dump complete.\n");
+ debugPrintf("Script dump complete.\n");
return true;
}
bool RivenConsole::Cmd_ListZipCards(int argc, const char **argv) {
if (_vm->_zipModeData.size() == 0) {
- DebugPrintf("No zip card data.\n");
+ debugPrintf("No zip card data.\n");
} else {
- DebugPrintf("Listing zip cards:\n");
+ debugPrintf("Listing zip cards:\n");
for (uint32 i = 0; i < _vm->_zipModeData.size(); i++)
- DebugPrintf("ID = %d, Name = %s\n", _vm->_zipModeData[i].id, _vm->_zipModeData[i].name.c_str());
+ debugPrintf("ID = %d, Name = %s\n", _vm->_zipModeData[i].id, _vm->_zipModeData[i].name.c_str());
}
return true;
@@ -621,7 +619,7 @@ bool RivenConsole::Cmd_ListZipCards(int argc, const char **argv) {
bool RivenConsole::Cmd_GetRMAP(int argc, const char **argv) {
uint32 rmapCode = _vm->getCurCardRMAP();
- DebugPrintf("RMAP for %s %d = %08x\n", _vm->getStackName(_vm->getCurStack()).c_str(), _vm->getCurCard(), rmapCode);
+ debugPrintf("RMAP for %s %d = %08x\n", _vm->getStackName(_vm->getCurStack()).c_str(), _vm->getCurCard(), rmapCode);
return true;
}
@@ -635,20 +633,20 @@ bool RivenConsole::Cmd_Combos(int argc, const char **argv) {
uint32 prisonCombo = _vm->_vars["pcorrectorder"];
uint32 domeCombo = _vm->_vars["adomecombo"];
- DebugPrintf("Telescope Combo:\n ");
+ debugPrintf("Telescope Combo:\n ");
for (int i = 0; i < 5; i++)
- DebugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(teleCombo, i));
+ debugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(teleCombo, i));
- DebugPrintf("\nPrison Combo:\n ");
+ debugPrintf("\nPrison Combo:\n ");
for (int i = 0; i < 5; i++)
- DebugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(prisonCombo, i));
+ debugPrintf("%d ", _vm->_externalScriptHandler->getComboDigit(prisonCombo, i));
- DebugPrintf("\nDome Combo:\n ");
+ debugPrintf("\nDome Combo:\n ");
for (int i = 1; i <= 25; i++)
if (domeCombo & (1 << (25 - i)))
- DebugPrintf("%d ", i);
+ debugPrintf("%d ", i);
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
@@ -656,17 +654,17 @@ bool RivenConsole::Cmd_SliderState(int argc, const char **argv) {
if (argc > 1)
_vm->_externalScriptHandler->setDomeSliderState((uint32)atoi(argv[1]));
- DebugPrintf("Dome Slider State = %08x\n", _vm->_externalScriptHandler->getDomeSliderState());
+ debugPrintf("Dome Slider State = %08x\n", _vm->_externalScriptHandler->getDomeSliderState());
return true;
}
#endif // ENABLE_RIVEN
LivingBooksConsole::LivingBooksConsole(MohawkEngine_LivingBooks *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("playSound", WRAP_METHOD(LivingBooksConsole, Cmd_PlaySound));
- DCmd_Register("stopSound", WRAP_METHOD(LivingBooksConsole, Cmd_StopSound));
- DCmd_Register("drawImage", WRAP_METHOD(LivingBooksConsole, Cmd_DrawImage));
- DCmd_Register("changePage", WRAP_METHOD(LivingBooksConsole, Cmd_ChangePage));
+ registerCmd("playSound", WRAP_METHOD(LivingBooksConsole, Cmd_PlaySound));
+ registerCmd("stopSound", WRAP_METHOD(LivingBooksConsole, Cmd_StopSound));
+ registerCmd("drawImage", WRAP_METHOD(LivingBooksConsole, Cmd_DrawImage));
+ registerCmd("changePage", WRAP_METHOD(LivingBooksConsole, Cmd_ChangePage));
}
LivingBooksConsole::~LivingBooksConsole() {
@@ -674,7 +672,7 @@ LivingBooksConsole::~LivingBooksConsole() {
bool LivingBooksConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: playSound <value>\n");
+ debugPrintf("Usage: playSound <value>\n");
return true;
}
@@ -684,7 +682,7 @@ bool LivingBooksConsole::Cmd_PlaySound(int argc, const char **argv) {
}
bool LivingBooksConsole::Cmd_StopSound(int argc, const char **argv) {
- DebugPrintf("Stopping Sound\n");
+ debugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
return true;
@@ -692,7 +690,7 @@ bool LivingBooksConsole::Cmd_StopSound(int argc, const char **argv) {
bool LivingBooksConsole::Cmd_DrawImage(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: drawImage <value>\n");
+ debugPrintf("Usage: drawImage <value>\n");
return true;
}
@@ -703,13 +701,13 @@ bool LivingBooksConsole::Cmd_DrawImage(int argc, const char **argv) {
bool LivingBooksConsole::Cmd_ChangePage(int argc, const char **argv) {
if (argc < 2 || argc > 3) {
- DebugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n");
+ debugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n");
return true;
}
int page, subpage = 0;
if (sscanf(argv[1], "%d.%d", &page, &subpage) == 0) {
- DebugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n");
+ debugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n");
return true;
}
LBMode mode = argc == 2 ? _vm->getCurMode() : (LBMode)atoi(argv[2]);
@@ -720,21 +718,21 @@ bool LivingBooksConsole::Cmd_ChangePage(int argc, const char **argv) {
if (_vm->loadPage(mode, page, subpage))
return false;
}
- DebugPrintf("no such page %d.%d\n", page, subpage);
+ debugPrintf("no such page %d.%d\n", page, subpage);
return true;
}
#ifdef ENABLE_CSTIME
CSTimeConsole::CSTimeConsole(MohawkEngine_CSTime *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("playSound", WRAP_METHOD(CSTimeConsole, Cmd_PlaySound));
- DCmd_Register("stopSound", WRAP_METHOD(CSTimeConsole, Cmd_StopSound));
- DCmd_Register("drawImage", WRAP_METHOD(CSTimeConsole, Cmd_DrawImage));
- DCmd_Register("drawSubimage", WRAP_METHOD(CSTimeConsole, Cmd_DrawSubimage));
- DCmd_Register("changeCase", WRAP_METHOD(CSTimeConsole, Cmd_ChangeCase));
- DCmd_Register("changeScene", WRAP_METHOD(CSTimeConsole, Cmd_ChangeScene));
- DCmd_Register("caseVariable", WRAP_METHOD(CSTimeConsole, Cmd_CaseVariable));
- DCmd_Register("invItem", WRAP_METHOD(CSTimeConsole, Cmd_InvItem));
+ registerCmd("playSound", WRAP_METHOD(CSTimeConsole, Cmd_PlaySound));
+ registerCmd("stopSound", WRAP_METHOD(CSTimeConsole, Cmd_StopSound));
+ registerCmd("drawImage", WRAP_METHOD(CSTimeConsole, Cmd_DrawImage));
+ registerCmd("drawSubimage", WRAP_METHOD(CSTimeConsole, Cmd_DrawSubimage));
+ registerCmd("changeCase", WRAP_METHOD(CSTimeConsole, Cmd_ChangeCase));
+ registerCmd("changeScene", WRAP_METHOD(CSTimeConsole, Cmd_ChangeScene));
+ registerCmd("caseVariable", WRAP_METHOD(CSTimeConsole, Cmd_CaseVariable));
+ registerCmd("invItem", WRAP_METHOD(CSTimeConsole, Cmd_InvItem));
}
CSTimeConsole::~CSTimeConsole() {
@@ -742,7 +740,7 @@ CSTimeConsole::~CSTimeConsole() {
bool CSTimeConsole::Cmd_PlaySound(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: playSound <value>\n");
+ debugPrintf("Usage: playSound <value>\n");
return true;
}
@@ -752,7 +750,7 @@ bool CSTimeConsole::Cmd_PlaySound(int argc, const char **argv) {
}
bool CSTimeConsole::Cmd_StopSound(int argc, const char **argv) {
- DebugPrintf("Stopping Sound\n");
+ debugPrintf("Stopping Sound\n");
_vm->_sound->stopSound();
return true;
@@ -760,7 +758,7 @@ bool CSTimeConsole::Cmd_StopSound(int argc, const char **argv) {
bool CSTimeConsole::Cmd_DrawImage(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: drawImage <value>\n");
+ debugPrintf("Usage: drawImage <value>\n");
return true;
}
@@ -771,7 +769,7 @@ bool CSTimeConsole::Cmd_DrawImage(int argc, const char **argv) {
bool CSTimeConsole::Cmd_DrawSubimage(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Usage: drawSubimage <value> <subimage>\n");
+ debugPrintf("Usage: drawSubimage <value> <subimage>\n");
return true;
}
@@ -782,7 +780,7 @@ bool CSTimeConsole::Cmd_DrawSubimage(int argc, const char **argv) {
bool CSTimeConsole::Cmd_ChangeCase(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: changeCase <value>\n");
+ debugPrintf("Usage: changeCase <value>\n");
return true;
}
@@ -792,7 +790,7 @@ bool CSTimeConsole::Cmd_ChangeCase(int argc, const char **argv) {
bool CSTimeConsole::Cmd_ChangeScene(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: changeScene <value>\n");
+ debugPrintf("Usage: changeScene <value>\n");
return true;
}
@@ -802,12 +800,12 @@ bool CSTimeConsole::Cmd_ChangeScene(int argc, const char **argv) {
bool CSTimeConsole::Cmd_CaseVariable(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: caseVariable <id> [<value>]\n");
+ debugPrintf("Usage: caseVariable <id> [<value>]\n");
return true;
}
if (argc == 2) {
- DebugPrintf("case variable %d has value %d\n", atoi(argv[1]), _vm->_caseVariable[atoi(argv[1])]);
+ debugPrintf("case variable %d has value %d\n", atoi(argv[1]), _vm->_caseVariable[atoi(argv[1])]);
} else {
_vm->_caseVariable[atoi(argv[1])] = atoi(argv[2]);
}
@@ -816,7 +814,7 @@ bool CSTimeConsole::Cmd_CaseVariable(int argc, const char **argv) {
bool CSTimeConsole::Cmd_InvItem(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Usage: invItem <id> <0 or 1>\n");
+ debugPrintf("Usage: invItem <id> <0 or 1>\n");
return true;
}
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index e1059bebaa..a7fe12b9e1 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -55,7 +55,7 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio
_activatedSLST = false;
_ignoreNextMouseUp = false;
_extrasFile = 0;
- _curStack = aspit;
+ _curStack = kStackUnknown;
_hotspots = 0;
removeTimer();
@@ -161,7 +161,7 @@ Common::Error MohawkEngine_Riven::run() {
// Let's begin, shall we?
if (getFeatures() & GF_DEMO) {
// Start the demo off with the videos
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(6);
} else if (ConfMan.hasKey("save_slot")) {
// Load game from launcher/command line if requested
@@ -172,12 +172,12 @@ Common::Error MohawkEngine_Riven::run() {
// Attempt to load the game. On failure, just send us to the main menu.
if (_saveLoad->loadGame(savedGamesList[gameToLoad]).getCode() != Common::kNoError) {
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(1);
}
} else {
// Otherwise, start us off at aspit's card 1 (the main menu)
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(1);
}
@@ -255,16 +255,16 @@ void MohawkEngine_Riven::handleEvents() {
case Common::KEYCODE_r:
// Return to the main menu in the demo on ctrl+r
if (event.kbd.flags & Common::KBD_CTRL && getFeatures() & GF_DEMO) {
- if (_curStack != aspit)
- changeToStack(aspit);
+ if (_curStack != kStackAspit)
+ changeToStack(kStackAspit);
changeToCard(1);
}
break;
case Common::KEYCODE_p:
// Play the intro videos in the demo on ctrl+p
if (event.kbd.flags & Common::KBD_CTRL && getFeatures() & GF_DEMO) {
- if (_curStack != aspit)
- changeToStack(aspit);
+ if (_curStack != kStackAspit)
+ changeToStack(kStackAspit);
changeToCard(6);
}
break;
@@ -343,20 +343,22 @@ struct RivenSpecialChange {
uint32 startCardRMAP;
byte targetStack;
uint32 targetCardRMAP;
-} rivenSpecialChange[] = {
- { aspit, 0x1f04, ospit, 0x44ad }, // Trap Book
- { bspit, 0x1c0e7, ospit, 0x2e76 }, // Dome Linking Book
- { gspit, 0x111b1, ospit, 0x2e76 }, // Dome Linking Book
- { jspit, 0x28a18, rspit, 0xf94 }, // Tay Linking Book
- { jspit, 0x26228, ospit, 0x2e76 }, // Dome Linking Book
- { ospit, 0x5f0d, pspit, 0x3bf0 }, // Return from 233rd Age
- { ospit, 0x470a, jspit, 0x1508e }, // Return from 233rd Age
- { ospit, 0x5c52, gspit, 0x10bea }, // Return from 233rd Age
- { ospit, 0x5d68, bspit, 0x1adfd }, // Return from 233rd Age
- { ospit, 0x5e49, tspit, 0xe87 }, // Return from 233rd Age
- { pspit, 0x4108, ospit, 0x2e76 }, // Dome Linking Book
- { rspit, 0x32d8, jspit, 0x1c474 }, // Return from Tay
- { tspit, 0x21b69, ospit, 0x2e76 } // Dome Linking Book
+};
+
+static const RivenSpecialChange rivenSpecialChange[] = {
+ { kStackAspit, 0x1f04, kStackOspit, 0x44ad }, // Trap Book
+ { kStackBspit, 0x1c0e7, kStackOspit, 0x2e76 }, // Dome Linking Book
+ { kStackGspit, 0x111b1, kStackOspit, 0x2e76 }, // Dome Linking Book
+ { kStackJspit, 0x28a18, kStackRspit, 0xf94 }, // Tay Linking Book
+ { kStackJspit, 0x26228, kStackOspit, 0x2e76 }, // Dome Linking Book
+ { kStackOspit, 0x5f0d, kStackPspit, 0x3bf0 }, // Return from 233rd Age
+ { kStackOspit, 0x470a, kStackJspit, 0x1508e }, // Return from 233rd Age
+ { kStackOspit, 0x5c52, kStackGspit, 0x10bea }, // Return from 233rd Age
+ { kStackOspit, 0x5d68, kStackBspit, 0x1adfd }, // Return from 233rd Age
+ { kStackOspit, 0x5e49, kStackTspit, 0xe87 }, // Return from 233rd Age
+ { kStackPspit, 0x4108, kStackOspit, 0x2e76 }, // Dome Linking Book
+ { kStackRspit, 0x32d8, kStackJspit, 0x1c474 }, // Return from Tay
+ { kStackTspit, 0x21b69, kStackOspit, 0x2e76 } // Dome Linking Book
};
void MohawkEngine_Riven::changeToCard(uint16 dest) {
@@ -556,16 +558,16 @@ void MohawkEngine_Riven::checkInventoryClick() {
// In the demo, check if we've clicked the exit button
if (getFeatures() & GF_DEMO) {
if (g_demoExitRect->contains(mousePos)) {
- if (_curStack == aspit && _curCard == 1) {
+ if (_curStack == kStackAspit && _curCard == 1) {
// From the main menu, go to the "quit" screen
changeToCard(12);
- } else if (_curStack == aspit && _curCard == 12) {
+ } else if (_curStack == kStackAspit && _curCard == 12) {
// From the "quit" screen, just quit
_gameOver = true;
} else {
// Otherwise, return to the main menu
- if (_curStack != aspit)
- changeToStack(aspit);
+ if (_curStack != kStackAspit)
+ changeToStack(kStackAspit);
changeToCard(1);
}
}
@@ -573,7 +575,7 @@ void MohawkEngine_Riven::checkInventoryClick() {
}
// No inventory shown on aspit
- if (_curStack == aspit)
+ if (_curStack == kStackAspit)
return;
// Set the return stack/card id's.
@@ -589,31 +591,31 @@ void MohawkEngine_Riven::checkInventoryClick() {
if (!hasCathBook) {
if (g_atrusJournalRect1->contains(mousePos)) {
_gfx->hideInventory();
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(5);
}
} else if (!hasTrapBook) {
if (g_atrusJournalRect2->contains(mousePos)) {
_gfx->hideInventory();
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(5);
} else if (g_cathJournalRect2->contains(mousePos)) {
_gfx->hideInventory();
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(6);
}
} else {
if (g_atrusJournalRect3->contains(mousePos)) {
_gfx->hideInventory();
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(5);
} else if (g_cathJournalRect3->contains(mousePos)) {
_gfx->hideInventory();
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(6);
} else if (g_trapBookRect3->contains(mousePos)) {
_gfx->hideInventory();
- changeToStack(aspit);
+ changeToStack(kStackAspit);
changeToCard(7);
}
}
@@ -735,16 +737,20 @@ Common::Error MohawkEngine_Riven::saveGameState(int slot, const Common::String &
Common::String MohawkEngine_Riven::getStackName(uint16 stack) const {
static const char *rivenStackNames[] = {
- "aspit",
- "bspit",
- "gspit",
- "jspit",
+ "<unknown>",
"ospit",
"pspit",
"rspit",
- "tspit"
+ "tspit",
+ "bspit",
+ "gspit",
+ "jspit",
+ "aspit"
};
+ // Sanity check.
+ assert(stack < ARRAYSIZE(rivenStackNames));
+
return rivenStackNames[stack];
}
diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h
index c22b9f7f87..9c23d07c52 100644
--- a/engines/mohawk/riven.h
+++ b/engines/mohawk/riven.h
@@ -44,18 +44,20 @@ class RivenConsole;
class RivenSaveLoad;
class RivenOptionsDialog;
-#define RIVEN_STACKS 8
-
// Riven Stack Types
enum {
- aspit = 0, // Main Menu, Books, Setup
- bspit = 1, // Book-Making Island
- gspit = 2, // Garden Island
- jspit = 3, // Jungle Island
- ospit = 4, // 233rd Age (Gehn's Office)
- pspit = 5, // Prison Island
- rspit = 6, // Rebel Age (Tay)
- tspit = 7 // Temple Island
+ kStackUnknown = 0, // Default value for ReturnStackID
+ kStackOspit = 1, // 233rd Age (Gehn's Office)
+ kStackPspit = 2, // Prison Island
+ kStackRspit = 3, // Temple Island
+ kStackTspit = 4, // Rebel Age (Tay)
+ kStackBspit = 5, // Book-Making Island
+ kStackGspit = 6, // Garden Island
+ kStackJspit = 7, // Jungle Island
+ kStackAspit = 8, // Main Menu, Books, Setup
+
+ kStackFirst = kStackOspit,
+ kStackLast = kStackAspit
};
// NAME Resource ID's
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 10dcfd9fa7..3d0bccc47f 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -405,7 +405,7 @@ void RivenExternal::drawDomeSliders(uint16 startHotspot) {
// On pspit, the rect is different by two pixels
// (alternatively, we could just use hotspot 3 here, but only on pspit is there a hotspot for this)
- if (_vm->getCurStack() == pspit)
+ if (_vm->getCurStack() == kStackPspit)
dstAreaRect.translate(-2, 0);
// Find out bitmap id
@@ -2016,8 +2016,8 @@ void RivenExternal::xorollcredittime(uint16 argc, uint16 *argv) {
// WORKAROUND: The special change stuff only handles one destination and it would
// be messy to modify the way that currently works. If we use the trap book on Tay,
// we should be using the Tay end game sequences.
- if (_vm->_vars["returnstackid"] == rspit) {
- _vm->changeToStack(rspit);
+ if (_vm->_vars["returnstackid"] == kStackRspit) {
+ _vm->changeToStack(kStackRspit);
_vm->changeToCard(2);
return;
}
diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp
index 615b2fdadb..b44fbb828e 100644
--- a/engines/mohawk/riven_graphics.cpp
+++ b/engines/mohawk/riven_graphics.cpp
@@ -289,7 +289,7 @@ void RivenGraphics::showInventory() {
drawInventoryImage(101, g_demoExitRect);
} else {
// We don't want to show the inventory on setup screens or in other journals.
- if (_vm->getCurStack() == aspit)
+ if (_vm->getCurStack() == kStackAspit)
return;
// There are three books and three vars. We have three different
diff --git a/engines/mohawk/riven_saveload.cpp b/engines/mohawk/riven_saveload.cpp
index d97d0e174b..6af66f7a2d 100644
--- a/engines/mohawk/riven_saveload.cpp
+++ b/engines/mohawk/riven_saveload.cpp
@@ -38,56 +38,6 @@ Common::StringArray RivenSaveLoad::generateSaveGameList() {
return _saveFileMan->listSavefiles("*.rvn");
}
-// Note: The stack numbers we use do not match up to what the original executable,
-// so, match them ;)
-static uint16 mapOldStackIDToNew(uint16 oldID) {
- switch (oldID) {
- case 1:
- return ospit;
- case 2:
- return pspit;
- case 3:
- return rspit;
- case 4:
- return tspit;
- case 5:
- return bspit;
- case 6:
- return gspit;
- case 7:
- return jspit;
- case 8:
- return aspit;
- }
-
- error("Unknown old stack ID %d", oldID);
- return 0;
-}
-
-static uint16 mapNewStackIDToOld(uint16 newID) {
- switch (newID) {
- case aspit:
- return 8;
- case bspit:
- return 5;
- case gspit:
- return 6;
- case jspit:
- return 7;
- case ospit:
- return 1;
- case pspit:
- return 2;
- case rspit:
- return 3;
- case tspit:
- return 4;
- }
-
- error("Unknown new stack ID %d", newID);
- return 0;
-}
-
Common::Error RivenSaveLoad::loadGame(Common::String filename) {
if (_vm->getFeatures() & GF_DEMO) // Don't load games in the demo
return Common::kNoError;
@@ -141,9 +91,6 @@ Common::Error RivenSaveLoad::loadGame(Common::String filename) {
names->readUint16BE(); // Skip unknown values
uint32 curNamesPos = names->pos();
- uint16 stackID = 0;
- uint16 cardID = 0;
-
for (uint32 i = 0; i < namesCount && !names->eos(); i++) {
names->seek(curNamesPos);
names->seek(stringOffsets[i], SEEK_CUR);
@@ -165,25 +112,18 @@ Common::Error RivenSaveLoad::loadGame(Common::String filename) {
uint32 &var = _vm->_vars[name];
name.toLowercase();
- // Handle any special variables here
// WORKAROUND: time variables are reset here for one main reason:
// The save does not store any start point for the time, so we don't know the real time.
// Because of this, in many cases, the original would just give a 'free' Ytram upon saving
// since the time would be used in a new (improper) time frame.
- if (name.equalsIgnoreCase("CurrentStackID")) // Remap to our definitions, store for later
- stackID = mapOldStackIDToNew(rawVariables[i]);
- else if (name.equalsIgnoreCase("CurrentCardID")) // Store for later
- cardID = rawVariables[i];
- else if (name.equalsIgnoreCase("ReturnStackID") && var != 0) // if 0, the game did not use the variable yet
- var = mapOldStackIDToNew(rawVariables[i]);
- else if (name.contains("time")) // WORKAROUND: See above
+ if (name.contains("time"))
var = 0;
- else // Otherwise, just store it
+ else
var = rawVariables[i];
}
- _vm->changeToStack(stackID);
- _vm->changeToCard(cardID);
+ _vm->changeToStack(_vm->_vars["CurrentStackID"]);
+ _vm->changeToCard(_vm->_vars["CurrentCardID"]);
delete names;
delete[] stringOffsets;
@@ -224,14 +164,7 @@ Common::MemoryWriteStreamDynamic *RivenSaveLoad::genVARSSection() {
for (RivenVariableMap::const_iterator it = _vm->_vars.begin(); it != _vm->_vars.end(); it++) {
stream->writeUint32BE(0); // Unknown
stream->writeUint32BE(0); // Unknown
-
- // Remap returnstackid here because we don't actually want to change
- // our internal returnstackid.
- uint32 variable = it->_value;
- if (it->_key == "returnstackid")
- variable = mapNewStackIDToOld(variable);
-
- stream->writeUint32BE(variable);
+ stream->writeUint32BE(it->_value);
}
return stream;
@@ -290,7 +223,7 @@ Common::Error RivenSaveLoad::saveGame(Common::String filename) {
filename += ".rvn";
// Convert class variables to variable numbers
- _vm->_vars["currentstackid"] = mapNewStackIDToOld(_vm->getCurStack());
+ _vm->_vars["currentstackid"] = _vm->getCurStack();
_vm->_vars["currentcardid"] = _vm->getCurCard();
Common::OutSaveFile *saveFile = _saveFileMan->openForSaving(filename);
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index 06b6afdf30..29ee5cd50b 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -403,7 +403,7 @@ void RivenScript::stopSound(uint16 op, uint16 argc, uint16 *argv) {
// would cause all ambient sounds not to play. An alternative
// fix would be to stop all scripts on a stack change, but this
// does fine for now.
- if (_vm->getCurStack() == tspit && (_vm->getCurCardRMAP() == 0x6e9a || _vm->getCurCardRMAP() == 0xfeeb))
+ if (_vm->getCurStack() == kStackTspit && (_vm->getCurCardRMAP() == 0x6e9a || _vm->getCurCardRMAP() == 0xfeeb))
return;
// The argument is a bitflag for the setting.
@@ -586,7 +586,7 @@ void RivenScript::activatePLST(uint16 op, uint16 argc, uint16 *argv) {
void RivenScript::activateSLST(uint16 op, uint16 argc, uint16 *argv) {
// WORKAROUND: Disable the SLST that is played during Riven's intro.
// Riven X does this too (spoke this over with Jeff)
- if (_vm->getCurStack() == tspit && _vm->getCurCardRMAP() == 0x6e9a && argv[0] == 2)
+ if (_vm->getCurStack() == kStackTspit && _vm->getCurCardRMAP() == 0x6e9a && argv[0] == 2)
return;
_vm->_sound->playSLST(argv[0], _vm->getCurCard());
diff --git a/engines/mohawk/riven_vars.cpp b/engines/mohawk/riven_vars.cpp
index 1cd748d8d6..f09aba7f90 100644
--- a/engines/mohawk/riven_vars.cpp
+++ b/engines/mohawk/riven_vars.cpp
@@ -31,240 +31,240 @@ namespace Mohawk {
static const char *variableNames[] = {
// aspit
- "aatrusbook",
- "aatruspage",
- "acathbook",
- "acathpage",
- "acathstate",
- "adoit",
- "adomecombo",
- "agehn",
- "ainventory",
- "aova",
- "apower",
- "araw",
- "atemp",
- "atrap",
- "atrapbook",
- "auservolume",
- "azip",
+ "aAtrusBook",
+ "aAtrusPage",
+ "aCathBook",
+ "aCathPage",
+ "aCathState",
+ "aDoIt",
+ "aDomeCombo",
+ "aGehn",
+ "aInventory",
+ "aOva",
+ "aPower",
+ "aRaw",
+ "aTemp",
+ "aTrap",
+ "aTrapBook",
+ "aUserVolume",
+ "aZip",
// bspit
- "bbacklock",
- "bbait",
- "bbigbridge",
- "bbirds",
- "bblrarm",
- "bblrdoor",
- "bblrgrt",
- "bblrsw",
- "bblrvalve",
- "bblrwtr",
- "bbook",
- "bbrlever",
- "bcavedoor",
+ "bBackLock",
+ "bBait",
+ "bBigBridge",
+ "bBirds",
+ "bBlrArm",
+ "bBlrDoor",
+ "bBlrGrt",
+ "bBlrSw",
+ "bBlrValve",
+ "bBlrWtr",
+ "bBook",
+ "bBrLever",
+ "bCaveDoor",
"bcombo",
- "bcpipegr",
- "bcratergg",
- "bdome",
- "bdrwr",
- "bfans",
- "bfmdoor",
- "bidvlv",
- "blab",
- "blabbackdr",
- "blabbook",
- "blabeye",
- "blabfrontdr",
- "blabpage",
- "blever",
- "bfrontlock",
- "bheat",
- "bmagcar",
- "bpipdr",
- "bprs",
- "bstove",
- "btrap",
- "bvalve",
- "bvise",
- "bytram",
- "bytramtime",
- "bytrap",
- "bytrapped",
+ "bCPipeGr",
+ "bCraterGg",
+ "bDome",
+ "bDrwr",
+ "bFans",
+ "bFMDoor",
+ "bIdVlv",
+ "bLab",
+ "bLabBackDr",
+ "bLabBook",
+ "bLabEye",
+ "bLabFrontDr",
+ "bLabPage",
+ "bLever",
+ "bFrontLock",
+ "bHeat",
+ "bMagCar",
+ "bPipDr",
+ "bPrs",
+ "bStove",
+ "bTrap",
+ "bValve",
+ "bVise",
+ "bYtram",
+ "bYtramTime",
+ "bYtrap",
+ "bYtrapped",
// gspit
- "gbook",
- "gcathtime",
- "gcathstate",
- "gcombo",
- "gdome",
- "gemagcar",
- "gimagecurr",
+ "gBook",
+ "gCathTime",
+ "gCathState",
+ "gCombo",
+ "gDome",
+ "gEmagCar",
+ "gImageCurr",
"gimagemax",
- "gimagerot",
- "glkbtns",
- "glkbridge",
- "glkelev",
- "glview",
- "glviewmpos",
- "glviewpos",
- "gnmagrot",
- "gnmagcar",
- "gpinup",
- "gpinpos",
- "gpinsmpos",
- "grview",
- "grviewmpos",
- "grviewpos",
- "gscribe",
- "gscribetime",
- "gsubelev",
- "gsubdr",
- "gupmoov",
- "gwhark",
- "gwharktime",
+ "gImageRot",
+ "gLkBtns",
+ "gLkBridge",
+ "gLkElev",
+ "gLView",
+ "gLViewMPos",
+ "gLViewPos",
+ "gNmagRot",
+ "gNmagCar",
+ "gPinUp",
+ "gPinPos",
+ "gPinsMPos",
+ "gRView",
+ "gRViewMPos",
+ "gRViewPos",
+ "gScribe",
+ "gScribeTime",
+ "gSubElev",
+ "gSubDr",
+ "gUpMoov",
+ "gWhark",
+ "gWharkTime",
// jspit
- "jwmagcar",
- "jbeetle",
- "jbeetlepool",
- "jbook",
- "jbridge1",
- "jbridge2",
- "jbridge3",
- "jbridge4",
- "jbridge5",
- "jccb",
- "jcombo",
- "jcrg",
- "jdome",
- "jdrain",
- "jgallows",
- "jgate",
- "jgirl",
- "jiconcorrectorder",
- "jiconorder",
- "jicons",
- "jladder",
- "jleftpos",
- "jpeek",
- "jplaybeetle",
- "jprebel",
- "jprisondr",
- "jprisonsecdr",
- "jrbook",
- "jrightpos",
- "jsouthpathdr",
- "jschooldr",
- "jsub",
- "jsubdir",
- "jsubhatch",
- "jsubsw",
- "jsunners",
- "jsunnertime",
- "jthronedr",
- "jtunneldr",
- "jtunnellamps",
- "jvillagepeople",
- "jwarning",
- "jwharkpos",
- "jwharkram",
- "jwmouth",
- "jwmagcar",
- "jymagcar",
+ "jWMagCar",
+ "jBeetle",
+ "jBeetlePool",
+ "jBook",
+ "jBridge1",
+ "jBridge2",
+ "jBridge3",
+ "jBridge4",
+ "jBridge5",
+ "jCCB",
+ "jCombo",
+ "jCrg",
+ "jDome",
+ "jDrain",
+ "jGallows",
+ "jGate",
+ "jGirl",
+ "jIconCorrectOrder",
+ "jIconOrder",
+ "jIcons",
+ "jLadder",
+ "jLeftPos",
+ "jPeek",
+ "jPlayBeetle",
+ "jPRebel",
+ "jPrisonDr",
+ "jPrisonSecDr",
+ "jrBook",
+ "jRightPos",
+ "jSouthPathDr",
+ "jSchoolDr",
+ "jSub",
+ "jSubDir",
+ "jSubHatch",
+ "jSubSw",
+ "jSunners",
+ "jSunnerTime",
+ "jThroneDr",
+ "jTunnelDr",
+ "jTunnelLamps",
+ "jVillagePeople",
+ "jWarning",
+ "jWharkPos",
+ "jWharkRam",
+ "jWMouth",
+ "jWMagCar",
+ "jYMagCar",
// ospit
"oambient",
- "obutton",
+ "oButton",
"ocage",
- "odeskbook",
- "ogehnpage",
- "omusicplayer",
- "ostanddrawer",
- "ostove",
+ "oDeskBook",
+ "oGehnPage",
+ "oMusicPlayer",
+ "oStandDrawer",
+ "oStove",
// pspit
- "pbook",
- "pcage",
- "pcathcheck",
- "pcathstate",
- "pcathtime",
- "pcombo",
- "pcorrectorder",
+ "pBook",
+ "pCage",
+ "pCathCheck",
+ "pCathState",
+ "pCathTime",
+ "pCombo",
+ "pCorrectOrder",
"pdome",
- "pelevcombo",
- "pleftpos",
- "prightpos",
- "ptemp",
- "pwharkpos",
+ "pElevCombo",
+ "pLeftPos",
+ "pRightPos",
+ "pTemp",
+ "pWharkPos",
// rspit
- "rrebel",
- "rrebelview",
- "rrichard",
- "rvillagetime",
+ "rRebel",
+ "rRebelView",
+ "rRichard",
+ "rVillageTime",
// tspit
- "tbars",
- "tbeetle",
- "tblue",
- "tbook",
- "tbookvalve",
- "tcage",
- "tcombo",
- "tcorrectorder",
- "tcovercombo",
- "tdl",
- "tdome",
- "tdomeelev",
- "tdomeelevbtn",
- "tgatebrhandle",
- "tgatebridge",
- "tgatestate",
- "tgreen",
- "tgridoor",
- "tgrodoor",
- "tgrmdoor",
- "tguard",
- "timagedoor",
- "tmagcar",
- "torange",
- "tred",
- "tsecdoor",
- "tsubbridge",
- "ttelecover",
- "ttelehandle",
- "ttelepin",
- "ttelescope",
- "ttelevalve",
- "ttemple",
- "ttempledoor",
- "ttunneldoor",
- "tviewer",
- "tviolet",
- "twabrvalve",
- "twaffle",
- "tyellow",
+ "tBars",
+ "tBeetle",
+ "tBlue",
+ "tBook",
+ "tBookValve",
+ "tCage",
+ "tCombo",
+ "tCorrectOrder",
+ "tCoverCombo",
+ "tDL",
+ "tDome",
+ "tDomeElev",
+ "tDomeElevBtn",
+ "tGateBrHandle",
+ "tGateBridge",
+ "tGateState",
+ "tGreen",
+ "tGRIDoor",
+ "tGRODoor",
+ "tGRMDoor",
+ "tGuard",
+ "tImageDoor",
+ "tMagCar",
+ "tOrange",
+ "tRed",
+ "tSecDoor",
+ "tSubBridge",
+ "tTeleCover",
+ "tTeleHandle",
+ "tTelePin",
+ "tTelescope",
+ "tTeleValve",
+ "tTemple",
+ "tTempleDoor",
+ "tTunnelDoor",
+ "tViewer",
+ "tViolet",
+ "tWaBrValve",
+ "tWaffle",
+ "tYellow",
// Miscellaneous
"elevbtn1",
"elevbtn2",
"elevbtn3",
- "domecheck",
- "transitionsenabled",
- "transitionmode",
- "waterenabled",
- "rivenambients",
- "stackvarsinitialized",
- "doingsetupscreens",
+ "domeCheck",
+ "transitionsEnabled",
+ "transitionMode",
+ "waterEnabled",
+ "RivenAmbients",
+ "stackVarsInitialized",
+ "DoingSetupScreens",
"all_book",
- "playerhasbook",
- "returnstackid",
- "returncardid",
- "newpos",
- "themarble",
- "currentstackid",
- "currentcardid"
+ "playerHasBook",
+ "returnStackID",
+ "returnCardID",
+ "NewPos",
+ "theMarble",
+ "CurrentStackID",
+ "CurrentCardID"
};
uint32 &MohawkEngine_Riven::getStackVar(uint32 index) {
diff --git a/engines/mortevielle/debugger.cpp b/engines/mortevielle/debugger.cpp
index c8f75918ab..b2c99b894a 100644
--- a/engines/mortevielle/debugger.cpp
+++ b/engines/mortevielle/debugger.cpp
@@ -27,9 +27,9 @@ namespace Mortevielle {
Debugger::Debugger(MortevielleEngine *vm) : GUI::Debugger() {
_vm = vm;
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("show_questions", WRAP_METHOD(Debugger, Cmd_showAllQuestions));
- DCmd_Register("reset_parano", WRAP_METHOD(Debugger, Cmd_resetParano));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("show_questions", WRAP_METHOD(Debugger, Cmd_showAllQuestions));
+ registerCmd("reset_parano", WRAP_METHOD(Debugger, Cmd_resetParano));
}
bool Debugger::Cmd_showAllQuestions(int argc, const char **argv) {
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp
index a4d1366880..91ab3e767a 100644
--- a/engines/neverhood/console.cpp
+++ b/engines/neverhood/console.cpp
@@ -34,13 +34,13 @@
namespace Neverhood {
Console::Console(NeverhoodEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("cheat", WRAP_METHOD(Console, Cmd_Cheat));
- DCmd_Register("checkresource", WRAP_METHOD(Console, Cmd_CheckResource));
- DCmd_Register("dumpresource", WRAP_METHOD(Console, Cmd_DumpResource));
- DCmd_Register("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars));
- DCmd_Register("playsound", WRAP_METHOD(Console, Cmd_PlaySound));
- DCmd_Register("scene", WRAP_METHOD(Console, Cmd_Scene));
- DCmd_Register("surfaces", WRAP_METHOD(Console, Cmd_Surfaces));
+ registerCmd("cheat", WRAP_METHOD(Console, Cmd_Cheat));
+ registerCmd("checkresource", WRAP_METHOD(Console, Cmd_CheckResource));
+ registerCmd("dumpresource", WRAP_METHOD(Console, Cmd_DumpResource));
+ registerCmd("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars));
+ registerCmd("playsound", WRAP_METHOD(Console, Cmd_PlaySound));
+ registerCmd("scene", WRAP_METHOD(Console, Cmd_Scene));
+ registerCmd("surfaces", WRAP_METHOD(Console, Cmd_Surfaces));
}
Console::~Console() {
@@ -55,33 +55,33 @@ bool Console::Cmd_Scene(int argc, const char **argv) {
const char *sceneTypes[] = { "normal", "smacker", "navigation" };
- DebugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
+ debugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
if (sceneType == kSceneTypeNormal) {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
// Normal scenes have a background and a cursor file hash
- DebugPrintf("Background hash: 0x%x, cursor hash: 0x%x\n", scene->getBackgroundFileHash(), scene->getCursorFileHash());
+ debugPrintf("Background hash: 0x%x, cursor hash: 0x%x\n", scene->getBackgroundFileHash(), scene->getCursorFileHash());
} else if (sceneType == kSceneTypeSmacker) {
SmackerScene *scene = (SmackerScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
// Smacker scenes have a file hash, or a list of hashes
// TODO: Only the first file hash is shown - any additional hashes, found in
// scenes with a list of hashes (two scenes in module 1100 and the making of
// video) aren't shown yet
- DebugPrintf("File hash: 0x%x\n", scene->getSmackerFileHash());
+ debugPrintf("File hash: 0x%x\n", scene->getSmackerFileHash());
} else if (sceneType == kSceneTypeNavigation) {
NavigationScene *scene = (NavigationScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
// Navigation scenes have a navigation list and its index
NavigationList *navigationList = _vm->_staticData->getNavigationList(scene->getNavigationListId());
int navigationIndex = scene->getGlobalVar(V_NAVIGATION_INDEX);
NavigationItem curNavigation = (*navigationList)[navigationIndex];
- DebugPrintf("Navigation list ID: 0x%x, index: %d\n", scene->getNavigationListId(), navigationIndex);
- DebugPrintf("File hash: 0x%x, cursor hash: 0x%x, Smacker hashes: [left: 0x%x, middle: 0x%x, right: 0x%x\n",
+ debugPrintf("Navigation list ID: 0x%x, index: %d\n", scene->getNavigationListId(), navigationIndex);
+ debugPrintf("File hash: 0x%x, cursor hash: 0x%x, Smacker hashes: [left: 0x%x, middle: 0x%x, right: 0x%x\n",
curNavigation.fileHash, curNavigation.mouseCursorFileHash,
curNavigation.leftSmackerFileHash, curNavigation.middleSmackerFileHash, curNavigation.rightSmackerFileHash);
}
- DebugPrintf("Use %s <module> <scene> to change scenes\n", argv[0]);
- DebugPrintf("Modules are incremental by 100, from 1000 to 3000\n");
+ debugPrintf("Use %s <module> <scene> to change scenes\n", argv[0]);
+ debugPrintf("Modules are incremental by 100, from 1000 to 3000\n");
} else {
int newModule = atoi(argv[1]);
int newScene = atoi(argv[2]);
@@ -102,17 +102,17 @@ bool Console::Cmd_Surfaces(int argc, const char **argv) {
bool Console::Cmd_Cheat(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Cheats for various puzzles in the game\n");
- DebugPrintf("Use %s <cheatname> to use a cheat.\n", argv[0]);
- DebugPrintf("Cheats:\n-------\n");
- DebugPrintf(" buttons - enables all 3 buttons on the door in the purple building, module 3000, scene 9\n");
- DebugPrintf(" cannon - sets the correct cannon combination in module 3000, scene 8\n");
- DebugPrintf(" dice - shows the correct dice combination in the teddy bear puzzle, module 1100, scene 6\n");
- DebugPrintf(" memory - solves the memory puzzle, module 1400, scene 4\n");
- DebugPrintf(" music - shows the correct index in the radio music puzzle, module 2800, scene 1\n");
- DebugPrintf(" radio - enables the radio, module 3000, scene 9 - same as pulling the rightmost cord in the flytrap room\n");
- DebugPrintf(" symbols - solves the symbols puzzle, module 1600, scene 8. Only available in that room\n");
- DebugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10\n");
+ debugPrintf("Cheats for various puzzles in the game\n");
+ debugPrintf("Use %s <cheatname> to use a cheat.\n", argv[0]);
+ debugPrintf("Cheats:\n-------\n");
+ debugPrintf(" buttons - enables all 3 buttons on the door in the purple building, module 3000, scene 9\n");
+ debugPrintf(" cannon - sets the correct cannon combination in module 3000, scene 8\n");
+ debugPrintf(" dice - shows the correct dice combination in the teddy bear puzzle, module 1100, scene 6\n");
+ debugPrintf(" memory - solves the memory puzzle, module 1400, scene 4\n");
+ debugPrintf(" music - shows the correct index in the radio music puzzle, module 2800, scene 1\n");
+ debugPrintf(" radio - enables the radio, module 3000, scene 9 - same as pulling the rightmost cord in the flytrap room\n");
+ debugPrintf(" symbols - solves the symbols puzzle, module 1600, scene 8. Only available in that room\n");
+ debugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10\n");
return true;
}
@@ -127,7 +127,7 @@ bool Console::Cmd_Cheat(int argc, const char **argv) {
scene->setSubVar(VA_LOCKS_DISABLED, 0x40119852, 1); // kScene3010ButtonNameHashes[1]
scene->setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1); // kScene3010ButtonNameHashes[2]
- DebugPrintf("All 3 door buttons have been enabled\n");
+ debugPrintf("All 3 door buttons have been enabled\n");
} else if (cheatName == "cannon") {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
@@ -137,10 +137,10 @@ bool Console::Cmd_Cheat(int argc, const char **argv) {
for (int i = 3; i < 6; i++)
scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_2, i - 3));
- DebugPrintf("Puzzle solved\n");
+ debugPrintf("Puzzle solved\n");
} else if (cheatName == "dice") {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
- DebugPrintf("Good: (%d %d %d), current: (%d %d %d)\n",
+ debugPrintf("Good: (%d %d %d), current: (%d %d %d)\n",
scene->getSubVar(VA_GOOD_DICE_NUMBERS, 0), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 1), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 2),
scene->getSubVar(VA_CURR_DICE_NUMBERS, 0), scene->getSubVar(VA_CURR_DICE_NUMBERS, 1), scene->getSubVar(VA_CURR_DICE_NUMBERS, 2)
);
@@ -162,15 +162,15 @@ bool Console::Cmd_Cheat(int argc, const char **argv) {
}
}
- DebugPrintf("Puzzle solved\n");
+ debugPrintf("Puzzle solved\n");
} else if (cheatName == "music") {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
- DebugPrintf("Good music index: %d, current radio music index: %d\n", scene->getGlobalVar(V_CURR_RADIO_MUSIC_INDEX), scene->getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX));
+ debugPrintf("Good music index: %d, current radio music index: %d\n", scene->getGlobalVar(V_CURR_RADIO_MUSIC_INDEX), scene->getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX));
} else if (cheatName == "radio") {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
scene->setGlobalVar(V_RADIO_ENABLED, 1);
- DebugPrintf("The radio has been enabled\n");
+ debugPrintf("The radio has been enabled\n");
} else if (cheatName == "symbols") {
if (moduleNum == 1600 && sceneNum == 8) {
Scene1609 *scene = ((Scene1609 *)((Module1600 *)_vm->_gameModule->_childObject)->_childObject);
@@ -183,14 +183,14 @@ bool Console::Cmd_Cheat(int argc, const char **argv) {
scene->_symbolPosition = 11;
scene->_countdown1 = 36;
- DebugPrintf("Puzzle solved\n");
+ debugPrintf("Puzzle solved\n");
} else {
- DebugPrintf("Only available in module 1600, scene 8\n");
+ debugPrintf("Only available in module 1600, scene 8\n");
}
} else if (cheatName == "tubes") {
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
- DebugPrintf("Tube set 1: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2));
- DebugPrintf("Tube set 2: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2));
+ debugPrintf("Tube set 1: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2));
+ debugPrintf("Tube set 2: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2));
}
return true;
@@ -204,7 +204,7 @@ bool Console::Cmd_Dumpvars(int argc, const char **argv) {
bool Console::Cmd_PlaySound(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: %s <sound hash>\n", argv[0]);
+ debugPrintf("Usage: %s <sound hash>\n", argv[0]);
} else {
uint32 soundHash = strtol(argv[1], NULL, 0);
AudioResourceManSoundItem *soundItem = new AudioResourceManSoundItem(_vm, soundHash);
@@ -223,17 +223,17 @@ bool Console::Cmd_CheckResource(int argc, const char **argv) {
const char *resourceNames[] = { "unknown", "unknown", "bitmap", "palette", "animation", "data", "text", "sound", "music", "unknown", "video" };
if (argc < 2) {
- DebugPrintf("Gets information about a resource\n");
- DebugPrintf("Usage: %s <resource hash>\n", argv[0]);
+ debugPrintf("Gets information about a resource\n");
+ debugPrintf("Usage: %s <resource hash>\n", argv[0]);
} else {
uint32 resourceHash = strtol(argv[1], NULL, 0);
ResourceHandle handle;
_vm->_res->queryResource(resourceHash, handle);
if (!handle.isValid()) {
- DebugPrintf("Invalid resource hash\n");
+ debugPrintf("Invalid resource hash\n");
} else {
- DebugPrintf("Resource type: %d (%s). Size: %d bytes\n", handle.type(), resourceNames[handle.type()], handle.size());
+ debugPrintf("Resource type: %d (%s). Size: %d bytes\n", handle.type(), resourceNames[handle.type()], handle.size());
}
}
@@ -242,8 +242,8 @@ bool Console::Cmd_CheckResource(int argc, const char **argv) {
bool Console::Cmd_DumpResource(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Dumps a resource to disk\n");
- DebugPrintf("Usage: %s <resource hash> <output file>\n", argv[0]);
+ debugPrintf("Dumps a resource to disk\n");
+ debugPrintf("Usage: %s <resource hash> <output file>\n", argv[0]);
} else {
uint32 resourceHash = strtol(argv[1], NULL, 0);
const char *outFileName = argv[2];
@@ -251,7 +251,7 @@ bool Console::Cmd_DumpResource(int argc, const char **argv) {
_vm->_res->queryResource(resourceHash, handle);
if (!handle.isValid()) {
- DebugPrintf("Invalid resource hash\n");
+ debugPrintf("Invalid resource hash\n");
} else {
_vm->_res->loadResource(handle, _vm->applyResourceFixes());
Common::DumpFile outFile;
diff --git a/engines/neverhood/gamevars.cpp b/engines/neverhood/gamevars.cpp
index 72b688c194..dcbe5583de 100644
--- a/engines/neverhood/gamevars.cpp
+++ b/engines/neverhood/gamevars.cpp
@@ -127,7 +127,7 @@ int16 GameVars::getSubVarIndex(int16 varIndex, uint32 subNameHash) {
void GameVars::dumpVars(Console *con) {
for (Common::Array<GameVar>::iterator it = _vars.begin(); it != _vars.end(); ++it) {
GameVar gameVar = *it;
- con->DebugPrintf("hash: %08X, var: %08X, first index: %3d, next index: %3d\n", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex);
+ con->debugPrintf("hash: %08X, var: %08X, first index: %3d, next index: %3d\n", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex);
}
}
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 3d1724ed8a..939428ed19 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -47,6 +47,7 @@ BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 h
}
BaseSurface::~BaseSurface() {
+ _surface->free();
delete _surface;
}
diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp
index b19ba05b32..5e4d67d2bc 100644
--- a/engines/neverhood/modules/module1000.cpp
+++ b/engines/neverhood/modules/module1000.cpp
@@ -693,22 +693,18 @@ uint32 Scene1005::getTextIndex1() {
uint32 Scene1005::getKloggsTextIndex() {
uint32 textIndex = getGlobalVar(V_TEXT_COUNTING_INDEX1);
if (textIndex + 1 > 10) {
- setGlobalVar(V_TEXT_COUNTING_INDEX1, 0);
textIndex = 0;
- } else {
- setGlobalVar(V_TEXT_COUNTING_INDEX1, textIndex + 1);
}
+ setGlobalVar(V_TEXT_COUNTING_INDEX1, textIndex + 1);
return textIndex + 40;
}
uint32 Scene1005::getTextIndex3() {
uint32 textIndex = getGlobalVar(V_TEXT_COUNTING_INDEX2);
- if (textIndex + 1 >= 10) {
- setGlobalVar(V_TEXT_COUNTING_INDEX2, 0);
+ if (textIndex + 1 > 10) {
textIndex = 0;
- } else {
- setGlobalVar(V_TEXT_COUNTING_INDEX2, textIndex + 1);
}
+ setGlobalVar(V_TEXT_COUNTING_INDEX2, textIndex + 1);
return textIndex + 30;
}
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 58056b65a9..1a8e74da38 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -148,7 +148,7 @@ void Scene::printSurfaces(Console *con) {
NDrawRect drawRect = _surfaces[index]->getDrawRect();
NRect clipRect = _surfaces[index]->getClipRect();
int priority = _surfaces[index]->getPriority();
- con->DebugPrintf("%d ('%s'): Priority %d, draw rect (%d, %d, %d, %d), clip rect (%d, %d, %d, %d)\n",
+ con->debugPrintf("%d ('%s'): Priority %d, draw rect (%d, %d, %d, %d), clip rect (%d, %d, %d, %d)\n",
index, _surfaces[index]->getName().c_str(), priority,
drawRect.x, drawRect.y, drawRect.x2(), drawRect.y2(),
clipRect.x1, clipRect.y1, clipRect.x2, clipRect.y2);
diff --git a/engines/neverhood/staticdata.cpp b/engines/neverhood/staticdata.cpp
index 552ea92604..03af44b2a5 100644
--- a/engines/neverhood/staticdata.cpp
+++ b/engines/neverhood/staticdata.cpp
@@ -28,6 +28,18 @@ StaticData::StaticData() {
}
StaticData::~StaticData() {
+ for (Common::HashMap<uint32, HitRectList*>::iterator i = _hitRectLists.begin(); i != _hitRectLists.end(); ++i)
+ delete i->_value;
+ for (Common::HashMap<uint32, RectList*>::iterator i = _rectLists.begin(); i != _rectLists.end(); ++i)
+ delete i->_value;
+ for (Common::HashMap<uint32, MessageList*>::iterator i = _messageLists.begin(); i != _messageLists.end(); ++i)
+ delete i->_value;
+ for (Common::HashMap<uint32, NavigationList*>::iterator i = _navigationLists.begin(); i != _navigationLists.end(); ++i)
+ delete i->_value;
+ for (Common::HashMap<uint32, HallOfRecordsInfo*>::iterator i = _hallOfRecordsInfoItems.begin(); i != _hallOfRecordsInfoItems.end(); ++i)
+ delete i->_value;
+ for (Common::HashMap<uint32, TrackInfo*>::iterator i = _trackInfoItems.begin(); i != _trackInfoItems.end(); ++i)
+ delete i->_value;
}
void StaticData::load(const char *filename) {
@@ -69,6 +81,11 @@ void StaticData::load(const char *filename) {
messageList->push_back(messageItem);
}
+ if(_messageLists.contains(id)) {
+ warning("Duplicate id %d in _messageLists - freeing older entry", id);
+ delete _messageLists[id];
+ }
+
_messageLists[id] = messageList;
}
@@ -98,6 +115,12 @@ void StaticData::load(const char *filename) {
}
rectList->push_back(rectItem);
}
+
+ if(_rectLists.contains(id)) {
+ warning("Duplicate id %d in _rectLists - freeing older entry", id);
+ delete _rectLists[id];
+ }
+
_rectLists[id] = rectList;
}
@@ -117,6 +140,12 @@ void StaticData::load(const char *filename) {
hitRect.type = fd.readUint16LE();
hitRectList->push_back(hitRect);
}
+
+ if(_hitRectLists.contains(id)) {
+ warning("Duplicate id %d in _hitRectLists - freeing older entry", id);
+ delete _hitRectLists[id];
+ }
+
_hitRectLists[id] = hitRectList;
}
@@ -138,6 +167,12 @@ void StaticData::load(const char *filename) {
navigationItem.mouseCursorFileHash = fd.readUint32LE();
navigationList->push_back(navigationItem);
}
+
+ if(_navigationLists.contains(id)) {
+ warning("Duplicate id %d in _navigationLists - freeing older entry", id);
+ delete _navigationLists[id];
+ }
+
_navigationLists[id] = navigationList;
}
@@ -153,6 +188,12 @@ void StaticData::load(const char *filename) {
hallOfRecordsInfo->bgFilename3 = fd.readUint32LE();
hallOfRecordsInfo->xPosIndex = fd.readByte();
hallOfRecordsInfo->count = fd.readByte();
+
+ if(_hallOfRecordsInfoItems.contains(id)) {
+ warning("Duplicate id %d in _hallOfRecordsInfoItems - freeing older entry", id);
+ delete _hallOfRecordsInfoItems[id];
+ }
+
_hallOfRecordsInfoItems[id] = hallOfRecordsInfo;
}
@@ -172,6 +213,12 @@ void StaticData::load(const char *filename) {
trackInfo->mouseCursorFilename = fd.readUint32LE();
trackInfo->which1 = fd.readUint16LE();
trackInfo->which2 = fd.readUint16LE();
+
+ if(_trackInfoItems.contains(id)) {
+ warning("Duplicate id %d in _trackInfoItems - freeing older entry", id);
+ delete _trackInfoItems[id];
+ }
+
_trackInfoItems[id] = trackInfo;
}
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index 1fea73a326..a7087c64d7 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -33,18 +33,18 @@ Debugger::Debugger(Parallaction *vm)
: GUI::Debugger() {
_vm = vm;
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("location", WRAP_METHOD(Debugger, Cmd_Location));
- DCmd_Register("give", WRAP_METHOD(Debugger, Cmd_Give));
- DCmd_Register("zones", WRAP_METHOD(Debugger, Cmd_Zones));
- DCmd_Register("animations", WRAP_METHOD(Debugger, Cmd_Animations));
- DCmd_Register("globalflags",WRAP_METHOD(Debugger, Cmd_GlobalFlags));
- DCmd_Register("toggleglobalflag",WRAP_METHOD(Debugger, Cmd_ToggleGlobalFlag));
- DCmd_Register("localflags", WRAP_METHOD(Debugger, Cmd_LocalFlags));
- DCmd_Register("locations", WRAP_METHOD(Debugger, Cmd_Locations));
- DCmd_Register("gfxobjects", WRAP_METHOD(Debugger, Cmd_GfxObjects));
- DCmd_Register("programs", WRAP_METHOD(Debugger, Cmd_Programs));
- DCmd_Register("showmouse", WRAP_METHOD(Debugger, Cmd_ShowMouse));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("location", WRAP_METHOD(Debugger, Cmd_Location));
+ registerCmd("give", WRAP_METHOD(Debugger, Cmd_Give));
+ registerCmd("zones", WRAP_METHOD(Debugger, Cmd_Zones));
+ registerCmd("animations", WRAP_METHOD(Debugger, Cmd_Animations));
+ registerCmd("globalflags",WRAP_METHOD(Debugger, Cmd_GlobalFlags));
+ registerCmd("toggleglobalflag",WRAP_METHOD(Debugger, Cmd_ToggleGlobalFlag));
+ registerCmd("localflags", WRAP_METHOD(Debugger, Cmd_LocalFlags));
+ registerCmd("locations", WRAP_METHOD(Debugger, Cmd_Locations));
+ registerCmd("gfxobjects", WRAP_METHOD(Debugger, Cmd_GfxObjects));
+ registerCmd("programs", WRAP_METHOD(Debugger, Cmd_Programs));
+ registerCmd("showmouse", WRAP_METHOD(Debugger, Cmd_ShowMouse));
}
@@ -81,7 +81,7 @@ bool Debugger::Cmd_Location(int argc, const char **argv) {
break;
case 1:
- DebugPrintf("location <location name> [character name]\n");
+ debugPrintf("location <location name> [character name]\n");
}
@@ -90,13 +90,13 @@ bool Debugger::Cmd_Location(int argc, const char **argv) {
bool Debugger::Cmd_Locations(int argc, const char **argv) {
- DebugPrintf("+------------------------------+---------+\n"
+ debugPrintf("+------------------------------+---------+\n"
"| location name | flags |\n"
"+------------------------------+---------+\n");
for (uint i = 0; i < _vm->_numLocations; i++) {
- DebugPrintf("|%-30s| %08x|\n", _vm->_locationNames[i], _vm->_localFlags[i]);
+ debugPrintf("|%-30s| %08x|\n", _vm->_locationNames[i], _vm->_localFlags[i]);
}
- DebugPrintf("+------------------------------+---------+\n");
+ debugPrintf("+------------------------------+---------+\n");
return true;
}
@@ -105,14 +105,14 @@ bool Debugger::Cmd_GlobalFlags(int argc, const char **argv) {
uint32 flags = g_globalFlags;
- DebugPrintf("+------------------------------+---------+\n"
+ debugPrintf("+------------------------------+---------+\n"
"| flag name | value |\n"
"+------------------------------+---------+\n");
for (uint i = 0; i < _vm->_globalFlagsNames->count(); i++) {
const char *value = ((flags & (1 << i)) == 0) ? "OFF" : "ON";
- DebugPrintf("|%-30s| %-6s|\n", _vm->_globalFlagsNames->item(i), value);
+ debugPrintf("|%-30s| %-6s|\n", _vm->_globalFlagsNames->item(i), value);
}
- DebugPrintf("+------------------------------+---------+\n");
+ debugPrintf("+------------------------------+---------+\n");
return true;
}
@@ -125,7 +125,7 @@ bool Debugger::Cmd_ToggleGlobalFlag(int argc, const char **argv) {
case 2:
i = _vm->_globalFlagsNames->lookup(argv[1]);
if (i == Table::notFound) {
- DebugPrintf("invalid flag '%s'\n", argv[1]);
+ debugPrintf("invalid flag '%s'\n", argv[1]);
} else {
i--;
if ((g_globalFlags & (1 << i)) == 0)
@@ -136,7 +136,7 @@ bool Debugger::Cmd_ToggleGlobalFlag(int argc, const char **argv) {
break;
default:
- DebugPrintf("toggleglobalflag <flag name>\n");
+ debugPrintf("toggleglobalflag <flag name>\n");
}
@@ -147,14 +147,14 @@ bool Debugger::Cmd_LocalFlags(int argc, const char **argv) {
uint32 flags = _vm->getLocationFlags();
- DebugPrintf("+------------------------------+---------+\n"
+ debugPrintf("+------------------------------+---------+\n"
"| flag name | value |\n"
"+------------------------------+---------+\n");
for (uint i = 0; i < _vm->_localFlagNames->count(); i++) {
const char *value = ((flags & (1 << i)) == 0) ? "OFF" : "ON";
- DebugPrintf("|%-30s| %-6s|\n", _vm->_localFlagNames->item(i), value);
+ debugPrintf("|%-30s| %-6s|\n", _vm->_localFlagNames->item(i), value);
}
- DebugPrintf("+------------------------------+---------+\n");
+ debugPrintf("+------------------------------+---------+\n");
return true;
}
@@ -162,13 +162,13 @@ bool Debugger::Cmd_LocalFlags(int argc, const char **argv) {
bool Debugger::Cmd_Give(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("give <item name>\n");
+ debugPrintf("give <item name>\n");
} else {
int index = _vm->_objectsNames->lookup(argv[1]);
if (index != Table::notFound)
_vm->addInventoryItem(index + 4);
else
- DebugPrintf("invalid item name '%s'\n", argv[1]);
+ debugPrintf("invalid item name '%s'\n", argv[1]);
}
return true;
@@ -181,15 +181,15 @@ bool Debugger::Cmd_Zones(int argc, const char **argv) {
ZoneList::iterator e = _vm->_location._zones.end();
Common::Rect r;
- DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"
+ debugPrintf("+--------------------+---+---+---+---+--------+--------+\n"
"| name | l | t | r | b | type | flag |\n"
"+--------------------+---+---+---+---+--------+--------+\n");
for ( ; b != e; ++b) {
ZonePtr z = *b;
z->getRect(r);
- DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, r.left, r.top, r.right, r.bottom, z->_type, z->_flags );
+ debugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, r.left, r.top, r.right, r.bottom, z->_type, z->_flags );
}
- DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n");
+ debugPrintf("+--------------------+---+---+---+---+--------+--------+\n");
return true;
@@ -260,15 +260,15 @@ bool Debugger::Cmd_Animations(int argc, const char **argv) {
AnimationList::iterator e = _vm->_location._animations.end();
Common::String flags;
- DebugPrintf("+--------------------+----+----+----+---+--------+----------------------------------------+\n"
+ debugPrintf("+--------------------+----+----+----+---+--------+----------------------------------------+\n"
"| name | x | y | z | f | type | flags | \n"
"+--------------------+----+----+----+---+--------+----------------------------------------+\n");
for ( ; b != e; ++b) {
AnimationPtr a = *b;
flags = decodeZoneFlags(a->_flags);
- DebugPrintf("|%-20s|%4i|%4i|%4i|%3i|%8x|%-40s|\n", a->_name, a->getX(), a->getY(), a->getZ(), a->getF(), a->_type, flags.c_str() );
+ debugPrintf("|%-20s|%4i|%4i|%4i|%3i|%8x|%-40s|\n", a->_name, a->getX(), a->getY(), a->getZ(), a->getF(), a->_type, flags.c_str() );
}
- DebugPrintf("+--------------------+---+---+---+---+--------+----------------------------------------+\n");
+ debugPrintf("+--------------------+---+---+---+---+--------+----------------------------------------+\n");
return true;
@@ -278,7 +278,7 @@ bool Debugger::Cmd_GfxObjects(int argc, const char **argv) {
const char *objType[] = { "DOOR", "GET", "ANIM" };
- DebugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n"
+ debugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n"
"| name | x | y | w | h | z | layer | f | type |\n"
"+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n");
@@ -289,11 +289,11 @@ bool Debugger::Cmd_GfxObjects(int argc, const char **argv) {
for ( ; b != e; ++b) {
GfxObj *obj = *b;
obj->getRect(obj->frame, r);
- DebugPrintf("|%-20s|%5i|%5i|%5i|%5i|%5i|%7i|%5i|%8s|\n", obj->getName(), r.left, r.top, r.width(), r.height(),
+ debugPrintf("|%-20s|%5i|%5i|%5i|%5i|%5i|%7i|%5i|%8s|\n", obj->getName(), r.left, r.top, r.width(), r.height(),
obj->z, obj->layer, obj->frame, objType[obj->type]);
}
- DebugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n");
+ debugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n");
return true;
}
@@ -307,14 +307,14 @@ bool Debugger::Cmd_Programs(int argc, const char** argv) {
int i = 1;
- DebugPrintf("+---+--------------------+--------+----------+\n"
+ debugPrintf("+---+--------------------+--------+----------+\n"
"| # | bound animation | size | status |\n"
"+---+--------------------+--------+----------+\n");
for ( ; b != e; b++, i++) {
ProgramPtr p = *b;
- DebugPrintf("|%3i|%-20s|%8i|%-10s|\n", i, p->_anim->_name, p->_instructions.size(), status[p->_status] );
+ debugPrintf("|%3i|%-20s|%8i|%-10s|\n", i, p->_anim->_name, p->_instructions.size(), status[p->_status] );
}
- DebugPrintf("+---+--------------------+--------+----------+\n");
+ debugPrintf("+---+--------------------+--------+----------+\n");
return true;
}
diff --git a/engines/parallaction/debug.h b/engines/parallaction/debug.h
index 887d08e945..551d746edf 100644
--- a/engines/parallaction/debug.h
+++ b/engines/parallaction/debug.h
@@ -22,7 +22,6 @@ private:
Parallaction *_vm;
MouseTriState _mouseState;
- bool Cmd_DebugLevel(int argc, const char **argv);
bool Cmd_Location(int argc, const char **argv);
bool Cmd_Give(int argc, const char **argv);
bool Cmd_Zones(int argc, const char **argv);
diff --git a/engines/pegasus/console.cpp b/engines/pegasus/console.cpp
index 64bd0ba5f2..e5a0cfec98 100644
--- a/engines/pegasus/console.cpp
+++ b/engines/pegasus/console.cpp
@@ -28,11 +28,11 @@
namespace Pegasus {
PegasusConsole::PegasusConsole(PegasusEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("die", WRAP_METHOD(PegasusConsole, Cmd_Die));
+ registerCmd("die", WRAP_METHOD(PegasusConsole, Cmd_Die));
// These functions are non-demo specific
if (!_vm->isDemo())
- DCmd_Register("jump", WRAP_METHOD(PegasusConsole, Cmd_Jump));
+ registerCmd("jump", WRAP_METHOD(PegasusConsole, Cmd_Jump));
}
PegasusConsole::~PegasusConsole() {
@@ -40,7 +40,7 @@ PegasusConsole::~PegasusConsole() {
bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
if (argc == 1) {
- DebugPrintf("Usage: die <death reason>\n");
+ debugPrintf("Usage: die <death reason>\n");
return true;
}
@@ -54,7 +54,7 @@ bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
if (invalidReason) {
- DebugPrintf("Invalid death reason %d\n", reason);
+ debugPrintf("Invalid death reason %d\n", reason);
return true;
}
@@ -65,14 +65,14 @@ bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
bool PegasusConsole::Cmd_Jump(int argc, const char **argv) {
if (!g_interface) {
// TODO
- DebugPrintf("Cannot jump without interface set up\n");
+ debugPrintf("Cannot jump without interface set up\n");
return true;
}
// TODO: Default room/direction for each neighborhood
if (argc < 4) {
- DebugPrintf("Usage: jump <neighborhood> <room> <direction>\n");
+ debugPrintf("Usage: jump <neighborhood> <room> <direction>\n");
return true;
}
@@ -82,14 +82,14 @@ bool PegasusConsole::Cmd_Jump(int argc, const char **argv) {
if ((neighborhood < kCaldoriaID || neighborhood > kNoradDeltaID || neighborhood == kFinalTSAID) &&
neighborhood != kNoradSubChaseID) {
- DebugPrintf("Invalid neighborhood %d", neighborhood);
+ debugPrintf("Invalid neighborhood %d", neighborhood);
return true;
}
// No real way to check room validity at this point
if (direction > kWest) {
- DebugPrintf("Invalid direction %d", direction);
+ debugPrintf("Invalid direction %d", direction);
return true;
}
diff --git a/engines/queen/debug.cpp b/engines/queen/debug.cpp
index 3706806ac2..125ddf30c6 100644
--- a/engines/queen/debug.cpp
+++ b/engines/queen/debug.cpp
@@ -36,15 +36,15 @@ namespace Queen {
Debugger::Debugger(QueenEngine *vm)
: _vm(vm), _flags(0) {
- DCmd_Register("areas", WRAP_METHOD(Debugger, Cmd_Areas));
- DCmd_Register("asm", WRAP_METHOD(Debugger, Cmd_Asm));
- DCmd_Register("bob", WRAP_METHOD(Debugger, Cmd_Bob));
- DCmd_Register("bobs", WRAP_METHOD(Debugger, Cmd_PrintBobs));
- DCmd_Register("gs", WRAP_METHOD(Debugger, Cmd_GameState));
- DCmd_Register("info", WRAP_METHOD(Debugger, Cmd_Info));
- DCmd_Register("items", WRAP_METHOD(Debugger, Cmd_Items));
- DCmd_Register("room", WRAP_METHOD(Debugger, Cmd_Room));
- DCmd_Register("song", WRAP_METHOD(Debugger, Cmd_Song));
+ registerCmd("areas", WRAP_METHOD(Debugger, Cmd_Areas));
+ registerCmd("asm", WRAP_METHOD(Debugger, Cmd_Asm));
+ registerCmd("bob", WRAP_METHOD(Debugger, Cmd_Bob));
+ registerCmd("bobs", WRAP_METHOD(Debugger, Cmd_PrintBobs));
+ registerCmd("gs", WRAP_METHOD(Debugger, Cmd_GameState));
+ registerCmd("info", WRAP_METHOD(Debugger, Cmd_Info));
+ registerCmd("items", WRAP_METHOD(Debugger, Cmd_Items));
+ registerCmd("room", WRAP_METHOD(Debugger, Cmd_Room));
+ registerCmd("song", WRAP_METHOD(Debugger, Cmd_Song));
}
Debugger::~Debugger() {} // we need this here for __SYMBIAN32__
@@ -73,14 +73,14 @@ bool Debugger::Cmd_Asm(int argc, const char **argv) {
_vm->logic()->executeSpecialMove(sm);
return false;
} else {
- DebugPrintf("Usage: %s smnum\n", argv[0]);
+ debugPrintf("Usage: %s smnum\n", argv[0]);
}
return true;
}
bool Debugger::Cmd_Areas(int argc, const char **argv) {
_flags ^= DF_DRAW_AREAS;
- DebugPrintf("Room areas display %s\n", (_flags & DF_DRAW_AREAS) != 0 ? "on" : "off");
+ debugPrintf("Room areas display %s\n", (_flags & DF_DRAW_AREAS) != 0 ? "on" : "off");
return true;
}
@@ -88,36 +88,36 @@ bool Debugger::Cmd_Bob(int argc, const char **argv) {
if (argc >= 3 && isNumeric(argv[1])) {
int bobNum = atoi(argv[1]);
if (bobNum >= Graphics::MAX_BOBS_NUMBER) {
- DebugPrintf("Bob %d is out of range (range: 0 - %d)\n", bobNum, Graphics::MAX_BOBS_NUMBER);
+ debugPrintf("Bob %d is out of range (range: 0 - %d)\n", bobNum, Graphics::MAX_BOBS_NUMBER);
} else {
int param = 0;
if (argc > 3 && isNumeric(argv[3])) {
param = atoi(argv[3]);
} else {
- DebugPrintf("Invalid parameter for bob command '%s'\n", argv[2]);
+ debugPrintf("Invalid parameter for bob command '%s'\n", argv[2]);
}
BobSlot *bob = _vm->graphics()->bob(bobNum);
if (!strcmp(argv[2], "toggle")) {
bob->active = !bob->active;
- DebugPrintf("bob[%d].active = %d\n", bobNum, bob->active);
+ debugPrintf("bob[%d].active = %d\n", bobNum, bob->active);
} else if (!strcmp(argv[2], "x")) {
bob->x = param;
- DebugPrintf("bob[%d].x = %d\n", bobNum, bob->x);
+ debugPrintf("bob[%d].x = %d\n", bobNum, bob->x);
} else if (!strcmp(argv[2], "y")) {
bob->y = param;
- DebugPrintf("bob[%d].y = %d\n", bobNum, bob->y);
+ debugPrintf("bob[%d].y = %d\n", bobNum, bob->y);
} else if (!strcmp(argv[2], "frame")) {
bob->frameNum = param;
- DebugPrintf("bob[%d].frameNum = %d\n", bobNum, bob->frameNum);
+ debugPrintf("bob[%d].frameNum = %d\n", bobNum, bob->frameNum);
} else if (!strcmp(argv[2], "speed")) {
bob->speed = param;
- DebugPrintf("bob[%d].speed = %d\n", bobNum, bob->speed);
+ debugPrintf("bob[%d].speed = %d\n", bobNum, bob->speed);
} else {
- DebugPrintf("Unknown bob command '%s'\n", argv[2]);
+ debugPrintf("Unknown bob command '%s'\n", argv[2]);
}
}
} else {
- DebugPrintf("Usage: %s bobnum command parameter\n", argv[0]);
+ debugPrintf("Usage: %s bobnum command parameter\n", argv[0]);
}
return true;
}
@@ -126,26 +126,26 @@ bool Debugger::Cmd_GameState(int argc, const char **argv) {
uint16 slot;
if ((argc == 2 || argc == 3) && isNumeric(argv[1])) {
slot = atoi(argv[1]);
- DebugPrintf("GAMESTATE[%d] ", slot);
- DebugPrintf("%s %d\n", (argc == 2) ? "is" : "was", _vm->logic()->gameState(slot));
+ debugPrintf("GAMESTATE[%d] ", slot);
+ debugPrintf("%s %d\n", (argc == 2) ? "is" : "was", _vm->logic()->gameState(slot));
if (argc == 3) {
if (isNumeric(argv[1])) {
_vm->logic()->gameState(slot, atoi(argv[2]));
- DebugPrintf("now %d\n", _vm->logic()->gameState(slot));
+ debugPrintf("now %d\n", _vm->logic()->gameState(slot));
} else {
- DebugPrintf("Usage: %s slotnum <value>\n", argv[0]);
+ debugPrintf("Usage: %s slotnum <value>\n", argv[0]);
}
}
} else {
- DebugPrintf("Usage: %s slotnum <value>\n", argv[0]);
+ debugPrintf("Usage: %s slotnum <value>\n", argv[0]);
}
return true;
}
bool Debugger::Cmd_Info(int argc, const char **argv) {
- DebugPrintf("Version: %s\n", _vm->resource()->getJASVersion());
- DebugPrintf("Audio compression: %d\n", _vm->resource()->getCompression());
+ debugPrintf("Version: %s\n", _vm->resource()->getJASVersion());
+ debugPrintf("Audio compression: %d\n", _vm->resource()->getCompression());
return true;
}
@@ -156,24 +156,24 @@ bool Debugger::Cmd_Items(int argc, const char **argv) {
item->name = ABS(item->name);
++item;
}
- DebugPrintf("Enabled all inventory items\n");
+ debugPrintf("Enabled all inventory items\n");
return true;
}
bool Debugger::Cmd_PrintBobs(int argc, const char**argv) {
int i;
BobSlot *bob = _vm->graphics()->bob(0);
- DebugPrintf("+------------------------------------+\n");
- DebugPrintf("|# | x| y|f|scl|frm|a|m|spd| ex| ey|\n");
- DebugPrintf("+--+---+---+-+---+---+-+-+---+---+---+\n");
+ debugPrintf("+------------------------------------+\n");
+ debugPrintf("|# | x| y|f|scl|frm|a|m|spd| ex| ey|\n");
+ debugPrintf("+--+---+---+-+---+---+-+-+---+---+---+\n");
for (i = 0; i < Graphics::MAX_BOBS_NUMBER; ++i, ++bob) {
if (bob->active) {
- DebugPrintf("|%2d|%3d|%3d|%1d|%3d|%3d|%1d|%1d|%3d|%3d|%3d|\n",
+ debugPrintf("|%2d|%3d|%3d|%1d|%3d|%3d|%1d|%1d|%3d|%3d|%3d|\n",
i, bob->x, bob->y, bob->xflip, bob->scale, bob->frameNum,
bob->animating, bob->moving, bob->speed, bob->endx, bob->endy);
}
}
- DebugPrintf("+--------------------------------+\n");
+ debugPrintf("+--------------------------------+\n");
return true;
}
@@ -185,7 +185,7 @@ bool Debugger::Cmd_Room(int argc, const char **argv) {
_vm->logic()->entryObj(_vm->logic()->roomData(roomNum) + 1);
return false;
} else {
- DebugPrintf("Current room: %d (%s), use '%s <roomnum>' to switch\n",
+ debugPrintf("Current room: %d (%s), use '%s <roomnum>' to switch\n",
_vm->logic()->currentRoom(),
_vm->logic()->roomName(_vm->logic()->currentRoom()),
argv[0]);
@@ -197,9 +197,9 @@ bool Debugger::Cmd_Song(int argc, const char **argv) {
if (argc == 2 && isNumeric(argv[1])) {
int16 songNum = atoi(argv[1]);
_vm->sound()->playSong(songNum);
- DebugPrintf("Playing song %d\n", songNum);
+ debugPrintf("Playing song %d\n", songNum);
} else {
- DebugPrintf("Usage: %s songnum\n", argv[0]);
+ debugPrintf("Usage: %s songnum\n", argv[0]);
}
return true;
}
diff --git a/engines/saga/actor_walk.cpp b/engines/saga/actor_walk.cpp
index a5345261c5..04741da2cd 100644
--- a/engines/saga/actor_walk.cpp
+++ b/engines/saga/actor_walk.cpp
@@ -1378,7 +1378,7 @@ void Actor::cmdActorWalkTo(int argc, const char **argv) {
location.fromScreenPoint(movePoint);
if (!validActorId(actorId)) {
- _vm->_console->DebugPrintf("Actor::cmActorWalkTo Invalid actorId 0x%X.\n", actorId);
+ _vm->_console->debugPrintf("Actor::cmActorWalkTo Invalid actorId 0x%X.\n", actorId);
return;
}
diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp
index 9e0bcf52ad..25119c6407 100644
--- a/engines/saga/animation.cpp
+++ b/engines/saga/animation.cpp
@@ -914,14 +914,14 @@ void Anim::animInfo() {
animCount = getAnimationCount();
- _vm->_console->DebugPrintf("There are %d animations loaded:\n", animCount);
+ _vm->_console->debugPrintf("There are %d animations loaded:\n", animCount);
for (i = 0; i < MAX_ANIMATIONS; i++) {
if (_animations[i] == NULL) {
continue;
}
- _vm->_console->DebugPrintf("%02d: Frames: %u Flags: %u\n", i, _animations[i]->maxFrame, _animations[i]->flags);
+ _vm->_console->debugPrintf("%02d: Frames: %u Flags: %u\n", i, _animations[i]->maxFrame, _animations[i]->flags);
}
}
@@ -929,10 +929,10 @@ void Anim::animInfo() {
void Anim::cutawayInfo() {
uint16 i;
- _vm->_console->DebugPrintf("There are %d cutaways loaded:\n", _cutawayList.size());
+ _vm->_console->debugPrintf("There are %d cutaways loaded:\n", _cutawayList.size());
for (i = 0; i < _cutawayList.size(); i++) {
- _vm->_console->DebugPrintf("%02d: Bg res: %u Anim res: %u Cycles: %u Framerate: %u\n", i,
+ _vm->_console->debugPrintf("%02d: Bg res: %u Anim res: %u Cycles: %u Framerate: %u\n", i,
_cutawayList[i].backgroundResourceId, _cutawayList[i].animResourceId,
_cutawayList[i].cycles, _cutawayList[i].frameRate);
}
diff --git a/engines/saga/console.cpp b/engines/saga/console.cpp
index eab615b33f..0b801eef3e 100644
--- a/engines/saga/console.cpp
+++ b/engines/saga/console.cpp
@@ -35,15 +35,15 @@ namespace Saga {
Console::Console(SagaEngine *vm) : GUI::Debugger() {
_vm = vm;
- DCmd_Register("continue", WRAP_METHOD(Console, Cmd_Exit));
+ registerCmd("continue", WRAP_METHOD(Console, cmdExit));
// Actor commands
- DCmd_Register("actor_walk_to", WRAP_METHOD(Console, cmdActorWalkTo));
+ registerCmd("actor_walk_to", WRAP_METHOD(Console, cmdActorWalkTo));
// Animation commands
- DCmd_Register("anim_info", WRAP_METHOD(Console, cmdAnimInfo));
- DCmd_Register("cutaway_info", WRAP_METHOD(Console, cmdCutawayInfo));
- DCmd_Register("play_cutaway", WRAP_METHOD(Console, cmdPlayCutaway));
+ registerCmd("anim_info", WRAP_METHOD(Console, cmdAnimInfo));
+ registerCmd("cutaway_info", WRAP_METHOD(Console, cmdCutawayInfo));
+ registerCmd("play_cutaway", WRAP_METHOD(Console, cmdPlayCutaway));
// Game stuff
@@ -60,28 +60,28 @@ Console::Console(SagaEngine *vm) : GUI::Debugger() {
#endif
// Scene commands
- DCmd_Register("current_scene", WRAP_METHOD(Console, cmdCurrentScene));
- DCmd_Register("current_chapter", WRAP_METHOD(Console, cmdCurrentChapter));
- DCmd_Register("scene_change", WRAP_METHOD(Console, cmdSceneChange));
- DCmd_Register("chapter_change", WRAP_METHOD(Console, cmdChapterChange));
+ registerCmd("current_scene", WRAP_METHOD(Console, cmdCurrentScene));
+ registerCmd("current_chapter", WRAP_METHOD(Console, cmdCurrentChapter));
+ registerCmd("scene_change", WRAP_METHOD(Console, cmdSceneChange));
+ registerCmd("chapter_change", WRAP_METHOD(Console, cmdChapterChange));
- DCmd_Register("action_map_info", WRAP_METHOD(Console, cmdActionMapInfo));
- DCmd_Register("object_map_info", WRAP_METHOD(Console, cmdObjectMapInfo));
+ registerCmd("action_map_info", WRAP_METHOD(Console, cmdActionMapInfo));
+ registerCmd("object_map_info", WRAP_METHOD(Console, cmdObjectMapInfo));
// Script commands
- DCmd_Register("wake_up_threads", WRAP_METHOD(Console, cmdWakeUpThreads));
+ registerCmd("wake_up_threads", WRAP_METHOD(Console, cmdWakeUpThreads));
// Panel commands
- DCmd_Register("current_panel_mode", WRAP_METHOD(Console, cmdCurrentPanelMode));
- DCmd_Register("set_panel_mode", WRAP_METHOD(Console, cmdSetPanelMode));
+ registerCmd("current_panel_mode", WRAP_METHOD(Console, cmdCurrentPanelMode));
+ registerCmd("set_panel_mode", WRAP_METHOD(Console, cmdSetPanelMode));
// Font commands
- DCmd_Register("set_font_mapping", WRAP_METHOD(Console, cmdSetFontMapping));
+ registerCmd("set_font_mapping", WRAP_METHOD(Console, cmdSetFontMapping));
// Global flags commands
- DCmd_Register("global_flags_info", WRAP_METHOD(Console, cmdGlobalFlagsInfo));
- DCmd_Register("set_global_flag", WRAP_METHOD(Console, cmdSetGlobalFlag));
- DCmd_Register("clear_global_flag", WRAP_METHOD(Console, cmdClearGlobalFlag));
+ registerCmd("global_flags_info", WRAP_METHOD(Console, cmdGlobalFlagsInfo));
+ registerCmd("set_global_flag", WRAP_METHOD(Console, cmdSetGlobalFlag));
+ registerCmd("clear_global_flag", WRAP_METHOD(Console, cmdClearGlobalFlag));
}
Console::~Console() {
@@ -89,7 +89,7 @@ Console::~Console() {
bool Console::cmdActorWalkTo(int argc, const char **argv) {
if (argc != 4)
- DebugPrintf("Usage: %s <Actor id> <lx> <ly>\n", argv[0]);
+ debugPrintf("Usage: %s <Actor id> <lx> <ly>\n", argv[0]);
else
_vm->_actor->cmdActorWalkTo(argc, argv);
return true;
@@ -110,7 +110,7 @@ bool Console::cmdCutawayInfo(int argc, const char **argv) {
bool Console::cmdPlayCutaway(int argc, const char **argv) {
#ifdef ENABLE_IHNM
if (argc != 2)
- DebugPrintf("Usage: %s <Cutaway number>\n", argv[0]);
+ debugPrintf("Usage: %s <Cutaway number>\n", argv[0]);
else
_vm->_anim->playCutaway(atoi(argv[1]), false);
#endif
@@ -118,19 +118,19 @@ bool Console::cmdPlayCutaway(int argc, const char **argv) {
}
bool Console::cmdCurrentScene(int argc, const char **argv) {
- DebugPrintf("Current Scene is: %i, scene resource id: %i\n",
+ debugPrintf("Current Scene is: %i, scene resource id: %i\n",
_vm->_scene->currentSceneNumber(), _vm->_scene->currentSceneResourceId());
return true;
}
bool Console::cmdCurrentChapter(int argc, const char **argv) {
- DebugPrintf("Current Chapter is: %i\n", _vm->_scene->currentChapterNumber());
+ debugPrintf("Current Chapter is: %i\n", _vm->_scene->currentChapterNumber());
return true;
}
bool Console::cmdSceneChange(int argc, const char **argv) {
if (argc != 2)
- DebugPrintf("Usage: %s <Scene number>\n", argv[0]);
+ debugPrintf("Usage: %s <Scene number>\n", argv[0]);
else
_vm->_scene->cmdSceneChange(argc, argv);
return true;
@@ -138,7 +138,7 @@ bool Console::cmdSceneChange(int argc, const char **argv) {
bool Console::cmdChapterChange(int argc, const char **argv) {
if (argc != 3)
- DebugPrintf("Usage: %s <Chapter number> <Scene number>\n", argv[0]);
+ debugPrintf("Usage: %s <Chapter number> <Scene number>\n", argv[0]);
else {
_vm->_scene->setChapterNumber(atoi(argv[2]));
_vm->_scene->cmdSceneChange(argc, argv);
@@ -158,9 +158,9 @@ bool Console::cmdObjectMapInfo(int argc, const char **argv) {
bool Console::cmdWakeUpThreads(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s <wait type>\n", argv[0]);
- DebugPrintf("e.g.: 1 for kWaitTypeDelay, 2 for kWaitTypeSpeech, 10 for kWaitTypeWaitFrames");
- DebugPrintf("Refer to saga/script.h for additional types");
+ debugPrintf("Usage: %s <wait type>\n", argv[0]);
+ debugPrintf("e.g.: 1 for kWaitTypeDelay, 2 for kWaitTypeSpeech, 10 for kWaitTypeWaitFrames");
+ debugPrintf("Refer to saga/script.h for additional types");
} else {
_vm->_script->wakeUpThreads(atoi(argv[1]));
}
@@ -168,13 +168,13 @@ bool Console::cmdWakeUpThreads(int argc, const char **argv) {
}
bool Console::cmdCurrentPanelMode(int argc, const char **argv) {
- DebugPrintf("Current Panel Mode is: %i\n", _vm->_interface->getMode());
+ debugPrintf("Current Panel Mode is: %i\n", _vm->_interface->getMode());
return true;
}
bool Console::cmdSetPanelMode(int argc, const char **argv) {
if (argc != 2)
- DebugPrintf("Usage: %s <Panel mode number>\n", argv[0]);
+ debugPrintf("Usage: %s <Panel mode number>\n", argv[0]);
else
_vm->_interface->setMode(atoi(argv[1]));
return true;
@@ -182,8 +182,8 @@ bool Console::cmdSetPanelMode(int argc, const char **argv) {
bool Console::cmdSetFontMapping(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Sets font mapping\nUsage: %s <Font mapping flag>\n", argv[0]);
- DebugPrintf("Mapping flags:\n0 - default game behavior\n1 - force font mapping\n2 - ignore font mapping\n");
+ debugPrintf("Sets font mapping\nUsage: %s <Font mapping flag>\n", argv[0]);
+ debugPrintf("Mapping flags:\n0 - default game behavior\n1 - force font mapping\n2 - ignore font mapping\n");
} else {
_vm->_font->setFontMapping(atoi(argv[1]));
}
@@ -191,7 +191,7 @@ bool Console::cmdSetFontMapping(int argc, const char **argv) {
}
bool Console::cmdGlobalFlagsInfo(int argc, const char **argv) {
- DebugPrintf("Global flags status for IHNM:\n");
+ debugPrintf("Global flags status for IHNM:\n");
// Global flags in IHNM:
// 00: Tested when Gorrister's chapter ends. 0: Gorrister failed, 1: Gorrister won
@@ -232,9 +232,9 @@ bool Console::cmdGlobalFlagsInfo(int argc, const char **argv) {
for (i = 0; i < 32; i += 8) {
for (k = i; k < i + 8; k ++) {
flagStatus = _vm->_globalFlags & (1 << k) ? 1 : 0;
- _vm->_console->DebugPrintf("%02d: %u |", k, flagStatus);
+ _vm->_console->debugPrintf("%02d: %u |", k, flagStatus);
}
- _vm->_console->DebugPrintf("\n");
+ _vm->_console->debugPrintf("\n");
}
return true;
@@ -242,13 +242,13 @@ bool Console::cmdGlobalFlagsInfo(int argc, const char **argv) {
bool Console::cmdSetGlobalFlag(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s <Global flag number>\nValid flag numbers are 0 - 31\n", argv[0]);
+ debugPrintf("Usage: %s <Global flag number>\nValid flag numbers are 0 - 31\n", argv[0]);
} else {
int flagNumber = atoi(argv[1]);
if (flagNumber >= 0 && flagNumber <= 31) {
_vm->_globalFlags |= (1 << flagNumber);
} else {
- DebugPrintf("Valid flag numbers are 0 - 31\n");
+ debugPrintf("Valid flag numbers are 0 - 31\n");
}
}
return true;
@@ -256,13 +256,13 @@ bool Console::cmdSetGlobalFlag(int argc, const char **argv) {
bool Console::cmdClearGlobalFlag(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s <Global flag number>\nValid flag numbers are 0 - 31\n", argv[0]);
+ debugPrintf("Usage: %s <Global flag number>\nValid flag numbers are 0 - 31\n", argv[0]);
} else {
int flagNumber = atoi(argv[1]);
if (flagNumber >= 0 && flagNumber <= 31) {
_vm->_globalFlags &= ~(1 << flagNumber);
} else {
- DebugPrintf("Valid flag numbers are 0 - 31\n");
+ debugPrintf("Valid flag numbers are 0 - 31\n");
}
}
return true;
diff --git a/engines/saga/objectmap.cpp b/engines/saga/objectmap.cpp
index f27c888a61..ad5167209c 100644
--- a/engines/saga/objectmap.cpp
+++ b/engines/saga/objectmap.cpp
@@ -231,7 +231,7 @@ int ObjectMap::hitTest(const Point& testPoint) {
}
void ObjectMap::cmdInfo() {
- _vm->_console->DebugPrintf("%d zone(s) loaded.\n\n", _hitZoneList.size());
+ _vm->_console->debugPrintf("%d zone(s) loaded.\n\n", _hitZoneList.size());
}
} // End of namespace Saga
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index 7f77cbab38..04776bd5dc 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -1220,7 +1220,7 @@ void Scene::cmdSceneChange(int argc, const char **argv) {
scene_num = atoi(argv[1]);
if ((scene_num < 1) || (uint(scene_num) >= _sceneLUT.size())) {
- _vm->_console->DebugPrintf("Invalid scene number.\n");
+ _vm->_console->debugPrintf("Invalid scene number.\n");
return;
}
diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp
index 91e39c54b6..cb963e23ac 100644
--- a/engines/saga/sfuncs.cpp
+++ b/engines/saga/sfuncs.cpp
@@ -139,7 +139,7 @@ void Script::setupITEScriptFuncList() {
void Script::sfPutString(SCRIPTFUNC_PARAMS) {
const char *str = thread->_strings->getString(thread->pop());
- _vm->_console->DebugPrintf("sfPutString: %s\n",str);
+ _vm->_console->debugPrintf("sfPutString: %s\n",str);
debug(0, "sfPutString: %s", str);
}
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 1bc0dd067c..1c4228eb7d 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -79,148 +79,151 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
assert(_engine->_gamestate);
// Variables
- DVar_Register("sleeptime_factor", &g_debug_sleeptime_factor, DVAR_INT, 0);
- DVar_Register("gc_interval", &engine->_gamestate->scriptGCInterval, DVAR_INT, 0);
- DVar_Register("simulated_key", &g_debug_simulated_key, DVAR_INT, 0);
- DVar_Register("track_mouse_clicks", &g_debug_track_mouse_clicks, DVAR_BOOL, 0);
- DVar_Register("script_abort_flag", &_engine->_gamestate->abortScriptProcessing, DVAR_INT, 0);
+ registerVar("sleeptime_factor", &g_debug_sleeptime_factor);
+ registerVar("gc_interval", &engine->_gamestate->scriptGCInterval);
+ registerVar("simulated_key", &g_debug_simulated_key);
+ registerVar("track_mouse_clicks", &g_debug_track_mouse_clicks);
+ // FIXME: This actually passes an enum type instead of an integer but no
+ // precaution is taken to assure that all assigned values are in the range
+ // of the enum type. We should handle this more carefully...
+ registerVar("script_abort_flag", (int *)&_engine->_gamestate->abortScriptProcessing);
// General
- DCmd_Register("help", WRAP_METHOD(Console, cmdHelp));
+ registerCmd("help", WRAP_METHOD(Console, cmdHelp));
// Kernel
-// DCmd_Register("classes", WRAP_METHOD(Console, cmdClasses)); // TODO
- DCmd_Register("opcodes", WRAP_METHOD(Console, cmdOpcodes));
- DCmd_Register("selector", WRAP_METHOD(Console, cmdSelector));
- DCmd_Register("selectors", WRAP_METHOD(Console, cmdSelectors));
- DCmd_Register("functions", WRAP_METHOD(Console, cmdKernelFunctions));
- DCmd_Register("class_table", WRAP_METHOD(Console, cmdClassTable));
+// registerCmd("classes", WRAP_METHOD(Console, cmdClasses)); // TODO
+ registerCmd("opcodes", WRAP_METHOD(Console, cmdOpcodes));
+ registerCmd("selector", WRAP_METHOD(Console, cmdSelector));
+ registerCmd("selectors", WRAP_METHOD(Console, cmdSelectors));
+ registerCmd("functions", WRAP_METHOD(Console, cmdKernelFunctions));
+ registerCmd("class_table", WRAP_METHOD(Console, cmdClassTable));
// Parser
- DCmd_Register("suffixes", WRAP_METHOD(Console, cmdSuffixes));
- DCmd_Register("parse_grammar", WRAP_METHOD(Console, cmdParseGrammar));
- DCmd_Register("parser_nodes", WRAP_METHOD(Console, cmdParserNodes));
- DCmd_Register("parser_words", WRAP_METHOD(Console, cmdParserWords));
- DCmd_Register("sentence_fragments", WRAP_METHOD(Console, cmdSentenceFragments));
- DCmd_Register("parse", WRAP_METHOD(Console, cmdParse));
- DCmd_Register("set_parse_nodes", WRAP_METHOD(Console, cmdSetParseNodes));
- DCmd_Register("said", WRAP_METHOD(Console, cmdSaid));
+ registerCmd("suffixes", WRAP_METHOD(Console, cmdSuffixes));
+ registerCmd("parse_grammar", WRAP_METHOD(Console, cmdParseGrammar));
+ registerCmd("parser_nodes", WRAP_METHOD(Console, cmdParserNodes));
+ registerCmd("parser_words", WRAP_METHOD(Console, cmdParserWords));
+ registerCmd("sentence_fragments", WRAP_METHOD(Console, cmdSentenceFragments));
+ registerCmd("parse", WRAP_METHOD(Console, cmdParse));
+ registerCmd("set_parse_nodes", WRAP_METHOD(Console, cmdSetParseNodes));
+ registerCmd("said", WRAP_METHOD(Console, cmdSaid));
// Resources
- DCmd_Register("diskdump", WRAP_METHOD(Console, cmdDiskDump));
- DCmd_Register("hexdump", WRAP_METHOD(Console, cmdHexDump));
- DCmd_Register("resource_id", WRAP_METHOD(Console, cmdResourceId));
- DCmd_Register("resource_info", WRAP_METHOD(Console, cmdResourceInfo));
- DCmd_Register("resource_types", WRAP_METHOD(Console, cmdResourceTypes));
- DCmd_Register("list", WRAP_METHOD(Console, cmdList));
- DCmd_Register("hexgrep", WRAP_METHOD(Console, cmdHexgrep));
- DCmd_Register("verify_scripts", WRAP_METHOD(Console, cmdVerifyScripts));
+ registerCmd("diskdump", WRAP_METHOD(Console, cmdDiskDump));
+ registerCmd("hexdump", WRAP_METHOD(Console, cmdHexDump));
+ registerCmd("resource_id", WRAP_METHOD(Console, cmdResourceId));
+ registerCmd("resource_info", WRAP_METHOD(Console, cmdResourceInfo));
+ registerCmd("resource_types", WRAP_METHOD(Console, cmdResourceTypes));
+ registerCmd("list", WRAP_METHOD(Console, cmdList));
+ registerCmd("hexgrep", WRAP_METHOD(Console, cmdHexgrep));
+ registerCmd("verify_scripts", WRAP_METHOD(Console, cmdVerifyScripts));
// Game
- DCmd_Register("save_game", WRAP_METHOD(Console, cmdSaveGame));
- DCmd_Register("restore_game", WRAP_METHOD(Console, cmdRestoreGame));
- DCmd_Register("restart_game", WRAP_METHOD(Console, cmdRestartGame));
- DCmd_Register("version", WRAP_METHOD(Console, cmdGetVersion));
- DCmd_Register("room", WRAP_METHOD(Console, cmdRoomNumber));
- DCmd_Register("quit", WRAP_METHOD(Console, cmdQuit));
- DCmd_Register("list_saves", WRAP_METHOD(Console, cmdListSaves));
+ registerCmd("save_game", WRAP_METHOD(Console, cmdSaveGame));
+ registerCmd("restore_game", WRAP_METHOD(Console, cmdRestoreGame));
+ registerCmd("restart_game", WRAP_METHOD(Console, cmdRestartGame));
+ registerCmd("version", WRAP_METHOD(Console, cmdGetVersion));
+ registerCmd("room", WRAP_METHOD(Console, cmdRoomNumber));
+ registerCmd("quit", WRAP_METHOD(Console, cmdQuit));
+ registerCmd("list_saves", WRAP_METHOD(Console, cmdListSaves));
// Graphics
- DCmd_Register("show_map", WRAP_METHOD(Console, cmdShowMap));
- DCmd_Register("set_palette", WRAP_METHOD(Console, cmdSetPalette));
- DCmd_Register("draw_pic", WRAP_METHOD(Console, cmdDrawPic));
- DCmd_Register("draw_cel", WRAP_METHOD(Console, cmdDrawCel));
- DCmd_Register("undither", WRAP_METHOD(Console, cmdUndither));
- DCmd_Register("pic_visualize", WRAP_METHOD(Console, cmdPicVisualize));
- DCmd_Register("play_video", WRAP_METHOD(Console, cmdPlayVideo));
- DCmd_Register("animate_list", WRAP_METHOD(Console, cmdAnimateList));
- DCmd_Register("al", WRAP_METHOD(Console, cmdAnimateList)); // alias
- DCmd_Register("window_list", WRAP_METHOD(Console, cmdWindowList));
- DCmd_Register("wl", WRAP_METHOD(Console, cmdWindowList)); // alias
- DCmd_Register("plane_list", WRAP_METHOD(Console, cmdPlaneList));
- DCmd_Register("pl", WRAP_METHOD(Console, cmdPlaneList)); // alias
- DCmd_Register("plane_items", WRAP_METHOD(Console, cmdPlaneItemList));
- DCmd_Register("pi", WRAP_METHOD(Console, cmdPlaneItemList)); // alias
- DCmd_Register("saved_bits", WRAP_METHOD(Console, cmdSavedBits));
- DCmd_Register("show_saved_bits", WRAP_METHOD(Console, cmdShowSavedBits));
+ registerCmd("show_map", WRAP_METHOD(Console, cmdShowMap));
+ registerCmd("set_palette", WRAP_METHOD(Console, cmdSetPalette));
+ registerCmd("draw_pic", WRAP_METHOD(Console, cmdDrawPic));
+ registerCmd("draw_cel", WRAP_METHOD(Console, cmdDrawCel));
+ registerCmd("undither", WRAP_METHOD(Console, cmdUndither));
+ registerCmd("pic_visualize", WRAP_METHOD(Console, cmdPicVisualize));
+ registerCmd("play_video", WRAP_METHOD(Console, cmdPlayVideo));
+ registerCmd("animate_list", WRAP_METHOD(Console, cmdAnimateList));
+ registerCmd("al", WRAP_METHOD(Console, cmdAnimateList)); // alias
+ registerCmd("window_list", WRAP_METHOD(Console, cmdWindowList));
+ registerCmd("wl", WRAP_METHOD(Console, cmdWindowList)); // alias
+ registerCmd("plane_list", WRAP_METHOD(Console, cmdPlaneList));
+ registerCmd("pl", WRAP_METHOD(Console, cmdPlaneList)); // alias
+ registerCmd("plane_items", WRAP_METHOD(Console, cmdPlaneItemList));
+ registerCmd("pi", WRAP_METHOD(Console, cmdPlaneItemList)); // alias
+ registerCmd("saved_bits", WRAP_METHOD(Console, cmdSavedBits));
+ registerCmd("show_saved_bits", WRAP_METHOD(Console, cmdShowSavedBits));
// Segments
- DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
- DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
- DCmd_Register("segment_info", WRAP_METHOD(Console, cmdSegmentInfo));
- DCmd_Register("seginfo", WRAP_METHOD(Console, cmdSegmentInfo)); // alias
- DCmd_Register("segment_kill", WRAP_METHOD(Console, cmdKillSegment));
- DCmd_Register("segkill", WRAP_METHOD(Console, cmdKillSegment)); // alias
+ registerCmd("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
+ registerCmd("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
+ registerCmd("segment_info", WRAP_METHOD(Console, cmdSegmentInfo));
+ registerCmd("seginfo", WRAP_METHOD(Console, cmdSegmentInfo)); // alias
+ registerCmd("segment_kill", WRAP_METHOD(Console, cmdKillSegment));
+ registerCmd("segkill", WRAP_METHOD(Console, cmdKillSegment)); // alias
// Garbage collection
- DCmd_Register("gc", WRAP_METHOD(Console, cmdGCInvoke));
- DCmd_Register("gc_objects", WRAP_METHOD(Console, cmdGCObjects));
- DCmd_Register("gc_reachable", WRAP_METHOD(Console, cmdGCShowReachable));
- DCmd_Register("gc_freeable", WRAP_METHOD(Console, cmdGCShowFreeable));
- DCmd_Register("gc_normalize", WRAP_METHOD(Console, cmdGCNormalize));
+ registerCmd("gc", WRAP_METHOD(Console, cmdGCInvoke));
+ registerCmd("gc_objects", WRAP_METHOD(Console, cmdGCObjects));
+ registerCmd("gc_reachable", WRAP_METHOD(Console, cmdGCShowReachable));
+ registerCmd("gc_freeable", WRAP_METHOD(Console, cmdGCShowFreeable));
+ registerCmd("gc_normalize", WRAP_METHOD(Console, cmdGCNormalize));
// Music/SFX
- DCmd_Register("songlib", WRAP_METHOD(Console, cmdSongLib));
- DCmd_Register("songinfo", WRAP_METHOD(Console, cmdSongInfo));
- DCmd_Register("is_sample", WRAP_METHOD(Console, cmdIsSample));
- DCmd_Register("startsound", WRAP_METHOD(Console, cmdStartSound));
- DCmd_Register("togglesound", WRAP_METHOD(Console, cmdToggleSound));
- DCmd_Register("stopallsounds", WRAP_METHOD(Console, cmdStopAllSounds));
- DCmd_Register("sfx01_header", WRAP_METHOD(Console, cmdSfx01Header));
- DCmd_Register("sfx01_track", WRAP_METHOD(Console, cmdSfx01Track));
- DCmd_Register("show_instruments", WRAP_METHOD(Console, cmdShowInstruments));
- DCmd_Register("map_instrument", WRAP_METHOD(Console, cmdMapInstrument));
+ registerCmd("songlib", WRAP_METHOD(Console, cmdSongLib));
+ registerCmd("songinfo", WRAP_METHOD(Console, cmdSongInfo));
+ registerCmd("is_sample", WRAP_METHOD(Console, cmdIsSample));
+ registerCmd("startsound", WRAP_METHOD(Console, cmdStartSound));
+ registerCmd("togglesound", WRAP_METHOD(Console, cmdToggleSound));
+ registerCmd("stopallsounds", WRAP_METHOD(Console, cmdStopAllSounds));
+ registerCmd("sfx01_header", WRAP_METHOD(Console, cmdSfx01Header));
+ registerCmd("sfx01_track", WRAP_METHOD(Console, cmdSfx01Track));
+ registerCmd("show_instruments", WRAP_METHOD(Console, cmdShowInstruments));
+ registerCmd("map_instrument", WRAP_METHOD(Console, cmdMapInstrument));
// Script
- DCmd_Register("addresses", WRAP_METHOD(Console, cmdAddresses));
- DCmd_Register("registers", WRAP_METHOD(Console, cmdRegisters));
- DCmd_Register("dissect_script", WRAP_METHOD(Console, cmdDissectScript));
- DCmd_Register("backtrace", WRAP_METHOD(Console, cmdBacktrace));
- DCmd_Register("bt", WRAP_METHOD(Console, cmdBacktrace)); // alias
- DCmd_Register("trace", WRAP_METHOD(Console, cmdTrace));
- DCmd_Register("t", WRAP_METHOD(Console, cmdTrace)); // alias
- DCmd_Register("s", WRAP_METHOD(Console, cmdTrace)); // alias
- DCmd_Register("stepover", WRAP_METHOD(Console, cmdStepOver));
- DCmd_Register("p", WRAP_METHOD(Console, cmdStepOver)); // alias
- DCmd_Register("step_ret", WRAP_METHOD(Console, cmdStepRet));
- DCmd_Register("pret", WRAP_METHOD(Console, cmdStepRet)); // alias
- DCmd_Register("step_event", WRAP_METHOD(Console, cmdStepEvent));
- DCmd_Register("se", WRAP_METHOD(Console, cmdStepEvent)); // alias
- DCmd_Register("step_global", WRAP_METHOD(Console, cmdStepGlobal));
- DCmd_Register("sg", WRAP_METHOD(Console, cmdStepGlobal)); // alias
- DCmd_Register("step_callk", WRAP_METHOD(Console, cmdStepCallk));
- DCmd_Register("snk", WRAP_METHOD(Console, cmdStepCallk)); // alias
- DCmd_Register("disasm", WRAP_METHOD(Console, cmdDisassemble));
- DCmd_Register("disasm_addr", WRAP_METHOD(Console, cmdDisassembleAddress));
- DCmd_Register("find_callk", WRAP_METHOD(Console, cmdFindKernelFunctionCall));
- DCmd_Register("send", WRAP_METHOD(Console, cmdSend));
- DCmd_Register("go", WRAP_METHOD(Console, cmdGo));
- DCmd_Register("logkernel", WRAP_METHOD(Console, cmdLogKernel));
+ registerCmd("addresses", WRAP_METHOD(Console, cmdAddresses));
+ registerCmd("registers", WRAP_METHOD(Console, cmdRegisters));
+ registerCmd("dissect_script", WRAP_METHOD(Console, cmdDissectScript));
+ registerCmd("backtrace", WRAP_METHOD(Console, cmdBacktrace));
+ registerCmd("bt", WRAP_METHOD(Console, cmdBacktrace)); // alias
+ registerCmd("trace", WRAP_METHOD(Console, cmdTrace));
+ registerCmd("t", WRAP_METHOD(Console, cmdTrace)); // alias
+ registerCmd("s", WRAP_METHOD(Console, cmdTrace)); // alias
+ registerCmd("stepover", WRAP_METHOD(Console, cmdStepOver));
+ registerCmd("p", WRAP_METHOD(Console, cmdStepOver)); // alias
+ registerCmd("step_ret", WRAP_METHOD(Console, cmdStepRet));
+ registerCmd("pret", WRAP_METHOD(Console, cmdStepRet)); // alias
+ registerCmd("step_event", WRAP_METHOD(Console, cmdStepEvent));
+ registerCmd("se", WRAP_METHOD(Console, cmdStepEvent)); // alias
+ registerCmd("step_global", WRAP_METHOD(Console, cmdStepGlobal));
+ registerCmd("sg", WRAP_METHOD(Console, cmdStepGlobal)); // alias
+ registerCmd("step_callk", WRAP_METHOD(Console, cmdStepCallk));
+ registerCmd("snk", WRAP_METHOD(Console, cmdStepCallk)); // alias
+ registerCmd("disasm", WRAP_METHOD(Console, cmdDisassemble));
+ registerCmd("disasm_addr", WRAP_METHOD(Console, cmdDisassembleAddress));
+ registerCmd("find_callk", WRAP_METHOD(Console, cmdFindKernelFunctionCall));
+ registerCmd("send", WRAP_METHOD(Console, cmdSend));
+ registerCmd("go", WRAP_METHOD(Console, cmdGo));
+ registerCmd("logkernel", WRAP_METHOD(Console, cmdLogKernel));
// Breakpoints
- DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
- DCmd_Register("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias
- DCmd_Register("bl", WRAP_METHOD(Console, cmdBreakpointList)); // alias
- DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
- DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
- DCmd_Register("bc", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
- DCmd_Register("bp_method", WRAP_METHOD(Console, cmdBreakpointMethod));
- DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointMethod)); // alias
- DCmd_Register("bp_read", WRAP_METHOD(Console, cmdBreakpointRead));
- DCmd_Register("bpr", WRAP_METHOD(Console, cmdBreakpointRead)); // alias
- DCmd_Register("bp_write", WRAP_METHOD(Console, cmdBreakpointWrite));
- DCmd_Register("bpw", WRAP_METHOD(Console, cmdBreakpointWrite)); // alias
- DCmd_Register("bp_kernel", WRAP_METHOD(Console, cmdBreakpointKernel));
- DCmd_Register("bpk", WRAP_METHOD(Console, cmdBreakpointKernel)); // alias
- DCmd_Register("bp_function", WRAP_METHOD(Console, cmdBreakpointFunction));
- DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias
+ registerCmd("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
+ registerCmd("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias
+ registerCmd("bl", WRAP_METHOD(Console, cmdBreakpointList)); // alias
+ registerCmd("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
+ registerCmd("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
+ registerCmd("bc", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
+ registerCmd("bp_method", WRAP_METHOD(Console, cmdBreakpointMethod));
+ registerCmd("bpx", WRAP_METHOD(Console, cmdBreakpointMethod)); // alias
+ registerCmd("bp_read", WRAP_METHOD(Console, cmdBreakpointRead));
+ registerCmd("bpr", WRAP_METHOD(Console, cmdBreakpointRead)); // alias
+ registerCmd("bp_write", WRAP_METHOD(Console, cmdBreakpointWrite));
+ registerCmd("bpw", WRAP_METHOD(Console, cmdBreakpointWrite)); // alias
+ registerCmd("bp_kernel", WRAP_METHOD(Console, cmdBreakpointKernel));
+ registerCmd("bpk", WRAP_METHOD(Console, cmdBreakpointKernel)); // alias
+ registerCmd("bp_function", WRAP_METHOD(Console, cmdBreakpointFunction));
+ registerCmd("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias
// VM
- DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
- DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
- DCmd_Register("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias
- DCmd_Register("vl", WRAP_METHOD(Console, cmdVMVarlist)); // alias
- DCmd_Register("vm_vars", WRAP_METHOD(Console, cmdVMVars));
- DCmd_Register("vmvars", WRAP_METHOD(Console, cmdVMVars)); // alias
- DCmd_Register("vv", WRAP_METHOD(Console, cmdVMVars)); // alias
- DCmd_Register("stack", WRAP_METHOD(Console, cmdStack));
- DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType));
- DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode));
- DCmd_Register("view_reference", WRAP_METHOD(Console, cmdViewReference));
- DCmd_Register("vr", WRAP_METHOD(Console, cmdViewReference)); // alias
- DCmd_Register("view_object", WRAP_METHOD(Console, cmdViewObject));
- DCmd_Register("vo", WRAP_METHOD(Console, cmdViewObject)); // alias
- DCmd_Register("active_object", WRAP_METHOD(Console, cmdViewActiveObject));
- DCmd_Register("acc_object", WRAP_METHOD(Console, cmdViewAccumulatorObject));
+ registerCmd("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
+ registerCmd("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
+ registerCmd("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias
+ registerCmd("vl", WRAP_METHOD(Console, cmdVMVarlist)); // alias
+ registerCmd("vm_vars", WRAP_METHOD(Console, cmdVMVars));
+ registerCmd("vmvars", WRAP_METHOD(Console, cmdVMVars)); // alias
+ registerCmd("vv", WRAP_METHOD(Console, cmdVMVars)); // alias
+ registerCmd("stack", WRAP_METHOD(Console, cmdStack));
+ registerCmd("value_type", WRAP_METHOD(Console, cmdValueType));
+ registerCmd("view_listnode", WRAP_METHOD(Console, cmdViewListNode));
+ registerCmd("view_reference", WRAP_METHOD(Console, cmdViewReference));
+ registerCmd("vr", WRAP_METHOD(Console, cmdViewReference)); // alias
+ registerCmd("view_object", WRAP_METHOD(Console, cmdViewObject));
+ registerCmd("vo", WRAP_METHOD(Console, cmdViewObject)); // alias
+ registerCmd("active_object", WRAP_METHOD(Console, cmdViewActiveObject));
+ registerCmd("acc_object", WRAP_METHOD(Console, cmdViewAccumulatorObject));
_debugState.seeking = kDebugSeekNothing;
_debugState.seekLevel = 0;
@@ -307,137 +310,137 @@ void Console::postEnter() {
}
bool Console::cmdHelp(int argc, const char **argv) {
- DebugPrintf("\n");
- DebugPrintf("Variables\n");
- DebugPrintf("---------\n");
- DebugPrintf("sleeptime_factor: Factor to multiply with wait times in kWait()\n");
- DebugPrintf("gc_interval: Number of kernel calls in between garbage collections\n");
- DebugPrintf("simulated_key: Add a key with the specified scan code to the event list\n");
- DebugPrintf("track_mouse_clicks: Toggles mouse click tracking to the console\n");
- DebugPrintf("weak_validations: Turns some validation errors into warnings\n");
- DebugPrintf("script_abort_flag: Set to 1 to abort script execution. Set to 2 to force a replay afterwards\n");
- DebugPrintf("\n");
- DebugPrintf("Debug flags\n");
- DebugPrintf("-----------\n");
- DebugPrintf("debugflag_list - Lists the available debug flags and their status\n");
- DebugPrintf("debugflag_enable - Enables a debug flag\n");
- DebugPrintf("debugflag_disable - Disables a debug flag\n");
- DebugPrintf("\n");
- DebugPrintf("Commands\n");
- DebugPrintf("--------\n");
- DebugPrintf("Kernel:\n");
- DebugPrintf(" opcodes - Lists the opcode names\n");
- DebugPrintf(" selectors - Lists the selector names\n");
- DebugPrintf(" selector - Attempts to find the requested selector by name\n");
- DebugPrintf(" functions - Lists the kernel functions\n");
- DebugPrintf(" class_table - Shows the available classes\n");
- DebugPrintf("\n");
- DebugPrintf("Parser:\n");
- DebugPrintf(" suffixes - Lists the vocabulary suffixes\n");
- DebugPrintf(" parse_grammar - Shows the parse grammar, in strict GNF\n");
- DebugPrintf(" parser_nodes - Shows the specified number of nodes from the parse node tree\n");
- DebugPrintf(" parser_words - Shows the words from the parse node tree\n");
- DebugPrintf(" sentence_fragments - Shows the sentence fragments (used to build Parse trees)\n");
- DebugPrintf(" parse - Parses a sequence of words and prints the resulting parse tree\n");
- DebugPrintf(" set_parse_nodes - Sets the contents of all parse nodes\n");
- DebugPrintf(" said - Match a string against a said spec\n");
- DebugPrintf("\n");
- DebugPrintf("Resources:\n");
- DebugPrintf(" diskdump - Dumps the specified resource to disk as a patch file\n");
- DebugPrintf(" hexdump - Dumps the specified resource to standard output\n");
- DebugPrintf(" resource_id - Identifies a resource number by splitting it up in resource type and resource number\n");
- DebugPrintf(" resource_info - Shows info about a resource\n");
- DebugPrintf(" resource_types - Shows the valid resource types\n");
- DebugPrintf(" list - Lists all the resources of a given type\n");
- DebugPrintf(" hexgrep - Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers\n");
- DebugPrintf(" verify_scripts - Performs sanity checks on SCI1.1-SCI2.1 game scripts (e.g. if they're up to 64KB in total)\n");
- DebugPrintf("\n");
- DebugPrintf("Game:\n");
- DebugPrintf(" save_game - Saves the current game state to the hard disk\n");
- DebugPrintf(" restore_game - Restores a saved game from the hard disk\n");
- DebugPrintf(" list_saves - List all saved games including filenames\n");
- DebugPrintf(" restart_game - Restarts the game\n");
- DebugPrintf(" version - Shows the resource and interpreter versions\n");
- DebugPrintf(" room - Gets or sets the current room number\n");
- DebugPrintf(" quit - Quits the game\n");
- DebugPrintf("\n");
- DebugPrintf("Graphics:\n");
- DebugPrintf(" show_map - Switches to visual, priority, control or display screen\n");
- DebugPrintf(" set_palette - Sets a palette resource\n");
- DebugPrintf(" draw_pic - Draws a pic resource\n");
- DebugPrintf(" draw_cel - Draws a cel from a view resource\n");
- DebugPrintf(" pic_visualize - Enables visualization of the drawing process of EGA pictures\n");
- DebugPrintf(" undither - Enable/disable undithering\n");
- DebugPrintf(" play_video - Plays a SEQ, AVI, VMD, RBT or DUK video\n");
- DebugPrintf(" animate_list / al - Shows the current list of objects in kAnimate's draw list (SCI0 - SCI1.1)\n");
- DebugPrintf(" window_list / wl - Shows a list of all the windows (ports) in the draw list (SCI0 - SCI1.1)\n");
- DebugPrintf(" plane_list / pl - Shows a list of all the planes in the draw list (SCI2+)\n");
- DebugPrintf(" plane_items / pi - Shows a list of all items for a plane (SCI2+)\n");
- DebugPrintf(" saved_bits - List saved bits on the hunk\n");
- DebugPrintf(" show_saved_bits - Display saved bits\n");
- DebugPrintf("\n");
- DebugPrintf("Segments:\n");
- DebugPrintf(" segment_table / segtable - Lists all segments\n");
- DebugPrintf(" segment_info / seginfo - Provides information on the specified segment\n");
- DebugPrintf(" segment_kill / segkill - Deletes the specified segment\n");
- DebugPrintf("\n");
- DebugPrintf("Garbage collection:\n");
- DebugPrintf(" gc - Invokes the garbage collector\n");
- DebugPrintf(" gc_objects - Lists all reachable objects, normalized\n");
- DebugPrintf(" gc_reachable - Lists all addresses directly reachable from a given memory object\n");
- DebugPrintf(" gc_freeable - Lists all addresses freeable in a given segment\n");
- DebugPrintf(" gc_normalize - Prints the \"normal\" address of a given address\n");
- DebugPrintf("\n");
- DebugPrintf("Music/SFX:\n");
- DebugPrintf(" songlib - Shows the song library\n");
- DebugPrintf(" songinfo - Shows information about a specified song in the song library\n");
- DebugPrintf(" togglesound - Starts/stops a sound in the song library\n");
- DebugPrintf(" stopallsounds - Stops all sounds in the playlist\n");
- DebugPrintf(" startsound - Starts the specified sound resource, replacing the first song in the song library\n");
- DebugPrintf(" is_sample - Shows information on a given sound resource, if it's a PCM sample\n");
- DebugPrintf(" sfx01_header - Dumps the header of a SCI01 song\n");
- DebugPrintf(" sfx01_track - Dumps a track of a SCI01 song\n");
- DebugPrintf(" show_instruments - Shows the instruments of a specific song, or all songs\n");
- DebugPrintf(" map_instrument - Dynamically maps an MT-32 instrument to a GM instrument\n");
- DebugPrintf("\n");
- DebugPrintf("Script:\n");
- DebugPrintf(" addresses - Provides information on how to pass addresses\n");
- DebugPrintf(" registers - Shows the current register values\n");
- DebugPrintf(" dissect_script - Examines a script\n");
- DebugPrintf(" backtrace / bt - Dumps the send/self/super/call/calle/callb stack\n");
- DebugPrintf(" trace / t / s - Executes one operation (no parameters) or several operations (specified as a parameter) \n");
- DebugPrintf(" stepover / p - Executes one operation, skips over call/send\n");
- DebugPrintf(" step_ret / pret - Steps forward until ret is called on the current execution stack level.\n");
- DebugPrintf(" step_event / se - Steps forward until a SCI event is received.\n");
- DebugPrintf(" step_global / sg - Steps until the global variable with the specified index is modified.\n");
- DebugPrintf(" step_callk / snk - Steps forward until it hits the next callk operation, or a specific callk (specified as a parameter)\n");
- DebugPrintf(" disasm - Disassembles a method by name\n");
- DebugPrintf(" disasm_addr - Disassembles one or more commands\n");
- DebugPrintf(" send - Sends a message to an object\n");
- DebugPrintf(" go - Executes the script\n");
- DebugPrintf(" logkernel - Logs kernel calls\n");
- DebugPrintf("\n");
- DebugPrintf("Breakpoints:\n");
- DebugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
- DebugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n");
- DebugPrintf(" bp_method / bpx - Sets a breakpoint on the execution of a specified method/selector\n");
- DebugPrintf(" bp_read / bpr - Sets a breakpoint on reading of a specified selector\n");
- DebugPrintf(" bp_write / bpw - Sets a breakpoint on writing to a specified selector\n");
- DebugPrintf(" bp_kernel / bpk - Sets a breakpoint on execution of a kernel function\n");
- DebugPrintf(" bp_function / bpe - Sets a breakpoint on the execution of the specified exported function\n");
- DebugPrintf("\n");
- DebugPrintf("VM:\n");
- DebugPrintf(" script_steps - Shows the number of executed SCI operations\n");
- DebugPrintf(" vm_varlist / vmvarlist / vl - Shows the addresses of variables in the VM\n");
- DebugPrintf(" vm_vars / vmvars / vv - Displays or changes variables in the VM\n");
- DebugPrintf(" stack - Lists the specified number of stack elements\n");
- DebugPrintf(" value_type - Determines the type of a value\n");
- DebugPrintf(" view_listnode - Examines the list node at the given address\n");
- DebugPrintf(" view_reference / vr - Examines an arbitrary reference\n");
- DebugPrintf(" view_object / vo - Examines the object at the given address\n");
- DebugPrintf(" active_object - Shows information on the currently active object or class\n");
- DebugPrintf(" acc_object - Shows information on the object or class at the address indexed by the accumulator\n");
- DebugPrintf("\n");
+ debugPrintf("\n");
+ debugPrintf("Variables\n");
+ debugPrintf("---------\n");
+ debugPrintf("sleeptime_factor: Factor to multiply with wait times in kWait()\n");
+ debugPrintf("gc_interval: Number of kernel calls in between garbage collections\n");
+ debugPrintf("simulated_key: Add a key with the specified scan code to the event list\n");
+ debugPrintf("track_mouse_clicks: Toggles mouse click tracking to the console\n");
+ debugPrintf("weak_validations: Turns some validation errors into warnings\n");
+ debugPrintf("script_abort_flag: Set to 1 to abort script execution. Set to 2 to force a replay afterwards\n");
+ debugPrintf("\n");
+ debugPrintf("Debug flags\n");
+ debugPrintf("-----------\n");
+ debugPrintf("debugflag_list - Lists the available debug flags and their status\n");
+ debugPrintf("debugflag_enable - Enables a debug flag\n");
+ debugPrintf("debugflag_disable - Disables a debug flag\n");
+ debugPrintf("\n");
+ debugPrintf("Commands\n");
+ debugPrintf("--------\n");
+ debugPrintf("Kernel:\n");
+ debugPrintf(" opcodes - Lists the opcode names\n");
+ debugPrintf(" selectors - Lists the selector names\n");
+ debugPrintf(" selector - Attempts to find the requested selector by name\n");
+ debugPrintf(" functions - Lists the kernel functions\n");
+ debugPrintf(" class_table - Shows the available classes\n");
+ debugPrintf("\n");
+ debugPrintf("Parser:\n");
+ debugPrintf(" suffixes - Lists the vocabulary suffixes\n");
+ debugPrintf(" parse_grammar - Shows the parse grammar, in strict GNF\n");
+ debugPrintf(" parser_nodes - Shows the specified number of nodes from the parse node tree\n");
+ debugPrintf(" parser_words - Shows the words from the parse node tree\n");
+ debugPrintf(" sentence_fragments - Shows the sentence fragments (used to build Parse trees)\n");
+ debugPrintf(" parse - Parses a sequence of words and prints the resulting parse tree\n");
+ debugPrintf(" set_parse_nodes - Sets the contents of all parse nodes\n");
+ debugPrintf(" said - Match a string against a said spec\n");
+ debugPrintf("\n");
+ debugPrintf("Resources:\n");
+ debugPrintf(" diskdump - Dumps the specified resource to disk as a patch file\n");
+ debugPrintf(" hexdump - Dumps the specified resource to standard output\n");
+ debugPrintf(" resource_id - Identifies a resource number by splitting it up in resource type and resource number\n");
+ debugPrintf(" resource_info - Shows info about a resource\n");
+ debugPrintf(" resource_types - Shows the valid resource types\n");
+ debugPrintf(" list - Lists all the resources of a given type\n");
+ debugPrintf(" hexgrep - Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers\n");
+ debugPrintf(" verify_scripts - Performs sanity checks on SCI1.1-SCI2.1 game scripts (e.g. if they're up to 64KB in total)\n");
+ debugPrintf("\n");
+ debugPrintf("Game:\n");
+ debugPrintf(" save_game - Saves the current game state to the hard disk\n");
+ debugPrintf(" restore_game - Restores a saved game from the hard disk\n");
+ debugPrintf(" list_saves - List all saved games including filenames\n");
+ debugPrintf(" restart_game - Restarts the game\n");
+ debugPrintf(" version - Shows the resource and interpreter versions\n");
+ debugPrintf(" room - Gets or sets the current room number\n");
+ debugPrintf(" quit - Quits the game\n");
+ debugPrintf("\n");
+ debugPrintf("Graphics:\n");
+ debugPrintf(" show_map - Switches to visual, priority, control or display screen\n");
+ debugPrintf(" set_palette - Sets a palette resource\n");
+ debugPrintf(" draw_pic - Draws a pic resource\n");
+ debugPrintf(" draw_cel - Draws a cel from a view resource\n");
+ debugPrintf(" pic_visualize - Enables visualization of the drawing process of EGA pictures\n");
+ debugPrintf(" undither - Enable/disable undithering\n");
+ debugPrintf(" play_video - Plays a SEQ, AVI, VMD, RBT or DUK video\n");
+ debugPrintf(" animate_list / al - Shows the current list of objects in kAnimate's draw list (SCI0 - SCI1.1)\n");
+ debugPrintf(" window_list / wl - Shows a list of all the windows (ports) in the draw list (SCI0 - SCI1.1)\n");
+ debugPrintf(" plane_list / pl - Shows a list of all the planes in the draw list (SCI2+)\n");
+ debugPrintf(" plane_items / pi - Shows a list of all items for a plane (SCI2+)\n");
+ debugPrintf(" saved_bits - List saved bits on the hunk\n");
+ debugPrintf(" show_saved_bits - Display saved bits\n");
+ debugPrintf("\n");
+ debugPrintf("Segments:\n");
+ debugPrintf(" segment_table / segtable - Lists all segments\n");
+ debugPrintf(" segment_info / seginfo - Provides information on the specified segment\n");
+ debugPrintf(" segment_kill / segkill - Deletes the specified segment\n");
+ debugPrintf("\n");
+ debugPrintf("Garbage collection:\n");
+ debugPrintf(" gc - Invokes the garbage collector\n");
+ debugPrintf(" gc_objects - Lists all reachable objects, normalized\n");
+ debugPrintf(" gc_reachable - Lists all addresses directly reachable from a given memory object\n");
+ debugPrintf(" gc_freeable - Lists all addresses freeable in a given segment\n");
+ debugPrintf(" gc_normalize - Prints the \"normal\" address of a given address\n");
+ debugPrintf("\n");
+ debugPrintf("Music/SFX:\n");
+ debugPrintf(" songlib - Shows the song library\n");
+ debugPrintf(" songinfo - Shows information about a specified song in the song library\n");
+ debugPrintf(" togglesound - Starts/stops a sound in the song library\n");
+ debugPrintf(" stopallsounds - Stops all sounds in the playlist\n");
+ debugPrintf(" startsound - Starts the specified sound resource, replacing the first song in the song library\n");
+ debugPrintf(" is_sample - Shows information on a given sound resource, if it's a PCM sample\n");
+ debugPrintf(" sfx01_header - Dumps the header of a SCI01 song\n");
+ debugPrintf(" sfx01_track - Dumps a track of a SCI01 song\n");
+ debugPrintf(" show_instruments - Shows the instruments of a specific song, or all songs\n");
+ debugPrintf(" map_instrument - Dynamically maps an MT-32 instrument to a GM instrument\n");
+ debugPrintf("\n");
+ debugPrintf("Script:\n");
+ debugPrintf(" addresses - Provides information on how to pass addresses\n");
+ debugPrintf(" registers - Shows the current register values\n");
+ debugPrintf(" dissect_script - Examines a script\n");
+ debugPrintf(" backtrace / bt - Dumps the send/self/super/call/calle/callb stack\n");
+ debugPrintf(" trace / t / s - Executes one operation (no parameters) or several operations (specified as a parameter) \n");
+ debugPrintf(" stepover / p - Executes one operation, skips over call/send\n");
+ debugPrintf(" step_ret / pret - Steps forward until ret is called on the current execution stack level.\n");
+ debugPrintf(" step_event / se - Steps forward until a SCI event is received.\n");
+ debugPrintf(" step_global / sg - Steps until the global variable with the specified index is modified.\n");
+ debugPrintf(" step_callk / snk - Steps forward until it hits the next callk operation, or a specific callk (specified as a parameter)\n");
+ debugPrintf(" disasm - Disassembles a method by name\n");
+ debugPrintf(" disasm_addr - Disassembles one or more commands\n");
+ debugPrintf(" send - Sends a message to an object\n");
+ debugPrintf(" go - Executes the script\n");
+ debugPrintf(" logkernel - Logs kernel calls\n");
+ debugPrintf("\n");
+ debugPrintf("Breakpoints:\n");
+ debugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
+ debugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n");
+ debugPrintf(" bp_method / bpx - Sets a breakpoint on the execution of a specified method/selector\n");
+ debugPrintf(" bp_read / bpr - Sets a breakpoint on reading of a specified selector\n");
+ debugPrintf(" bp_write / bpw - Sets a breakpoint on writing to a specified selector\n");
+ debugPrintf(" bp_kernel / bpk - Sets a breakpoint on execution of a kernel function\n");
+ debugPrintf(" bp_function / bpe - Sets a breakpoint on the execution of the specified exported function\n");
+ debugPrintf("\n");
+ debugPrintf("VM:\n");
+ debugPrintf(" script_steps - Shows the number of executed SCI operations\n");
+ debugPrintf(" vm_varlist / vmvarlist / vl - Shows the addresses of variables in the VM\n");
+ debugPrintf(" vm_vars / vmvars / vv - Displays or changes variables in the VM\n");
+ debugPrintf(" stack - Lists the specified number of stack elements\n");
+ debugPrintf(" value_type - Determines the type of a value\n");
+ debugPrintf(" view_listnode - Examines the list node at the given address\n");
+ debugPrintf(" view_reference / vr - Examines an arbitrary reference\n");
+ debugPrintf(" view_object / vo - Examines the object at the given address\n");
+ debugPrintf(" active_object - Shows information on the currently active object or class\n");
+ debugPrintf(" acc_object - Shows information on the object or class at the address indexed by the accumulator\n");
+ debugPrintf("\n");
return true;
}
@@ -464,30 +467,30 @@ bool Console::cmdGetVersion(int argc, const char **argv) {
versionFile.close();
}
- DebugPrintf("Game ID: %s\n", _engine->getGameIdStr());
- DebugPrintf("Emulated interpreter version: %s\n", getSciVersionDesc(getSciVersion()));
- DebugPrintf("\n");
- DebugPrintf("Detected features:\n");
- DebugPrintf("------------------\n");
- DebugPrintf("Sound type: %s\n", getSciVersionDesc(_engine->_features->detectDoSoundType()));
- DebugPrintf("Graphics functions type: %s\n", getSciVersionDesc(_engine->_features->detectGfxFunctionsType()));
- DebugPrintf("Lofs type: %s\n", getSciVersionDesc(_engine->_features->detectLofsType()));
- DebugPrintf("Move count type: %s\n", (_engine->_features->handleMoveCount()) ? "increment" : "ignore");
- DebugPrintf("SetCursor type: %s\n", getSciVersionDesc(_engine->_features->detectSetCursorType()));
+ debugPrintf("Game ID: %s\n", _engine->getGameIdStr());
+ debugPrintf("Emulated interpreter version: %s\n", getSciVersionDesc(getSciVersion()));
+ debugPrintf("\n");
+ debugPrintf("Detected features:\n");
+ debugPrintf("------------------\n");
+ debugPrintf("Sound type: %s\n", getSciVersionDesc(_engine->_features->detectDoSoundType()));
+ debugPrintf("Graphics functions type: %s\n", getSciVersionDesc(_engine->_features->detectGfxFunctionsType()));
+ debugPrintf("Lofs type: %s\n", getSciVersionDesc(_engine->_features->detectLofsType()));
+ debugPrintf("Move count type: %s\n", (_engine->_features->handleMoveCount()) ? "increment" : "ignore");
+ debugPrintf("SetCursor type: %s\n", getSciVersionDesc(_engine->_features->detectSetCursorType()));
#ifdef ENABLE_SCI32
if (getSciVersion() >= SCI_VERSION_2)
- DebugPrintf("kString type: %s\n", (_engine->_features->detectSci2StringFunctionType() == kSci2StringFunctionOld) ? "SCI2 (old)" : "SCI2.1 (new)");
+ debugPrintf("kString type: %s\n", (_engine->_features->detectSci2StringFunctionType() == kSci2StringFunctionOld) ? "SCI2 (old)" : "SCI2.1 (new)");
if (getSciVersion() == SCI_VERSION_2_1)
- DebugPrintf("SCI2.1 kernel table: %s\n", (_engine->_features->detectSci21KernelType() == SCI_VERSION_2) ? "modified SCI2 (old)" : "SCI2.1 (new)");
+ debugPrintf("SCI2.1 kernel table: %s\n", (_engine->_features->detectSci21KernelType() == SCI_VERSION_2) ? "modified SCI2 (old)" : "SCI2.1 (new)");
#endif
- DebugPrintf("View type: %s\n", viewTypeDesc[g_sci->getResMan()->getViewType()]);
- DebugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette->isMerging() ? "yes" : "no");
- DebugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
- DebugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc());
- DebugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no");
- DebugPrintf("Has CantBeHere selector: %s\n", g_sci->getKernel()->_selectorCache.cantBeHere != -1 ? "yes" : "no");
- DebugPrintf("Game version (VERSION file): %s\n", gameVersion.c_str());
- DebugPrintf("\n");
+ debugPrintf("View type: %s\n", viewTypeDesc[g_sci->getResMan()->getViewType()]);
+ debugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette->isMerging() ? "yes" : "no");
+ debugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
+ debugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc());
+ debugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no");
+ debugPrintf("Has CantBeHere selector: %s\n", g_sci->getKernel()->_selectorCache.cantBeHere != -1 ? "yes" : "no");
+ debugPrintf("Game version (VERSION file): %s\n", gameVersion.c_str());
+ debugPrintf("\n");
return true;
}
@@ -498,13 +501,13 @@ bool Console::cmdOpcodes(int argc, const char **argv) {
// If the resource couldn't be loaded, leave
if (!r) {
- DebugPrintf("unable to load vocab.998");
+ debugPrintf("unable to load vocab.998");
return true;
}
int count = READ_LE_UINT16(r->data);
- DebugPrintf("Opcode names in numeric order [index: type name]:\n");
+ debugPrintf("Opcode names in numeric order [index: type name]:\n");
for (int i = 0; i < count; i++) {
int offset = READ_LE_UINT16(r->data + 2 + i * 2);
@@ -512,49 +515,49 @@ bool Console::cmdOpcodes(int argc, const char **argv) {
int type = READ_LE_UINT16(r->data + offset + 2);
// QFG3 has empty opcodes
Common::String name = len > 0 ? Common::String((const char *)r->data + offset + 4, len) : "Dummy";
- DebugPrintf("%03x: %03x %20s | ", i, type, name.c_str());
+ debugPrintf("%03x: %03x %20s | ", i, type, name.c_str());
if ((i % 3) == 2)
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
bool Console::cmdSelector(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Attempts to find the requested selector by name.\n");
- DebugPrintf("Usage: %s <selector name>\n", argv[0]);
+ debugPrintf("Attempts to find the requested selector by name.\n");
+ debugPrintf("Usage: %s <selector name>\n", argv[0]);
return true;
}
Common::String name = argv[1];
int seeker = _engine->getKernel()->findSelector(name.c_str());
if (seeker >= 0) {
- DebugPrintf("Selector %s found at %03x (%d)\n", name.c_str(), seeker, seeker);
+ debugPrintf("Selector %s found at %03x (%d)\n", name.c_str(), seeker, seeker);
return true;
}
- DebugPrintf("Selector %s wasn't found\n", name.c_str());
+ debugPrintf("Selector %s wasn't found\n", name.c_str());
return true;
}
bool Console::cmdSelectors(int argc, const char **argv) {
- DebugPrintf("Selector names in numeric order:\n");
+ debugPrintf("Selector names in numeric order:\n");
Common::String selectorName;
for (uint seeker = 0; seeker < _engine->getKernel()->getSelectorNamesSize(); seeker++) {
selectorName = _engine->getKernel()->getSelectorName(seeker);
if (selectorName != "BAD SELECTOR")
- DebugPrintf("%03x: %20s | ", seeker, selectorName.c_str());
+ debugPrintf("%03x: %20s | ", seeker, selectorName.c_str());
else
continue;
if ((seeker % 3) == 2)
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("\n");
+ debugPrintf("\n");
#if 0
// For debug/development
@@ -584,14 +587,14 @@ bool Console::cmdSelectors(int argc, const char **argv) {
}
bool Console::cmdKernelFunctions(int argc, const char **argv) {
- DebugPrintf("Kernel function names in numeric order:\n");
+ debugPrintf("Kernel function names in numeric order:\n");
for (uint seeker = 0; seeker < _engine->getKernel()->getKernelNamesSize(); seeker++) {
- DebugPrintf("%03x: %20s | ", seeker, _engine->getKernel()->getKernelName(seeker).c_str());
+ debugPrintf("%03x: %20s | ", seeker, _engine->getKernel()->getKernelName(seeker).c_str());
if ((seeker % 3) == 2)
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
@@ -610,9 +613,9 @@ bool Console::cmdParserWords(int argc, const char **argv) {
bool Console::cmdSetParseNodes(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Sets the contents of all parse nodes.\n");
- DebugPrintf("Usage: %s <parse node1> <parse node2> ... <parse noden>\n", argv[0]);
- DebugPrintf("Tokens should be separated by blanks and enclosed in parentheses\n");
+ debugPrintf("Sets the contents of all parse nodes.\n");
+ debugPrintf("Usage: %s <parse node1> <parse node2> ... <parse noden>\n", argv[0]);
+ debugPrintf("Tokens should be separated by blanks and enclosed in parentheses\n");
return true;
}
@@ -643,23 +646,23 @@ bool Console::cmdSetParseNodes(int argc, const char **argv) {
bool Console::cmdRegisters(int argc, const char **argv) {
EngineState *s = _engine->_gamestate;
- DebugPrintf("Current register values:\n");
- DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(s->r_acc), PRINT_REG(s->r_prev), s->r_rest);
+ debugPrintf("Current register values:\n");
+ debugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(s->r_acc), PRINT_REG(s->r_prev), s->r_rest);
if (!s->_executionStack.empty()) {
- DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n",
+ debugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n",
PRINT_REG(s->xs->addr.pc), PRINT_REG(s->xs->objp),
(unsigned)(s->xs->fp - s->stack_base), (unsigned)(s->xs->sp - s->stack_base));
} else
- DebugPrintf("<no execution stack: pc,obj,fp omitted>\n");
+ debugPrintf("<no execution stack: pc,obj,fp omitted>\n");
return true;
}
bool Console::cmdDiskDump(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Dumps the specified resource to disk as a patch file\n");
- DebugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
+ debugPrintf("Dumps the specified resource to disk as a patch file\n");
+ debugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
cmdResourceTypes(argc, argv);
return true;
}
@@ -668,7 +671,7 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
ResourceType res = parseResourceType(argv[1]);
if (res == kResourceTypeInvalid)
- DebugPrintf("Resource type '%s' is not valid\n", argv[1]);
+ debugPrintf("Resource type '%s' is not valid\n", argv[1]);
else {
Resource *resource = _engine->getResMan()->findResource(ResourceId(res, resNum), 0);
if (resource) {
@@ -680,9 +683,9 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
outFile->finalize();
outFile->close();
delete outFile;
- DebugPrintf("Resource %s.%03d (located in %s) has been dumped to disk\n", argv[1], resNum, resource->getResourceLocation().c_str());
+ debugPrintf("Resource %s.%03d (located in %s) has been dumped to disk\n", argv[1], resNum, resource->getResourceLocation().c_str());
} else {
- DebugPrintf("Resource %s.%03d not found\n", argv[1], resNum);
+ debugPrintf("Resource %s.%03d not found\n", argv[1], resNum);
}
}
@@ -691,8 +694,8 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
bool Console::cmdHexDump(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Dumps the specified resource to standard output\n");
- DebugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
+ debugPrintf("Dumps the specified resource to standard output\n");
+ debugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
cmdResourceTypes(argc, argv);
return true;
}
@@ -701,14 +704,14 @@ bool Console::cmdHexDump(int argc, const char **argv) {
ResourceType res = parseResourceType(argv[1]);
if (res == kResourceTypeInvalid)
- DebugPrintf("Resource type '%s' is not valid\n", argv[1]);
+ debugPrintf("Resource type '%s' is not valid\n", argv[1]);
else {
Resource *resource = _engine->getResMan()->findResource(ResourceId(res, resNum), 0);
if (resource) {
Common::hexdump(resource->data, resource->size, 16, 0);
- DebugPrintf("Resource %s.%03d has been dumped to standard output\n", argv[1], resNum);
+ debugPrintf("Resource %s.%03d has been dumped to standard output\n", argv[1], resNum);
} else {
- DebugPrintf("Resource %s.%03d not found\n", argv[1], resNum);
+ debugPrintf("Resource %s.%03d not found\n", argv[1], resNum);
}
}
@@ -717,21 +720,21 @@ bool Console::cmdHexDump(int argc, const char **argv) {
bool Console::cmdResourceId(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Identifies a resource number by splitting it up in resource type and resource number\n");
- DebugPrintf("Usage: %s <resource number>\n", argv[0]);
+ debugPrintf("Identifies a resource number by splitting it up in resource type and resource number\n");
+ debugPrintf("Usage: %s <resource number>\n", argv[0]);
return true;
}
int id = atoi(argv[1]);
- DebugPrintf("%s.%d (0x%x)\n", getResourceTypeName((ResourceType)(id >> 11)), id & 0x7ff, id & 0x7ff);
+ debugPrintf("%s.%d (0x%x)\n", getResourceTypeName((ResourceType)(id >> 11)), id & 0x7ff, id & 0x7ff);
return true;
}
bool Console::cmdDissectScript(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Examines a script\n");
- DebugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Examines a script\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
return true;
}
@@ -745,13 +748,13 @@ bool Console::cmdRoomNumber(int argc, const char **argv) {
// The same functionality is provided by "vmvars g 13" (but this one is more straighforward)
if (argc != 2) {
- DebugPrintf("Current room number is %d\n", _engine->_gamestate->currentRoomNumber());
- DebugPrintf("Calling this command with the room number (in decimal or hexadecimal) changes the room\n");
+ debugPrintf("Current room number is %d\n", _engine->_gamestate->currentRoomNumber());
+ debugPrintf("Calling this command with the room number (in decimal or hexadecimal) changes the room\n");
} else {
Common::String roomNumberStr = argv[1];
int roomNumber = strtol(roomNumberStr.c_str(), NULL, roomNumberStr.hasSuffix("h") ? 16 : 10);
_engine->_gamestate->setRoomNumber(roomNumber);
- DebugPrintf("Room number changed to %d (%x in hex)\n", roomNumber, roomNumber);
+ debugPrintf("Room number changed to %d (%x in hex)\n", roomNumber, roomNumber);
}
return true;
@@ -759,8 +762,8 @@ bool Console::cmdRoomNumber(int argc, const char **argv) {
bool Console::cmdResourceInfo(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Shows information about a resource\n");
- DebugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
+ debugPrintf("Shows information about a resource\n");
+ debugPrintf("Usage: %s <resource type> <resource number>\n", argv[0]);
return true;
}
@@ -768,14 +771,14 @@ bool Console::cmdResourceInfo(int argc, const char **argv) {
ResourceType res = parseResourceType(argv[1]);
if (res == kResourceTypeInvalid)
- DebugPrintf("Resource type '%s' is not valid\n", argv[1]);
+ debugPrintf("Resource type '%s' is not valid\n", argv[1]);
else {
Resource *resource = _engine->getResMan()->findResource(ResourceId(res, resNum), 0);
if (resource) {
- DebugPrintf("Resource size: %d\n", resource->size);
- DebugPrintf("Resource location: %s\n", resource->getResourceLocation().c_str());
+ debugPrintf("Resource size: %d\n", resource->size);
+ debugPrintf("Resource location: %s\n", resource->getResourceLocation().c_str());
} else {
- DebugPrintf("Resource %s.%03d not found\n", argv[1], resNum);
+ debugPrintf("Resource %s.%03d not found\n", argv[1], resNum);
}
}
@@ -783,10 +786,10 @@ bool Console::cmdResourceInfo(int argc, const char **argv) {
}
bool Console::cmdResourceTypes(int argc, const char **argv) {
- DebugPrintf("The %d valid resource types are:\n", kResourceTypeInvalid);
+ debugPrintf("The %d valid resource types are:\n", kResourceTypeInvalid);
for (int i = 0; i < kResourceTypeInvalid; i++) {
- DebugPrintf("%s", getResourceTypeName((ResourceType) i));
- DebugPrintf((i < kResourceTypeInvalid - 1) ? ", " : "\n");
+ debugPrintf("%s", getResourceTypeName((ResourceType) i));
+ debugPrintf((i < kResourceTypeInvalid - 1) ? ", " : "\n");
}
return true;
@@ -794,10 +797,10 @@ bool Console::cmdResourceTypes(int argc, const char **argv) {
bool Console::cmdHexgrep(int argc, const char **argv) {
if (argc < 4) {
- DebugPrintf("Searches some resources for a particular sequence of bytes, represented as decimal or hexadecimal numbers.\n");
- DebugPrintf("Usage: %s <resource type> <resource number> <search string>\n", argv[0]);
- DebugPrintf("<resource number> can be a specific resource number, or \"all\" for all of the resources of the specified type\n");
- DebugPrintf("EXAMPLES:\n hexgrep script all 0xe8 0x03 0xc8 0x00\n hexgrep pic 0x42 0xfe\n");
+ debugPrintf("Searches some resources for a particular sequence of bytes, represented as decimal or hexadecimal numbers.\n");
+ debugPrintf("Usage: %s <resource type> <resource number> <search string>\n", argv[0]);
+ debugPrintf("<resource number> can be a specific resource number, or \"all\" for all of the resources of the specified type\n");
+ debugPrintf("EXAMPLES:\n hexgrep script all 0xe8 0x03 0xc8 0x00\n hexgrep pic 0x42 0xfe\n");
cmdResourceTypes(argc, argv);
return true;
}
@@ -807,7 +810,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) {
Resource *script = NULL;
if (restype == kResourceTypeInvalid) {
- DebugPrintf("Resource type '%s' is not valid\n", argv[1]);
+ debugPrintf("Resource type '%s' is not valid\n", argv[1]);
return true;
}
@@ -845,10 +848,10 @@ bool Console::cmdHexgrep(int argc, const char **argv) {
seeker = seekerold + 1;
if (!output_script_name) {
- DebugPrintf("\nIn %s.%03d:\n", getResourceTypeName((ResourceType)restype), resNumber);
+ debugPrintf("\nIn %s.%03d:\n", getResourceTypeName((ResourceType)restype), resNumber);
output_script_name = 1;
}
- DebugPrintf(" 0x%04x\n", seekerold);
+ debugPrintf(" 0x%04x\n", seekerold);
}
} else
comppos = 0;
@@ -863,38 +866,38 @@ bool Console::cmdHexgrep(int argc, const char **argv) {
bool Console::cmdVerifyScripts(int argc, const char **argv) {
if (getSciVersion() < SCI_VERSION_1_1) {
- DebugPrintf("This script check is only meant for SCI1.1-SCI3 games\n");
+ debugPrintf("This script check is only meant for SCI1.1-SCI3 games\n");
return true;
}
Common::List<ResourceId> resources = _engine->getResMan()->listResources(kResourceTypeScript);
Common::sort(resources.begin(), resources.end());
- DebugPrintf("%d SCI1.1-SCI3 scripts found, performing sanity checks...\n", resources.size());
+ debugPrintf("%d SCI1.1-SCI3 scripts found, performing sanity checks...\n", resources.size());
Resource *script, *heap;
Common::List<ResourceId>::iterator itr;
for (itr = resources.begin(); itr != resources.end(); ++itr) {
script = _engine->getResMan()->findResource(*itr, false);
if (!script)
- DebugPrintf("Error: script %d couldn't be loaded\n", itr->getNumber());
+ debugPrintf("Error: script %d couldn't be loaded\n", itr->getNumber());
if (getSciVersion() <= SCI_VERSION_2_1) {
heap = _engine->getResMan()->findResource(ResourceId(kResourceTypeHeap, itr->getNumber()), false);
if (!heap)
- DebugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->getNumber());
+ debugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->getNumber());
if (script && heap && (script->size + heap->size > 65535))
- DebugPrintf("Error: script and heap %d together are larger than 64KB (%d bytes)\n",
+ debugPrintf("Error: script and heap %d together are larger than 64KB (%d bytes)\n",
itr->getNumber(), script->size + heap->size);
} else { // SCI3
if (script && script->size > 65535)
- DebugPrintf("Error: script %d is larger than 64KB (%d bytes)\n",
+ debugPrintf("Error: script %d is larger than 64KB (%d bytes)\n",
itr->getNumber(), script->size);
}
}
- DebugPrintf("SCI1.1-SCI2.1 script check finished\n");
+ debugPrintf("SCI1.1-SCI2.1 script check finished\n");
return true;
}
@@ -931,9 +934,9 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
instrumentsSongs[i][j] = false;
if (songNumber == -1) {
- DebugPrintf("%d sounds found, checking their instrument mappings...\n", resources.size());
- DebugPrintf("Instruments:\n");
- DebugPrintf("============\n");
+ debugPrintf("%d sounds found, checking their instrument mappings...\n", resources.size());
+ debugPrintf("Instruments:\n");
+ debugPrintf("============\n");
}
Common::List<ResourceId>::iterator itr;
@@ -956,7 +959,7 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
bool endOfTrack = false;
bool firstOneShown = false;
- DebugPrintf("Song %d: ", itr->getNumber());
+ debugPrintf("Song %d: ", itr->getNumber());
do {
while (*channelData == 0xF8)
@@ -984,9 +987,9 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
if (!firstOneShown)
firstOneShown = true;
else
- DebugPrintf(",");
+ debugPrintf(",");
- DebugPrintf(" %d", instrument);
+ debugPrintf(" %d", instrument);
instruments[instrument]++;
instrumentsSongs[instrument][itr->getNumber()] = true;
} else {
@@ -1024,44 +1027,44 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
}
} while (!endOfTrack);
- DebugPrintf("\n");
+ debugPrintf("\n");
}
delete parser;
delete player;
- DebugPrintf("\n");
+ debugPrintf("\n");
if (songNumber == -1) {
- DebugPrintf("Used instruments: ");
+ debugPrintf("Used instruments: ");
for (int i = 0; i < 128; i++) {
if (instruments[i] > 0)
- DebugPrintf("%d, ", i);
+ debugPrintf("%d, ", i);
}
- DebugPrintf("\n\n");
+ debugPrintf("\n\n");
}
- DebugPrintf("Instruments not mapped in the MT32->GM map: ");
+ debugPrintf("Instruments not mapped in the MT32->GM map: ");
for (int i = 0; i < 128; i++) {
if (instruments[i] > 0 && getGmInstrument(Mt32MemoryTimbreMaps[i]) == MIDI_UNMAPPED)
- DebugPrintf("%d, ", i);
+ debugPrintf("%d, ", i);
}
- DebugPrintf("\n\n");
+ debugPrintf("\n\n");
if (songNumber == -1) {
- DebugPrintf("Used instruments in songs:\n");
+ debugPrintf("Used instruments in songs:\n");
for (int i = 0; i < 128; i++) {
if (instruments[i] > 0) {
- DebugPrintf("Instrument %d: ", i);
+ debugPrintf("Instrument %d: ", i);
for (int j = 0; j < 1000; j++) {
if (instrumentsSongs[i][j])
- DebugPrintf("%d, ", j);
+ debugPrintf("%d, ", j);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
}
- DebugPrintf("\n\n");
+ debugPrintf("\n\n");
}
return true;
@@ -1069,13 +1072,13 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
bool Console::cmdMapInstrument(int argc, const char **argv) {
if (argc != 4) {
- DebugPrintf("Maps an MT-32 custom instrument to a GM instrument on the fly\n\n");
- DebugPrintf("Usage %s <MT-32 instrument name> <GM instrument> <GM rhythm key>\n", argv[0]);
- DebugPrintf("Each MT-32 instrument is always 10 characters and is mapped to either a GM instrument, or a GM rhythm key\n");
- DebugPrintf("A value of 255 (0xff) signifies an unmapped instrument\n");
- DebugPrintf("Please replace the spaces in the instrument name with underscores (\"_\"). They'll be converted to spaces afterwards\n\n");
- DebugPrintf("Example: %s test_0__XX 1 255\n", argv[0]);
- DebugPrintf("The above example will map the MT-32 instrument \"test 0 XX\" to GM instrument 1\n\n");
+ debugPrintf("Maps an MT-32 custom instrument to a GM instrument on the fly\n\n");
+ debugPrintf("Usage %s <MT-32 instrument name> <GM instrument> <GM rhythm key>\n", argv[0]);
+ debugPrintf("Each MT-32 instrument is always 10 characters and is mapped to either a GM instrument, or a GM rhythm key\n");
+ debugPrintf("A value of 255 (0xff) signifies an unmapped instrument\n");
+ debugPrintf("Please replace the spaces in the instrument name with underscores (\"_\"). They'll be converted to spaces afterwards\n\n");
+ debugPrintf("Example: %s test_0__XX 1 255\n", argv[0]);
+ debugPrintf("The above example will map the MT-32 instrument \"test 0 XX\" to GM instrument 1\n\n");
} else {
if (Mt32dynamicMappings != NULL) {
Mt32ToGmMap newMapping;
@@ -1093,11 +1096,11 @@ bool Console::cmdMapInstrument(int argc, const char **argv) {
}
}
- DebugPrintf("Current dynamic mappings:\n");
+ debugPrintf("Current dynamic mappings:\n");
if (Mt32dynamicMappings != NULL) {
const Mt32ToGmMapList::iterator end = Mt32dynamicMappings->end();
for (Mt32ToGmMapList::iterator it = Mt32dynamicMappings->begin(); it != end; ++it) {
- DebugPrintf("\"%s\" -> %d / %d\n", (*it).name, (*it).gmInstr, (*it).gmRhythmKey);
+ debugPrintf("\"%s\" -> %d / %d\n", (*it).name, (*it).gmInstr, (*it).gmRhythmKey);
}
}
@@ -1106,7 +1109,7 @@ bool Console::cmdMapInstrument(int argc, const char **argv) {
bool Console::cmdList(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Lists all the resources of a given type\n");
+ debugPrintf("Lists all the resources of a given type\n");
cmdResourceTypes(argc, argv);
return true;
}
@@ -1114,13 +1117,13 @@ bool Console::cmdList(int argc, const char **argv) {
ResourceType res = parseResourceType(argv[1]);
if (res == kResourceTypeInvalid)
- DebugPrintf("Unknown resource type: '%s'\n", argv[1]);
+ debugPrintf("Unknown resource type: '%s'\n", argv[1]);
else {
int number = -1;
if ((res == kResourceTypeAudio36) || (res == kResourceTypeSync36)) {
if (argc != 3) {
- DebugPrintf("Please specify map number (-1: all maps)\n");
+ debugPrintf("Please specify map number (-1: all maps)\n");
return true;
}
number = atoi(argv[2]);
@@ -1133,18 +1136,18 @@ bool Console::cmdList(int argc, const char **argv) {
Common::List<ResourceId>::iterator itr;
for (itr = resources.begin(); itr != resources.end(); ++itr) {
if (number == -1) {
- DebugPrintf("%8i", itr->getNumber());
+ debugPrintf("%8i", itr->getNumber());
if (++cnt % 10 == 0)
- DebugPrintf("\n");
+ debugPrintf("\n");
} else if (number == (int)itr->getNumber()) {
const uint32 tuple = itr->getTuple();
- DebugPrintf("(%3i, %3i, %3i, %3i) ", (tuple >> 24) & 0xff, (tuple >> 16) & 0xff,
+ debugPrintf("(%3i, %3i, %3i, %3i) ", (tuple >> 24) & 0xff, (tuple >> 16) & 0xff,
(tuple >> 8) & 0xff, tuple & 0xff);
if (++cnt % 4 == 0)
- DebugPrintf("\n");
+ debugPrintf("\n");
}
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
return true;
@@ -1152,8 +1155,8 @@ bool Console::cmdList(int argc, const char **argv) {
bool Console::cmdSaveGame(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Saves the current game state to the hard disk\n");
- DebugPrintf("Usage: %s <filename>\n", argv[0]);
+ debugPrintf("Saves the current game state to the hard disk\n");
+ debugPrintf("Usage: %s <filename>\n", argv[0]);
return true;
}
@@ -1163,19 +1166,19 @@ bool Console::cmdSaveGame(int argc, const char **argv) {
result++;
if (result)
- DebugPrintf("Note: Game state has %d open file handles.\n", result);
+ debugPrintf("Note: Game state has %d open file handles.\n", result);
Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager();
Common::OutSaveFile *out = saveFileMan->openForSaving(argv[1]);
const char *version = "";
if (!out) {
- DebugPrintf("Error opening savegame \"%s\" for writing\n", argv[1]);
+ debugPrintf("Error opening savegame \"%s\" for writing\n", argv[1]);
return true;
}
// TODO: enable custom descriptions? force filename into a specific format?
if (!gamestate_save(_engine->_gamestate, out, "debugging", version)) {
- DebugPrintf("Saving the game state to '%s' failed\n", argv[1]);
+ debugPrintf("Saving the game state to '%s' failed\n", argv[1]);
} else {
out->finalize();
if (out->err()) {
@@ -1189,8 +1192,8 @@ bool Console::cmdSaveGame(int argc, const char **argv) {
bool Console::cmdRestoreGame(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Restores a saved game from the hard disk\n");
- DebugPrintf("Usage: %s <filename>\n", argv[0]);
+ debugPrintf("Restores a saved game from the hard disk\n");
+ debugPrintf("Usage: %s <filename>\n", argv[0]);
return true;
}
@@ -1203,17 +1206,17 @@ bool Console::cmdRestoreGame(int argc, const char **argv) {
}
if (_engine->_gamestate->r_acc == make_reg(0, 1)) {
- DebugPrintf("Restoring gamestate '%s' failed.\n", argv[1]);
+ debugPrintf("Restoring gamestate '%s' failed.\n", argv[1]);
return true;
}
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdRestartGame(int argc, const char **argv) {
_engine->_gamestate->abortScriptProcessing = kAbortRestartGame;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
// The scripts get IDs ranging from 100->199, because the scripts require us to assign unique ids THAT EVEN STAY BETWEEN
@@ -1231,25 +1234,25 @@ bool Console::cmdListSaves(int argc, const char **argv) {
for (uint i = 0; i < saves.size(); i++) {
Common::String filename = g_sci->getSavegameName(saves[i].id);
- DebugPrintf("%s: '%s'\n", filename.c_str(), saves[i].name);
+ debugPrintf("%s: '%s'\n", filename.c_str(), saves[i].name);
}
return true;
}
bool Console::cmdClassTable(int argc, const char **argv) {
- DebugPrintf("Available classes (parse a parameter to filter the table by a specific class):\n");
+ debugPrintf("Available classes (parse a parameter to filter the table by a specific class):\n");
for (uint i = 0; i < _engine->_gamestate->_segMan->classTableSize(); i++) {
Class temp = _engine->_gamestate->_segMan->_classTable[i];
if (temp.reg.getSegment()) {
const char *className = _engine->_gamestate->_segMan->getObjectName(temp.reg);
if (argc == 1 || (argc == 2 && !strcmp(className, argv[1]))) {
- DebugPrintf(" Class 0x%x (%s) at %04x:%04x (script %d)\n", i,
+ debugPrintf(" Class 0x%x (%s) at %04x:%04x (script %d)\n", i,
className,
PRINT_REG(temp.reg),
temp.script);
- } else DebugPrintf(" Class 0x%x (not loaded; can't get name) (script %d)\n", i, temp.script);
+ } else debugPrintf(" Class 0x%x (not loaded; can't get name) (script %d)\n", i, temp.script);
}
}
@@ -1257,52 +1260,52 @@ bool Console::cmdClassTable(int argc, const char **argv) {
}
bool Console::cmdSentenceFragments(int argc, const char **argv) {
- DebugPrintf("Sentence fragments (used to build Parse trees)\n");
+ debugPrintf("Sentence fragments (used to build Parse trees)\n");
for (uint i = 0; i < _engine->getVocabulary()->getParserBranchesSize(); i++) {
int j = 0;
const parse_tree_branch_t &branch = _engine->getVocabulary()->getParseTreeBranch(i);
- DebugPrintf("R%02d: [%x] ->", i, branch.id);
+ debugPrintf("R%02d: [%x] ->", i, branch.id);
while ((j < 10) && branch.data[j]) {
int dat = branch.data[j++];
switch (dat) {
case VOCAB_TREE_NODE_COMPARE_TYPE:
dat = branch.data[j++];
- DebugPrintf(" C(%x)", dat);
+ debugPrintf(" C(%x)", dat);
break;
case VOCAB_TREE_NODE_COMPARE_GROUP:
dat = branch.data[j++];
- DebugPrintf(" WG(%x)", dat);
+ debugPrintf(" WG(%x)", dat);
break;
case VOCAB_TREE_NODE_FORCE_STORAGE:
dat = branch.data[j++];
- DebugPrintf(" FORCE(%x)", dat);
+ debugPrintf(" FORCE(%x)", dat);
break;
default:
if (dat > VOCAB_TREE_NODE_LAST_WORD_STORAGE) {
int dat2 = branch.data[j++];
- DebugPrintf(" %x[%x]", dat, dat2);
+ debugPrintf(" %x[%x]", dat, dat2);
} else
- DebugPrintf(" ?%x?", dat);
+ debugPrintf(" ?%x?", dat);
}
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf("%d rules.\n", _engine->getVocabulary()->getParserBranchesSize());
+ debugPrintf("%d rules.\n", _engine->getVocabulary()->getParserBranchesSize());
return true;
}
bool Console::cmdParse(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Parses a sequence of words with a GNF rule set and prints the resulting parse tree\n");
- DebugPrintf("Usage: %s <word1> <word2> ... <wordn>\n", argv[0]);
+ debugPrintf("Parses a sequence of words with a GNF rule set and prints the resulting parse tree\n");
+ debugPrintf("Usage: %s <word1> <word2> ... <wordn>\n", argv[0]);
return true;
}
@@ -1316,7 +1319,7 @@ bool Console::cmdParse(int argc, const char **argv) {
strcat(string, argv[i]);
}
- DebugPrintf("Parsing '%s'\n", string);
+ debugPrintf("Parsing '%s'\n", string);
ResultWordListList words;
bool res = _engine->getVocabulary()->tokenizeString(words, string, &error);
@@ -1325,26 +1328,26 @@ bool Console::cmdParse(int argc, const char **argv) {
_engine->getVocabulary()->synonymizeTokens(words);
- DebugPrintf("Parsed to the following blocks:\n");
+ debugPrintf("Parsed to the following blocks:\n");
for (ResultWordListList::const_iterator i = words.begin(); i != words.end(); ++i) {
- DebugPrintf(" ");
+ debugPrintf(" ");
for (ResultWordList::const_iterator j = i->begin(); j != i->end(); ++j) {
- DebugPrintf("%sType[%04x] Group[%04x]", j == i->begin() ? "" : " / ", j->_class, j->_group);
+ debugPrintf("%sType[%04x] Group[%04x]", j == i->begin() ? "" : " / ", j->_class, j->_group);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
if (_engine->getVocabulary()->parseGNF(words, true))
syntax_fail = 1; // Building a tree failed
if (syntax_fail)
- DebugPrintf("Building a tree failed.\n");
+ debugPrintf("Building a tree failed.\n");
else
_engine->getVocabulary()->dumpParseTree();
} else {
- DebugPrintf("Unknown word: '%s'\n", error);
+ debugPrintf("Unknown word: '%s'\n", error);
free(error);
}
@@ -1353,10 +1356,10 @@ bool Console::cmdParse(int argc, const char **argv) {
bool Console::cmdSaid(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Matches a string against a said spec\n");
- DebugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]);
- DebugPrintf("<string> is a sequence of actual words.\n");
- DebugPrintf("<said spec> is a sequence of hex tokens.\n");
+ debugPrintf("Matches a string against a said spec\n");
+ debugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]);
+ debugPrintf("<string> is a sequence of actual words.\n");
+ debugPrintf("<said spec> is a sequence of hex tokens.\n");
return true;
}
@@ -1373,10 +1376,10 @@ bool Console::cmdSaid(int argc, const char **argv) {
}
if (p >= argc-1) {
- DebugPrintf("Matches a string against a said spec\n");
- DebugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]);
- DebugPrintf("<string> is a sequence of actual words.\n");
- DebugPrintf("<said spec> is a sequence of hex tokens.\n");
+ debugPrintf("Matches a string against a said spec\n");
+ debugPrintf("Usage: %s <string> > & <said spec>\n", argv[0]);
+ debugPrintf("<string> is a sequence of actual words.\n");
+ debugPrintf("<said spec> is a sequence of hex tokens.\n");
return true;
}
@@ -1440,14 +1443,14 @@ bool Console::cmdSaid(int argc, const char **argv) {
_engine->getVocabulary()->synonymizeTokens(words);
- DebugPrintf("Parsed to the following blocks:\n");
+ debugPrintf("Parsed to the following blocks:\n");
for (ResultWordListList::const_iterator i = words.begin(); i != words.end(); ++i) {
- DebugPrintf(" ");
+ debugPrintf(" ");
for (ResultWordList::const_iterator j = i->begin(); j != i->end(); ++j) {
- DebugPrintf("%sType[%04x] Group[%04x]", j == i->begin() ? "" : " / ", j->_class, j->_group);
+ debugPrintf("%sType[%04x] Group[%04x]", j == i->begin() ? "" : " / ", j->_class, j->_group);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
@@ -1456,17 +1459,17 @@ bool Console::cmdSaid(int argc, const char **argv) {
syntax_fail = 1; // Building a tree failed
if (syntax_fail)
- DebugPrintf("Building a tree failed.\n");
+ debugPrintf("Building a tree failed.\n");
else {
_engine->getVocabulary()->dumpParseTree();
_engine->getVocabulary()->parserIsValid = true;
int ret = said((byte *)spec, true);
- DebugPrintf("kSaid: %s\n", (ret == SAID_NO_MATCH ? "No match" : "Match"));
+ debugPrintf("kSaid: %s\n", (ret == SAID_NO_MATCH ? "No match" : "Match"));
}
} else {
- DebugPrintf("Unknown word: '%s'\n", error);
+ debugPrintf("Unknown word: '%s'\n", error);
free(error);
}
@@ -1476,9 +1479,9 @@ bool Console::cmdSaid(int argc, const char **argv) {
bool Console::cmdParserNodes(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Shows the specified number of nodes from the parse node tree\n");
- DebugPrintf("Usage: %s <nr>\n", argv[0]);
- DebugPrintf("where <nr> is the number of nodes to show from the parse node tree\n");
+ debugPrintf("Shows the specified number of nodes from the parse node tree\n");
+ debugPrintf("Usage: %s <nr>\n", argv[0]);
+ debugPrintf("where <nr> is the number of nodes to show from the parse node tree\n");
return true;
}
@@ -1491,9 +1494,9 @@ bool Console::cmdParserNodes(int argc, const char **argv) {
bool Console::cmdSetPalette(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Sets a palette resource\n");
- DebugPrintf("Usage: %s <resourceId>\n", argv[0]);
- DebugPrintf("where <resourceId> is the number of the palette resource to set\n");
+ debugPrintf("Sets a palette resource\n");
+ debugPrintf("Usage: %s <resourceId>\n", argv[0]);
+ debugPrintf("where <resourceId> is the number of the palette resource to set\n");
return true;
}
@@ -1505,9 +1508,9 @@ bool Console::cmdSetPalette(int argc, const char **argv) {
bool Console::cmdDrawPic(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Draws a pic resource\n");
- DebugPrintf("Usage: %s <resourceId>\n", argv[0]);
- DebugPrintf("where <resourceId> is the number of the pic resource to draw\n");
+ debugPrintf("Draws a pic resource\n");
+ debugPrintf("Usage: %s <resourceId>\n", argv[0]);
+ debugPrintf("where <resourceId> is the number of the pic resource to draw\n");
return true;
}
@@ -1532,9 +1535,9 @@ bool Console::cmdDrawPic(int argc, const char **argv) {
bool Console::cmdDrawCel(int argc, const char **argv) {
if (argc < 4) {
- DebugPrintf("Draws a cel from a view resource\n");
- DebugPrintf("Usage: %s <resourceId> <loopNr> <celNr> \n", argv[0]);
- DebugPrintf("where <resourceId> is the number of the view resource to draw\n");
+ debugPrintf("Draws a cel from a view resource\n");
+ debugPrintf("Usage: %s <resourceId> <loopNr> <celNr> \n", argv[0]);
+ debugPrintf("where <resourceId> is the number of the view resource to draw\n");
return true;
}
@@ -1555,24 +1558,24 @@ bool Console::cmdDrawCel(int argc, const char **argv) {
bool Console::cmdUndither(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Enable/disable undithering.\n");
- DebugPrintf("Usage: %s <0/1>\n", argv[0]);
+ debugPrintf("Enable/disable undithering.\n");
+ debugPrintf("Usage: %s <0/1>\n", argv[0]);
return true;
}
bool flag = atoi(argv[1]) ? true : false;
_engine->_gfxScreen->enableUndithering(flag);
if (flag)
- DebugPrintf("undithering ENABLED\n");
+ debugPrintf("undithering ENABLED\n");
else
- DebugPrintf("undithering DISABLED\n");
+ debugPrintf("undithering DISABLED\n");
return true;
}
bool Console::cmdPicVisualize(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Enable/disable picture visualization (EGA only)\n");
- DebugPrintf("Usage: %s <0/1>\n", argv[0]);
+ debugPrintf("Enable/disable picture visualization (EGA only)\n");
+ debugPrintf("Usage: %s <0/1>\n", argv[0]);
return true;
}
@@ -1581,21 +1584,21 @@ bool Console::cmdPicVisualize(int argc, const char **argv) {
if (_engine->_resMan->getViewType() == kViewEga) {
_engine->_gfxPaint16->debugSetEGAdrawingVisualize(state);
if (state)
- DebugPrintf("picture visualization ENABLED\n");
+ debugPrintf("picture visualization ENABLED\n");
else
- DebugPrintf("picture visualization DISABLED\n");
+ debugPrintf("picture visualization DISABLED\n");
} else {
- DebugPrintf("picture visualization only available for EGA games\n");
+ debugPrintf("picture visualization only available for EGA games\n");
}
return true;
}
bool Console::cmdPlayVideo(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Plays a SEQ, AVI, VMD, RBT or DUK video.\n");
- DebugPrintf("Usage: %s <video file name> <delay>\n", argv[0]);
- DebugPrintf("The video file name should include the extension\n");
- DebugPrintf("Delay is only used in SEQ videos and is measured in ticks (default: 10)\n");
+ debugPrintf("Plays a SEQ, AVI, VMD, RBT or DUK video.\n");
+ debugPrintf("Usage: %s <video file name> <delay>\n", argv[0]);
+ debugPrintf("The video file name should include the extension\n");
+ debugPrintf("Delay is only used in SEQ videos and is measured in ticks (default: 10)\n");
return true;
}
@@ -1606,29 +1609,29 @@ bool Console::cmdPlayVideo(int argc, const char **argv) {
filename.hasSuffix(".rbt") || filename.hasSuffix(".duk")) {
_videoFile = filename;
_videoFrameDelay = (argc == 2) ? 10 : atoi(argv[2]);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
} else {
- DebugPrintf("Unknown video file type\n");
+ debugPrintf("Unknown video file type\n");
return true;
}
}
bool Console::cmdAnimateList(int argc, const char **argv) {
if (_engine->_gfxAnimate) {
- DebugPrintf("Animate list:\n");
+ debugPrintf("Animate list:\n");
_engine->_gfxAnimate->printAnimateList(this);
} else {
- DebugPrintf("This SCI version does not have an animate list\n");
+ debugPrintf("This SCI version does not have an animate list\n");
}
return true;
}
bool Console::cmdWindowList(int argc, const char **argv) {
if (_engine->_gfxPorts) {
- DebugPrintf("Window list:\n");
+ debugPrintf("Window list:\n");
_engine->_gfxPorts->printWindowList(this);
} else {
- DebugPrintf("This SCI version does not have a list of ports\n");
+ debugPrintf("This SCI version does not have a list of ports\n");
}
return true;
}
@@ -1636,41 +1639,41 @@ bool Console::cmdWindowList(int argc, const char **argv) {
bool Console::cmdPlaneList(int argc, const char **argv) {
#ifdef ENABLE_SCI32
if (_engine->_gfxFrameout) {
- DebugPrintf("Plane list:\n");
+ debugPrintf("Plane list:\n");
_engine->_gfxFrameout->printPlaneList(this);
} else {
- DebugPrintf("This SCI version does not have a list of planes\n");
+ debugPrintf("This SCI version does not have a list of planes\n");
}
#else
- DebugPrintf("SCI32 isn't included in this compiled executable\n");
+ debugPrintf("SCI32 isn't included in this compiled executable\n");
#endif
return true;
}
bool Console::cmdPlaneItemList(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Shows the list of items for a plane\n");
- DebugPrintf("Usage: %s <plane address>\n", argv[0]);
+ debugPrintf("Shows the list of items for a plane\n");
+ debugPrintf("Usage: %s <plane address>\n", argv[0]);
return true;
}
reg_t planeObject = NULL_REG;
if (parse_reg_t(_engine->_gamestate, argv[1], &planeObject, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
#ifdef ENABLE_SCI32
if (_engine->_gfxFrameout) {
- DebugPrintf("Plane item list:\n");
+ debugPrintf("Plane item list:\n");
_engine->_gfxFrameout->printPlaneItemList(this, planeObject);
} else {
- DebugPrintf("This SCI version does not have a list of plane items\n");
+ debugPrintf("This SCI version does not have a list of plane items\n");
}
#else
- DebugPrintf("SCI32 isn't included in this compiled executable\n");
+ debugPrintf("SCI32 isn't included in this compiled executable\n");
#endif
return true;
}
@@ -1680,7 +1683,7 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
HunkTable* hunks = (HunkTable *)segman->getSegmentObj(id);
if (!hunks) {
- DebugPrintf("No hunk segment found.\n");
+ debugPrintf("No hunk segment found.\n");
return true;
}
@@ -1693,7 +1696,7 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
byte* memoryPtr = (byte *)h.mem;
if (memoryPtr) {
- DebugPrintf("%04x:%04x:", PRINT_REG(entries[i]));
+ debugPrintf("%04x:%04x:", PRINT_REG(entries[i]));
Common::Rect rect;
byte mask;
@@ -1702,17 +1705,17 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
memcpy((void *)&rect, memoryPtr, sizeof(rect));
memcpy((void *)&mask, memoryPtr + sizeof(rect), sizeof(mask));
- DebugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
+ debugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
rect.bottom, rect.right);
if (mask & GFX_SCREEN_MASK_VISUAL)
- DebugPrintf(" visual");
+ debugPrintf(" visual");
if (mask & GFX_SCREEN_MASK_PRIORITY)
- DebugPrintf(" priority");
+ debugPrintf(" priority");
if (mask & GFX_SCREEN_MASK_CONTROL)
- DebugPrintf(" control");
+ debugPrintf(" control");
if (mask & GFX_SCREEN_MASK_DISPLAY)
- DebugPrintf(" display");
- DebugPrintf("\n");
+ debugPrintf(" display");
+ debugPrintf("\n");
}
}
}
@@ -1723,22 +1726,22 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
bool Console::cmdShowSavedBits(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Display saved bits.\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Display saved bits.\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t memoryHandle = NULL_REG;
if (parse_reg_t(_engine->_gamestate, argv[1], &memoryHandle, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
if (memoryHandle.isNull()) {
- DebugPrintf("Invalid address.\n");
+ debugPrintf("Invalid address.\n");
return true;
}
@@ -1746,26 +1749,26 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
HunkTable* hunks = (HunkTable *)segman->getSegmentObj(id);
if (!hunks) {
- DebugPrintf("No hunk segment found.\n");
+ debugPrintf("No hunk segment found.\n");
return true;
}
if (memoryHandle.getSegment() != id || !hunks->isValidOffset(memoryHandle.getOffset())) {
- DebugPrintf("Invalid address.\n");
+ debugPrintf("Invalid address.\n");
return true;
}
const Hunk& h = hunks->_table[memoryHandle.getOffset()];
if (strcmp(h.type, "SaveBits()") != 0) {
- DebugPrintf("Invalid address.\n");
+ debugPrintf("Invalid address.\n");
return true;
}
byte *memoryPtr = segman->getHunkPointer(memoryHandle);
if (!memoryPtr) {
- DebugPrintf("Invalid or freed bits.\n");
+ debugPrintf("Invalid or freed bits.\n");
return true;
}
@@ -1783,17 +1786,17 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
Common::Point bl(rect.left, rect.bottom-1);
Common::Point br(rect.right-1, rect.bottom-1);
- DebugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
+ debugPrintf(" %d,%d - %d,%d", rect.top, rect.left,
rect.bottom, rect.right);
if (mask & GFX_SCREEN_MASK_VISUAL)
- DebugPrintf(" visual");
+ debugPrintf(" visual");
if (mask & GFX_SCREEN_MASK_PRIORITY)
- DebugPrintf(" priority");
+ debugPrintf(" priority");
if (mask & GFX_SCREEN_MASK_CONTROL)
- DebugPrintf(" control");
+ debugPrintf(" control");
if (mask & GFX_SCREEN_MASK_DISPLAY)
- DebugPrintf(" display");
- DebugPrintf("\n");
+ debugPrintf(" display");
+ debugPrintf("\n");
if (!_engine->_gfxPaint16 || !_engine->_gfxScreen)
return true;
@@ -1843,7 +1846,7 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
bool Console::cmdParseGrammar(int argc, const char **argv) {
- DebugPrintf("Parse grammar, in strict GNF:\n");
+ debugPrintf("Parse grammar, in strict GNF:\n");
_engine->getVocabulary()->buildGNF(true);
@@ -1851,71 +1854,71 @@ bool Console::cmdParseGrammar(int argc, const char **argv) {
}
bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
- DebugPrintf("Segment table:\n");
+ debugPrintf("Segment table:\n");
for (uint i = 0; i < _engine->_gamestate->_segMan->_heap.size(); i++) {
SegmentObj *mobj = _engine->_gamestate->_segMan->_heap[i];
if (mobj && mobj->getType()) {
- DebugPrintf(" [%04x] ", i);
+ debugPrintf(" [%04x] ", i);
switch (mobj->getType()) {
case SEG_TYPE_SCRIPT:
- DebugPrintf("S script.%03d l:%d ", (*(Script *)mobj).getScriptNumber(), (*(Script *)mobj).getLockers());
+ debugPrintf("S script.%03d l:%d ", (*(Script *)mobj).getScriptNumber(), (*(Script *)mobj).getLockers());
break;
case SEG_TYPE_CLONES:
- DebugPrintf("C clones (%d allocd)", (*(CloneTable *)mobj).entries_used);
+ debugPrintf("C clones (%d allocd)", (*(CloneTable *)mobj).entries_used);
break;
case SEG_TYPE_LOCALS:
- DebugPrintf("V locals %03d", (*(LocalVariables *)mobj).script_id);
+ debugPrintf("V locals %03d", (*(LocalVariables *)mobj).script_id);
break;
case SEG_TYPE_STACK:
- DebugPrintf("D data stack (%d)", (*(DataStack *)mobj)._capacity);
+ debugPrintf("D data stack (%d)", (*(DataStack *)mobj)._capacity);
break;
case SEG_TYPE_LISTS:
- DebugPrintf("L lists (%d)", (*(ListTable *)mobj).entries_used);
+ debugPrintf("L lists (%d)", (*(ListTable *)mobj).entries_used);
break;
case SEG_TYPE_NODES:
- DebugPrintf("N nodes (%d)", (*(NodeTable *)mobj).entries_used);
+ debugPrintf("N nodes (%d)", (*(NodeTable *)mobj).entries_used);
break;
case SEG_TYPE_HUNK:
- DebugPrintf("H hunk (%d)", (*(HunkTable *)mobj).entries_used);
+ debugPrintf("H hunk (%d)", (*(HunkTable *)mobj).entries_used);
break;
case SEG_TYPE_DYNMEM:
- DebugPrintf("M dynmem: %d bytes", (*(DynMem *)mobj)._size);
+ debugPrintf("M dynmem: %d bytes", (*(DynMem *)mobj)._size);
break;
#ifdef ENABLE_SCI32
case SEG_TYPE_ARRAY:
- DebugPrintf("A SCI32 arrays (%d)", (*(ArrayTable *)mobj).entries_used);
+ debugPrintf("A SCI32 arrays (%d)", (*(ArrayTable *)mobj).entries_used);
break;
case SEG_TYPE_STRING:
- DebugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used);
+ debugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used);
break;
#endif
default:
- DebugPrintf("I Invalid (type = %x)", mobj->getType());
+ debugPrintf("I Invalid (type = %x)", mobj->getType());
break;
}
- DebugPrintf(" \n");
+ debugPrintf(" \n");
}
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
bool Console::segmentInfo(int nr) {
- DebugPrintf("[%04x] ", nr);
+ debugPrintf("[%04x] ", nr);
if ((nr < 0) || ((uint)nr >= _engine->_gamestate->_segMan->_heap.size()) || !_engine->_gamestate->_segMan->_heap[nr])
return false;
@@ -1926,30 +1929,30 @@ bool Console::segmentInfo(int nr) {
case SEG_TYPE_SCRIPT: {
Script *scr = (Script *)mobj;
- DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->getScriptNumber(), scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize());
+ debugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->getScriptNumber(), scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize());
if (scr->getExportTable())
- DebugPrintf(" Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->getBuf())));
+ debugPrintf(" Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->getBuf())));
else
- DebugPrintf(" Exports: none\n");
+ debugPrintf(" Exports: none\n");
- DebugPrintf(" Synonyms: %4d\n", scr->getSynonymsNr());
+ debugPrintf(" Synonyms: %4d\n", scr->getSynonymsNr());
if (scr->getLocalsCount() > 0)
- DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->getLocalsCount(), scr->getLocalsSegment());
+ debugPrintf(" Locals : %4d in segment 0x%x\n", scr->getLocalsCount(), scr->getLocalsSegment());
else
- DebugPrintf(" Locals : none\n");
+ debugPrintf(" Locals : none\n");
ObjMap objects = scr->getObjectMap();
- DebugPrintf(" Objects: %4d\n", objects.size());
+ debugPrintf(" Objects: %4d\n", objects.size());
ObjMap::iterator it;
const ObjMap::iterator end = objects.end();
for (it = objects.begin(); it != end; ++it) {
- DebugPrintf(" ");
+ debugPrintf(" ");
// Object header
const Object *obj = _engine->_gamestate->_segMan->getObject(it->_value.getPos());
if (obj)
- DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value.getPos()),
+ debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value.getPos()),
_engine->_gamestate->_segMan->getObjectName(it->_value.getPos()),
obj->getVarCount(), obj->getMethodCount());
}
@@ -1958,31 +1961,31 @@ bool Console::segmentInfo(int nr) {
case SEG_TYPE_LOCALS: {
LocalVariables *locals = (LocalVariables *)mobj;
- DebugPrintf("locals for script.%03d\n", locals->script_id);
- DebugPrintf(" %d (0x%x) locals\n", locals->_locals.size(), locals->_locals.size());
+ debugPrintf("locals for script.%03d\n", locals->script_id);
+ debugPrintf(" %d (0x%x) locals\n", locals->_locals.size(), locals->_locals.size());
}
break;
case SEG_TYPE_STACK: {
DataStack *stack = (DataStack *)mobj;
- DebugPrintf("stack\n");
- DebugPrintf(" %d (0x%x) entries\n", stack->_capacity, stack->_capacity);
+ debugPrintf("stack\n");
+ debugPrintf(" %d (0x%x) entries\n", stack->_capacity, stack->_capacity);
}
break;
case SEG_TYPE_CLONES: {
CloneTable *ct = (CloneTable *)mobj;
- DebugPrintf("clones\n");
+ debugPrintf("clones\n");
for (uint i = 0; i < ct->_table.size(); i++)
if (ct->isValidEntry(i)) {
reg_t objpos = make_reg(nr, i);
- DebugPrintf(" [%04x] %s; copy of ", i, _engine->_gamestate->_segMan->getObjectName(objpos));
+ debugPrintf(" [%04x] %s; copy of ", i, _engine->_gamestate->_segMan->getObjectName(objpos));
// Object header
const Object *obj = _engine->_gamestate->_segMan->getObject(ct->_table[i].getPos());
if (obj)
- DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()),
+ debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()),
_engine->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()),
obj->getVarCount(), obj->getMethodCount());
}
@@ -1992,34 +1995,34 @@ bool Console::segmentInfo(int nr) {
case SEG_TYPE_LISTS: {
ListTable *lt = (ListTable *)mobj;
- DebugPrintf("lists\n");
+ debugPrintf("lists\n");
for (uint i = 0; i < lt->_table.size(); i++)
if (lt->isValidEntry(i)) {
- DebugPrintf(" [%04x]: ", i);
+ debugPrintf(" [%04x]: ", i);
printList(&(lt->_table[i]));
}
}
break;
case SEG_TYPE_NODES: {
- DebugPrintf("nodes (total %d)\n", (*(NodeTable *)mobj).entries_used);
+ debugPrintf("nodes (total %d)\n", (*(NodeTable *)mobj).entries_used);
break;
}
case SEG_TYPE_HUNK: {
HunkTable *ht = (HunkTable *)mobj;
- DebugPrintf("hunk (total %d)\n", ht->entries_used);
+ debugPrintf("hunk (total %d)\n", ht->entries_used);
for (uint i = 0; i < ht->_table.size(); i++)
if (ht->isValidEntry(i)) {
- DebugPrintf(" [%04x] %d bytes at %p, type=%s\n",
+ debugPrintf(" [%04x] %d bytes at %p, type=%s\n",
i, ht->_table[i].size, ht->_table[i].mem, ht->_table[i].type);
}
}
break;
case SEG_TYPE_DYNMEM: {
- DebugPrintf("dynmem (%s): %d bytes\n",
+ debugPrintf("dynmem (%s): %d bytes\n",
(*(DynMem *)mobj)._description.c_str(), (*(DynMem *)mobj)._size);
Common::hexdump((*(DynMem *)mobj)._buf, (*(DynMem *)mobj)._size, 16, 0);
@@ -2028,28 +2031,28 @@ bool Console::segmentInfo(int nr) {
#ifdef ENABLE_SCI32
case SEG_TYPE_STRING:
- DebugPrintf("SCI32 strings\n");
+ debugPrintf("SCI32 strings\n");
break;
case SEG_TYPE_ARRAY:
- DebugPrintf("SCI32 arrays\n");
+ debugPrintf("SCI32 arrays\n");
break;
#endif
default :
- DebugPrintf("Invalid type %d\n", mobj->getType());
+ debugPrintf("Invalid type %d\n", mobj->getType());
break;
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
bool Console::cmdSegmentInfo(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Provides information on the specified segment(s)\n");
- DebugPrintf("Usage: %s <segment number>\n", argv[0]);
- DebugPrintf("<segment number> can be a number, which shows the information of the segment with\n");
- DebugPrintf("the specified number, or \"all\" to show information on all active segments\n");
+ debugPrintf("Provides information on the specified segment(s)\n");
+ debugPrintf("Usage: %s <segment number>\n", argv[0]);
+ debugPrintf("<segment number> can be a number, which shows the information of the segment with\n");
+ debugPrintf("the specified number, or \"all\" to show information on all active segments\n");
return true;
}
@@ -2061,7 +2064,7 @@ bool Console::cmdSegmentInfo(int argc, const char **argv) {
if (!parseInteger(argv[1], segmentNr))
return true;
if (!segmentInfo(segmentNr))
- DebugPrintf("Segment %04xh does not exist\n", segmentNr);
+ debugPrintf("Segment %04xh does not exist\n", segmentNr);
}
return true;
@@ -2070,8 +2073,8 @@ bool Console::cmdSegmentInfo(int argc, const char **argv) {
bool Console::cmdKillSegment(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Deletes the specified segment\n");
- DebugPrintf("Usage: %s <segment number>\n", argv[0]);
+ debugPrintf("Deletes the specified segment\n");
+ debugPrintf("Usage: %s <segment number>\n", argv[0]);
return true;
}
int segmentNumber;
@@ -2084,13 +2087,13 @@ bool Console::cmdKillSegment(int argc, const char **argv) {
bool Console::cmdShowMap(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Switches to one of the following screen maps\n");
- DebugPrintf("Usage: %s <screen map>\n", argv[0]);
- DebugPrintf("Screen maps:\n");
- DebugPrintf("- 0: visual map\n");
- DebugPrintf("- 1: priority map\n");
- DebugPrintf("- 2: control map\n");
- DebugPrintf("- 3: display screen\n");
+ debugPrintf("Switches to one of the following screen maps\n");
+ debugPrintf("Usage: %s <screen map>\n", argv[0]);
+ debugPrintf("Screen maps:\n");
+ debugPrintf("- 0: visual map\n");
+ debugPrintf("- 1: priority map\n");
+ debugPrintf("- 2: control map\n");
+ debugPrintf("- 3: display screen\n");
return true;
}
@@ -2105,14 +2108,14 @@ bool Console::cmdShowMap(int argc, const char **argv) {
break;
default:
- DebugPrintf("Map %d is not available.\n", map);
+ debugPrintf("Map %d is not available.\n", map);
return true;
}
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdSongLib(int argc, const char **argv) {
- DebugPrintf("Song library:\n");
+ debugPrintf("Song library:\n");
g_sci->_soundCmd->printPlayList(this);
return true;
@@ -2120,16 +2123,16 @@ bool Console::cmdSongLib(int argc, const char **argv) {
bool Console::cmdSongInfo(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Shows information about a given song in the playlist\n");
- DebugPrintf("Usage: %s <song object>\n", argv[0]);
+ debugPrintf("Shows information about a given song in the playlist\n");
+ debugPrintf("Usage: %s <song object>\n", argv[0]);
return true;
}
reg_t addr;
if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2140,38 +2143,38 @@ bool Console::cmdSongInfo(int argc, const char **argv) {
bool Console::cmdStartSound(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Adds the requested sound resource to the playlist, and starts playing it\n");
- DebugPrintf("Usage: %s <sound resource id>\n", argv[0]);
+ debugPrintf("Adds the requested sound resource to the playlist, and starts playing it\n");
+ debugPrintf("Usage: %s <sound resource id>\n", argv[0]);
return true;
}
int16 number = atoi(argv[1]);
if (!_engine->getResMan()->testResource(ResourceId(kResourceTypeSound, number))) {
- DebugPrintf("Unable to load this sound resource, most probably it has an equivalent audio resource (SCI1.1)\n");
+ debugPrintf("Unable to load this sound resource, most probably it has an equivalent audio resource (SCI1.1)\n");
return true;
}
g_sci->_soundCmd->startNewSound(number);
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdToggleSound(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Plays or stops the specified sound in the playlist\n");
- DebugPrintf("Usage: %s <address> <state>\n", argv[0]);
- DebugPrintf("Where:\n");
- DebugPrintf("- <address> is the address of the sound to play or stop.\n");
- DebugPrintf("- <state> is the new state (play or stop).\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Plays or stops the specified sound in the playlist\n");
+ debugPrintf("Usage: %s <address> <state>\n", argv[0]);
+ debugPrintf("Where:\n");
+ debugPrintf("- <address> is the address of the sound to play or stop.\n");
+ debugPrintf("- <state> is the new state (play or stop).\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t id;
if (parse_reg_t(_engine->_gamestate, argv[1], &id, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2183,7 +2186,7 @@ bool Console::cmdToggleSound(int argc, const char **argv) {
else if (newState == "stop")
g_sci->_soundCmd->processStopSound(id, false);
else
- DebugPrintf("New state can either be 'play' or 'stop'");
+ debugPrintf("New state can either be 'play' or 'stop'");
return true;
}
@@ -2191,40 +2194,40 @@ bool Console::cmdToggleSound(int argc, const char **argv) {
bool Console::cmdStopAllSounds(int argc, const char **argv) {
g_sci->_soundCmd->stopAllSounds();
- DebugPrintf("All sounds have been stopped\n");
+ debugPrintf("All sounds have been stopped\n");
return true;
}
bool Console::cmdIsSample(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Tests whether a given sound resource is a PCM sample, \n");
- DebugPrintf("and displays information on it if it is.\n");
- DebugPrintf("Usage: %s <sample id>\n", argv[0]);
+ debugPrintf("Tests whether a given sound resource is a PCM sample, \n");
+ debugPrintf("and displays information on it if it is.\n");
+ debugPrintf("Usage: %s <sample id>\n", argv[0]);
return true;
}
int16 number = atoi(argv[1]);
if (!_engine->getResMan()->testResource(ResourceId(kResourceTypeSound, number))) {
- DebugPrintf("Unable to load this sound resource, most probably it has an equivalent audio resource (SCI1.1)\n");
+ debugPrintf("Unable to load this sound resource, most probably it has an equivalent audio resource (SCI1.1)\n");
return true;
}
SoundResource *soundRes = new SoundResource(number, _engine->getResMan(), _engine->_features->detectDoSoundType());
if (!soundRes) {
- DebugPrintf("Not a sound resource!\n");
+ debugPrintf("Not a sound resource!\n");
return true;
}
SoundResource::Track *track = soundRes->getDigitalTrack();
if (!track || track->digitalChannelNr == -1) {
- DebugPrintf("Valid song, but not a sample.\n");
+ debugPrintf("Valid song, but not a sample.\n");
delete soundRes;
return true;
}
- DebugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
+ debugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
track->digitalSampleSize, track->digitalSampleRate, track->channelCount, track->digitalChannelNr);
delete soundRes;
@@ -2232,7 +2235,7 @@ bool Console::cmdIsSample(int argc, const char **argv) {
}
bool Console::cmdGCInvoke(int argc, const char **argv) {
- DebugPrintf("Performing garbage collection...\n");
+ debugPrintf("Performing garbage collection...\n");
run_gc(_engine->_gamestate);
return true;
}
@@ -2240,9 +2243,9 @@ bool Console::cmdGCInvoke(int argc, const char **argv) {
bool Console::cmdGCObjects(int argc, const char **argv) {
AddrSet *use_map = findAllActiveReferences(_engine->_gamestate);
- DebugPrintf("Reachable object references (normalised):\n");
+ debugPrintf("Reachable object references (normalised):\n");
for (AddrSet::iterator i = use_map->begin(); i != use_map->end(); ++i) {
- DebugPrintf(" - %04x:%04x\n", PRINT_REG(i->_key));
+ debugPrintf(" - %04x:%04x\n", PRINT_REG(i->_key));
}
delete use_map;
@@ -2252,93 +2255,93 @@ bool Console::cmdGCObjects(int argc, const char **argv) {
bool Console::cmdGCShowReachable(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Prints all addresses directly reachable from the memory object specified as parameter.\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Prints all addresses directly reachable from the memory object specified as parameter.\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t addr;
if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.getSegment());
if (!mobj) {
- DebugPrintf("Unknown segment : %x\n", addr.getSegment());
+ debugPrintf("Unknown segment : %x\n", addr.getSegment());
return 1;
}
- DebugPrintf("Reachable from %04x:%04x:\n", PRINT_REG(addr));
+ debugPrintf("Reachable from %04x:%04x:\n", PRINT_REG(addr));
const Common::Array<reg_t> tmp = mobj->listAllOutgoingReferences(addr);
for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
if (it->getSegment())
- g_sci->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(*it));
+ g_sci->getSciDebugger()->debugPrintf(" %04x:%04x\n", PRINT_REG(*it));
return true;
}
bool Console::cmdGCShowFreeable(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Prints all addresses freeable in the segment associated with the\n");
- DebugPrintf("given address (offset is ignored).\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Prints all addresses freeable in the segment associated with the\n");
+ debugPrintf("given address (offset is ignored).\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t addr;
if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.getSegment());
if (!mobj) {
- DebugPrintf("Unknown segment : %x\n", addr.getSegment());
+ debugPrintf("Unknown segment : %x\n", addr.getSegment());
return true;
}
- DebugPrintf("Freeable in segment %04x:\n", addr.getSegment());
+ debugPrintf("Freeable in segment %04x:\n", addr.getSegment());
const Common::Array<reg_t> tmp = mobj->listAllDeallocatable(addr.getSegment());
for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
if (it->getSegment())
- g_sci->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(*it));
+ g_sci->getSciDebugger()->debugPrintf(" %04x:%04x\n", PRINT_REG(*it));
return true;
}
bool Console::cmdGCNormalize(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Prints the \"normal\" address of a given address,\n");
- DebugPrintf("i.e. the address we would free in order to free\n");
- DebugPrintf("the object associated with the original address.\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Prints the \"normal\" address of a given address,\n");
+ debugPrintf("i.e. the address we would free in order to free\n");
+ debugPrintf("the object associated with the original address.\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t addr;
if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.getSegment());
if (!mobj) {
- DebugPrintf("Unknown segment : %x\n", addr.getSegment());
+ debugPrintf("Unknown segment : %x\n", addr.getSegment());
return true;
}
addr = mobj->findCanonicAddress(_engine->_gamestate->_segMan, addr);
- DebugPrintf(" %04x:%04x\n", PRINT_REG(addr));
+ debugPrintf(" %04x:%04x\n", PRINT_REG(addr));
return true;
}
@@ -2347,12 +2350,12 @@ bool Console::cmdVMVarlist(int argc, const char **argv) {
EngineState *s = _engine->_gamestate;
const char *varnames[] = {"global", "local", "temp", "param"};
- DebugPrintf("Addresses of variables in the VM:\n");
+ debugPrintf("Addresses of variables in the VM:\n");
for (int i = 0; i < 4; i++) {
- DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(s->variablesSegment[i], s->variables[i] - s->variablesBase[i])));
- DebugPrintf(" total %d", s->variablesMax[i]);
- DebugPrintf("\n");
+ debugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(s->variablesSegment[i], s->variables[i] - s->variablesBase[i])));
+ debugPrintf(" total %d", s->variablesMax[i]);
+ debugPrintf("\n");
}
return true;
@@ -2360,12 +2363,12 @@ bool Console::cmdVMVarlist(int argc, const char **argv) {
bool Console::cmdVMVars(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Displays or changes variables in the VM\n");
- DebugPrintf("Usage: %s <type> <varnum> [<value>]\n", argv[0]);
- DebugPrintf("First parameter is either g(lobal), l(ocal), t(emp), p(aram) or a(cc).\n");
- DebugPrintf("Second parameter is the var number (not specified on acc)\n");
- DebugPrintf("Third parameter (if specified) is the value to set the variable to, in address form\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Displays or changes variables in the VM\n");
+ debugPrintf("Usage: %s <type> <varnum> [<value>]\n", argv[0]);
+ debugPrintf("First parameter is either g(lobal), l(ocal), t(emp), p(aram) or a(cc).\n");
+ debugPrintf("Second parameter is the var number (not specified on acc)\n");
+ debugPrintf("Third parameter (if specified) is the value to set the variable to, in address form\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2379,7 +2382,7 @@ bool Console::cmdVMVars(int argc, const char **argv) {
const char *setValue = NULL;
if (!varType_pre) {
- DebugPrintf("Invalid variable type '%c'\n", *argv[1]);
+ debugPrintf("Invalid variable type '%c'\n", *argv[1]);
return true;
}
@@ -2392,11 +2395,11 @@ bool Console::cmdVMVars(int argc, const char **argv) {
case 3: {
// for global, local, temp and param, we need an index
if (argc < 3) {
- DebugPrintf("Variable number must be specified for requested type\n");
+ debugPrintf("Variable number must be specified for requested type\n");
return true;
}
if (argc > 4) {
- DebugPrintf("Too many arguments\n");
+ debugPrintf("Too many arguments\n");
return true;
}
@@ -2404,12 +2407,12 @@ bool Console::cmdVMVars(int argc, const char **argv) {
return true;
if (varIndex < 0) {
- DebugPrintf("Variable number may not be negative\n");
+ debugPrintf("Variable number may not be negative\n");
return true;
}
if (s->variablesMax[varType] <= varIndex) {
- DebugPrintf("Maximum variable number for this type is %d (0x%x)\n", s->variablesMax[varType], s->variablesMax[varType]);
+ debugPrintf("Maximum variable number for this type is %d (0x%x)\n", s->variablesMax[varType], s->variablesMax[varType]);
return true;
}
curValue = &s->variables[varType][varIndex];
@@ -2421,7 +2424,7 @@ bool Console::cmdVMVars(int argc, const char **argv) {
case 4:
// acc
if (argc > 3) {
- DebugPrintf("Too many arguments\n");
+ debugPrintf("Too many arguments\n");
return true;
}
curValue = &s->r_acc;
@@ -2435,16 +2438,16 @@ bool Console::cmdVMVars(int argc, const char **argv) {
if (!setValue) {
if (varType == 4)
- DebugPrintf("%s == %04x:%04x", varNames[varType], PRINT_REG(*curValue));
+ debugPrintf("%s == %04x:%04x", varNames[varType], PRINT_REG(*curValue));
else
- DebugPrintf("%s var %d == %04x:%04x", varNames[varType], varIndex, PRINT_REG(*curValue));
+ debugPrintf("%s var %d == %04x:%04x", varNames[varType], varIndex, PRINT_REG(*curValue));
printBasicVarInfo(*curValue);
- DebugPrintf("\n");
+ debugPrintf("\n");
} else {
if (parse_reg_t(s, setValue, curValue, true)) {
- DebugPrintf("Invalid value/address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
- DebugPrintf("Or pass a decimal or hexadecimal value directly (e.g. 12, 1Ah)\n");
+ debugPrintf("Invalid value/address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Or pass a decimal or hexadecimal value directly (e.g. 12, 1Ah)\n");
return true;
}
}
@@ -2453,13 +2456,13 @@ bool Console::cmdVMVars(int argc, const char **argv) {
bool Console::cmdStack(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Lists the specified number of stack elements.\n");
- DebugPrintf("Usage: %s <elements>\n", argv[0]);
+ debugPrintf("Lists the specified number of stack elements.\n");
+ debugPrintf("Usage: %s <elements>\n", argv[0]);
return true;
}
if (_engine->_gamestate->_executionStack.empty()) {
- DebugPrintf("No exec stack!");
+ debugPrintf("No exec stack!");
return true;
}
@@ -2468,9 +2471,9 @@ bool Console::cmdStack(int argc, const char **argv) {
for (int i = nr; i > 0; i--) {
if ((xs.sp - xs.fp - i) == 0)
- DebugPrintf("-- temp variables --\n");
+ debugPrintf("-- temp variables --\n");
if (xs.sp - i >= _engine->_gamestate->stack_base)
- DebugPrintf("ST:%04x = %04x:%04x\n", (unsigned)(xs.sp - i - _engine->_gamestate->stack_base), PRINT_REG(xs.sp[-i]));
+ debugPrintf("ST:%04x = %04x:%04x\n", (unsigned)(xs.sp - i - _engine->_gamestate->stack_base), PRINT_REG(xs.sp[-i]));
}
return true;
@@ -2478,19 +2481,19 @@ bool Console::cmdStack(int argc, const char **argv) {
bool Console::cmdValueType(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Determines the type of a value.\n");
- DebugPrintf("The type can be one of the following:\n");
- DebugPrintf("Invalid, list, object, reference or arithmetic\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Determines the type of a value.\n");
+ debugPrintf("The type can be one of the following:\n");
+ debugPrintf("Invalid, list, object, reference or arithmetic\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t val;
if (parse_reg_t(_engine->_gamestate, argv[1], &val, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2498,22 +2501,22 @@ bool Console::cmdValueType(int argc, const char **argv) {
switch (t) {
case SIG_TYPE_LIST:
- DebugPrintf("List");
+ debugPrintf("List");
break;
case SIG_TYPE_OBJECT:
- DebugPrintf("Object");
+ debugPrintf("Object");
break;
case SIG_TYPE_REFERENCE:
- DebugPrintf("Reference");
+ debugPrintf("Reference");
break;
case SIG_TYPE_INTEGER:
- DebugPrintf("Integer");
+ debugPrintf("Integer");
break;
case SIG_TYPE_INTEGER | SIG_TYPE_NULL:
- DebugPrintf("Null");
+ debugPrintf("Null");
break;
default:
- DebugPrintf("Erroneous unknown type 0x%02x (%d decimal)\n", t, t);
+ debugPrintf("Erroneous unknown type 0x%02x (%d decimal)\n", t, t);
}
return true;
@@ -2521,17 +2524,17 @@ bool Console::cmdValueType(int argc, const char **argv) {
bool Console::cmdViewListNode(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Examines the list node at the given address.\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Examines the list node at the given address.\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t addr;
if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2541,11 +2544,11 @@ bool Console::cmdViewListNode(int argc, const char **argv) {
bool Console::cmdViewReference(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Examines an arbitrary reference.\n");
- DebugPrintf("Usage: %s <start address> [<end address>]\n", argv[0]);
- DebugPrintf("Where <start address> is the starting address to examine\n");
- DebugPrintf("<end address>, if provided, is the address where examining ends at\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Examines an arbitrary reference.\n");
+ debugPrintf("Usage: %s <start address> [<end address>]\n", argv[0]);
+ debugPrintf("Where <start address> is the starting address to examine\n");
+ debugPrintf("<end address>, if provided, is the address where examining ends at\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2553,15 +2556,15 @@ bool Console::cmdViewReference(int argc, const char **argv) {
reg_t reg_end = NULL_REG;
if (parse_reg_t(_engine->_gamestate, argv[1], &reg, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
if (argc > 2) {
if (parse_reg_t(_engine->_gamestate, argv[2], &reg_end, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
}
@@ -2570,15 +2573,15 @@ bool Console::cmdViewReference(int argc, const char **argv) {
int filter;
int found = 0;
- DebugPrintf("%04x:%04x is of type 0x%x: ", PRINT_REG(reg), type_mask);
+ debugPrintf("%04x:%04x is of type 0x%x: ", PRINT_REG(reg), type_mask);
if (reg.getSegment() == 0 && reg.getOffset() == 0) {
- DebugPrintf("Null.\n");
+ debugPrintf("Null.\n");
return true;
}
if (reg_end.getSegment() != reg.getSegment() && reg_end != NULL_REG) {
- DebugPrintf("Ending segment different from starting segment. Assuming no bound on dump.\n");
+ debugPrintf("Ending segment different from starting segment. Assuming no bound on dump.\n");
reg_end = NULL_REG;
}
@@ -2586,7 +2589,7 @@ bool Console::cmdViewReference(int argc, const char **argv) {
int type = type_mask & filter;
if (found && type) {
- DebugPrintf("--- Alternatively, it could be a ");
+ debugPrintf("--- Alternatively, it could be a ");
}
@@ -2596,33 +2599,33 @@ bool Console::cmdViewReference(int argc, const char **argv) {
case SIG_TYPE_LIST: {
List *list = _engine->_gamestate->_segMan->lookupList(reg);
- DebugPrintf("list\n");
+ debugPrintf("list\n");
if (list)
printList(list);
else
- DebugPrintf("Invalid list.\n");
+ debugPrintf("Invalid list.\n");
}
break;
case SIG_TYPE_NODE:
- DebugPrintf("list node\n");
+ debugPrintf("list node\n");
printNode(reg);
break;
case SIG_TYPE_OBJECT:
- DebugPrintf("object\n");
+ debugPrintf("object\n");
printObject(reg);
break;
case SIG_TYPE_REFERENCE: {
switch (_engine->_gamestate->_segMan->getSegmentType(reg.getSegment())) {
#ifdef ENABLE_SCI32
case SEG_TYPE_STRING: {
- DebugPrintf("SCI32 string\n");
+ debugPrintf("SCI32 string\n");
const SciString *str = _engine->_gamestate->_segMan->lookupString(reg);
Common::hexdump((const byte *) str->getRawData(), str->getSize(), 16, 0);
break;
}
case SEG_TYPE_ARRAY: {
- DebugPrintf("SCI32 array:\n");
+ debugPrintf("SCI32 array:\n");
const SciArray<reg_t> *array = _engine->_gamestate->_segMan->lookupArray(reg);
hexDumpReg(array->getRawData(), array->getSize(), 4, 0, true);
break;
@@ -2632,10 +2635,10 @@ bool Console::cmdViewReference(int argc, const char **argv) {
const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg);
uint16 size = block.maxSize;
- DebugPrintf("raw data\n");
+ debugPrintf("raw data\n");
if (reg_end.getSegment() != 0 && (size < reg_end.getOffset() - reg.getOffset())) {
- DebugPrintf("Block end out of bounds (size %d). Resetting.\n", size);
+ debugPrintf("Block end out of bounds (size %d). Resetting.\n", size);
reg_end = NULL_REG;
}
@@ -2643,7 +2646,7 @@ bool Console::cmdViewReference(int argc, const char **argv) {
size = reg_end.getOffset() - reg.getOffset();
if (reg_end.getSegment() != 0)
- DebugPrintf("Block size less than or equal to %d\n", size);
+ debugPrintf("Block size less than or equal to %d\n", size);
if (block.isRaw)
Common::hexdump(block.raw, size, 16, 0);
@@ -2654,14 +2657,14 @@ bool Console::cmdViewReference(int argc, const char **argv) {
break;
}
case SIG_TYPE_INTEGER:
- DebugPrintf("arithmetic value\n %d (%04x)\n", (int16) reg.getOffset(), reg.getOffset());
+ debugPrintf("arithmetic value\n %d (%04x)\n", (int16) reg.getOffset(), reg.getOffset());
break;
default:
- DebugPrintf("unknown type %d.\n", type);
+ debugPrintf("unknown type %d.\n", type);
}
if (type) {
- DebugPrintf("\n");
+ debugPrintf("\n");
found = 1;
}
}
@@ -2671,47 +2674,47 @@ bool Console::cmdViewReference(int argc, const char **argv) {
bool Console::cmdViewObject(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Examines the object at the given address.\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Examines the object at the given address.\n");
+ debugPrintf("Usage: %s <address>\n", argv[0]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
reg_t addr;
if (parse_reg_t(_engine->_gamestate, argv[1], &addr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
- DebugPrintf("Information on the object at the given address:\n");
+ debugPrintf("Information on the object at the given address:\n");
printObject(addr);
return true;
}
bool Console::cmdViewActiveObject(int argc, const char **argv) {
- DebugPrintf("Information on the currently active object or class:\n");
+ debugPrintf("Information on the currently active object or class:\n");
printObject(_engine->_gamestate->xs->objp);
return true;
}
bool Console::cmdViewAccumulatorObject(int argc, const char **argv) {
- DebugPrintf("Information on the currently active object or class at the address indexed by the accumulator:\n");
+ debugPrintf("Information on the currently active object or class at the address indexed by the accumulator:\n");
printObject(_engine->_gamestate->r_acc);
return true;
}
bool Console::cmdScriptSteps(int argc, const char **argv) {
- DebugPrintf("Number of executed SCI operations: %d\n", _engine->_gamestate->scriptStepCounter);
+ debugPrintf("Number of executed SCI operations: %d\n", _engine->_gamestate->scriptStepCounter);
return true;
}
bool Console::cmdBacktrace(int argc, const char **argv) {
- DebugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
+ debugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
Common::List<ExecStack>::const_iterator iter;
uint i = 0;
@@ -2724,22 +2727,22 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
switch (call.type) {
case EXEC_STACK_TYPE_CALL: // Normal function
if (call.type == EXEC_STACK_TYPE_CALL)
- DebugPrintf(" %x: script %d - ", i, (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.getSegment()]).getScriptNumber());
+ debugPrintf(" %x: script %d - ", i, (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.getSegment()]).getScriptNumber());
if (call.debugSelector != -1) {
- DebugPrintf("%s::%s(", objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str());
+ debugPrintf("%s::%s(", objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str());
} else if (call.debugExportId != -1) {
- DebugPrintf("export %d (", call.debugExportId);
+ debugPrintf("export %d (", call.debugExportId);
} else if (call.debugLocalCallOffset != -1) {
- DebugPrintf("call %x (", call.debugLocalCallOffset);
+ debugPrintf("call %x (", call.debugLocalCallOffset);
}
break;
case EXEC_STACK_TYPE_KERNEL: // Kernel function
- DebugPrintf(" %x:[%x] k%s(", i, call.debugOrigin, _engine->getKernel()->getKernelName(call.debugSelector).c_str());
+ debugPrintf(" %x:[%x] k%s(", i, call.debugOrigin, _engine->getKernel()->getKernelName(call.debugSelector).c_str());
break;
case EXEC_STACK_TYPE_VARSELECTOR:
- DebugPrintf(" %x:[%x] vs%s %s::%s (", i, call.debugOrigin, (call.argc) ? "write" : "read",
+ debugPrintf(" %x:[%x] vs%s %s::%s (", i, call.debugOrigin, (call.argc) ? "write" : "read",
objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str());
break;
}
@@ -2750,32 +2753,32 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
totalparamc = 16;
for (paramc = 1; paramc <= totalparamc; paramc++) {
- DebugPrintf("%04x:%04x", PRINT_REG(call.variables_argp[paramc]));
+ debugPrintf("%04x:%04x", PRINT_REG(call.variables_argp[paramc]));
if (paramc < call.argc)
- DebugPrintf(", ");
+ debugPrintf(", ");
}
if (call.argc > 16)
- DebugPrintf("...");
+ debugPrintf("...");
- DebugPrintf(")\n ");
+ debugPrintf(")\n ");
if (call.debugOrigin != -1)
- DebugPrintf("by %x ", call.debugOrigin);
- DebugPrintf("obj@%04x:%04x", PRINT_REG(call.objp));
+ debugPrintf("by %x ", call.debugOrigin);
+ debugPrintf("obj@%04x:%04x", PRINT_REG(call.objp));
if (call.type == EXEC_STACK_TYPE_CALL) {
- DebugPrintf(" pc=%04x:%04x", PRINT_REG(call.addr.pc));
+ debugPrintf(" pc=%04x:%04x", PRINT_REG(call.addr.pc));
if (call.sp == CALL_SP_CARRY)
- DebugPrintf(" sp,fp:carry");
+ debugPrintf(" sp,fp:carry");
else {
- DebugPrintf(" sp=ST:%04x", (unsigned)(call.sp - _engine->_gamestate->stack_base));
- DebugPrintf(" fp=ST:%04x", (unsigned)(call.fp - _engine->_gamestate->stack_base));
+ debugPrintf(" sp=ST:%04x", (unsigned)(call.sp - _engine->_gamestate->stack_base));
+ debugPrintf(" fp=ST:%04x", (unsigned)(call.fp - _engine->_gamestate->stack_base));
}
} else
- DebugPrintf(" pc:none");
+ debugPrintf(" pc:none");
- DebugPrintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _engine->_gamestate->stack_base));
- DebugPrintf("\n");
+ debugPrintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _engine->_gamestate->stack_base));
+ debugPrintf("\n");
}
return true;
@@ -2786,7 +2789,7 @@ bool Console::cmdTrace(int argc, const char **argv) {
_debugState.runningStep = atoi(argv[1]) - 1;
_debugState.debugging = true;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdStepOver(int argc, const char **argv) {
@@ -2794,14 +2797,14 @@ bool Console::cmdStepOver(int argc, const char **argv) {
_debugState.seekLevel = _engine->_gamestate->_executionStack.size();
_debugState.debugging = true;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdStepEvent(int argc, const char **argv) {
_debugState.stopOnEvent = true;
_debugState.debugging = true;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdStepRet(int argc, const char **argv) {
@@ -2809,13 +2812,13 @@ bool Console::cmdStepRet(int argc, const char **argv) {
_debugState.seekLevel = _engine->_gamestate->_executionStack.size() - 1;
_debugState.debugging = true;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdStepGlobal(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Steps until the global variable with the specified index is modified.\n");
- DebugPrintf("Usage: %s <global variable index>\n", argv[0]);
+ debugPrintf("Steps until the global variable with the specified index is modified.\n");
+ debugPrintf("Usage: %s <global variable index>\n", argv[0]);
return true;
}
@@ -2823,7 +2826,7 @@ bool Console::cmdStepGlobal(int argc, const char **argv) {
_debugState.seekSpecial = atoi(argv[1]);
_debugState.debugging = true;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdStepCallk(int argc, const char **argv) {
@@ -2844,7 +2847,7 @@ bool Console::cmdStepCallk(int argc, const char **argv) {
}
if (callk_index == -1) {
- DebugPrintf("Unknown kernel function '%s'\n", argv[1]);
+ debugPrintf("Unknown kernel function '%s'\n", argv[1]);
return true;
}
}
@@ -2856,16 +2859,16 @@ bool Console::cmdStepCallk(int argc, const char **argv) {
}
_debugState.debugging = true;
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdDisassemble(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Disassembles a method by name.\n");
- DebugPrintf("Usage: %s <object> <method> <options>\n", argv[0]);
- DebugPrintf("Valid options are:\n");
- DebugPrintf(" bwt : Print byte/word tag\n");
- DebugPrintf(" bc : Print bytecode\n");
+ debugPrintf("Disassembles a method by name.\n");
+ debugPrintf("Usage: %s <object> <method> <options>\n", argv[0]);
+ debugPrintf("Valid options are:\n");
+ debugPrintf(" bwt : Print byte/word tag\n");
+ debugPrintf(" bc : Print bytecode\n");
return true;
}
@@ -2874,8 +2877,8 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
bool printBWTag = false;
if (parse_reg_t(_engine->_gamestate, argv[1], &objAddr, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2884,17 +2887,17 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
reg_t addr = NULL_REG;
if (!obj) {
- DebugPrintf("Not an object.\n");
+ debugPrintf("Not an object.\n");
return true;
}
if (selectorId < 0) {
- DebugPrintf("Not a valid selector name.\n");
+ debugPrintf("Not a valid selector name.\n");
return true;
}
if (lookupSelector(_engine->_gamestate->_segMan, objAddr, selectorId, NULL, &addr) != kSelectorMethod) {
- DebugPrintf("Not a method.\n");
+ debugPrintf("Not a method.\n");
return true;
}
@@ -2924,12 +2927,12 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
bool Console::cmdDisassembleAddress(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Disassembles one or more commands.\n");
- DebugPrintf("Usage: %s [startaddr] <options>\n", argv[0]);
- DebugPrintf("Valid options are:\n");
- DebugPrintf(" bwt : Print byte/word tag\n");
- DebugPrintf(" c<x> : Disassemble <x> bytes\n");
- DebugPrintf(" bc : Print bytecode\n");
+ debugPrintf("Disassembles one or more commands.\n");
+ debugPrintf("Usage: %s [startaddr] <options>\n", argv[0]);
+ debugPrintf("Valid options are:\n");
+ debugPrintf(" bwt : Print byte/word tag\n");
+ debugPrintf(" c<x> : Disassemble <x> bytes\n");
+ debugPrintf(" bc : Print bytecode\n");
return true;
}
@@ -2940,8 +2943,8 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
uint16 size;
if (parse_reg_t(_engine->_gamestate, argv[1], &vpc, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -2956,7 +2959,7 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
else if (toupper(argv[i][0]) == 'C')
opCount = atoi(argv[i] + 1);
else {
- DebugPrintf("Invalid option '%s'\n", argv[i]);
+ debugPrintf("Invalid option '%s'\n", argv[i]);
return true;
}
}
@@ -2974,7 +2977,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
Common::sort(resources.begin(), resources.end());
if (showFoundScripts)
- DebugPrintf("%d scripts found, dissassembling...\n", resources.size());
+ debugPrintf("%d scripts found, dissassembling...\n", resources.size());
int scriptSegment;
Script *script;
@@ -3023,7 +3026,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
uint16 argc2 = opparams[1];
if (kFuncNum == kernelFuncNum) {
- DebugPrintf("Called from script %d, object %s, method %s(%d) with %d bytes for arguments\n",
+ debugPrintf("Called from script %d, object %s, method %s(%d) with %d bytes for arguments\n",
itr->getNumber(), objName,
_engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), i, argc2);
}
@@ -3055,19 +3058,19 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Finds the scripts and methods that call a specific kernel function.\n");
- DebugPrintf("Usage: %s <kernel function>\n", argv[0]);
- DebugPrintf("Example: %s Display\n", argv[0]);
- DebugPrintf("Special usage:\n");
- DebugPrintf("%s Dummy - find all calls to actual dummy functions "
+ debugPrintf("Finds the scripts and methods that call a specific kernel function.\n");
+ debugPrintf("Usage: %s <kernel function>\n", argv[0]);
+ debugPrintf("Example: %s Display\n", argv[0]);
+ debugPrintf("Special usage:\n");
+ debugPrintf("%s Dummy - find all calls to actual dummy functions "
"(mapped to kDummy, and dummy in the kernel table). "
"There shouldn't be calls to these (apart from a known "
"one in Shivers)\n", argv[0]);
- DebugPrintf("%s Unused - find all calls to unused functions (mapped to "
+ debugPrintf("%s Unused - find all calls to unused functions (mapped to "
"kDummy - i.e. mapped in SSCI but dummy in ScummVM, thus "
"they'll error out when called). Only debug scripts should "
"be calling these\n", argv[0]);
- DebugPrintf("%s Unmapped - find all calls to currently unmapped or "
+ debugPrintf("%s Unmapped - find all calls to currently unmapped or "
"unimplemented functions (mapped to kStub/kStubNull)\n", argv[0]);
return true;
}
@@ -3080,7 +3083,7 @@ bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
int kernelFuncNum = kernel->findKernelFuncPos(argv[1]);
if (kernelFuncNum < 0) {
- DebugPrintf("Invalid kernel function requested\n");
+ debugPrintf("Invalid kernel function requested\n");
return true;
}
@@ -3090,7 +3093,7 @@ bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
// in the kernel table)
for (uint i = 0; i < kernel->_kernelFuncs.size(); i++) {
if (kernel->_kernelFuncs[i].function == &kDummy && kernel->getKernelName(i) == "Dummy") {
- DebugPrintf("Searching for kernel function %d (%s)...\n", i, kernel->getKernelName(i).c_str());
+ debugPrintf("Searching for kernel function %d (%s)...\n", i, kernel->getKernelName(i).c_str());
printKernelCallsFound(i, false);
}
}
@@ -3100,7 +3103,7 @@ bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
// called)
for (uint i = 0; i < kernel->_kernelFuncs.size(); i++) {
if (kernel->_kernelFuncs[i].function == &kDummy && kernel->getKernelName(i) != "Dummy") {
- DebugPrintf("Searching for kernel function %d (%s)...\n", i, kernel->getKernelName(i).c_str());
+ debugPrintf("Searching for kernel function %d (%s)...\n", i, kernel->getKernelName(i).c_str());
printKernelCallsFound(i, false);
}
}
@@ -3109,7 +3112,7 @@ bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
for (uint i = 0; i < kernel->_kernelFuncs.size(); i++) {
if (kernel->_kernelFuncs[i].function == &kStub ||
kernel->_kernelFuncs[i].function == &kStubNull) {
- DebugPrintf("Searching for kernel function %d (%s)...\n", i, kernel->getKernelName(i).c_str());
+ debugPrintf("Searching for kernel function %d (%s)...\n", i, kernel->getKernelName(i).c_str());
printKernelCallsFound(i, false);
}
}
@@ -3120,17 +3123,17 @@ bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
bool Console::cmdSend(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Sends a message to an object.\n");
- DebugPrintf("Usage: %s <object> <selector name> <param1> <param2> ... <paramn>\n", argv[0]);
- DebugPrintf("Example: %s ?fooScript cue\n", argv[0]);
+ debugPrintf("Sends a message to an object.\n");
+ debugPrintf("Usage: %s <object> <selector name> <param1> <param2> ... <paramn>\n", argv[0]);
+ debugPrintf("Example: %s ?fooScript cue\n", argv[0]);
return true;
}
reg_t object;
if (parse_reg_t(_engine->_gamestate, argv[1], &object, false)) {
- DebugPrintf("Invalid address \"%s\" passed.\n", argv[1]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address \"%s\" passed.\n", argv[1]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
@@ -3138,20 +3141,20 @@ bool Console::cmdSend(int argc, const char **argv) {
int selectorId = _engine->getKernel()->findSelector(selectorName);
if (selectorId < 0) {
- DebugPrintf("Unknown selector: \"%s\"\n", selectorName);
+ debugPrintf("Unknown selector: \"%s\"\n", selectorName);
return true;
}
const Object *o = _engine->_gamestate->_segMan->getObject(object);
if (o == NULL) {
- DebugPrintf("Address \"%04x:%04x\" is not an object\n", PRINT_REG(object));
+ debugPrintf("Address \"%04x:%04x\" is not an object\n", PRINT_REG(object));
return true;
}
SelectorType selector_type = lookupSelector(_engine->_gamestate->_segMan, object, selectorId, NULL, NULL);
if (selector_type == kSelectorNone) {
- DebugPrintf("Object does not support selector: \"%s\"\n", selectorName);
+ debugPrintf("Object does not support selector: \"%s\"\n", selectorName);
return true;
}
@@ -3165,8 +3168,8 @@ bool Console::cmdSend(int argc, const char **argv) {
stackframe[1] = make_reg(0, send_argc);
for (int i = 0; i < send_argc; i++) {
if (parse_reg_t(_engine->_gamestate, argv[3+i], &stackframe[2+i], false)) {
- DebugPrintf("Invalid address \"%s\" passed.\n", argv[3+i]);
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ debugPrintf("Invalid address \"%s\" passed.\n", argv[3+i]);
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
return true;
}
}
@@ -3184,7 +3187,7 @@ bool Console::cmdSend(int argc, const char **argv) {
if (old_xstack != xstack) {
_engine->_gamestate->_executionStackPosChanged = true;
- DebugPrintf("Message scheduled for execution\n");
+ debugPrintf("Message scheduled for execution\n");
// We call run_engine explictly so we can restore the value of r_acc
// after execution.
@@ -3194,7 +3197,7 @@ bool Console::cmdSend(int argc, const char **argv) {
if (restore_acc) {
// varselector read or message executed
- DebugPrintf("Message completed. Value returned: %04x:%04x\n", PRINT_REG(_engine->_gamestate->r_acc));
+ debugPrintf("Message completed. Value returned: %04x:%04x\n", PRINT_REG(_engine->_gamestate->r_acc));
_engine->_gamestate->r_acc = old_acc;
}
@@ -3205,14 +3208,14 @@ bool Console::cmdGo(int argc, const char **argv) {
// CHECKME: is this necessary?
_debugState.seeking = kDebugSeekNothing;
- return Cmd_Exit(argc, argv);
+ return cmdExit(argc, argv);
}
bool Console::cmdLogKernel(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Logs calls to specified kernel function.\n");
- DebugPrintf("Usage: %s <kernel function/*> <on/off>\n", argv[0]);
- DebugPrintf("Example: %s StrCpy on\n", argv[0]);
+ debugPrintf("Logs calls to specified kernel function.\n");
+ debugPrintf("Usage: %s <kernel function/*> <on/off>\n", argv[0]);
+ debugPrintf("Example: %s StrCpy on\n", argv[0]);
return true;
}
@@ -3222,14 +3225,14 @@ bool Console::cmdLogKernel(int argc, const char **argv) {
else if (strcmp(argv[2], "off") == 0)
logging = false;
else {
- DebugPrintf("2nd parameter must be either on or off\n");
+ debugPrintf("2nd parameter must be either on or off\n");
return true;
}
if (g_sci->getKernel()->debugSetFunction(argv[1], logging, -1))
- DebugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]);
+ debugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]);
else
- DebugPrintf("Unknown kernel function %s\n", argv[1]);
+ debugPrintf("Unknown kernel function %s\n", argv[1]);
return true;
}
@@ -3237,25 +3240,25 @@ bool Console::cmdBreakpointList(int argc, const char **argv) {
int i = 0;
int bpdata;
- DebugPrintf("Breakpoint list:\n");
+ debugPrintf("Breakpoint list:\n");
Common::List<Breakpoint>::const_iterator bp = _debugState._breakpoints.begin();
Common::List<Breakpoint>::const_iterator end = _debugState._breakpoints.end();
for (; bp != end; ++bp) {
- DebugPrintf(" #%i: ", i);
+ debugPrintf(" #%i: ", i);
switch (bp->type) {
case BREAK_SELECTOREXEC:
- DebugPrintf("Execute %s\n", bp->name.c_str());
+ debugPrintf("Execute %s\n", bp->name.c_str());
break;
case BREAK_SELECTORREAD:
- DebugPrintf("Read %s\n", bp->name.c_str());
+ debugPrintf("Read %s\n", bp->name.c_str());
break;
case BREAK_SELECTORWRITE:
- DebugPrintf("Write %s\n", bp->name.c_str());
+ debugPrintf("Write %s\n", bp->name.c_str());
break;
case BREAK_EXPORT:
bpdata = bp->address;
- DebugPrintf("Execute script %d, export %d\n", bpdata >> 16, bpdata & 0xFFFF);
+ debugPrintf("Execute script %d, export %d\n", bpdata >> 16, bpdata & 0xFFFF);
break;
}
@@ -3263,16 +3266,16 @@ bool Console::cmdBreakpointList(int argc, const char **argv) {
}
if (!i)
- DebugPrintf(" No breakpoints defined.\n");
+ debugPrintf(" No breakpoints defined.\n");
return true;
}
bool Console::cmdBreakpointDelete(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Deletes a breakpoint with the specified index.\n");
- DebugPrintf("Usage: %s <breakpoint index>\n", argv[0]);
- DebugPrintf("<index> * will remove all breakpoints\n");
+ debugPrintf("Deletes a breakpoint with the specified index.\n");
+ debugPrintf("Usage: %s <breakpoint index>\n", argv[0]);
+ debugPrintf("<index> * will remove all breakpoints\n");
return true;
}
@@ -3292,7 +3295,7 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) {
}
if (bp == end) {
- DebugPrintf("Invalid breakpoint index %i\n", idx);
+ debugPrintf("Invalid breakpoint index %i\n", idx);
return true;
}
@@ -3312,11 +3315,11 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) {
bool Console::cmdBreakpointMethod(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Sets a breakpoint on execution of a specified method/selector.\n");
- DebugPrintf("Usage: %s <name>\n", argv[0]);
- DebugPrintf("Example: %s ego::doit\n", argv[0]);
- DebugPrintf("May also be used to set a breakpoint that applies whenever an object\n");
- DebugPrintf("of a specific type is touched: %s foo::\n", argv[0]);
+ debugPrintf("Sets a breakpoint on execution of a specified method/selector.\n");
+ debugPrintf("Usage: %s <name>\n", argv[0]);
+ debugPrintf("Example: %s ego::doit\n", argv[0]);
+ debugPrintf("May also be used to set a breakpoint that applies whenever an object\n");
+ debugPrintf("of a specific type is touched: %s foo::\n", argv[0]);
return true;
}
@@ -3334,9 +3337,9 @@ bool Console::cmdBreakpointMethod(int argc, const char **argv) {
bool Console::cmdBreakpointRead(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Sets a breakpoint on reading of a specified selector.\n");
- DebugPrintf("Usage: %s <name>\n", argv[0]);
- DebugPrintf("Example: %s ego::view\n", argv[0]);
+ debugPrintf("Sets a breakpoint on reading of a specified selector.\n");
+ debugPrintf("Usage: %s <name>\n", argv[0]);
+ debugPrintf("Example: %s ego::view\n", argv[0]);
return true;
}
@@ -3351,9 +3354,9 @@ bool Console::cmdBreakpointRead(int argc, const char **argv) {
bool Console::cmdBreakpointWrite(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Sets a breakpoint on writing of a specified selector.\n");
- DebugPrintf("Usage: %s <name>\n", argv[0]);
- DebugPrintf("Example: %s ego::view\n", argv[0]);
+ debugPrintf("Sets a breakpoint on writing of a specified selector.\n");
+ debugPrintf("Usage: %s <name>\n", argv[0]);
+ debugPrintf("Example: %s ego::view\n", argv[0]);
return true;
}
@@ -3368,9 +3371,9 @@ bool Console::cmdBreakpointWrite(int argc, const char **argv) {
bool Console::cmdBreakpointKernel(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("Sets a breakpoint on execution of a kernel function.\n");
- DebugPrintf("Usage: %s <name> <on/off>\n", argv[0]);
- DebugPrintf("Example: %s DrawPic on\n", argv[0]);
+ debugPrintf("Sets a breakpoint on execution of a kernel function.\n");
+ debugPrintf("Usage: %s <name> <on/off>\n", argv[0]);
+ debugPrintf("Example: %s DrawPic on\n", argv[0]);
return true;
}
@@ -3380,22 +3383,22 @@ bool Console::cmdBreakpointKernel(int argc, const char **argv) {
else if (strcmp(argv[2], "off") == 0)
breakpoint = false;
else {
- DebugPrintf("2nd parameter must be either on or off\n");
+ debugPrintf("2nd parameter must be either on or off\n");
return true;
}
if (g_sci->getKernel()->debugSetFunction(argv[1], -1, breakpoint))
- DebugPrintf("Breakpoint %s for k%s\n", (breakpoint ? "enabled" : "disabled"), argv[1]);
+ debugPrintf("Breakpoint %s for k%s\n", (breakpoint ? "enabled" : "disabled"), argv[1]);
else
- DebugPrintf("Unknown kernel function %s\n", argv[1]);
+ debugPrintf("Unknown kernel function %s\n", argv[1]);
return true;
}
bool Console::cmdBreakpointFunction(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
- DebugPrintf("Usage: %s <script number> <export number\n", argv[0]);
+ debugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
+ debugPrintf("Usage: %s <script number> <export number\n", argv[0]);
return true;
}
@@ -3415,21 +3418,21 @@ bool Console::cmdBreakpointFunction(int argc, const char **argv) {
bool Console::cmdSfx01Header(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Dumps the header of a SCI01 song\n");
- DebugPrintf("Usage: %s <track>\n", argv[0]);
+ debugPrintf("Dumps the header of a SCI01 song\n");
+ debugPrintf("Usage: %s <track>\n", argv[0]);
return true;
}
Resource *song = _engine->getResMan()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0);
if (!song) {
- DebugPrintf("Doesn't exist\n");
+ debugPrintf("Doesn't exist\n");
return true;
}
uint32 offset = 0;
- DebugPrintf("SCI01 song track mappings:\n");
+ debugPrintf("SCI01 song track mappings:\n");
if (*song->data == 0xf0) // SCI1 priority spec
offset = 8;
@@ -3439,7 +3442,7 @@ bool Console::cmdSfx01Header(int argc, const char **argv) {
while (song->data[offset] != 0xff) {
byte device_id = song->data[offset];
- DebugPrintf("* Device %02x:\n", device_id);
+ debugPrintf("* Device %02x:\n", device_id);
offset++;
if (offset + 1 >= song->size)
@@ -3461,12 +3464,12 @@ bool Console::cmdSfx01Header(int argc, const char **argv) {
track_offset += 2;
end = READ_LE_UINT16(song->data + offset + 2);
- DebugPrintf(" - %04x -- %04x", track_offset, track_offset + end);
+ debugPrintf(" - %04x -- %04x", track_offset, track_offset + end);
if (track_offset == 0xfe)
- DebugPrintf(" (PCM data)\n");
+ debugPrintf(" (PCM data)\n");
else
- DebugPrintf(" (channel %d, special %d, %d playing notes, %d foo)\n",
+ debugPrintf(" (channel %d, special %d, %d playing notes, %d foo)\n",
header1 & 0xf, header1 >> 4, header2 & 0xf, header2 >> 4);
offset += 4;
}
@@ -3580,8 +3583,8 @@ static void midi_hexdump(byte *data, int size, int notational_offset) {
bool Console::cmdSfx01Track(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Dumps a track of a SCI01 song\n");
- DebugPrintf("Usage: %s <track> <offset>\n", argv[0]);
+ debugPrintf("Dumps a track of a SCI01 song\n");
+ debugPrintf("Usage: %s <track> <offset>\n", argv[0]);
return true;
}
@@ -3590,7 +3593,7 @@ bool Console::cmdSfx01Track(int argc, const char **argv) {
int offset = atoi(argv[2]);
if (!song) {
- DebugPrintf("Doesn't exist\n");
+ debugPrintf("Doesn't exist\n");
return true;
}
@@ -3614,29 +3617,29 @@ bool Console::cmdQuit(int argc, const char **argv) {
_debugState.runningStep = 0;
} else {
- DebugPrintf("%s [game] - exit gracefully\n", argv[0]);
- DebugPrintf("%s now - exit ungracefully\n", argv[0]);
+ debugPrintf("%s [game] - exit gracefully\n", argv[0]);
+ debugPrintf("%s now - exit ungracefully\n", argv[0]);
return true;
}
- return Cmd_Exit(0, 0);
+ return cmdExit(0, 0);
}
bool Console::cmdAddresses(int argc, const char **argv) {
- DebugPrintf("Address parameters may be passed in one of three forms:\n");
- DebugPrintf(" - ssss:oooo -- where 'ssss' denotes a segment and 'oooo' an offset.\n");
- DebugPrintf(" Example: \"a:c5\" would address something in segment 0xa at offset 0xc5.\n");
- DebugPrintf(" - &scr:oooo -- where 'scr' is a script number and oooo an offset within that script; will\n");
- DebugPrintf(" fail if the script is not currently loaded\n");
- DebugPrintf(" - $REG -- where 'REG' is one of 'PC', 'ACC', 'PREV' or 'OBJ': References the address\n");
- DebugPrintf(" indicated by the register of this name.\n");
- DebugPrintf(" - $REG+n (or -n) -- Like $REG, but modifies the offset part by a specific amount (which\n");
- DebugPrintf(" is specified in hexadecimal).\n");
- DebugPrintf(" - ?obj -- Looks up an object with the specified name, uses its address. This will abort if\n");
- DebugPrintf(" the object name is ambiguous; in that case, a list of addresses and indices is provided.\n");
- DebugPrintf(" ?obj.idx may be used to disambiguate 'obj' by the index 'idx'.\n");
- DebugPrintf(" Underscores are used as substitute characters for spaces in object names.\n");
- DebugPrintf(" For example, an object named \"Glass Jar\" can be accessed as \"Glass_Jar\".\n");
+ debugPrintf("Address parameters may be passed in one of three forms:\n");
+ debugPrintf(" - ssss:oooo -- where 'ssss' denotes a segment and 'oooo' an offset.\n");
+ debugPrintf(" Example: \"a:c5\" would address something in segment 0xa at offset 0xc5.\n");
+ debugPrintf(" - &scr:oooo -- where 'scr' is a script number and oooo an offset within that script; will\n");
+ debugPrintf(" fail if the script is not currently loaded\n");
+ debugPrintf(" - $REG -- where 'REG' is one of 'PC', 'ACC', 'PREV' or 'OBJ': References the address\n");
+ debugPrintf(" indicated by the register of this name.\n");
+ debugPrintf(" - $REG+n (or -n) -- Like $REG, but modifies the offset part by a specific amount (which\n");
+ debugPrintf(" is specified in hexadecimal).\n");
+ debugPrintf(" - ?obj -- Looks up an object with the specified name, uses its address. This will abort if\n");
+ debugPrintf(" the object name is ambiguous; in that case, a list of addresses and indices is provided.\n");
+ debugPrintf(" ?obj.idx may be used to disambiguate 'obj' by the index 'idx'.\n");
+ debugPrintf(" Underscores are used as substitute characters for spaces in object names.\n");
+ debugPrintf(" For example, an object named \"Glass Jar\" can be accessed as \"Glass_Jar\".\n");
return true;
}
@@ -3887,14 +3890,14 @@ bool Console::parseInteger(const char *argument, int &result) {
// hexadecimal number
result = strtol(argument, &endPtr, 16);
if ((*endPtr != 0) && (*endPtr != 'h')) {
- DebugPrintf("Invalid hexadecimal number '%s'\n", argument);
+ debugPrintf("Invalid hexadecimal number '%s'\n", argument);
return false;
}
} else {
// decimal number
result = strtol(argument, &endPtr, 10);
if (*endPtr != 0) {
- DebugPrintf("Invalid decimal number '%s'\n", argument);
+ debugPrintf("Invalid decimal number '%s'\n", argument);
return false;
}
}
@@ -3912,57 +3915,57 @@ void Console::printBasicVarInfo(reg_t variable) {
case SIG_TYPE_INTEGER: {
uint16 content = variable.toUint16();
if (content >= 10)
- DebugPrintf(" (%dd)", content);
+ debugPrintf(" (%dd)", content);
break;
}
case SIG_TYPE_OBJECT:
- DebugPrintf(" (object '%s')", segMan->getObjectName(variable));
+ debugPrintf(" (object '%s')", segMan->getObjectName(variable));
break;
case SIG_TYPE_REFERENCE:
- DebugPrintf(" (reference)");
+ debugPrintf(" (reference)");
break;
case SIG_TYPE_NODE:
- DebugPrintf(" (node)");
+ debugPrintf(" (node)");
break;
case SIG_TYPE_LIST:
- DebugPrintf(" (list)");
+ debugPrintf(" (list)");
break;
case SIG_TYPE_UNINITIALIZED:
- DebugPrintf(" (uninitialized)");
+ debugPrintf(" (uninitialized)");
break;
case SIG_TYPE_ERROR:
- DebugPrintf(" (error)");
+ debugPrintf(" (error)");
break;
default:
- DebugPrintf(" (??\?)");
+ debugPrintf(" (??\?)");
}
if (regType & SIG_IS_INVALID)
- DebugPrintf(" IS INVALID!");
+ debugPrintf(" IS INVALID!");
}
void Console::printList(List *list) {
reg_t pos = list->first;
reg_t my_prev = NULL_REG;
- DebugPrintf("\t<\n");
+ debugPrintf("\t<\n");
while (!pos.isNull()) {
Node *node;
NodeTable *nt = (NodeTable *)_engine->_gamestate->_segMan->getSegment(pos.getSegment(), SEG_TYPE_NODES);
if (!nt || !nt->isValidEntry(pos.getOffset())) {
- DebugPrintf(" WARNING: %04x:%04x: Doesn't contain list node!\n",
+ debugPrintf(" WARNING: %04x:%04x: Doesn't contain list node!\n",
PRINT_REG(pos));
return;
}
node = &(nt->_table[pos.getOffset()]);
- DebugPrintf("\t%04x:%04x : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));
+ debugPrintf("\t%04x:%04x : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));
if (my_prev != node->pred)
- DebugPrintf(" WARNING: current node gives %04x:%04x as predecessor!\n",
+ debugPrintf(" WARNING: current node gives %04x:%04x as predecessor!\n",
PRINT_REG(node->pred));
my_prev = pos;
@@ -3970,9 +3973,9 @@ void Console::printList(List *list) {
}
if (my_prev != list->last)
- DebugPrintf(" WARNING: Last node was expected to be %04x:%04x, was %04x:%04x!\n",
+ debugPrintf(" WARNING: Last node was expected to be %04x:%04x, was %04x:%04x!\n",
PRINT_REG(list->last), PRINT_REG(my_prev));
- DebugPrintf("\t>\n");
+ debugPrintf("\t>\n");
}
int Console::printNode(reg_t addr) {
@@ -3983,32 +3986,32 @@ int Console::printNode(reg_t addr) {
List *list;
if (!lt->isValidEntry(addr.getOffset())) {
- DebugPrintf("Address does not contain a list\n");
+ debugPrintf("Address does not contain a list\n");
return 1;
}
list = &(lt->_table[addr.getOffset()]);
- DebugPrintf("%04x:%04x : first x last = (%04x:%04x, %04x:%04x)\n", PRINT_REG(addr), PRINT_REG(list->first), PRINT_REG(list->last));
+ debugPrintf("%04x:%04x : first x last = (%04x:%04x, %04x:%04x)\n", PRINT_REG(addr), PRINT_REG(list->first), PRINT_REG(list->last));
} else {
NodeTable *nt;
Node *node;
mobj = _engine->_gamestate->_segMan->getSegment(addr.getSegment(), SEG_TYPE_NODES);
if (!mobj) {
- DebugPrintf("Segment #%04x is not a list or node segment\n", addr.getSegment());
+ debugPrintf("Segment #%04x is not a list or node segment\n", addr.getSegment());
return 1;
}
nt = (NodeTable *)mobj;
if (!nt->isValidEntry(addr.getOffset())) {
- DebugPrintf("Address does not contain a node\n");
+ debugPrintf("Address does not contain a node\n");
return 1;
}
node = &(nt->_table[addr.getOffset()]);
- DebugPrintf("%04x:%04x : prev x next = (%04x:%04x, %04x:%04x); maps %04x:%04x -> %04x:%04x\n",
+ debugPrintf("%04x:%04x : prev x next = (%04x:%04x, %04x:%04x); maps %04x:%04x -> %04x:%04x\n",
PRINT_REG(addr), PRINT_REG(node->pred), PRINT_REG(node->succ), PRINT_REG(node->key), PRINT_REG(node->value));
}
@@ -4022,44 +4025,44 @@ int Console::printObject(reg_t pos) {
uint i;
if (!obj) {
- DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos));
+ debugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos));
return 1;
}
// Object header
- DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos),
+ debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos),
obj->getVarCount(), obj->getMethodCount());
if (!obj->isClass() && getSciVersion() != SCI_VERSION_3)
var_container = s->_segMan->getObject(obj->getSuperClassSelector());
- DebugPrintf(" -- member variables:\n");
+ debugPrintf(" -- member variables:\n");
for (i = 0; (uint)i < obj->getVarCount(); i++) {
- DebugPrintf(" ");
+ debugPrintf(" ");
if (var_container && i < var_container->getVarCount()) {
uint16 varSelector = var_container->getVarSelector(i);
- DebugPrintf("[%03x] %s = ", varSelector, _engine->getKernel()->getSelectorName(varSelector).c_str());
+ debugPrintf("[%03x] %s = ", varSelector, _engine->getKernel()->getSelectorName(varSelector).c_str());
} else
- DebugPrintf("p#%x = ", i);
+ debugPrintf("p#%x = ", i);
reg_t val = obj->getVariable(i);
- DebugPrintf("%04x:%04x", PRINT_REG(val));
+ debugPrintf("%04x:%04x", PRINT_REG(val));
if (!val.getSegment())
- DebugPrintf(" (%d)", val.getOffset());
+ debugPrintf(" (%d)", val.getOffset());
const Object *ref = s->_segMan->getObject(val);
if (ref)
- DebugPrintf(" (%s)", s->_segMan->getObjectName(val));
+ debugPrintf(" (%s)", s->_segMan->getObjectName(val));
- DebugPrintf("\n");
+ debugPrintf("\n");
}
- DebugPrintf(" -- methods:\n");
+ debugPrintf(" -- methods:\n");
for (i = 0; i < obj->getMethodCount(); i++) {
reg_t fptr = obj->getFunction(i);
- DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), PRINT_REG(fptr));
+ debugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), PRINT_REG(fptr));
}
if (s->_segMan->_heap[pos.getSegment()]->getType() == SEG_TYPE_SCRIPT)
- DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.getSegment())->getScriptNumber());
+ debugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.getSegment())->getScriptNumber());
return 0;
}
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 8c5f9be425..368b82cb93 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -4054,7 +4054,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
FANMADE("SCI Capture the Flag", "4cd679a51d93b8b27c6b38d81be24b8b", 432, "98ae1f6ed7b4c21f88addbf643dd1d2f", 147878),
FANMADE("SCI Companion Template", "ad54d4f504086cd597aa2348d0aa3b09", 354, "6798b7b601ce8154c1d1bc0f0edcdd18", 113061),
FANMADE("SCI Logging Demo", "615c30c1445ea9349847e8868312a674", 558, "2df6858526177612ef9473e7af5b31c6", 171012),
-#ifdef 0
+#if 0
// Disabled as this requires network access to the Google Translate API, which is not available as OSystem has no network API.
FANMADE("SCI Narration Demo", "731f4f2b726a13c153380af08da16591", 360, "38c80558fb942e8568f011d4a1a4af59", 109789),
#endif
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index 59f741a254..cb81da2279 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -126,7 +126,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
// track left buttton clicks, if requested
if (curEvent.type == SCI_EVENT_MOUSE_PRESS && curEvent.data == 1 && g_debug_track_mouse_clicks) {
- g_sci->getSciDebugger()->DebugPrintf("Mouse clicked at %d, %d\n",
+ g_sci->getSciDebugger()->debugPrintf("Mouse clicked at %d, %d\n",
mousePos.x, mousePos.y);
}
@@ -163,20 +163,20 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
// A SCI event occurred, and we have been asked to stop, so open the debug console
Console *con = g_sci->getSciDebugger();
- con->DebugPrintf("SCI event occurred: ");
+ con->debugPrintf("SCI event occurred: ");
switch (curEvent.type) {
case SCI_EVENT_QUIT:
- con->DebugPrintf("quit event\n");
+ con->debugPrintf("quit event\n");
break;
case SCI_EVENT_KEYBOARD:
- con->DebugPrintf("keyboard event\n");
+ con->debugPrintf("keyboard event\n");
break;
case SCI_EVENT_MOUSE_RELEASE:
case SCI_EVENT_MOUSE_PRESS:
- con->DebugPrintf("mouse click event\n");
+ con->debugPrintf("mouse click event\n");
break;
default:
- con->DebugPrintf("unknown or no event (event type %d)\n", curEvent.type);
+ con->debugPrintf("unknown or no event (event type %d)\n", curEvent.type);
}
con->attach();
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index b4d245197b..8bbbd713a6 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -1218,7 +1218,7 @@ static const uint16 kq6CDPatchAudioTextSupportGirlInTheTower[] = {
// Adds another button state for the text/audio button. We currently use the "speech" view for "dual" mode.
// View 947, loop 9, cel 0+1 -> "text"
// View 947, loop 8, cel 0+1 -> "speech"
-// View 947, loop 12, cel 0+1 -> "dual" (TODO: inject our own 2 views for the new "dual" mode)
+// View 947, loop 12, cel 0+1 -> "dual" (this view is injected by us into the game)
// Applies to at least: PC-CD
// Patched method: iconTextSwitch::show, iconTextSwitch::doit
static const uint16 kq6CDSignatureAudioTextMenuSupport[] = {
@@ -1595,6 +1595,86 @@ static const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
PATCH_END
};
+// Opening/Closing the east door in the pterodactyl room doesn't
+// check, if it's locked and will open/close the door internally
+// even when it is.
+//
+// It will get wired shut later in the game by Laura Bow and will be
+// "locked" because of this. We patch in a check for the locked
+// state. We also add code, that will set the "locked" state
+// in case our eastDoor-wired-global is set. This makes the locked
+// state effectively persistent.
+//
+// Applies to at least: English PC-CD, English PC-Floppy
+// Responsible method (CD): eastDoor::doVerb
+// Responsible method (Floppy): eastDoor::<noname300>
+// Fixes bug: #6458 (partly, see additional patch below)
+static const uint16 laurabow2CDSignatureFixWiredEastDoor[] = {
+ 0x30, SIG_UINT16(0x0022), // bnt [skip hand action]
+ 0x67, SIG_ADDTOOFFSET(+1), // pTos CD: doorState, Floppy: state
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x08, // bnt [close door code]
+ 0x78, // push1
+ SIG_MAGICDWORD,
+ 0x39, 0x63, // pushi 63h
+ 0x45, 0x04, 0x02, // callb export000_4, 02 (sets door-bitflag)
+ 0x33, 0x06, // jmp [super-code]
+ 0x78, // push1
+ 0x39, 0x63, // pushi 63h
+ 0x45, 0x03, 0x02, // callb export000_3, 02 (resets door-bitflag)
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi CD: 011dh, Floppy: 012ch
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[01]
+ 0x59, 0x02, // rest 02
+ 0x57, SIG_ADDTOOFFSET(+1), 0x06, // super CD: LbDoor, Floppy: Door, 06
+ 0x33, 0x0b, // jmp [ret]
+ SIG_END
+};
+
+static const uint16 laurabow2CDPatchFixWiredEastDoor[] = {
+ 0x31, 0x23, // bnt [skip hand action] (saves 1 byte)
+ 0x81, 97, // lag 97d (get our eastDoor-wired-global)
+ 0x31, 0x04, // bnt [skip setting locked property]
+ 0x35, 0x01, // ldi 01
+ 0x65, 0x6a, // aTop locked (set eastDoor::locked to 1)
+ 0x63, 0x6a, // pToa locked (get eastDoor::locked)
+ 0x2f, 0x17, // bt [skip hand action]
+ 0x63, PATCH_GETORIGINALBYTE(+4), // pToa CD: doorState, Floppy: state
+ 0x78, // push1
+ 0x39, 0x63, // pushi 63h
+ 0x2f, 0x05, // bt [close door code]
+ 0x45, 0x04, 0x02, // callb export000_4, 02 (sets door-bitflag)
+ 0x33, 0x0b, // jmp [super-code]
+ 0x45, 0x03, 0x02, // callb export000_3, 02 (resets door-bitflag)
+ 0x33, 0x06, // jmp [super-code]
+ PATCH_END
+};
+
+// We patch in code, so that our eastDoor-wired-global will get set to 1.
+// This way the wired-state won't get lost when exiting room 430.
+//
+// Applies to at least: English PC-CD, English PC-Floppy
+// Responsible method (CD): sWireItShut::changeState
+// Responsible method (Floppy): sWireItShut::<noname144>
+// Fixes bug: #6458 (partly, see additional patch above)
+static const uint16 laurabow2SignatureRememberWiredEastDoor[] = {
+ SIG_MAGICDWORD,
+ 0x33, 0x27, // jmp [ret]
+ 0x3c, // dup
+ 0x35, 0x06, // ldi 06
+ 0x1a, // eq?
+ 0x31, 0x21, // bnt [skip step]
+ SIG_END
+};
+
+static const uint16 laurabow2PatchRememberWiredEastDoor[] = {
+ PATCH_ADDTOOFFSET(+2), // skip jmp [ret]
+ 0x34, PATCH_UINT16(0x0001), // ldi 0001
+ 0xa1, PATCH_UINT16(97), // sag 97d (set our eastDoor-wired-global)
+ PATCH_END
+};
+
// Laura Bow 2 CD resets the audio mode to speech on init/restart
// We already sync the settings from ScummVM (see SciEngine::syncIngameAudioOptions())
// and this script code would make it impossible to see the intro using "dual" mode w/o using debugger command
@@ -1617,7 +1697,7 @@ static const uint16 laurabow2CDPatchAudioTextSupportModeReset[] = {
// That way it's possible to use a new "dual" mode view in the game menu
// View 995, loop 13, cel 0 -> "text"
// View 995, loop 13, cel 1 -> "speech"
-// View 995, loop 13, cel 2 -> "dual" (TODO: inject our own view for the new "dual" mode)
+// View 995, loop 13, cel 2 -> "dual" (this view is injected by us into the game)
// Patched method: gcWin::open
static const uint16 laurabow2CDSignatureAudioTextMenuSupport1[] = {
SIG_MAGICDWORD,
@@ -1636,7 +1716,6 @@ static const uint16 laurabow2CDPatchAudioTextMenuSupport1[] = {
};
// Adds another button state for the text/audio button. We currently use the "speech" view for "dual" mode.
-// TODO: inject our own 2 views for the new "dual" mode
// Patched method: iconMode::doit
static const uint16 laurabow2CDSignatureAudioTextMenuSupport2[] = {
SIG_MAGICDWORD,
@@ -1684,6 +1763,8 @@ static const uint16 laurabow2CDPatchAudioTextMenuSupport2[] = {
static const SciScriptPatcherEntry laurabow2Signatures[] = {
{ true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
{ true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+ { true, 430, "CD/Floppy: make wired east door persistent", 1, laurabow2SignatureRememberWiredEastDoor, laurabow2PatchRememberWiredEastDoor },
+ { true, 430, "CD/Floppy: fix wired east door", 1, laurabow2CDSignatureFixWiredEastDoor, laurabow2CDPatchFixWiredEastDoor },
// King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
{ false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
{ false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
@@ -2373,11 +2454,91 @@ static const uint16 sq1vgaPatchEgoShowsCard[] = {
PATCH_END
};
+// The spider droid on planet Korona has a fixed movement speed,
+// which is way faster than the default movement speed of ego.
+// This means that the player would have to turn up movement speed,
+// otherwise it will be impossible to escape it.
+// We fix this issue by making the droid move a bit slower than ego
+// does (relative to movement speed setting).
+//
+// Applies to at least: English PC floppy
+// Responsible method: spider::doit
+static const uint16 sq1vgaSignatureSpiderDroidTiming[] = {
+ SIG_MAGICDWORD,
+ 0x63, 0x4e, // pToa script
+ 0x30, SIG_UINT16(0x0005), // bnt [further method code]
+ 0x35, 0x00, // ldi 00
+ 0x32, SIG_UINT16(0x0062), // jmp [super-call]
+ 0x38, SIG_UINT16(0x0088), // pushi 0088h (script)
+ 0x76, // push0
+ 0x81, 0x02, // lag global[2] (current room)
+ 0x4a, 0x04, // send 04 (get [current room].script)
+ 0x30, SIG_UINT16(0x0005), // bnt [further method code]
+ 0x35, 0x00, // ldi 00
+ 0x32, SIG_UINT16(0x0052), // jmp [super-call]
+ 0x89, 0xa6, // lsg global[a6]
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x0012), // bnt [2nd code], in case global A6 <> 1
+ 0x81, 0xb5, // lag global[b5]
+ 0x30, SIG_UINT16(0x000d), // bnt [2nd code], in case global B5 == 0
+ 0x38, SIG_UINT16(0x008c), // pushi 008c
+ 0x78, // push1
+ 0x72, SIG_UINT16(0x1cb6), // lofsa 1CB6 (moveToPath)
+ 0x36, // push
+ 0x54, 0x06, // self 06
+ 0x32, SIG_UINT16(0x0038), // jmp [super-call]
+ 0x81, 0xb5, // lag global[B5]
+ 0x18, // not
+ 0x30, SIG_UINT16(0x0032), // bnt [super-call], in case global B5 <> 0
+ SIG_END
+}; // 58 bytes)
+
+static const uint16 sq1vgaPatchSpiderDroidTiming[] = {
+ 0x63, 0x4e, // pToa script
+ 0x2f, 0x68, // bt [super-call]
+ 0x38, PATCH_UINT16(0x0088), // pushi 0088 (script)
+ 0x76, // push0
+ 0x81, 0x02, // lag global[2] (current room)
+ 0x4a, 0x04, // send 04
+ 0x2f, 0x5e, // bt [super-call]
+ // --> 12 bytes saved
+ // new code
+ 0x38, PATCH_UINT16(0x0176), // pushi 0176 (egoMoveSpeed)
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - sq1::egoMoveSpeed
+ 0x36, // push
+ 0x36, // push
+ 0x35, 0x03, // ldi 03
+ 0x0c, // shr
+ 0x02, // add --> egoMoveSpeed + (egoMoveSpeed >> 3)
+ 0x39, 0x01, // push 01 (waste 1 byte)
+ 0x02, // add --> egoMoveSpeed++
+ 0x65, 0x4c, // aTop cycleSpeed
+ 0x65, 0x5e, // aTop moveSpeed
+ // new code end
+ 0x89, 0xb5, // lsg global[B5]
+ 0x31, 0x13, // bnt [2nd code chunk]
+ 0x89, 0xa6, // lsg global[A6]
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x3e, // bnt [super-call]
+ 0x38, PATCH_UINT16(0x008c), // pushi 008c
+ 0x78, // push1
+ 0x72, PATCH_UINT16(0x1cb6), // lofsa moveToPath
+ 0x36, // push
+ 0x54, 0x06, // self 06 - spider::setScript(movePath)
+ 0x33, 0x32, // jmp [super-call]
+ // --> 9 bytes saved
+ PATCH_END
+};
// script, description, signature patch
static const SciScriptPatcherEntry sq1vgaSignatures[] = {
{ true, 45, "Ulence Flats: timepod graphic glitch", 1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
{ true, 58, "Sarien armory droid zapping ego first time", 1, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
+ { true, 704, "spider droid timing issue", 1, sq1vgaSignatureSpiderDroidTiming, sq1vgaPatchSpiderDroidTiming },
SCI_SIGNATUREENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 44910058ef..f0157a6569 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -604,7 +604,7 @@ bool SciEngine::checkSelectorBreakpoint(BreakpointType breakpointType, reg_t sen
Common::List<Breakpoint>::const_iterator bpIter;
for (bpIter = _debugState._breakpoints.begin(); bpIter != _debugState._breakpoints.end(); ++bpIter) {
if ((*bpIter).type == breakpointType && (*bpIter).name == methodName) {
- _console->DebugPrintf("Break on %s (in [%04x:%04x])\n", methodName.c_str(), PRINT_REG(send_obj));
+ _console->debugPrintf("Break on %s (in [%04x:%04x])\n", methodName.c_str(), PRINT_REG(send_obj));
_debugState.debugging = true;
_debugState.breakpointWasHit = true;
return true;
@@ -620,7 +620,7 @@ bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
Common::List<Breakpoint>::const_iterator bp;
for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
if (bp->type == BREAK_EXPORT && bp->address == bpaddress) {
- _console->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
+ _console->debugPrintf("Break on script %d, export %d\n", script, pubfunct);
_debugState.debugging = true;
_debugState.breakpointWasHit = true;
return true;
@@ -666,12 +666,12 @@ void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr arg
reg_t selectorValue = *varp.getPointer(segMan);
if (!argc && (activeBreakpointTypes & BREAK_SELECTORREAD)) {
if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
- con->DebugPrintf("Read from selector (%s:%s): %04x:%04x\n",
+ con->debugPrintf("Read from selector (%s:%s): %04x:%04x\n",
objectName, selectorName,
PRINT_REG(selectorValue));
} else if (argc && (activeBreakpointTypes & BREAK_SELECTORWRITE)) {
if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector))
- con->DebugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
+ con->debugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
objectName, selectorName,
PRINT_REG(selectorValue), PRINT_REG(argp[1]));
}
@@ -690,13 +690,13 @@ void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr arg
if (true) {
if (true) {
#endif
- con->DebugPrintf("%s::%s(", objectName, selectorName);
+ con->debugPrintf("%s::%s(", objectName, selectorName);
for (int i = 0; i < argc; i++) {
- con->DebugPrintf("%04x:%04x", PRINT_REG(argp[i+1]));
+ con->debugPrintf("%04x:%04x", PRINT_REG(argp[i+1]));
if (i + 1 < argc)
- con->DebugPrintf(", ");
+ con->debugPrintf(", ");
}
- con->DebugPrintf(") at %04x:%04x\n", PRINT_REG(funcp));
+ con->debugPrintf(") at %04x:%04x\n", PRINT_REG(funcp));
}
}
break;
diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp
index 73cd7240d3..7957ed6a55 100644
--- a/engines/sci/graphics/animate.cpp
+++ b/engines/sci/graphics/animate.cpp
@@ -726,7 +726,7 @@ void GfxAnimate::printAnimateList(Console *con) {
Script *scr = _s->_segMan->getScriptIfLoaded(it->object.getSegment());
int16 scriptNo = scr ? scr->getScriptNumber() : -1;
- con->DebugPrintf("%04x:%04x (%s), script %d, view %d (%d, %d), pal %d, "
+ con->debugPrintf("%04x:%04x (%s), script %d, view %d (%d, %d), pal %d, "
"at %d, %d, scale %d, %d / %d (z: %d, prio: %d, shown: %d, signal: %d)\n",
PRINT_REG(it->object), _s->_segMan->getObjectName(it->object),
scriptNo, it->viewId, it->loopNo, it->celNo, it->paletteNo,
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index ffed7b596e..a322eb8e61 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -852,21 +852,21 @@ void GfxFrameout::printPlaneList(Console *con) {
Common::Rect r = p.upscaledPlaneRect;
Common::Rect cr = p.upscaledPlaneClipRect;
- con->DebugPrintf("%04x:%04x (%s): prio %d, lastprio %d, offsetX %d, offsetY %d, pic %d, mirror %d, back %d\n",
+ con->debugPrintf("%04x:%04x (%s): prio %d, lastprio %d, offsetX %d, offsetY %d, pic %d, mirror %d, back %d\n",
PRINT_REG(p.object), curPlaneName.c_str(),
(int16)p.priority, (int16)p.lastPriority,
p.planeOffsetX, p.planeOffsetY, p.pictureId,
p.planePictureMirrored, p.planeBack);
- con->DebugPrintf(" rect: (%d, %d, %d, %d), clip rect: (%d, %d, %d, %d)\n",
+ con->debugPrintf(" rect: (%d, %d, %d, %d), clip rect: (%d, %d, %d, %d)\n",
r.left, r.top, r.right, r.bottom,
cr.left, cr.top, cr.right, cr.bottom);
if (p.pictureId != 0xffff && p.pictureId != 0xfffe) {
- con->DebugPrintf("Pictures:\n");
+ con->debugPrintf("Pictures:\n");
for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
if (pictureIt->object == p.object) {
- con->DebugPrintf(" Picture %d: x %d, y %d\n", pictureIt->pictureId, pictureIt->startX, pictureIt->startY);
+ con->debugPrintf(" Picture %d: x %d, y %d\n", pictureIt->pictureId, pictureIt->startX, pictureIt->startY);
}
}
}
@@ -883,7 +883,7 @@ void GfxFrameout::printPlaneItemList(Console *con, reg_t planeObject) {
Common::Rect icr = e->celRect;
GuiResourceId picId = e->picture ? e->picture->getResourceId() : 0;
- con->DebugPrintf("%d: %04x:%04x (%s), view %d, loop %d, cel %d, x %d, y %d, z %d, "
+ con->debugPrintf("%d: %04x:%04x (%s), view %d, loop %d, cel %d, x %d, y %d, z %d, "
"signal %d, scale signal %d, scaleX %d, scaleY %d, rect (%d, %d, %d, %d), "
"pic %d, picX %d, picY %d, visible %d\n",
e->givenOrderNr, PRINT_REG(e->object), curItemName.c_str(),
diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp
index bd0b5f4081..56c63a7b12 100644
--- a/engines/sci/graphics/ports.cpp
+++ b/engines/sci/graphics/ports.cpp
@@ -748,7 +748,7 @@ void GfxPorts::printWindowList(Console *con) {
for (PortList::const_iterator it = _windowList.begin(); it != _windowList.end(); ++it) {
if ((*it)->isWindow()) {
Window *wnd = ((Window *)*it);
- con->DebugPrintf("%d: '%s' at %d, %d, (%d, %d, %d, %d), drawn: %d, style: %d\n",
+ con->debugPrintf("%d: '%s' at %d, %d, (%d, %d, %d, %d), drawn: %d, style: %d\n",
wnd->id, wnd->title.c_str(), wnd->left, wnd->top,
wnd->rect.left, wnd->rect.top, wnd->rect.right, wnd->rect.bottom,
wnd->bDrawn, wnd->wndStyle);
diff --git a/engines/sci/parser/grammar.cpp b/engines/sci/parser/grammar.cpp
index ee0125b7c9..05764ba0a8 100644
--- a/engines/sci/parser/grammar.cpp
+++ b/engines/sci/parser/grammar.cpp
@@ -397,7 +397,7 @@ ParseRuleList *Vocabulary::buildGNF(bool verbose) {
ntrules_nr = _vocab_rule_list_length(ntlist);
if (verbose)
- con->DebugPrintf("Starting with %d rules\n", ntrules_nr);
+ con->debugPrintf("Starting with %d rules\n", ntrules_nr);
new_tlist = tlist;
tlist = NULL;
@@ -425,17 +425,17 @@ ParseRuleList *Vocabulary::buildGNF(bool verbose) {
termrules = _vocab_rule_list_length(new_new_tlist);
if (verbose)
- con->DebugPrintf("After iteration #%d: %d new term rules\n", ++iterations, termrules);
+ con->debugPrintf("After iteration #%d: %d new term rules\n", ++iterations, termrules);
} while (termrules && (iterations < 30));
freeRuleList(ntlist);
if (verbose) {
- con->DebugPrintf("\nGNF rules:\n");
+ con->debugPrintf("\nGNF rules:\n");
tlist->print();
- con->DebugPrintf("%d allocd rules\n", _allocd_rules);
- con->DebugPrintf("Freeing rule list...\n");
+ con->debugPrintf("%d allocd rules\n", _allocd_rules);
+ con->debugPrintf("Freeing rule list...\n");
freeRuleList(tlist);
return NULL;
}
@@ -548,7 +548,7 @@ int Vocabulary::parseGNF(const ResultWordListList &words, bool verbose) {
ParseRuleList *seeker, *subseeker;
if (verbose)
- con->DebugPrintf("Adding word %d...\n", word);
+ con->debugPrintf("Adding word %d...\n", word);
seeker = work;
while (seeker) {
@@ -562,7 +562,7 @@ int Vocabulary::parseGNF(const ResultWordListList &words, bool verbose) {
if (reduced_rules == NULL) {
freeRuleList(work);
if (verbose)
- con->DebugPrintf("No results.\n");
+ con->debugPrintf("No results.\n");
return 1;
}
@@ -592,10 +592,10 @@ int Vocabulary::parseGNF(const ResultWordListList &words, bool verbose) {
work = new_work;
if (verbose)
- con->DebugPrintf("Now at %d candidates\n", _vocab_rule_list_length(work));
+ con->debugPrintf("Now at %d candidates\n", _vocab_rule_list_length(work));
if (work == NULL) {
if (verbose)
- con->DebugPrintf("No results.\n");
+ con->debugPrintf("No results.\n");
return 1;
}
}
@@ -603,9 +603,9 @@ int Vocabulary::parseGNF(const ResultWordListList &words, bool verbose) {
results = work;
if (verbose) {
- con->DebugPrintf("All results (excluding the surrounding '(141 %03x' and ')'):\n", _parserBranches[0].id);
+ con->debugPrintf("All results (excluding the surrounding '(141 %03x' and ')'):\n", _parserBranches[0].id);
results->print();
- con->DebugPrintf("\n");
+ con->debugPrintf("\n");
}
// now use the first result
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index 7c560dfaef..b4a223dcff 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -577,7 +577,7 @@ void Vocabulary::printSuffixes() const {
strncpy(alt_buf, suf->alt_suffix, suf->alt_suffix_length);
alt_buf[suf->alt_suffix_length] = 0;
- con->DebugPrintf("%4d: (%03x) -%12s => -%12s (%03x)\n", i, suf->class_mask, word_buf, alt_buf, suf->result_class);
+ con->debugPrintf("%4d: (%03x) -%12s => -%12s (%03x)\n", i, suf->class_mask, word_buf, alt_buf, suf->result_class);
++i;
}
}
@@ -588,14 +588,14 @@ void Vocabulary::printParserWords() const {
int n = 0;
for (WordMap::iterator i = _parserWords.begin(); i != _parserWords.end(); ++i) {
for (ResultWordList::iterator j = i->_value.begin(); j != i->_value.end(); ++j) {
- con->DebugPrintf("%4d: %03x [%03x] %20s |", n, j->_class, j->_group, i->_key.c_str());
+ con->debugPrintf("%4d: %03x [%03x] %20s |", n, j->_class, j->_group, i->_key.c_str());
if (n % 3 == 0)
- con->DebugPrintf("\n");
+ con->debugPrintf("\n");
n++;
}
}
- con->DebugPrintf("\n");
+ con->debugPrintf("\n");
}
void _vocab_recursive_ptree_dump(ParseTreeNode *tree, int blanks) {
@@ -665,15 +665,15 @@ void Vocabulary::printParserNodes(int num) {
Console *con = g_sci->getSciDebugger();
for (int i = 0; i < num; i++) {
- con->DebugPrintf(" Node %03x: ", i);
+ con->debugPrintf(" Node %03x: ", i);
if (_parserNodes[i].type == kParseTreeLeafNode)
- con->DebugPrintf("Leaf: %04x\n", _parserNodes[i].value);
+ con->debugPrintf("Leaf: %04x\n", _parserNodes[i].value);
else {
// FIXME: Do we really want to print the *addresses*
// of the left & right child?
// Note that one or both may be zero pointers, so we can't just
// print their values.
- con->DebugPrintf("Branch: ->%p, ->%p\n",
+ con->debugPrintf("Branch: ->%p, ->%p\n",
(const void *)_parserNodes[i].left,
(const void *)_parserNodes[i].right);
}
@@ -694,11 +694,11 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c
return *pos;
}
if (type == kParseEndOfInput) {
- con->DebugPrintf("Unbalanced parentheses\n");
+ con->debugPrintf("Unbalanced parentheses\n");
return -1;
}
if (type == kParseClosingParenthesis) {
- con->DebugPrintf("Syntax error at token %d\n", *i);
+ con->debugPrintf("Syntax error at token %d\n", *i);
return -1;
}
@@ -735,7 +735,7 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c
const char *token = argv[(*i)++];
if (strcmp(token, ")"))
- con->DebugPrintf("Expected ')' at token %d\n", *i);
+ con->debugPrintf("Expected ')' at token %d\n", *i);
return oldPos;
}
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 97675a140e..362cca699d 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -142,6 +142,8 @@ void SciMusic::init() {
_driverLastChannel = _pMidiDrv->getLastChannel();
if (getSciVersion() <= SCI_VERSION_0_LATE)
_globalReverb = _pMidiDrv->getReverb(); // Init global reverb for SCI0
+
+ _currentlyPlayingSample = NULL;
}
void SciMusic::miditimerCallback(void *p) {
@@ -432,6 +434,17 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
if (pSnd->pStreamAud) {
if (!_pMixer->isSoundHandleActive(pSnd->hCurrentAud)) {
+ if ((_currentlyPlayingSample) && (_pMixer->isSoundHandleActive(_currentlyPlayingSample->hCurrentAud))) {
+ // Another sample is already playing, we have to stop that one
+ // SSCI is only able to play 1 sample at a time
+ // In Space Quest 5 room 250 the player is able to open the air-hatch and kill himself.
+ // In that situation the scripts are playing 2 samples at the same time and the first sample
+ // is not supposed to play.
+ // TODO: SSCI actually calls kDoAudio(play) internally, which stops other samples from being played
+ // but such a change isn't trivial, because we also handle Sound resources in here, that contain samples
+ _pMixer->stopHandle(_currentlyPlayingSample->hCurrentAud);
+ warning("kDoSound: sample already playing, old resource %d, new resource %d", _currentlyPlayingSample->resourceId, pSnd->resourceId);
+ }
// Sierra SCI ignores volume set when playing samples via kDoSound
// At least freddy pharkas/CD has a script bug that sets volume to 0
// when playing the "score" sample
@@ -449,6 +462,8 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
pSnd->pStreamAud, -1, _pMixer->kMaxChannelVolume, 0,
DisposeAfterUse::NO);
}
+ // Remember the sample, that is now playing
+ _currentlyPlayingSample = pSnd;
}
} else {
if (pSnd->pMidiParser) {
@@ -495,8 +510,11 @@ void SciMusic::soundStop(MusicEntry *pSnd) {
pSnd->status = kSoundStopped;
if (_soundVersion <= SCI_VERSION_0_LATE)
pSnd->isQueued = false;
- if (pSnd->pStreamAud)
+ if (pSnd->pStreamAud) {
+ if (_currentlyPlayingSample == pSnd)
+ _currentlyPlayingSample = NULL;
_pMixer->stopHandle(pSnd->hCurrentAud);
+ }
if (pSnd->pMidiParser) {
Common::StackLock lock(_mutex);
@@ -556,6 +574,10 @@ void SciMusic::soundKill(MusicEntry *pSnd) {
_mutex.unlock();
if (pSnd->pStreamAud) {
+ if (_currentlyPlayingSample == pSnd) {
+ // Forget about this sound, in case it was currently playing
+ _currentlyPlayingSample = NULL;
+ }
_pMixer->stopHandle(pSnd->hCurrentAud);
delete pSnd->pStreamAud;
pSnd->pStreamAud = NULL;
@@ -666,7 +688,7 @@ void SciMusic::printPlayList(Console *con) {
for (uint32 i = 0; i < _playList.size(); i++) {
MusicEntry *song = _playList[i];
- con->DebugPrintf("%d: %04x:%04x (%s), resource id: %d, status: %s, %s type\n",
+ con->debugPrintf("%d: %04x:%04x (%s), resource id: %d, status: %s, %s type\n",
i, PRINT_REG(song->soundObj),
g_sci->getEngineState()->_segMan->getObjectName(song->soundObj),
song->resourceId, musicStatus[song->status],
@@ -683,26 +705,26 @@ void SciMusic::printSongInfo(reg_t obj, Console *con) {
for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
MusicEntry *song = *i;
if (song->soundObj == obj) {
- con->DebugPrintf("Resource id: %d, status: %s\n", song->resourceId, musicStatus[song->status]);
- con->DebugPrintf("dataInc: %d, hold: %d, loop: %d\n", song->dataInc, song->hold, song->loop);
- con->DebugPrintf("signal: %d, priority: %d\n", song->signal, song->priority);
- con->DebugPrintf("ticker: %d, volume: %d\n", song->ticker, song->volume);
+ con->debugPrintf("Resource id: %d, status: %s\n", song->resourceId, musicStatus[song->status]);
+ con->debugPrintf("dataInc: %d, hold: %d, loop: %d\n", song->dataInc, song->hold, song->loop);
+ con->debugPrintf("signal: %d, priority: %d\n", song->signal, song->priority);
+ con->debugPrintf("ticker: %d, volume: %d\n", song->ticker, song->volume);
if (song->pMidiParser) {
- con->DebugPrintf("Type: MIDI\n");
+ con->debugPrintf("Type: MIDI\n");
if (song->soundRes) {
SoundResource::Track *track = song->soundRes->getTrackByType(_pMidiDrv->getPlayId());
- con->DebugPrintf("Channels: %d\n", track->channelCount);
+ con->debugPrintf("Channels: %d\n", track->channelCount);
}
} else if (song->pStreamAud || song->pLoopStream) {
- con->DebugPrintf("Type: digital audio (%s), sound active: %s\n",
+ con->debugPrintf("Type: digital audio (%s), sound active: %s\n",
song->pStreamAud ? "non looping" : "looping",
_pMixer->isSoundHandleActive(song->hCurrentAud) ? "yes" : "no");
if (song->soundRes) {
- con->DebugPrintf("Sound resource information:\n");
+ con->debugPrintf("Sound resource information:\n");
SoundResource::Track *track = song->soundRes->getTrackByType(_pMidiDrv->getPlayId());
if (track && track->digitalChannelNr != -1) {
- con->DebugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
+ con->debugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
track->digitalSampleSize, track->digitalSampleRate, track->channelCount, track->digitalChannelNr);
}
}
@@ -712,7 +734,7 @@ void SciMusic::printSongInfo(reg_t obj, Console *con) {
}
}
- con->DebugPrintf("Song object not found in playlist");
+ con->debugPrintf("Song object not found in playlist");
}
MusicEntry::MusicEntry() {
@@ -1169,8 +1191,14 @@ ChannelRemapping *SciMusic::determineChannelMap() {
int neededVoices = channel._voices;
// do we have enough free voices?
- // We only care for essential channels
- if (map->_freeVoices < neededVoices && prio > 0) {
+ if (map->_freeVoices < neededVoices) {
+ // We only care for essential channels
+ if (prio > 0) {
+#ifdef DEBUG_REMAP
+ debug(" not enough voices; need %d, have %d. Skipping this channel.", neededVoices, map->_freeVoices);
+#endif
+ continue;
+ }
do {
int j = map->lowestPrio();
if (j == -1) {
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index bfc542d2a5..6149bb799e 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -264,6 +264,8 @@ private:
int _driverFirstChannel;
int _driverLastChannel;
+
+ MusicEntry *_currentlyPlayingSample;
};
} // End of namespace Sci
diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp
index a792d63149..2b718b2cfe 100644
--- a/engines/scumm/debugger.cpp
+++ b/engines/scumm/debugger.cpp
@@ -58,52 +58,63 @@ ScummDebugger::ScummDebugger(ScummEngine *s)
_vm = s;
// Register variables
- DVar_Register("scumm_speed", &_vm->_fastMode, DVAR_BYTE, 0);
- DVar_Register("scumm_room", &_vm->_currentRoom, DVAR_BYTE, 0);
- DVar_Register("scumm_roomresource", &_vm->_roomResource, DVAR_INT, 0);
- DVar_Register("scumm_vars", &_vm->_scummVars, DVAR_INTARRAY, _vm->_numVariables);
+ registerVar("scumm_speed", &_vm->_fastMode);
+ registerVar("scumm_room", &_vm->_currentRoom);
+ registerVar("scumm_roomresource", &_vm->_roomResource);
+ registerVar("scumm_vars", &_vm->_scummVars, _vm->_numVariables);
// Register commands
- DCmd_Register("continue", WRAP_METHOD(ScummDebugger, Cmd_Exit));
- DCmd_Register("restart", WRAP_METHOD(ScummDebugger, Cmd_Restart));
-
- DCmd_Register("actor", WRAP_METHOD(ScummDebugger, Cmd_Actor));
- DCmd_Register("actors", WRAP_METHOD(ScummDebugger, Cmd_PrintActor));
- DCmd_Register("box", WRAP_METHOD(ScummDebugger, Cmd_PrintBox));
- DCmd_Register("matrix", WRAP_METHOD(ScummDebugger, Cmd_PrintBoxMatrix));
- DCmd_Register("camera", WRAP_METHOD(ScummDebugger, Cmd_Camera));
- DCmd_Register("room", WRAP_METHOD(ScummDebugger, Cmd_Room));
- DCmd_Register("objects", WRAP_METHOD(ScummDebugger, Cmd_PrintObjects));
- DCmd_Register("object", WRAP_METHOD(ScummDebugger, Cmd_Object));
- DCmd_Register("script", WRAP_METHOD(ScummDebugger, Cmd_Script));
- DCmd_Register("scr", WRAP_METHOD(ScummDebugger, Cmd_Script));
- DCmd_Register("scripts", WRAP_METHOD(ScummDebugger, Cmd_PrintScript));
- DCmd_Register("importres", WRAP_METHOD(ScummDebugger, Cmd_ImportRes));
+ registerCmd("continue", WRAP_METHOD(ScummDebugger, cmdExit));
+ registerCmd("restart", WRAP_METHOD(ScummDebugger, Cmd_Restart));
+
+ registerCmd("actor", WRAP_METHOD(ScummDebugger, Cmd_Actor));
+ registerCmd("actors", WRAP_METHOD(ScummDebugger, Cmd_PrintActor));
+ registerCmd("box", WRAP_METHOD(ScummDebugger, Cmd_PrintBox));
+ registerCmd("matrix", WRAP_METHOD(ScummDebugger, Cmd_PrintBoxMatrix));
+ registerCmd("camera", WRAP_METHOD(ScummDebugger, Cmd_Camera));
+ registerCmd("room", WRAP_METHOD(ScummDebugger, Cmd_Room));
+ registerCmd("objects", WRAP_METHOD(ScummDebugger, Cmd_PrintObjects));
+ registerCmd("object", WRAP_METHOD(ScummDebugger, Cmd_Object));
+ registerCmd("script", WRAP_METHOD(ScummDebugger, Cmd_Script));
+ registerCmd("scr", WRAP_METHOD(ScummDebugger, Cmd_Script));
+ registerCmd("scripts", WRAP_METHOD(ScummDebugger, Cmd_PrintScript));
+ registerCmd("importres", WRAP_METHOD(ScummDebugger, Cmd_ImportRes));
if (_vm->_game.id == GID_LOOM)
- DCmd_Register("drafts", WRAP_METHOD(ScummDebugger, Cmd_PrintDraft));
+ registerCmd("drafts", WRAP_METHOD(ScummDebugger, Cmd_PrintDraft));
if (_vm->_game.id == GID_MONKEY && _vm->_game.platform == Common::kPlatformSegaCD)
- DCmd_Register("passcode", WRAP_METHOD(ScummDebugger, Cmd_Passcode));
+ registerCmd("passcode", WRAP_METHOD(ScummDebugger, Cmd_Passcode));
- DCmd_Register("loadgame", WRAP_METHOD(ScummDebugger, Cmd_LoadGame));
- DCmd_Register("savegame", WRAP_METHOD(ScummDebugger, Cmd_SaveGame));
+ registerCmd("loadgame", WRAP_METHOD(ScummDebugger, Cmd_LoadGame));
+ registerCmd("savegame", WRAP_METHOD(ScummDebugger, Cmd_SaveGame));
- DCmd_Register("level", WRAP_METHOD(ScummDebugger, Cmd_DebugLevel));
- DCmd_Register("debug", WRAP_METHOD(ScummDebugger, Cmd_Debug));
+ registerCmd("debug", WRAP_METHOD(ScummDebugger, Cmd_Debug));
- DCmd_Register("show", WRAP_METHOD(ScummDebugger, Cmd_Show));
- DCmd_Register("hide", WRAP_METHOD(ScummDebugger, Cmd_Hide));
+ registerCmd("show", WRAP_METHOD(ScummDebugger, Cmd_Show));
+ registerCmd("hide", WRAP_METHOD(ScummDebugger, Cmd_Hide));
- DCmd_Register("imuse", WRAP_METHOD(ScummDebugger, Cmd_IMuse));
+ registerCmd("imuse", WRAP_METHOD(ScummDebugger, Cmd_IMuse));
- DCmd_Register("resetcursors", WRAP_METHOD(ScummDebugger, Cmd_ResetCursors));
+ registerCmd("resetcursors", WRAP_METHOD(ScummDebugger, Cmd_ResetCursors));
}
ScummDebugger::~ScummDebugger() {
// we need this destructor, even if it is empty, for __SYMBIAN32__
}
+void ScummDebugger::preEnter() {
+}
+
+void ScummDebugger::postEnter() {
+ // Runtime debug level change is dealt with by the base class "debuglevel" command
+ // but need to ensure that the _debugMode parameter is updated in sync.
+ _vm->_debugMode = (gDebugLevel >= 0);
+ // Boot params often need debugging switched on to work
+ if (_vm->_bootParam)
+ _vm->_debugMode = true;
+}
+
///////////////////////////////////////////////////
// Now the fun stuff:
@@ -117,51 +128,51 @@ bool ScummDebugger::Cmd_Restart(int argc, const char **argv) {
bool ScummDebugger::Cmd_IMuse(int argc, const char **argv) {
if (!_vm->_imuse && !_vm->_musicEngine) {
- DebugPrintf("No iMuse engine is active.\n");
+ debugPrintf("No iMuse engine is active.\n");
return true;
}
if (argc > 1) {
if (!strcmp(argv[1], "panic")) {
_vm->_musicEngine->stopAllSounds();
- DebugPrintf("AAAIIIEEEEEE!\n");
- DebugPrintf("Shutting down all music tracks\n");
+ debugPrintf("AAAIIIEEEEEE!\n");
+ debugPrintf("Shutting down all music tracks\n");
return true;
} else if (!strcmp(argv[1], "play")) {
if (argc > 2 && (!strcmp(argv[2], "random") || atoi(argv[2]) != 0)) {
int sound = atoi(argv[2]);
if (!strcmp(argv[2], "random")) {
- DebugPrintf("Selecting from %d songs...\n", _vm->_numSounds);
+ debugPrintf("Selecting from %d songs...\n", _vm->_numSounds);
sound = _vm->_rnd.getRandomNumber(_vm->_numSounds);
}
_vm->ensureResourceLoaded(rtSound, sound);
_vm->_musicEngine->startSound(sound);
- DebugPrintf("Attempted to start music %d.\n", sound);
+ debugPrintf("Attempted to start music %d.\n", sound);
} else {
- DebugPrintf("Specify a music resource # from 1-255.\n");
+ debugPrintf("Specify a music resource # from 1-255.\n");
}
return true;
} else if (!strcmp(argv[1], "stop")) {
if (argc > 2 && (!strcmp(argv[2], "all") || atoi(argv[2]) != 0)) {
if (!strcmp(argv[2], "all")) {
_vm->_musicEngine->stopAllSounds();
- DebugPrintf("Shutting down all music tracks.\n");
+ debugPrintf("Shutting down all music tracks.\n");
} else {
_vm->_musicEngine->stopSound(atoi(argv[2]));
- DebugPrintf("Attempted to stop music %d.\n", atoi(argv[2]));
+ debugPrintf("Attempted to stop music %d.\n", atoi(argv[2]));
}
} else {
- DebugPrintf("Specify a music resource # or \"all\".\n");
+ debugPrintf("Specify a music resource # or \"all\".\n");
}
return true;
}
}
- DebugPrintf("Available iMuse commands:\n");
- DebugPrintf(" panic - Stop all music tracks\n");
- DebugPrintf(" play # - Play a music resource\n");
- DebugPrintf(" stop # - Stop a music resource\n");
+ debugPrintf("Available iMuse commands:\n");
+ debugPrintf(" panic - Stop all music tracks\n");
+ debugPrintf(" play # - Play a music resource\n");
+ debugPrintf(" stop # - Stop a music resource\n");
return true;
}
@@ -174,7 +185,7 @@ bool ScummDebugger::Cmd_Room(int argc, const char **argv) {
_vm->_fullRedraw = true;
return false;
} else {
- DebugPrintf("Current room: %d [%d] - use 'room <roomnum>' to switch\n", _vm->_currentRoom, _vm->_roomResource);
+ debugPrintf("Current room: %d [%d] - use 'room <roomnum>' to switch\n", _vm->_currentRoom, _vm->_roomResource);
return true;
}
}
@@ -189,7 +200,7 @@ bool ScummDebugger::Cmd_LoadGame(int argc, const char **argv) {
return false;
}
- DebugPrintf("Syntax: loadgame <slotnum>\n");
+ debugPrintf("Syntax: loadgame <slotnum>\n");
return true;
}
@@ -199,7 +210,7 @@ bool ScummDebugger::Cmd_SaveGame(int argc, const char **argv) {
_vm->requestSave(slot, argv[2]);
} else
- DebugPrintf("Syntax: savegame <slotnum> <name>\n");
+ debugPrintf("Syntax: savegame <slotnum> <name>\n");
return true;
}
@@ -207,18 +218,18 @@ bool ScummDebugger::Cmd_SaveGame(int argc, const char **argv) {
bool ScummDebugger::Cmd_Show(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Syntax: show <parameter>\n");
+ debugPrintf("Syntax: show <parameter>\n");
return true;
}
if (!strcmp(argv[1], "hex")) {
_vm->_hexdumpScripts = true;
- DebugPrintf("Script hex dumping on\n");
+ debugPrintf("Script hex dumping on\n");
} else if (!strncmp(argv[1], "sta", 3)) {
_vm->_showStack = 1;
- DebugPrintf("Stack tracing on\n");
+ debugPrintf("Stack tracing on\n");
} else {
- DebugPrintf("Unknown show parameter '%s'\nParameters are 'hex' for hex dumping and 'sta' for stack tracing\n", argv[1]);
+ debugPrintf("Unknown show parameter '%s'\nParameters are 'hex' for hex dumping and 'sta' for stack tracing\n", argv[1]);
}
return true;
}
@@ -226,18 +237,18 @@ bool ScummDebugger::Cmd_Show(int argc, const char **argv) {
bool ScummDebugger::Cmd_Hide(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Syntax: hide <parameter>\n");
+ debugPrintf("Syntax: hide <parameter>\n");
return true;
}
if (!strcmp(argv[1], "hex")) {
_vm->_hexdumpScripts = false;
- DebugPrintf("Script hex dumping off\n");
+ debugPrintf("Script hex dumping off\n");
} else if (!strncmp(argv[1], "sta", 3)) {
_vm->_showStack = 0;
- DebugPrintf("Stack tracing off\n");
+ debugPrintf("Stack tracing off\n");
} else {
- DebugPrintf("Unknown hide parameter '%s'\nParameters are 'hex' to turn off hex dumping and 'sta' to turn off stack tracing\n", argv[1]);
+ debugPrintf("Unknown hide parameter '%s'\nParameters are 'hex' to turn off hex dumping and 'sta' to turn off stack tracing\n", argv[1]);
}
return true;
}
@@ -246,7 +257,7 @@ bool ScummDebugger::Cmd_Script(int argc, const char** argv) {
int scriptnum;
if (argc < 2) {
- DebugPrintf("Syntax: script <scriptnum> <command>\n");
+ debugPrintf("Syntax: script <scriptnum> <command>\n");
return true;
}
@@ -254,7 +265,7 @@ bool ScummDebugger::Cmd_Script(int argc, const char** argv) {
// FIXME: what is the max range on these?
// if (scriptnum >= _vm->_numScripts) {
- // DebugPrintf("Script number %d is out of range (range: 1 - %d)\n", scriptnum, _vm->_numScripts);
+ // debugPrintf("Script number %d is out of range (range: 1 - %d)\n", scriptnum, _vm->_numScripts);
// return true;
//}
@@ -264,7 +275,7 @@ bool ScummDebugger::Cmd_Script(int argc, const char** argv) {
_vm->runScript(scriptnum, 0, 0, 0);
return false;
} else {
- DebugPrintf("Unknown script command '%s'\nUse <kill/stop | run/start> as command\n", argv[2]);
+ debugPrintf("Unknown script command '%s'\nUse <kill/stop | run/start> as command\n", argv[2]);
}
return true;
@@ -276,7 +287,7 @@ bool ScummDebugger::Cmd_ImportRes(int argc, const char** argv) {
int resnum;
if (argc != 4) {
- DebugPrintf("Syntax: importres <restype> <filename> <resnum>\n");
+ debugPrintf("Syntax: importres <restype> <filename> <resnum>\n");
return true;
}
@@ -286,7 +297,7 @@ bool ScummDebugger::Cmd_ImportRes(int argc, const char** argv) {
if (!strncmp(argv[1], "scr", 3)) {
file.open(argv[2]);
if (file.isOpen() == false) {
- DebugPrintf("Could not open file %s\n", argv[2]);
+ debugPrintf("Could not open file %s\n", argv[2]);
return true;
}
if (_vm->_game.features & GF_SMALL_HEADER) {
@@ -307,25 +318,25 @@ bool ScummDebugger::Cmd_ImportRes(int argc, const char** argv) {
file.read(_vm->_res->createResource(rtScript, resnum, size), size);
} else
- DebugPrintf("Unknown importres type '%s'\n", argv[1]);
+ debugPrintf("Unknown importres type '%s'\n", argv[1]);
return true;
}
bool ScummDebugger::Cmd_PrintScript(int argc, const char **argv) {
int i;
ScriptSlot *ss = _vm->vm.slot;
- DebugPrintf("+-----------------------------------+\n");
- DebugPrintf("|# | num|offst|sta|typ|fr|rec|fc|cut|\n");
- DebugPrintf("+--+----+-----+---+---+--+---+--+---+\n");
+ debugPrintf("+-----------------------------------+\n");
+ debugPrintf("|# | num|offst|sta|typ|fr|rec|fc|cut|\n");
+ debugPrintf("+--+----+-----+---+---+--+---+--+---+\n");
for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
if (ss->number) {
- DebugPrintf("|%2d|%4d|%05x|%3d|%3d|%2d|%3d|%2d|%3d|\n",
+ debugPrintf("|%2d|%4d|%05x|%3d|%3d|%2d|%3d|%2d|%3d|\n",
i, ss->number, ss->offs, ss->status, ss->where,
ss->freezeResistant, ss->recursive,
ss->freezeCount, ss->cutsceneOverride);
}
}
- DebugPrintf("+-----------------------------------+\n");
+ debugPrintf("+-----------------------------------+\n");
return true;
}
@@ -336,13 +347,13 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) {
int value = 0, value2 = 0;
if (argc < 3) {
- DebugPrintf("Syntax: actor <actornum> <command> <parameter>\n");
+ debugPrintf("Syntax: actor <actornum> <command> <parameter>\n");
return true;
}
actnum = atoi(argv[1]);
if (actnum >= _vm->_numActors) {
- DebugPrintf("Actor %d is out of range (range: 1 - %d)\n", actnum, _vm->_numActors);
+ debugPrintf("Actor %d is out of range (range: 1 - %d)\n", actnum, _vm->_numActors);
return true;
}
@@ -354,43 +365,43 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) {
if (!strcmp(argv[2], "animvar")) {
a->setAnimVar(value, value2);
- DebugPrintf("Actor[%d].animVar[%d] = %d\n", actnum, value, a->getAnimVar(value));
+ debugPrintf("Actor[%d].animVar[%d] = %d\n", actnum, value, a->getAnimVar(value));
} else if (!strcmp(argv[2], "anim")) {
a->animateActor(value);
- DebugPrintf("Actor[%d].animateActor(%d)\n", actnum, value);
+ debugPrintf("Actor[%d].animateActor(%d)\n", actnum, value);
} else if (!strcmp(argv[2], "ignoreboxes")) {
a->_ignoreBoxes = (value > 0);
- DebugPrintf("Actor[%d].ignoreBoxes = %d\n", actnum, a->_ignoreBoxes);
+ debugPrintf("Actor[%d].ignoreBoxes = %d\n", actnum, a->_ignoreBoxes);
} else if (!strcmp(argv[2], "x")) {
a->putActor(value, a->getRealPos().y);
- DebugPrintf("Actor[%d].x = %d\n", actnum, a->getRealPos().x);
+ debugPrintf("Actor[%d].x = %d\n", actnum, a->getRealPos().x);
_vm->_fullRedraw = true;
} else if (!strcmp(argv[2], "y")) {
a->putActor(a->getRealPos().x, value);
- DebugPrintf("Actor[%d].y = %d\n", actnum, a->getRealPos().y);
+ debugPrintf("Actor[%d].y = %d\n", actnum, a->getRealPos().y);
_vm->_fullRedraw = true;
} else if (!strcmp(argv[2], "_elevation")) {
a->setElevation(value);
- DebugPrintf("Actor[%d]._elevation = %d\n", actnum, a->getElevation());
+ debugPrintf("Actor[%d]._elevation = %d\n", actnum, a->getElevation());
_vm->_fullRedraw = true;
} else if (!strcmp(argv[2], "costume")) {
if (value >= (int)_vm->_res->_types[rtCostume].size())
- DebugPrintf("Costume not changed as %d exceeds max of %d\n", value, _vm->_res->_types[rtCostume].size());
+ debugPrintf("Costume not changed as %d exceeds max of %d\n", value, _vm->_res->_types[rtCostume].size());
else {
a->setActorCostume(value);
_vm->_fullRedraw = true;
- DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume);
+ debugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume);
}
} else if (!strcmp(argv[2], "name")) {
- DebugPrintf("Name of actor %d: %s\n", actnum,
+ debugPrintf("Name of actor %d: %s\n", actnum,
_vm->getObjOrActorName(_vm->actorToObj(actnum)));
} else if (!strcmp(argv[2], "condmask")) {
if (argc > 3) {
a->_heCondMask = value;
}
- DebugPrintf("Actor[%d]._heCondMask = 0x%X\n", actnum, a->_heCondMask);
+ debugPrintf("Actor[%d]._heCondMask = 0x%X\n", actnum, a->_heCondMask);
} else {
- DebugPrintf("Unknown actor command '%s'\nUse <ignoreboxes |costume> as command\n", argv[2]);
+ debugPrintf("Unknown actor command '%s'\nUse <ignoreboxes |costume> as command\n", argv[2]);
}
return true;
@@ -400,40 +411,40 @@ bool ScummDebugger::Cmd_PrintActor(int argc, const char **argv) {
int i;
Actor *a;
- DebugPrintf("+---------------------------------------------------------------+\n");
- DebugPrintf("|# | x | y | w | h |elev|cos|box|mov| zp|frm|scl|dir| cls |\n");
- DebugPrintf("+--+----+----+---+---+----+---+---+---+---+---+---+---+---------+\n");
+ debugPrintf("+---------------------------------------------------------------+\n");
+ debugPrintf("|# | x | y | w | h |elev|cos|box|mov| zp|frm|scl|dir| cls |\n");
+ debugPrintf("+--+----+----+---+---+----+---+---+---+---+---+---+---+---------+\n");
for (i = 1; i < _vm->_numActors; i++) {
a = _vm->_actors[i];
if (a->_visible)
- DebugPrintf("|%2d|%4d|%4d|%3d|%3d|%4d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|$%08x|\n",
+ debugPrintf("|%2d|%4d|%4d|%3d|%3d|%4d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|$%08x|\n",
a->_number, a->getRealPos().x, a->getRealPos().y, a->_width, a->_bottom - a->_top,
a->getElevation(),
a->_costume, a->_walkbox, a->_moving, a->_forceClip, a->_frame,
a->_scalex, a->getFacing(), _vm->_classData[a->_number]);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
bool ScummDebugger::Cmd_PrintObjects(int argc, const char **argv) {
int i;
ObjectData *o;
- DebugPrintf("Objects in current room\n");
- DebugPrintf("+---------------------------------+------------+\n");
- DebugPrintf("|num | x | y |width|height|state|fl| cls |\n");
- DebugPrintf("+----+----+----+-----+------+-----+--+---------+\n");
+ debugPrintf("Objects in current room\n");
+ debugPrintf("+---------------------------------+------------+\n");
+ debugPrintf("|num | x | y |width|height|state|fl| cls |\n");
+ debugPrintf("+----+----+----+-----+------+-----+--+---------+\n");
for (i = 1; i < _vm->_numLocalObjects; i++) {
o = &(_vm->_objs[i]);
if (o->obj_nr == 0)
continue;
int classData = (_vm->_game.version != 0 ? _vm->_classData[o->obj_nr] : 0);
- DebugPrintf("|%4d|%4d|%4d|%5d|%6d|%5d|%2d|$%08x|\n",
+ debugPrintf("|%4d|%4d|%4d|%5d|%6d|%5d|%2d|$%08x|\n",
o->obj_nr, o->x_pos, o->y_pos, o->width, o->height, o->state,
o->fl_object_index, classData);
}
- DebugPrintf("\n");
+ debugPrintf("\n");
return true;
}
@@ -443,13 +454,13 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) {
int obj;
if (argc < 3) {
- DebugPrintf("Syntax: object <objectnum> <command> <parameter>\n");
+ debugPrintf("Syntax: object <objectnum> <command> <parameter>\n");
return true;
}
obj = atoi(argv[1]);
if (_vm->_game.version != 0 && obj >= _vm->_numGlobalObjects) {
- DebugPrintf("Object %d is out of range (range: 1 - %d)\n", obj, _vm->_numGlobalObjects);
+ debugPrintf("Object %d is out of range (range: 1 - %d)\n", obj, _vm->_numGlobalObjects);
return true;
}
@@ -479,12 +490,12 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) {
//is BgNeedsRedraw enough?
_vm->_bgNeedsRedraw = true;
} else {
- DebugPrintf("State of object %d: %d\n", obj, _vm->getState(obj));
+ debugPrintf("State of object %d: %d\n", obj, _vm->getState(obj));
}
} else if (!strcmp(argv[2], "name")) {
- DebugPrintf("Name of object %d: %s\n", obj, _vm->getObjOrActorName(obj));
+ debugPrintf("Name of object %d: %s\n", obj, _vm->getObjOrActorName(obj));
} else {
- DebugPrintf("Unknown object command '%s'\nUse <pickup | state | name> as command\n", argv[2]);
+ debugPrintf("Unknown object command '%s'\nUse <pickup | state | name> as command\n", argv[2]);
}
return true;
@@ -495,9 +506,9 @@ bool ScummDebugger::Cmd_Debug(int argc, const char **argv) {
// No parameters given: Print out a list of all channels and their status
if (argc <= 1) {
- DebugPrintf("Available debug channels:\n");
+ debugPrintf("Available debug channels:\n");
for (Common::DebugManager::DebugChannelList::const_iterator i = lvls.begin(); i != lvls.end(); ++i) {
- DebugPrintf("%c%s - %s (%s)\n", i->enabled ? '+' : ' ',
+ debugPrintf("%c%s - %s (%s)\n", i->enabled ? '+' : ' ',
i->name.c_str(), i->description.c_str(),
i->enabled ? "enabled" : "disabled");
}
@@ -513,39 +524,18 @@ bool ScummDebugger::Cmd_Debug(int argc, const char **argv) {
}
if (result) {
- DebugPrintf("%s %s\n", (argv[1][0] == '+') ? "Enabled" : "Disabled", argv[1] + 1);
+ debugPrintf("%s %s\n", (argv[1][0] == '+') ? "Enabled" : "Disabled", argv[1] + 1);
} else {
- DebugPrintf("Usage: debug [+CHANNEL|-CHANNEL]\n");
- DebugPrintf("Enables or disables the given debug channel.\n");
- DebugPrintf("When used without parameters, lists all available debug channels and their status.\n");
- }
-
- return true;
-}
-
-bool ScummDebugger::Cmd_DebugLevel(int argc, const char **argv) {
- if (argc == 1) {
- if (_vm->_debugMode == false)
- DebugPrintf("Debugging is not enabled at this time\n");
- else
- DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel);
- } else { // set level
- gDebugLevel = atoi(argv[1]);
- if (gDebugLevel >= 0) {
- _vm->_debugMode = true;
- DebugPrintf("Debug level set to level %d\n", gDebugLevel);
- } else if (gDebugLevel < 0) {
- _vm->_debugMode = false;
- DebugPrintf("Debugging is now disabled\n");
- } else
- DebugPrintf("Not a valid debug level\n");
+ debugPrintf("Usage: debug [+CHANNEL|-CHANNEL]\n");
+ debugPrintf("Enables or disables the given debug channel.\n");
+ debugPrintf("When used without parameters, lists all available debug channels and their status.\n");
}
return true;
}
bool ScummDebugger::Cmd_Camera(int argc, const char **argv) {
- DebugPrintf("Camera: cur (%d,%d) - dest (%d,%d) - accel (%d,%d) -- last (%d,%d)\n",
+ debugPrintf("Camera: cur (%d,%d) - dest (%d,%d) - accel (%d,%d) -- last (%d,%d)\n",
_vm->camera._cur.x, _vm->camera._cur.y, _vm->camera._dest.x, _vm->camera._dest.y,
_vm->camera._accel.x, _vm->camera._accel.y, _vm->camera._last.x, _vm->camera._last.y);
@@ -560,7 +550,7 @@ bool ScummDebugger::Cmd_PrintBox(int argc, const char **argv) {
printBox(atoi(argv[i]));
} else {
num = _vm->getNumBoxes();
- DebugPrintf("\nWalk boxes:\n");
+ debugPrintf("\nWalk boxes:\n");
for (i = 0; i < num; i++)
printBox(i);
}
@@ -572,29 +562,29 @@ bool ScummDebugger::Cmd_PrintBoxMatrix(int argc, const char **argv) {
int num = _vm->getNumBoxes();
int i, j;
- DebugPrintf("Walk matrix:\n");
+ debugPrintf("Walk matrix:\n");
if (_vm->_game.version <= 2)
boxm += num;
for (i = 0; i < num; i++) {
- DebugPrintf("%d: ", i);
+ debugPrintf("%d: ", i);
if (_vm->_game.version <= 2) {
for (j = 0; j < num; j++)
- DebugPrintf("[%d] ", *boxm++);
+ debugPrintf("[%d] ", *boxm++);
} else {
while (*boxm != 0xFF) {
- DebugPrintf("[%d-%d=>%d] ", boxm[0], boxm[1], boxm[2]);
+ debugPrintf("[%d-%d=>%d] ", boxm[0], boxm[1], boxm[2]);
boxm += 3;
}
boxm++;
}
- DebugPrintf("\n");
+ debugPrintf("\n");
}
return true;
}
void ScummDebugger::printBox(int box) {
if (box < 0 || box >= _vm->getNumBoxes()) {
- DebugPrintf("%d is not a valid box!\n", box);
+ debugPrintf("%d is not a valid box!\n", box);
return;
}
BoxCoords coords;
@@ -605,7 +595,7 @@ void ScummDebugger::printBox(int box) {
coords = _vm->getBoxCoordinates(box);
// Print out coords, flags, zbuffer mask
- DebugPrintf("%d: [%d x %d] [%d x %d] [%d x %d] [%d x %d], flags=0x%02x, mask=%d, scale=%d\n",
+ debugPrintf("%d: [%d x %d] [%d x %d] [%d x %d] [%d x %d], flags=0x%02x, mask=%d, scale=%d\n",
box,
coords.ul.x, coords.ul.y, coords.ll.x, coords.ll.y,
coords.ur.x, coords.ur.y, coords.lr.x, coords.lr.y,
@@ -746,7 +736,7 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) {
int i, base, draft;
if (_vm->_game.id != GID_LOOM) {
- DebugPrintf("Command only works with Loom/LoomCD\n");
+ debugPrintf("Command only works with Loom/LoomCD\n");
return true;
}
@@ -797,7 +787,7 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) {
// the distaff, but I don't know if that's a safe
// thing to do.
- DebugPrintf("Learned all drafts and notes.\n");
+ debugPrintf("Learned all drafts and notes.\n");
return true;
}
}
@@ -806,7 +796,7 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) {
for (i = 0; i < 16; i++) {
draft = _vm->_scummVars[base + i * 2];
- DebugPrintf("%d %-13s %c%c%c%c %c%c\n",
+ debugPrintf("%d %-13s %c%c%c%c %c%c\n",
base + 2 * i,
names[i],
notes[draft & 0x0007],
@@ -830,7 +820,7 @@ bool ScummDebugger::Cmd_Passcode(int argc, const char **argv) {
_vm->runScript(61, 0, 0, args);
if (_vm->_bootParam != _vm->_scummVars[411]){
- DebugPrintf("Invalid Passcode\n");
+ debugPrintf("Invalid Passcode\n");
return true;
}
@@ -838,7 +828,7 @@ bool ScummDebugger::Cmd_Passcode(int argc, const char **argv) {
detach();
} else {
- DebugPrintf("Current Passcode is %d \nUse 'passcode <SEGA CD Passcode>'\n",_vm->_scummVars[411]);
+ debugPrintf("Current Passcode is %d \nUse 'passcode <SEGA CD Passcode>'\n",_vm->_scummVars[411]);
return true;
}
return false;
diff --git a/engines/scumm/debugger.h b/engines/scumm/debugger.h
index 43bf9d6fd4..657f6be286 100644
--- a/engines/scumm/debugger.h
+++ b/engines/scumm/debugger.h
@@ -37,6 +37,9 @@ public:
private:
ScummEngine *_vm;
+ virtual void preEnter();
+ virtual void postEnter();
+
// Commands
bool Cmd_Room(int argc, const char **argv);
bool Cmd_LoadGame(int argc, const char **argv);
@@ -58,7 +61,6 @@ private:
bool Cmd_Passcode(int argc, const char **argv);
bool Cmd_Debug(int argc, const char **argv);
- bool Cmd_DebugLevel(int argc, const char **argv);
bool Cmd_Show(int argc, const char **argv);
bool Cmd_Hide(int argc, const char **argv);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 54f22ecad3..34c231e5d4 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -205,7 +205,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_lastInputScriptTime = 0;
_bootParam = 0;
_dumpScripts = false;
- _debugMode = 0;
+ _debugMode = false;
_objectOwnerTable = NULL;
_objectRoomTable = NULL;
_objectStateTable = NULL;
@@ -2281,7 +2281,7 @@ void ScummEngine::scummLoop_updateScummVars() {
VAR(VAR_MOUSE_Y) = _mouse.y;
if (VAR_DEBUGMODE != 0xFF) {
// This is NOT for the Mac version of Indy3/Loom
- VAR(VAR_DEBUGMODE) = _debugMode;
+ VAR(VAR_DEBUGMODE) = (_debugMode ? 1 : 0);
}
} else if (_game.version >= 1) {
// We use shifts below instead of dividing by V12_X_MULTIPLIER resp.
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index b4afa09bb2..be5a83d8c9 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -586,7 +586,7 @@ protected:
bool _dumpScripts;
bool _hexdumpScripts;
bool _showStack;
- uint16 _debugMode;
+ bool _debugMode;
// Save/Load class - some of this may be GUI
byte _saveLoadFlag, _saveLoadSlot;
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 73028c8513..79d7ed03da 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -805,7 +805,7 @@ void ScummEngine::resetScummVars() {
}
if (VAR_DEBUGMODE != 0xFF) {
- VAR(VAR_DEBUGMODE) = _debugMode;
+ VAR(VAR_DEBUGMODE) = (_debugMode ? 1 : 0);
if (_game.heversion >= 80 && _debugMode)
VAR(85) = 1;
}
diff --git a/engines/sky/debug.cpp b/engines/sky/debug.cpp
index 63da42eec2..d663bd206d 100644
--- a/engines/sky/debug.cpp
+++ b/engines/sky/debug.cpp
@@ -1087,14 +1087,14 @@ void Debug::mcode(uint32 mcode, uint32 a, uint32 b, uint32 c) {
Debugger::Debugger(Logic *logic, Mouse *mouse, Screen *screen, SkyCompact *skyCompact)
: GUI::Debugger(), _logic(logic), _mouse(mouse), _screen(screen), _skyCompact(skyCompact), _showGrid(false) {
- DCmd_Register("info", WRAP_METHOD(Debugger, Cmd_Info));
- DCmd_Register("showgrid", WRAP_METHOD(Debugger, Cmd_ShowGrid));
- DCmd_Register("reloadgrid", WRAP_METHOD(Debugger, Cmd_ReloadGrid));
- DCmd_Register("compact", WRAP_METHOD(Debugger, Cmd_ShowCompact));
- DCmd_Register("logiccmd", WRAP_METHOD(Debugger, Cmd_LogicCommand));
- DCmd_Register("scriptvar", WRAP_METHOD(Debugger, Cmd_ScriptVar));
- DCmd_Register("section", WRAP_METHOD(Debugger, Cmd_Section));
- DCmd_Register("logiclist", WRAP_METHOD(Debugger, Cmd_LogicList));
+ registerCmd("info", WRAP_METHOD(Debugger, Cmd_Info));
+ registerCmd("showgrid", WRAP_METHOD(Debugger, Cmd_ShowGrid));
+ registerCmd("reloadgrid", WRAP_METHOD(Debugger, Cmd_ReloadGrid));
+ registerCmd("compact", WRAP_METHOD(Debugger, Cmd_ShowCompact));
+ registerCmd("logiccmd", WRAP_METHOD(Debugger, Cmd_LogicCommand));
+ registerCmd("scriptvar", WRAP_METHOD(Debugger, Cmd_ScriptVar));
+ registerCmd("section", WRAP_METHOD(Debugger, Cmd_Section));
+ registerCmd("logiclist", WRAP_METHOD(Debugger, Cmd_LogicList));
}
Debugger::~Debugger() {} // we need this here for __SYMBIAN32__
@@ -1119,14 +1119,14 @@ static bool isNumeric(const char *arg) {
bool Debugger::Cmd_ShowGrid(int argc, const char **argv) {
_showGrid = !_showGrid;
- DebugPrintf("Show grid: %s\n", _showGrid ? "On" : "Off");
+ debugPrintf("Show grid: %s\n", _showGrid ? "On" : "Off");
if (!_showGrid) _screen->forceRefresh();
return true;
}
bool Debugger::Cmd_ReloadGrid(int argc, const char **argv) {
_logic->_skyGrid->loadGrids();
- DebugPrintf("Grid reloaded\n");
+ debugPrintf("Grid reloaded\n");
return true;
}
@@ -1143,35 +1143,35 @@ void Debugger::dumpCompact(uint16 cptId) {
Compact *cpt = _skyCompact->fetchCptInfo(cptId, &size, &type, name);
if (type == COMPACT) {
- DebugPrintf("Compact %s: id = %04X, section %d, id %d\n", name, cptId, cptId >> 12, cptId & 0xFFF);
- DebugPrintf("logic : %04X: %s\n", cpt->logic, (cpt->logic <= 16) ? logicTypes[cpt->logic] : "unknown");
- DebugPrintf("status : %04X\n", cpt->status);
- DebugPrintf(" : background : %s\n", noYes[(cpt->status & ST_BACKGROUND) >> 0]);
- DebugPrintf(" : foreground : %s\n", noYes[(cpt->status & ST_FOREGROUND) >> 1]);
- DebugPrintf(" : sort list : %s\n", noYes[(cpt->status & ST_SORT) >> 2]);
- DebugPrintf(" : recreate : %s\n", noYes[(cpt->status & ST_RECREATE) >> 3]);
- DebugPrintf(" : mouse : %s\n", noYes[(cpt->status & ST_MOUSE) >> 4]);
- DebugPrintf(" : collision : %s\n", noYes[(cpt->status & ST_COLLISION) >> 5]);
- DebugPrintf(" : logic : %s\n", noYes[(cpt->status & ST_LOGIC) >> 6]);
- DebugPrintf(" : on grid : %s\n", noYes[(cpt->status & ST_GRID_PLOT) >> 7]);
- DebugPrintf(" : ar priority : %s\n", noYes[(cpt->status & ST_AR_PRIORITY) >> 8]);
- DebugPrintf("sync : %04X\n", cpt->sync);
- DebugPrintf("screen : %d\n", cpt->screen);
+ debugPrintf("Compact %s: id = %04X, section %d, id %d\n", name, cptId, cptId >> 12, cptId & 0xFFF);
+ debugPrintf("logic : %04X: %s\n", cpt->logic, (cpt->logic <= 16) ? logicTypes[cpt->logic] : "unknown");
+ debugPrintf("status : %04X\n", cpt->status);
+ debugPrintf(" : background : %s\n", noYes[(cpt->status & ST_BACKGROUND) >> 0]);
+ debugPrintf(" : foreground : %s\n", noYes[(cpt->status & ST_FOREGROUND) >> 1]);
+ debugPrintf(" : sort list : %s\n", noYes[(cpt->status & ST_SORT) >> 2]);
+ debugPrintf(" : recreate : %s\n", noYes[(cpt->status & ST_RECREATE) >> 3]);
+ debugPrintf(" : mouse : %s\n", noYes[(cpt->status & ST_MOUSE) >> 4]);
+ debugPrintf(" : collision : %s\n", noYes[(cpt->status & ST_COLLISION) >> 5]);
+ debugPrintf(" : logic : %s\n", noYes[(cpt->status & ST_LOGIC) >> 6]);
+ debugPrintf(" : on grid : %s\n", noYes[(cpt->status & ST_GRID_PLOT) >> 7]);
+ debugPrintf(" : ar priority : %s\n", noYes[(cpt->status & ST_AR_PRIORITY) >> 8]);
+ debugPrintf("sync : %04X\n", cpt->sync);
+ debugPrintf("screen : %d\n", cpt->screen);
_skyCompact->fetchCptInfo(cpt->place, NULL, NULL, name);
- DebugPrintf("place : %04X: %s\n", cpt->place, name);
+ debugPrintf("place : %04X: %s\n", cpt->place, name);
_skyCompact->fetchCptInfo(cpt->getToTableId, NULL, NULL, name);
- DebugPrintf("get to tab : %04X: %s\n", cpt->getToTableId, name);
- DebugPrintf("x/y : %d/%d\n", cpt->xcood, cpt->ycood);
+ debugPrintf("get to tab : %04X: %s\n", cpt->getToTableId, name);
+ debugPrintf("x/y : %d/%d\n", cpt->xcood, cpt->ycood);
} else {
- DebugPrintf("Can't dump binary data\n");
+ debugPrintf("Can't dump binary data\n");
}
}
bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Example: \"%s foster\" dumps compact \"foster\"\n", argv[0]);
- DebugPrintf("Example: \"%s list 1\" lists all compacts from section 1\n", argv[0]);
- DebugPrintf("Example: \"%s list 1 all\" lists all entities from section 1\n", argv[0]);
+ debugPrintf("Example: \"%s foster\" dumps compact \"foster\"\n", argv[0]);
+ debugPrintf("Example: \"%s list 1\" lists all compacts from section 1\n", argv[0]);
+ debugPrintf("Example: \"%s list 1 all\" lists all entities from section 1\n", argv[0]);
return true;
}
@@ -1181,7 +1181,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
if (argc >= 3) {
sectionNumber = atoi(argv[2]);
if (sectionNumber >= _skyCompact->giveNumDataLists()) {
- DebugPrintf("Section number %d does not exist\n", sectionNumber);
+ debugPrintf("Section number %d does not exist\n", sectionNumber);
return true;
}
if ((argc == 4) && (scumm_stricmp(argv[3], "all") == 0))
@@ -1189,14 +1189,14 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
}
for (int sec = 0; sec < _skyCompact->giveNumDataLists(); sec++) {
if ((sectionNumber == -1) || (sectionNumber == sec)) {
- DebugPrintf("Compacts in section %d:\n", sec);
+ debugPrintf("Compacts in section %d:\n", sec);
if (showAll) {
char line[256];
char *linePos = line;
for (int cpt = 0; cpt < _skyCompact->giveDataListLen(sec); cpt++) {
if (cpt != 0) {
if ((cpt % 3) == 0) {
- DebugPrintf("%s\n", line);
+ debugPrintf("%s\n", line);
linePos = line;
} else
linePos += sprintf(linePos, ", ");
@@ -1208,7 +1208,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
linePos += sprintf(linePos, "%04X: %10s %22s", cptId, _skyCompact->nameForType(type), name);
}
if (linePos != line)
- DebugPrintf("%s\n", line);
+ debugPrintf("%s\n", line);
} else {
for (int cpt = 0; cpt < _skyCompact->giveDataListLen(sec); cpt++) {
uint16 cptId = (uint16)((sec << 12) | cpt);
@@ -1216,7 +1216,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
char name[256];
_skyCompact->fetchCptInfo(cptId, &size, &type, name);
if (type == COMPACT)
- DebugPrintf("%04X: %s\n", cptId, name);
+ debugPrintf("%04X: %s\n", cptId, name);
}
}
}
@@ -1224,7 +1224,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
} else {
uint16 cptId = _skyCompact->findCptId(argv[1]);
if (cptId == 0)
- DebugPrintf("Unknown compact: '%s'\n", argv[1]);
+ debugPrintf("Unknown compact: '%s'\n", argv[1]);
else
dumpCompact(cptId);
}
@@ -1233,7 +1233,7 @@ bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
bool Debugger::Cmd_LogicCommand(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Example: %s fn_printf 42\n", argv[0]);
+ debugPrintf("Example: %s fn_printf 42\n", argv[0]);
return true;
}
@@ -1241,7 +1241,7 @@ bool Debugger::Cmd_LogicCommand(int argc, const char **argv) {
if (0 == strcmp(argv[1], "list")) {
for (int i = 0; i < numMCodes; ++i) {
- DebugPrintf("%s\n", mcodes[i]);
+ debugPrintf("%s\n", mcodes[i]);
}
return true;
}
@@ -1264,21 +1264,21 @@ bool Debugger::Cmd_LogicCommand(int argc, const char **argv) {
}
}
- DebugPrintf("Unknown function: '%s'\n", argv[1]);
+ debugPrintf("Unknown function: '%s'\n", argv[1]);
return true;
}
bool Debugger::Cmd_Info(int argc, const char **argv) {
- DebugPrintf("Beneath a Steel Sky version: 0.0%d\n", SkyEngine::_systemVars.gameVersion);
- DebugPrintf("Speech: %s\n", (SkyEngine::_systemVars.systemFlags & SF_ALLOW_SPEECH) ? "on" : "off");
- DebugPrintf("Text : %s\n", (SkyEngine::_systemVars.systemFlags & SF_ALLOW_TEXT) ? "on" : "off");
+ debugPrintf("Beneath a Steel Sky version: 0.0%d\n", SkyEngine::_systemVars.gameVersion);
+ debugPrintf("Speech: %s\n", (SkyEngine::_systemVars.systemFlags & SF_ALLOW_SPEECH) ? "on" : "off");
+ debugPrintf("Text : %s\n", (SkyEngine::_systemVars.systemFlags & SF_ALLOW_TEXT) ? "on" : "off");
return true;
}
bool Debugger::Cmd_ScriptVar(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Example: %s lamb_friend <value>\n", argv[0]);
+ debugPrintf("Example: %s lamb_friend <value>\n", argv[0]);
return true;
}
@@ -1286,7 +1286,7 @@ bool Debugger::Cmd_ScriptVar(int argc, const char **argv) {
if (0 == strcmp(argv[1], "list")) {
for (int i = 0; i < numScriptVars; ++i) {
- DebugPrintf("%s\n", scriptVars[i]);
+ debugPrintf("%s\n", scriptVars[i]);
}
return true;
}
@@ -1296,13 +1296,13 @@ bool Debugger::Cmd_ScriptVar(int argc, const char **argv) {
if (argc == 3) {
Logic::_scriptVariables[i] = atoi(argv[2]);
}
- DebugPrintf("%s = %d\n", argv[1], Logic::_scriptVariables[i]);
+ debugPrintf("%s = %d\n", argv[1], Logic::_scriptVariables[i]);
return true;
}
}
- DebugPrintf("Unknown ScriptVar: '%s'\n", argv[1]);
+ debugPrintf("Unknown ScriptVar: '%s'\n", argv[1]);
return true;
}
@@ -1317,30 +1317,30 @@ bool Debugger::Cmd_Section(int argc, const char **argv) {
_logic->fnAssignBase(ID_FOSTER, baseId[section], 0);
_skyCompact->fetchCpt(ID_FOSTER)->megaSet = 0;
} else {
- DebugPrintf("Section %d is out of range (range: %d - %d)\n", section, 0, 6);
+ debugPrintf("Section %d is out of range (range: %d - %d)\n", section, 0, 6);
}
} else {
- DebugPrintf("Example: %s 4\n", argv[0]);
+ debugPrintf("Example: %s 4\n", argv[0]);
}
return true;
}
bool Debugger::Cmd_LogicList(int argc, const char **argv) {
if (argc != 1)
- DebugPrintf("%s does not expect any parameters\n", argv[0]);
+ debugPrintf("%s does not expect any parameters\n", argv[0]);
char cptName[256];
uint16 numElems, type;
uint16 *logicList = (uint16 *)_skyCompact->fetchCptInfo(Logic::_scriptVariables[LOGIC_LIST_NO], &numElems, &type, cptName);
- DebugPrintf("Current LogicList: %04X (%s)\n", Logic::_scriptVariables[LOGIC_LIST_NO], cptName);
+ debugPrintf("Current LogicList: %04X (%s)\n", Logic::_scriptVariables[LOGIC_LIST_NO], cptName);
while (*logicList != 0) {
if (*logicList == 0xFFFF) {
uint16 newList = logicList[1];
logicList = (uint16 *)_skyCompact->fetchCptInfo(newList, &numElems, &type, cptName);
- DebugPrintf("New List: %04X (%s)\n", newList, cptName);
+ debugPrintf("New List: %04X (%s)\n", newList, cptName);
} else {
_skyCompact->fetchCptInfo(*logicList, &numElems, &type, cptName);
- DebugPrintf(" Cpt %04X (%s) (%s)\n", *logicList, cptName, _skyCompact->nameForType(type));
+ debugPrintf(" Cpt %04X (%s) (%s)\n", *logicList, cptName, _skyCompact->nameForType(type));
logicList++;
}
}
diff --git a/engines/sword2/console.cpp b/engines/sword2/console.cpp
index 4838bd15f6..0aa78f552b 100644
--- a/engines/sword2/console.cpp
+++ b/engines/sword2/console.cpp
@@ -82,55 +82,55 @@ Debugger::Debugger(Sword2Engine *vm)
// Register commands
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("q", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("mem", WRAP_METHOD(Debugger, Cmd_Mem));
- DCmd_Register("tony", WRAP_METHOD(Debugger, Cmd_Tony));
- DCmd_Register("res", WRAP_METHOD(Debugger, Cmd_Res));
- DCmd_Register("reslist", WRAP_METHOD(Debugger, Cmd_ResList));
- DCmd_Register("starts", WRAP_METHOD(Debugger, Cmd_Starts));
- DCmd_Register("start", WRAP_METHOD(Debugger, Cmd_Start));
- DCmd_Register("s", WRAP_METHOD(Debugger, Cmd_Start));
- DCmd_Register("info", WRAP_METHOD(Debugger, Cmd_Info));
- DCmd_Register("walkgrid", WRAP_METHOD(Debugger, Cmd_WalkGrid));
- DCmd_Register("mouse", WRAP_METHOD(Debugger, Cmd_Mouse));
- DCmd_Register("player", WRAP_METHOD(Debugger, Cmd_Player));
- DCmd_Register("reslook", WRAP_METHOD(Debugger, Cmd_ResLook));
- DCmd_Register("cur", WRAP_METHOD(Debugger, Cmd_CurrentInfo));
- DCmd_Register("runlist", WRAP_METHOD(Debugger, Cmd_RunList));
- DCmd_Register("kill", WRAP_METHOD(Debugger, Cmd_Kill));
- DCmd_Register("nuke", WRAP_METHOD(Debugger, Cmd_Nuke));
- DCmd_Register("var", WRAP_METHOD(Debugger, Cmd_Var));
- DCmd_Register("rect", WRAP_METHOD(Debugger, Cmd_Rect));
- DCmd_Register("clear", WRAP_METHOD(Debugger, Cmd_Clear));
- DCmd_Register("debugon", WRAP_METHOD(Debugger, Cmd_DebugOn));
- DCmd_Register("debugoff", WRAP_METHOD(Debugger, Cmd_DebugOff));
- DCmd_Register("saverest", WRAP_METHOD(Debugger, Cmd_SaveRest));
- DCmd_Register("timeon", WRAP_METHOD(Debugger, Cmd_TimeOn));
- DCmd_Register("timeoff", WRAP_METHOD(Debugger, Cmd_TimeOff));
- DCmd_Register("text", WRAP_METHOD(Debugger, Cmd_Text));
- DCmd_Register("showvar", WRAP_METHOD(Debugger, Cmd_ShowVar));
- DCmd_Register("hidevar", WRAP_METHOD(Debugger, Cmd_HideVar));
- DCmd_Register("version", WRAP_METHOD(Debugger, Cmd_Version));
- DCmd_Register("animtest", WRAP_METHOD(Debugger, Cmd_AnimTest));
- DCmd_Register("texttest", WRAP_METHOD(Debugger, Cmd_TextTest));
- DCmd_Register("linetest", WRAP_METHOD(Debugger, Cmd_LineTest));
- DCmd_Register("events", WRAP_METHOD(Debugger, Cmd_Events));
- DCmd_Register("sfx", WRAP_METHOD(Debugger, Cmd_Sfx));
- DCmd_Register("english", WRAP_METHOD(Debugger, Cmd_English));
- DCmd_Register("finnish", WRAP_METHOD(Debugger, Cmd_Finnish));
- DCmd_Register("polish", WRAP_METHOD(Debugger, Cmd_Polish));
- DCmd_Register("fxq", WRAP_METHOD(Debugger, Cmd_FxQueue));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("q", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("mem", WRAP_METHOD(Debugger, Cmd_Mem));
+ registerCmd("tony", WRAP_METHOD(Debugger, Cmd_Tony));
+ registerCmd("res", WRAP_METHOD(Debugger, Cmd_Res));
+ registerCmd("reslist", WRAP_METHOD(Debugger, Cmd_ResList));
+ registerCmd("starts", WRAP_METHOD(Debugger, Cmd_Starts));
+ registerCmd("start", WRAP_METHOD(Debugger, Cmd_Start));
+ registerCmd("s", WRAP_METHOD(Debugger, Cmd_Start));
+ registerCmd("info", WRAP_METHOD(Debugger, Cmd_Info));
+ registerCmd("walkgrid", WRAP_METHOD(Debugger, Cmd_WalkGrid));
+ registerCmd("mouse", WRAP_METHOD(Debugger, Cmd_Mouse));
+ registerCmd("player", WRAP_METHOD(Debugger, Cmd_Player));
+ registerCmd("reslook", WRAP_METHOD(Debugger, Cmd_ResLook));
+ registerCmd("cur", WRAP_METHOD(Debugger, Cmd_CurrentInfo));
+ registerCmd("runlist", WRAP_METHOD(Debugger, Cmd_RunList));
+ registerCmd("kill", WRAP_METHOD(Debugger, Cmd_Kill));
+ registerCmd("nuke", WRAP_METHOD(Debugger, Cmd_Nuke));
+ registerCmd("var", WRAP_METHOD(Debugger, Cmd_Var));
+ registerCmd("rect", WRAP_METHOD(Debugger, Cmd_Rect));
+ registerCmd("clear", WRAP_METHOD(Debugger, Cmd_Clear));
+ registerCmd("debugon", WRAP_METHOD(Debugger, Cmd_DebugOn));
+ registerCmd("debugoff", WRAP_METHOD(Debugger, Cmd_DebugOff));
+ registerCmd("saverest", WRAP_METHOD(Debugger, Cmd_SaveRest));
+ registerCmd("timeon", WRAP_METHOD(Debugger, Cmd_TimeOn));
+ registerCmd("timeoff", WRAP_METHOD(Debugger, Cmd_TimeOff));
+ registerCmd("text", WRAP_METHOD(Debugger, Cmd_Text));
+ registerCmd("showvar", WRAP_METHOD(Debugger, Cmd_ShowVar));
+ registerCmd("hidevar", WRAP_METHOD(Debugger, Cmd_HideVar));
+ registerCmd("version", WRAP_METHOD(Debugger, Cmd_Version));
+ registerCmd("animtest", WRAP_METHOD(Debugger, Cmd_AnimTest));
+ registerCmd("texttest", WRAP_METHOD(Debugger, Cmd_TextTest));
+ registerCmd("linetest", WRAP_METHOD(Debugger, Cmd_LineTest));
+ registerCmd("events", WRAP_METHOD(Debugger, Cmd_Events));
+ registerCmd("sfx", WRAP_METHOD(Debugger, Cmd_Sfx));
+ registerCmd("english", WRAP_METHOD(Debugger, Cmd_English));
+ registerCmd("finnish", WRAP_METHOD(Debugger, Cmd_Finnish));
+ registerCmd("polish", WRAP_METHOD(Debugger, Cmd_Polish));
+ registerCmd("fxq", WRAP_METHOD(Debugger, Cmd_FxQueue));
}
void Debugger::varGet(int var) {
- DebugPrintf("%d\n", _vm->_logic->readVar(var));
+ debugPrintf("%d\n", _vm->_logic->readVar(var));
}
void Debugger::varSet(int var, int val) {
- DebugPrintf("was %d, ", _vm->_logic->readVar(var));
+ debugPrintf("was %d, ", _vm->_logic->readVar(var));
_vm->_logic->writeVar(var, val);
- DebugPrintf("now %d\n", _vm->_logic->readVar(var));
+ debugPrintf("now %d\n", _vm->_logic->readVar(var));
}
void Debugger::preEnter() {
@@ -184,8 +184,8 @@ bool Debugger::Cmd_Mem(int argc, const char **argv) {
qsort(blocks, numBlocks, sizeof(MemBlock *), compare_blocks);
- DebugPrintf(" size id res type name\n");
- DebugPrintf("---------------------------------------------------------------------------\n");
+ debugPrintf(" size id res type name\n");
+ debugPrintf("---------------------------------------------------------------------------\n");
for (i = 0; i < numBlocks; i++) {
const char *type;
@@ -235,21 +235,21 @@ bool Debugger::Cmd_Mem(int argc, const char **argv) {
break;
}
- DebugPrintf("%9d %-3d %-4d %-20s %s\n",
+ debugPrintf("%9d %-3d %-4d %-20s %s\n",
blocks[i]->size, blocks[i]->id, blocks[i]->uid,
type, _vm->_resman->fetchName(blocks[i]->ptr));
}
free(blocks);
- DebugPrintf("---------------------------------------------------------------------------\n");
- DebugPrintf("%9d\n", _vm->_memory->getTotAlloc());
+ debugPrintf("---------------------------------------------------------------------------\n");
+ debugPrintf("%9d\n", _vm->_memory->getTotAlloc());
return true;
}
bool Debugger::Cmd_Tony(int argc, const char **argv) {
- DebugPrintf("What about him?\n");
+ debugPrintf("What about him?\n");
return true;
}
@@ -257,7 +257,7 @@ bool Debugger::Cmd_Res(int argc, const char **argv) {
uint32 numClusters = _vm->_resman->getNumClusters();
if (!numClusters) {
- DebugPrintf("Argh! No resources!\n");
+ debugPrintf("Argh! No resources!\n");
return true;
}
@@ -266,10 +266,10 @@ bool Debugger::Cmd_Res(int argc, const char **argv) {
for (uint i = 0; i < numClusters; i++) {
const char *locStr[3] = { "HDD", "CD1", "CD2" };
- DebugPrintf("%-20s %s\n", resFiles[i].fileName, locStr[resFiles[i].cd]);
+ debugPrintf("%-20s %s\n", resFiles[i].fileName, locStr[resFiles[i].cd]);
}
- DebugPrintf("%d resources\n", _vm->_resman->getNumResFiles());
+ debugPrintf("%d resources\n", _vm->_resman->getNumResFiles());
return true;
}
@@ -285,7 +285,7 @@ bool Debugger::Cmd_ResList(int argc, const char **argv) {
for (uint i = 0; i < numResFiles; i++) {
if (resList[i].ptr && resList[i].refCount >= minCount) {
- DebugPrintf("%-4d: %-35s refCount: %-3d\n", i, _vm->_resman->fetchName(resList[i].ptr), resList[i].refCount);
+ debugPrintf("%-4d: %-35s refCount: %-3d\n", i, _vm->_resman->fetchName(resList[i].ptr), resList[i].refCount);
}
}
@@ -296,21 +296,21 @@ bool Debugger::Cmd_Starts(int argc, const char **argv) {
uint32 numStarts = _vm->getNumStarts();
if (!numStarts) {
- DebugPrintf("Sorry - no startup positions registered?\n");
+ debugPrintf("Sorry - no startup positions registered?\n");
uint32 numScreenManagers = _vm->getNumScreenManagers();
if (!numScreenManagers)
- DebugPrintf("There is a problem with startup.inf\n");
+ debugPrintf("There is a problem with startup.inf\n");
else
- DebugPrintf(" (%d screen managers found in startup.inf)\n", numScreenManagers);
+ debugPrintf(" (%d screen managers found in startup.inf)\n", numScreenManagers);
return true;
}
StartUp *startList = _vm->getStartList();
for (uint i = 0; i < numStarts; i++)
- DebugPrintf("%d (%s)\n", i, startList[i].description);
+ debugPrintf("%d (%s)\n", i, startList[i].description);
return true;
}
@@ -319,25 +319,25 @@ bool Debugger::Cmd_Start(int argc, const char **argv) {
uint8 pal[3] = { 255, 255, 255 };
if (argc != 2) {
- DebugPrintf("Usage: %s number\n", argv[0]);
+ debugPrintf("Usage: %s number\n", argv[0]);
return true;
}
uint32 numStarts = _vm->getNumStarts();
if (!numStarts) {
- DebugPrintf("Sorry - there are no startups!\n");
+ debugPrintf("Sorry - there are no startups!\n");
return true;
}
int start = atoi(argv[1]);
if (start < 0 || start >= (int)numStarts) {
- DebugPrintf("Not a legal start position\n");
+ debugPrintf("Not a legal start position\n");
return true;
}
- DebugPrintf("Running start %d\n", start);
+ debugPrintf("Running start %d\n", start);
_vm->runStart(start);
_vm->_screen->setPalette(187, 1, pal, RDPAL_INSTANT);
@@ -348,9 +348,9 @@ bool Debugger::Cmd_Info(int argc, const char **argv) {
_displayDebugText = !_displayDebugText;
if (_displayDebugText)
- DebugPrintf("Info text on\n");
+ debugPrintf("Info text on\n");
else
- DebugPrintf("Info Text off\n");
+ debugPrintf("Info Text off\n");
return true;
}
@@ -359,9 +359,9 @@ bool Debugger::Cmd_WalkGrid(int argc, const char **argv) {
_displayWalkGrid = !_displayWalkGrid;
if (_displayWalkGrid)
- DebugPrintf("Walk-grid display on\n");
+ debugPrintf("Walk-grid display on\n");
else
- DebugPrintf("Walk-grid display off\n");
+ debugPrintf("Walk-grid display off\n");
return true;
}
@@ -370,9 +370,9 @@ bool Debugger::Cmd_Mouse(int argc, const char **argv) {
_displayMouseMarker = !_displayMouseMarker;
if (_displayMouseMarker)
- DebugPrintf("Mouse marker on\n");
+ debugPrintf("Mouse marker on\n");
else
- DebugPrintf("Mouse marker off\n");
+ debugPrintf("Mouse marker off\n");
return true;
}
@@ -381,16 +381,16 @@ bool Debugger::Cmd_Player(int argc, const char **argv) {
_displayPlayerMarker = !_displayPlayerMarker;
if (_displayPlayerMarker)
- DebugPrintf("Player feet marker on\n");
+ debugPrintf("Player feet marker on\n");
else
- DebugPrintf("Player feet marker off\n");
+ debugPrintf("Player feet marker off\n");
return true;
}
bool Debugger::Cmd_ResLook(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s number\n", argv[0]);
+ debugPrintf("Usage: %s number\n", argv[0]);
return true;
}
@@ -398,13 +398,13 @@ bool Debugger::Cmd_ResLook(int argc, const char **argv) {
uint32 numResFiles = _vm->_resman->getNumResFiles();
if (res < 0 || res >= (int)numResFiles) {
- DebugPrintf("Illegal resource %d. There are %d resources, 0-%d.\n",
+ debugPrintf("Illegal resource %d. There are %d resources, 0-%d.\n",
res, numResFiles, numResFiles - 1);
return true;
}
if (!_vm->_resman->checkValid(res)) {
- DebugPrintf("%d is a null & void resource number\n", res);
+ debugPrintf("%d is a null & void resource number\n", res);
return true;
}
@@ -413,40 +413,40 @@ bool Debugger::Cmd_ResLook(int argc, const char **argv) {
switch (type) {
case ANIMATION_FILE:
- DebugPrintf("<anim> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<anim> %s\n", _vm->_resman->fetchName(res));
break;
case SCREEN_FILE:
- DebugPrintf("<layer> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<layer> %s\n", _vm->_resman->fetchName(res));
break;
case GAME_OBJECT:
- DebugPrintf("<game object> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<game object> %s\n", _vm->_resman->fetchName(res));
break;
case WALK_GRID_FILE:
- DebugPrintf("<walk grid> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<walk grid> %s\n", _vm->_resman->fetchName(res));
break;
case GLOBAL_VAR_FILE:
- DebugPrintf("<global variables> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<global variables> %s\n", _vm->_resman->fetchName(res));
break;
case PARALLAX_FILE_null:
- DebugPrintf("<parallax file NOT USED!> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<parallax file NOT USED!> %s\n", _vm->_resman->fetchName(res));
break;
case RUN_LIST:
- DebugPrintf("<run list> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<run list> %s\n", _vm->_resman->fetchName(res));
break;
case TEXT_FILE:
- DebugPrintf("<text file> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<text file> %s\n", _vm->_resman->fetchName(res));
break;
case SCREEN_MANAGER:
- DebugPrintf("<screen manager> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<screen manager> %s\n", _vm->_resman->fetchName(res));
break;
case MOUSE_FILE:
- DebugPrintf("<mouse pointer> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<mouse pointer> %s\n", _vm->_resman->fetchName(res));
break;
case ICON_FILE:
- DebugPrintf("<menu icon> %s\n", _vm->_resman->fetchName(res));
+ debugPrintf("<menu icon> %s\n", _vm->_resman->fetchName(res));
break;
default:
- DebugPrintf("unrecognized fileType %d\n", type);
+ debugPrintf("unrecognized fileType %d\n", type);
break;
}
@@ -458,13 +458,13 @@ bool Debugger::Cmd_CurrentInfo(int argc, const char **argv) {
ScreenInfo *screenInfo = _vm->_screen->getScreenInfo();
if (screenInfo->background_layer_id) {
- DebugPrintf("background layer id %d\n", screenInfo->background_layer_id);
- DebugPrintf("%d wide, %d high\n", screenInfo->screen_wide, screenInfo->screen_deep);
- DebugPrintf("%d normal layers\n", screenInfo->number_of_layers);
+ debugPrintf("background layer id %d\n", screenInfo->background_layer_id);
+ debugPrintf("%d wide, %d high\n", screenInfo->screen_wide, screenInfo->screen_deep);
+ debugPrintf("%d normal layers\n", screenInfo->number_of_layers);
Cmd_RunList(argc, argv);
} else
- DebugPrintf("No screen\n");
+ debugPrintf("No screen\n");
return true;
}
@@ -476,26 +476,26 @@ bool Debugger::Cmd_RunList(int argc, const char **argv) {
readS.seek(ResHeader::size());
- DebugPrintf("Runlist number %d\n", runList);
+ debugPrintf("Runlist number %d\n", runList);
while (1) {
uint32 res = readS.readUint32LE();
if (!res)
break;
- DebugPrintf("%d %s\n", res, _vm->_resman->fetchName(res));
+ debugPrintf("%d %s\n", res, _vm->_resman->fetchName(res));
}
_vm->_resman->closeResource(runList);
} else
- DebugPrintf("No run list set\n");
+ debugPrintf("No run list set\n");
return true;
}
bool Debugger::Cmd_Kill(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s number\n", argv[0]);
+ debugPrintf("Usage: %s number\n", argv[0]);
return true;
}
@@ -503,7 +503,7 @@ bool Debugger::Cmd_Kill(int argc, const char **argv) {
uint32 numResFiles = _vm->_resman->getNumResFiles();
if (res < 0 || res >= (int)numResFiles) {
- DebugPrintf("Illegal resource %d. There are %d resources, 0-%d.\n",
+ debugPrintf("Illegal resource %d. There are %d resources, 0-%d.\n",
res, numResFiles, numResFiles - 1);
return true;
}
@@ -511,22 +511,22 @@ bool Debugger::Cmd_Kill(int argc, const char **argv) {
Resource *resList = _vm->_resman->getResList();
if (!resList[res].ptr) {
- DebugPrintf("Resource %d is not in memory\n", res);
+ debugPrintf("Resource %d is not in memory\n", res);
return true;
}
if (resList[res].refCount) {
- DebugPrintf("Resource %d is open - cannot remove\n", res);
+ debugPrintf("Resource %d is open - cannot remove\n", res);
return true;
}
_vm->_resman->remove(res);
- DebugPrintf("Trashed %d\n", res);
+ debugPrintf("Trashed %d\n", res);
return true;
}
bool Debugger::Cmd_Nuke(int argc, const char **argv) {
- DebugPrintf("Killing all resources except variable file and player object\n");
+ debugPrintf("Killing all resources except variable file and player object\n");
_vm->_resman->killAll(true);
return true;
}
@@ -540,7 +540,7 @@ bool Debugger::Cmd_Var(int argc, const char **argv) {
varSet(atoi(argv[1]), atoi(argv[2]));
break;
default:
- DebugPrintf("Usage: %s number value\n", argv[0]);
+ debugPrintf("Usage: %s number value\n", argv[0]);
break;
}
@@ -554,10 +554,10 @@ bool Debugger::Cmd_Rect(int argc, const char **argv) {
if (_definingRectangles) {
_vm->setInputEventFilter(filter & ~(RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP));
- DebugPrintf("Mouse rectangles enabled\n");
+ debugPrintf("Mouse rectangles enabled\n");
} else {
_vm->setInputEventFilter(filter | RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP);
- DebugPrintf("Mouse rectangles disabled\n");
+ debugPrintf("Mouse rectangles disabled\n");
}
_draggingRectangle = 0;
@@ -575,7 +575,7 @@ bool Debugger::Cmd_DebugOn(int argc, const char **argv) {
_displayMouseMarker = true;
_displayPlayerMarker = true;
_displayTextNumbers = true;
- DebugPrintf("Enabled all on-screen debug info\n");
+ debugPrintf("Enabled all on-screen debug info\n");
return true;
}
@@ -585,7 +585,7 @@ bool Debugger::Cmd_DebugOff(int argc, const char **argv) {
_displayMouseMarker = false;
_displayPlayerMarker = false;
_displayTextNumbers = false;
- DebugPrintf("Disabled all on-screen debug info\n");
+ debugPrintf("Disabled all on-screen debug info\n");
return true;
}
@@ -593,9 +593,9 @@ bool Debugger::Cmd_SaveRest(int argc, const char **argv) {
_testingSnR = !_testingSnR;
if (_testingSnR)
- DebugPrintf("Enabled S&R logic_script stability checking\n");
+ debugPrintf("Enabled S&R logic_script stability checking\n");
else
- DebugPrintf("Disabled S&R logic_script stability checking\n");
+ debugPrintf("Disabled S&R logic_script stability checking\n");
return true;
}
@@ -606,13 +606,13 @@ bool Debugger::Cmd_TimeOn(int argc, const char **argv) {
else if (_startTime == 0)
_startTime = _vm->_system->getMillis();
_displayTime = true;
- DebugPrintf("Timer display on\n");
+ debugPrintf("Timer display on\n");
return true;
}
bool Debugger::Cmd_TimeOff(int argc, const char **argv) {
_displayTime = false;
- DebugPrintf("Timer display off\n");
+ debugPrintf("Timer display off\n");
return true;
}
@@ -620,9 +620,9 @@ bool Debugger::Cmd_Text(int argc, const char **argv) {
_displayTextNumbers = !_displayTextNumbers;
if (_displayTextNumbers)
- DebugPrintf("Text numbers on\n");
+ debugPrintf("Text numbers on\n");
else
- DebugPrintf("Text numbers off\n");
+ debugPrintf("Text numbers off\n");
return true;
}
@@ -632,7 +632,7 @@ bool Debugger::Cmd_ShowVar(int argc, const char **argv) {
int32 varNo;
if (argc != 2) {
- DebugPrintf("Usage: %s number\n", argv[0]);
+ debugPrintf("Usage: %s number\n", argv[0]);
return true;
}
@@ -649,11 +649,11 @@ bool Debugger::Cmd_ShowVar(int argc, const char **argv) {
if (_showVar[showVarNo] == 0) {
// empty slot - add it to the list at this slot
_showVar[showVarNo] = varNo;
- DebugPrintf("var(%d) added to the watch-list\n", varNo);
+ debugPrintf("var(%d) added to the watch-list\n", varNo);
} else
- DebugPrintf("var(%d) already in the watch-list!\n", varNo);
+ debugPrintf("var(%d) already in the watch-list!\n", varNo);
} else
- DebugPrintf("Sorry - no more allowed - hide one or extend the system watch-list\n");
+ debugPrintf("Sorry - no more allowed - hide one or extend the system watch-list\n");
return true;
}
@@ -663,7 +663,7 @@ bool Debugger::Cmd_HideVar(int argc, const char **argv) {
int32 varNo;
if (argc != 2) {
- DebugPrintf("Usage: %s number\n", argv[0]);
+ debugPrintf("Usage: %s number\n", argv[0]);
return true;
}
@@ -676,9 +676,9 @@ bool Debugger::Cmd_HideVar(int argc, const char **argv) {
if (showVarNo < MAX_SHOWVARS) {
// We've found 'varNo' in the list - clear this slot
_showVar[showVarNo] = 0;
- DebugPrintf("var(%d) removed from watch-list\n", varNo);
+ debugPrintf("var(%d) removed from watch-list\n", varNo);
} else
- DebugPrintf("Sorry - can't find var(%d) in the list\n", varNo);
+ debugPrintf("Sorry - can't find var(%d) in the list\n", varNo);
return true;
}
@@ -687,13 +687,13 @@ bool Debugger::Cmd_Version(int argc, const char **argv) {
// This function used to print more information, but nothing we
// particularly care about.
- DebugPrintf("\"Broken Sword II\" (c) Revolution Software 1997.\n");
+ debugPrintf("\"Broken Sword II\" (c) Revolution Software 1997.\n");
return true;
}
bool Debugger::Cmd_AnimTest(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s value\n", argv[0]);
+ debugPrintf("Usage: %s value\n", argv[0]);
return true;
}
@@ -703,13 +703,13 @@ bool Debugger::Cmd_AnimTest(int argc, const char **argv) {
// Same as typing "VAR 912 <value>" at the console
varSet(912, atoi(argv[1]));
- DebugPrintf("Setting flag 'system_testing_anims'\n");
+ debugPrintf("Setting flag 'system_testing_anims'\n");
return true;
}
bool Debugger::Cmd_TextTest(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s value\n", argv[0]);
+ debugPrintf("Usage: %s value\n", argv[0]);
return true;
}
@@ -721,14 +721,14 @@ bool Debugger::Cmd_TextTest(int argc, const char **argv) {
_displayTextNumbers = true;
- DebugPrintf("Setting flag 'system_testing_text'\n");
- DebugPrintf("Text numbers on\n");
+ debugPrintf("Setting flag 'system_testing_text'\n");
+ debugPrintf("Text numbers on\n");
return true;
}
bool Debugger::Cmd_LineTest(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Usage: %s value1 value2\n", argv[0]);
+ debugPrintf("Usage: %s value1 value2\n", argv[0]);
return true;
}
@@ -743,24 +743,24 @@ bool Debugger::Cmd_LineTest(int argc, const char **argv) {
_displayTextNumbers = true;
- DebugPrintf("Setting flag 'system_testing_text'\n");
- DebugPrintf("Setting flag 'system_test_line_no'\n");
- DebugPrintf("Text numbers on\n");
+ debugPrintf("Setting flag 'system_testing_text'\n");
+ debugPrintf("Setting flag 'system_test_line_no'\n");
+ debugPrintf("Text numbers on\n");
return true;
}
bool Debugger::Cmd_Events(int argc, const char **argv) {
EventUnit *eventList = _vm->_logic->getEventList();
- DebugPrintf("EVENT LIST:\n");
+ debugPrintf("EVENT LIST:\n");
for (uint32 i = 0; i < MAX_events; i++) {
if (eventList[i].id) {
uint32 target = eventList[i].id;
uint32 script = eventList[i].interact_id;
- DebugPrintf("slot %2d: id = %s (%d)\n", i, _vm->_resman->fetchName(target), target);
- DebugPrintf(" script = %s (%d) pos %d\n", _vm->_resman->fetchName(script / 65536), script / 65536, script % 65536);
+ debugPrintf("slot %2d: id = %s (%d)\n", i, _vm->_resman->fetchName(target), target);
+ debugPrintf(" script = %s (%d) pos %d\n", _vm->_resman->fetchName(script / 65536), script / 65536, script % 65536);
}
}
@@ -771,28 +771,28 @@ bool Debugger::Cmd_Sfx(int argc, const char **argv) {
_vm->_wantSfxDebug = !_vm->_wantSfxDebug;
if (_vm->_wantSfxDebug)
- DebugPrintf("SFX logging activated\n");
+ debugPrintf("SFX logging activated\n");
else
- DebugPrintf("SFX logging deactivated\n");
+ debugPrintf("SFX logging deactivated\n");
return true;
}
bool Debugger::Cmd_English(int argc, const char **argv) {
_vm->initializeFontResourceFlags(DEFAULT_TEXT);
- DebugPrintf("Default fonts selected\n");
+ debugPrintf("Default fonts selected\n");
return true;
}
bool Debugger::Cmd_Finnish(int argc, const char **argv) {
_vm->initializeFontResourceFlags(FINNISH_TEXT);
- DebugPrintf("Finnish fonts selected\n");
+ debugPrintf("Finnish fonts selected\n");
return true;
}
bool Debugger::Cmd_Polish(int argc, const char **argv) {
_vm->initializeFontResourceFlags(POLISH_TEXT);
- DebugPrintf("Polish fonts selected\n");
+ debugPrintf("Polish fonts selected\n");
return true;
}
diff --git a/engines/sword2/resman.cpp b/engines/sword2/resman.cpp
index a0561641d7..44027fd281 100644
--- a/engines/sword2/resman.cpp
+++ b/engines/sword2/resman.cpp
@@ -38,7 +38,7 @@
#include "sword2/screen.h"
#include "sword2/sound.h"
-#define Debug_Printf _vm->_debugger->DebugPrintf
+#define Debug_Printf _vm->_debugger->debugPrintf
namespace Sword2 {
diff --git a/engines/sword2/sound.cpp b/engines/sword2/sound.cpp
index aea33e99e3..1e1687b1e6 100644
--- a/engines/sword2/sound.cpp
+++ b/engines/sword2/sound.cpp
@@ -49,7 +49,7 @@
#include "audio/decoders/wave.h"
#include "audio/decoders/xa.h"
-#define Debug_Printf _vm->_debugger->DebugPrintf
+#define Debug_Printf _vm->_debugger->debugPrintf
namespace Sword2 {
diff --git a/engines/teenagent/console.cpp b/engines/teenagent/console.cpp
index 13d5c687ce..2304829782 100644
--- a/engines/teenagent/console.cpp
+++ b/engines/teenagent/console.cpp
@@ -26,24 +26,24 @@
namespace TeenAgent {
Console::Console(TeenAgentEngine *engine) : _engine(engine) {
- DCmd_Register("enable_object", WRAP_METHOD(Console, enableObject));
- DCmd_Register("disable_object", WRAP_METHOD(Console, enableObject));
- DCmd_Register("set_ons", WRAP_METHOD(Console, setOns));
- DCmd_Register("set_music", WRAP_METHOD(Console, setMusic));
- DCmd_Register("animation", WRAP_METHOD(Console, playAnimation));
- DCmd_Register("actor_animation", WRAP_METHOD(Console, playActorAnimation));
- DCmd_Register("call", WRAP_METHOD(Console, call));
+ registerCmd("enable_object", WRAP_METHOD(Console, enableObject));
+ registerCmd("disable_object", WRAP_METHOD(Console, enableObject));
+ registerCmd("set_ons", WRAP_METHOD(Console, setOns));
+ registerCmd("set_music", WRAP_METHOD(Console, setMusic));
+ registerCmd("animation", WRAP_METHOD(Console, playAnimation));
+ registerCmd("actor_animation", WRAP_METHOD(Console, playActorAnimation));
+ registerCmd("call", WRAP_METHOD(Console, call));
}
bool Console::enableObject(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("usage: %s object_id [scene_id]\n", argv[0]);
+ debugPrintf("usage: %s object_id [scene_id]\n", argv[0]);
return true;
}
int id = atoi(argv[1]);
if (id < 0) {
- DebugPrintf("object id %d is invalid\n", id);
+ debugPrintf("object id %d is invalid\n", id);
return true;
}
@@ -51,7 +51,7 @@ bool Console::enableObject(int argc, const char **argv) {
if (argc > 2) {
scene_id = atoi(argv[2]);
if (scene_id < 0) {
- DebugPrintf("scene id %d is invalid\n", scene_id);
+ debugPrintf("scene id %d is invalid\n", scene_id);
return true;
}
}
@@ -66,20 +66,20 @@ bool Console::enableObject(int argc, const char **argv) {
bool Console::setOns(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("usage: %s index(0-3) value [scene_id]\n", argv[0]);
+ debugPrintf("usage: %s index(0-3) value [scene_id]\n", argv[0]);
return true;
}
int index = atoi(argv[1]);
if (index < 0 || index > 3) {
- DebugPrintf("index %d is invalid\n", index);
+ debugPrintf("index %d is invalid\n", index);
return true;
}
int value = 0;
value = atoi(argv[2]);
if (value < 0) {
- DebugPrintf("invalid value\n");
+ debugPrintf("invalid value\n");
return true;
}
@@ -87,7 +87,7 @@ bool Console::setOns(int argc, const char **argv) {
if (argc > 3) {
scene_id = atoi(argv[3]);
if (scene_id < 0) {
- DebugPrintf("scene id %d is invalid\n", scene_id);
+ debugPrintf("scene id %d is invalid\n", scene_id);
return true;
}
}
@@ -98,13 +98,13 @@ bool Console::setOns(int argc, const char **argv) {
bool Console::setMusic(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("usage: %s index(1-11)\n", argv[0]);
+ debugPrintf("usage: %s index(1-11)\n", argv[0]);
return true;
}
int index = atoi(argv[1]);
if (index <= 0 || index > 11) {
- DebugPrintf("invalid value\n");
+ debugPrintf("invalid value\n");
return true;
}
@@ -114,14 +114,14 @@ bool Console::setMusic(int argc, const char **argv) {
bool Console::playAnimation(int argc, const char **argv) {
if (argc < 3) {
- DebugPrintf("usage: %s id slot(0-3)\n", argv[0]);
+ debugPrintf("usage: %s id slot(0-3)\n", argv[0]);
return true;
}
int id = atoi(argv[1]);
int slot = atoi(argv[2]);
if (id < 0 || slot < 0 || slot > 3) {
- DebugPrintf("invalid slot or animation id\n");
+ debugPrintf("invalid slot or animation id\n");
return true;
}
@@ -131,13 +131,13 @@ bool Console::playAnimation(int argc, const char **argv) {
bool Console::playActorAnimation(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("usage: %s id\n", argv[0]);
+ debugPrintf("usage: %s id\n", argv[0]);
return true;
}
int id = atoi(argv[1]);
if (id < 0) {
- DebugPrintf("invalid animation id\n");
+ debugPrintf("invalid animation id\n");
return true;
}
@@ -147,18 +147,18 @@ bool Console::playActorAnimation(int argc, const char **argv) {
bool Console::call(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("usage: %s 0xHEXADDR\n", argv[0]);
+ debugPrintf("usage: %s 0xHEXADDR\n", argv[0]);
return true;
}
uint addr;
if (sscanf(argv[1], "0x%x", &addr) != 1) {
- DebugPrintf("invalid address\n");
+ debugPrintf("invalid address\n");
return true;
}
if (!_engine->processCallback(addr))
- DebugPrintf("calling callback %04x failed\n", addr);
+ debugPrintf("calling callback %04x failed\n", addr);
return true;
}
diff --git a/engines/tinsel/debugger.cpp b/engines/tinsel/debugger.cpp
index 45e3a05903..1dbb19d383 100644
--- a/engines/tinsel/debugger.cpp
+++ b/engines/tinsel/debugger.cpp
@@ -62,11 +62,11 @@ int strToInt(const char *s) {
//----------------- CONSOLE CLASS ---------------------
Console::Console() : GUI::Debugger() {
- DCmd_Register("item", WRAP_METHOD(Console, cmd_item));
- DCmd_Register("scene", WRAP_METHOD(Console, cmd_scene));
- DCmd_Register("music", WRAP_METHOD(Console, cmd_music));
- DCmd_Register("sound", WRAP_METHOD(Console, cmd_sound));
- DCmd_Register("string", WRAP_METHOD(Console, cmd_string));
+ registerCmd("item", WRAP_METHOD(Console, cmd_item));
+ registerCmd("scene", WRAP_METHOD(Console, cmd_scene));
+ registerCmd("music", WRAP_METHOD(Console, cmd_music));
+ registerCmd("sound", WRAP_METHOD(Console, cmd_sound));
+ registerCmd("string", WRAP_METHOD(Console, cmd_string));
}
Console::~Console() {
@@ -74,8 +74,8 @@ Console::~Console() {
bool Console::cmd_item(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("%s item_number\n", argv[0]);
- DebugPrintf("Sets the currently active 'held' item\n");
+ debugPrintf("%s item_number\n", argv[0]);
+ debugPrintf("Sets the currently active 'held' item\n");
return true;
}
@@ -86,14 +86,14 @@ bool Console::cmd_item(int argc, const char **argv) {
bool Console::cmd_scene(int argc, const char **argv) {
if (argc < 1 || argc > 3) {
- DebugPrintf("%s [scene_number [entry number]]\n", argv[0]);
- DebugPrintf("If no parameters are given, prints the current scene.\n");
- DebugPrintf("Otherwise changes to the specified scene number. Entry number defaults to 1 if none provided\n");
+ debugPrintf("%s [scene_number [entry number]]\n", argv[0]);
+ debugPrintf("If no parameters are given, prints the current scene.\n");
+ debugPrintf("Otherwise changes to the specified scene number. Entry number defaults to 1 if none provided\n");
return true;
}
if (argc == 1) {
- DebugPrintf("Current scene is %d\n", GetSceneHandle() >> SCNHANDLE_SHIFT);
+ debugPrintf("Current scene is %d\n", GetSceneHandle() >> SCNHANDLE_SHIFT);
return true;
}
@@ -106,15 +106,15 @@ bool Console::cmd_scene(int argc, const char **argv) {
bool Console::cmd_music(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("%s track_number or %s -offset\n", argv[0], argv[0]);
- DebugPrintf("Plays the MIDI track number provided, or the offset inside midi.dat\n");
- DebugPrintf("A positive number signifies a track number, whereas a negative signifies an offset\n");
+ debugPrintf("%s track_number or %s -offset\n", argv[0], argv[0]);
+ debugPrintf("Plays the MIDI track number provided, or the offset inside midi.dat\n");
+ debugPrintf("A positive number signifies a track number, whereas a negative signifies an offset\n");
return true;
}
int param = strToInt(argv[1]);
if (param == 0) {
- DebugPrintf("Track number/offset can't be 0!\n");
+ debugPrintf("Track number/offset can't be 0!\n");
} else if (param > 0) {
// Track provided
PlayMidiSequence(GetTrackOffset(param - 1), false);
@@ -128,8 +128,8 @@ bool Console::cmd_music(int argc, const char **argv) {
bool Console::cmd_sound(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("%s id\n", argv[0]);
- DebugPrintf("Plays the sound with the given ID\n");
+ debugPrintf("%s id\n", argv[0]);
+ debugPrintf("Plays the sound with the given ID\n");
return true;
}
@@ -140,7 +140,7 @@ bool Console::cmd_sound(int argc, const char **argv) {
else
_vm->_sound->playSample(id, 0, false, 0, 0, PRIORITY_TALK, Audio::Mixer::kSpeechSoundType);
} else {
- DebugPrintf("Sample %d does not exist!\n", id);
+ debugPrintf("Sample %d does not exist!\n", id);
}
return true;
@@ -148,15 +148,15 @@ bool Console::cmd_sound(int argc, const char **argv) {
bool Console::cmd_string(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("%s id\n", argv[0]);
- DebugPrintf("Prints the string with the given ID\n");
+ debugPrintf("%s id\n", argv[0]);
+ debugPrintf("Prints the string with the given ID\n");
return true;
}
char tmp[TBUFSZ];
int id = strToInt(argv[1]);
LoadStringRes(id, tmp, TBUFSZ);
- DebugPrintf("%s\n", tmp);
+ debugPrintf("%s\n", tmp);
return true;
}
diff --git a/engines/toltecs/console.cpp b/engines/toltecs/console.cpp
index f84a8e3c44..5a0c66c7b0 100644
--- a/engines/toltecs/console.cpp
+++ b/engines/toltecs/console.cpp
@@ -31,8 +31,8 @@
namespace Toltecs {
Console::Console(ToltecsEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room));
- DCmd_Register("dump", WRAP_METHOD(Console, Cmd_Dump));
+ registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
+ registerCmd("dump", WRAP_METHOD(Console, Cmd_Dump));
}
Console::~Console() {
@@ -40,10 +40,10 @@ Console::~Console() {
bool Console::Cmd_Room(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Current room number is %d\n", _vm->_sceneResIndex);
+ debugPrintf("Current room number is %d\n", _vm->_sceneResIndex);
#if 0
- DebugPrintf("Calling this command with the room number changes the room\n");
- DebugPrintf("WARNING: It's a bad idea to warp to rooms with this, as the room object scripts are not loaded\n");
+ debugPrintf("Calling this command with the room number changes the room\n");
+ debugPrintf("WARNING: It's a bad idea to warp to rooms with this, as the room object scripts are not loaded\n");
#endif
return true;
#if 0
@@ -65,13 +65,13 @@ bool Console::Cmd_Room(int argc, const char **argv) {
bool Console::Cmd_Dump(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: dump <resource number>\n");
+ debugPrintf("Usage: dump <resource number>\n");
return true;
}
int resNum = atoi(argv[1]);
_vm->_arc->dump(resNum);
- DebugPrintf("Resource %d has been dumped to disk\n", resNum);
+ debugPrintf("Resource %d has been dumped to disk\n", resNum);
return true;
}
diff --git a/engines/tony/debugger.cpp b/engines/tony/debugger.cpp
index 22c218a19c..e192c53d2b 100644
--- a/engines/tony/debugger.cpp
+++ b/engines/tony/debugger.cpp
@@ -28,9 +28,9 @@
namespace Tony {
Debugger::Debugger() : GUI::Debugger() {
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("scene", WRAP_METHOD(Debugger, Cmd_Scene));
- DCmd_Register("dirty_rects", WRAP_METHOD(Debugger, Cmd_DirtyRects));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("scene", WRAP_METHOD(Debugger, Cmd_Scene));
+ registerCmd("dirty_rects", WRAP_METHOD(Debugger, Cmd_DirtyRects));
}
static int strToInt(const char *s) {
@@ -82,13 +82,13 @@ void DebugChangeScene(CORO_PARAM, const void *param) {
*/
bool Debugger::Cmd_Scene(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: %s <scene number> [<x> <y>]\n", argv[0]);
+ debugPrintf("Usage: %s <scene number> [<x> <y>]\n", argv[0]);
return true;
}
int sceneNumber = strToInt(argv[1]);
if (sceneNumber >= g_vm->_theBoxes.getLocBoxesCount()) {
- DebugPrintf("Invalid scene\n");
+ debugPrintf("Invalid scene\n");
return true;
}
@@ -118,7 +118,7 @@ bool Debugger::Cmd_Scene(int argc, const char **argv) {
*/
bool Debugger::Cmd_DirtyRects(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage; %s [on | off]\n", argv[0]);
+ debugPrintf("Usage; %s [on | off]\n", argv[0]);
return true;
} else {
g_vm->_window.showDirtyRects(strcmp(argv[1], "on") == 0);
diff --git a/engines/tony/detection_tables.h b/engines/tony/detection_tables.h
index ce4651f0ab..28dcaac752 100644
--- a/engines/tony/detection_tables.h
+++ b/engines/tony/detection_tables.h
@@ -217,7 +217,7 @@ static const TonyGameDescription gameDescriptions[] = {
// Tony Tough German "Shoe Box", reported in bug #3582420
{
"tony",
- 0,
+ 0,
{
{"roasted.mpr", 0, "06203dbbc85fdd1e6dc8fc211c1a6207", 135911071},
{"roasted.mpc", 0, "bc3471f098e591dc509dcad401a8d8a5", 389554},
@@ -230,6 +230,23 @@ static const TonyGameDescription gameDescriptions[] = {
},
},
+ {
+ // Tony Tough Russian, reported in bug #6589
+ {
+ "tony",
+ 0,
+ {
+ {"roasted.mpr", 0, "06203dbbc85fdd1e6dc8fc211c1a6207", 135911071},
+ {"roasted.mpc", 0, "377d6e24adeedc6c5c09c31b92231218", 391536},
+ AD_LISTEND
+ },
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp
index cab31795f7..51e8dee19f 100644
--- a/engines/toon/character.cpp
+++ b/engines/toon/character.cpp
@@ -1059,12 +1059,14 @@ void Character::playAnim(int32 animId, int32 unused, int32 flags) {
_specialAnim->loadAnimation(animName);
_animSpecialId = animId;
-
- _animationInstance->setAnimation(_specialAnim);
- _animationInstance->setAnimationRange(0, _specialAnim->_numFrames - 1);
- _animationInstance->reset();
- _animationInstance->stopAnimation();
- _animationInstance->setLooping(false);
+
+ if (_animationInstance) {
+ _animationInstance->setAnimation(_specialAnim);
+ _animationInstance->setAnimationRange(0, _specialAnim->_numFrames - 1);
+ _animationInstance->reset();
+ _animationInstance->stopAnimation();
+ _animationInstance->setLooping(false);
+ }
}
int32 Character::getAnimFlag() {
diff --git a/engines/touche/console.cpp b/engines/touche/console.cpp
index c4272038dc..472863c817 100644
--- a/engines/touche/console.cpp
+++ b/engines/touche/console.cpp
@@ -26,8 +26,8 @@
namespace Touche {
ToucheConsole::ToucheConsole(ToucheEngine *vm) : GUI::Debugger(), _vm(vm) {
- DCmd_Register("startMusic", WRAP_METHOD(ToucheConsole, Cmd_StartMusic));
- DCmd_Register("stopMusic", WRAP_METHOD(ToucheConsole, Cmd_StopMusic));
+ registerCmd("startMusic", WRAP_METHOD(ToucheConsole, Cmd_StartMusic));
+ registerCmd("stopMusic", WRAP_METHOD(ToucheConsole, Cmd_StopMusic));
}
ToucheConsole::~ToucheConsole() {
@@ -35,7 +35,7 @@ ToucheConsole::~ToucheConsole() {
bool ToucheConsole::Cmd_StartMusic(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: startMusic <num>\n");
+ debugPrintf("Usage: startMusic <num>\n");
return true;
}
diff --git a/engines/touche/menu.cpp b/engines/touche/menu.cpp
index 19c10af8de..b94776eee5 100644
--- a/engines/touche/menu.cpp
+++ b/engines/touche/menu.cpp
@@ -31,96 +31,6 @@
namespace Touche {
-enum ActionId {
- kActionNone,
-
- // settings menu
- kActionLoadMenu,
- kActionSaveMenu,
- kActionRestartGame,
- kActionPlayGame,
- kActionQuitGame,
- kActionTextOnly,
- kActionVoiceOnly,
- kActionTextAndVoice,
- kActionLowerVolume,
- kActionUpperVolume,
-
- // saveLoad menu
- kActionGameState1,
- kActionGameState2,
- kActionGameState3,
- kActionGameState4,
- kActionGameState5,
- kActionGameState6,
- kActionGameState7,
- kActionGameState8,
- kActionGameState9,
- kActionGameState10,
- kActionScrollUpSaves,
- kActionScrollDownSaves,
- kActionPerformSaveLoad,
- kActionCancelSaveLoad
-};
-
-enum MenuMode {
- kMenuSettingsMode = 0,
- kMenuLoadStateMode,
- kMenuSaveStateMode
-};
-
-enum ButtonFlags {
- kButtonBorder = 1 << 0,
- kButtonText = 1 << 1,
- kButtonArrow = 1 << 2
-};
-
-struct Button {
- int x, y;
- int w, h;
- ActionId action;
- int data;
- uint8 flags;
-};
-
-struct MenuData {
- MenuMode mode;
- Button *buttonsTable;
- uint buttonsCount;
- bool quit;
- bool exit;
- char saveLoadDescriptionsTable[kMaxSaveStates][33];
-
- void removeLastCharFromDescription(int slot) {
- char *description = saveLoadDescriptionsTable[slot];
- int descriptionLen = strlen(description);
- if (descriptionLen > 0) {
- --descriptionLen;
- description[descriptionLen] = 0;
- }
- }
-
- void addCharToDescription(int slot, char chr) {
- char *description = saveLoadDescriptionsTable[slot];
- int descriptionLen = strlen(description);
- if (descriptionLen < 32 && Common::isPrint(chr)) {
- description[descriptionLen] = chr;
- description[descriptionLen + 1] = 0;
- }
- }
-
- const Button *findButtonUnderCursor(int cursorX, int cursorY) const {
- for (uint i = 0; i < buttonsCount; ++i) {
- const Button *button = &buttonsTable[i];
- if (cursorX >= button->x && cursorX < button->x + button->w &&
- cursorY >= button->y && cursorY < button->y + button->h) {
- return button;
- }
- }
- return 0;
- }
-};
-
static void drawArrow(uint8 *dst, int dstPitch, int x, int y, int delta, uint8 color) {
static const int8 arrowCoordsTable[7][4] = {
{ 5, 0, 9, 0 },
@@ -140,25 +50,24 @@ static void drawArrow(uint8 *dst, int dstPitch, int x, int y, int delta, uint8 c
}
}
-void ToucheEngine::drawButton(void *button) {
- Button *b = (Button *)button;
- if (b->flags & kButtonBorder) {
- Graphics::drawRect(_offscreenBuffer, kScreenWidth, b->x, b->y, b->w, b->h, 0xF7, 0xF9);
+void ToucheEngine::drawButton(Button *button) {
+ if (button->flags & kButtonBorder) {
+ Graphics::drawRect(_offscreenBuffer, kScreenWidth, button->x, button->y, button->w, button->h, 0xF7, 0xF9);
}
- if (b->flags & kButtonText) {
- if (b->data != 0) {
- const char *str = getString(b->data);
- const int w = getStringWidth(b->data);
+ if (button->flags & kButtonText) {
+ if (button->data != 0) {
+ const char *str = getString(button->data);
+ const int w = getStringWidth(button->data);
const int h = kTextHeight;
- const int x = b->x + (b->w - w) / 2;
- const int y = b->y + (b->h - h) / 2;
+ const int x = button->x + (button->w - w) / 2;
+ const int y = button->y + (button->h - h) / 2;
Graphics::drawString16(_offscreenBuffer, kScreenWidth, 0xFF, x, y, str);
}
}
- if (b->flags & kButtonArrow) {
+ if (button->flags & kButtonArrow) {
int dx = 0;
int dy = 0;
- switch (b->data) {
+ switch (button->data) {
case 2000: // up arrow
dx = 1;
dy = 2;
@@ -168,8 +77,8 @@ void ToucheEngine::drawButton(void *button) {
dy = -2;
break;
}
- const int x = b->x + b->w / 2;
- const int y = b->y + b->h / 2;
+ const int x = button->x + button->w / 2;
+ const int y = button->y + button->h / 2;
drawArrow(_offscreenBuffer, kScreenWidth, x, y + dy + 1, dx, 0xD2);
drawArrow(_offscreenBuffer, kScreenWidth, x, y + dy, dx, 0xFF);
}
@@ -253,49 +162,47 @@ static void setupMenu(MenuMode mode, MenuData *menuData) {
}
}
-void ToucheEngine::redrawMenu(void *menu) {
- MenuData *menuData = (MenuData *)menu;
+void ToucheEngine::redrawMenu(MenuData *menu) {
Graphics::fillRect(_offscreenBuffer, kScreenWidth, 90, 102, 460, 196, 0xF8);
Graphics::drawRect(_offscreenBuffer, kScreenWidth, 90, 102, 460, 196, 0xF7, 0xF9);
Graphics::drawRect(_offscreenBuffer, kScreenWidth, 106, 118, 340, 164, 0xF9, 0xF7);
- switch (menuData->mode) {
+ switch (menu->mode) {
case kMenuSettingsMode:
drawVolumeSlideBar(_offscreenBuffer, kScreenWidth, getMusicVolume());
- menuData->buttonsTable[5].data = 0;
- menuData->buttonsTable[6].data = 0;
- menuData->buttonsTable[7].data = 0;
- menuData->buttonsTable[5 + _talkTextMode].data = -86;
+ menu->buttonsTable[5].data = 0;
+ menu->buttonsTable[6].data = 0;
+ menu->buttonsTable[7].data = 0;
+ menu->buttonsTable[5 + _talkTextMode].data = -86;
break;
case kMenuLoadStateMode:
case kMenuSaveStateMode:
- drawSaveGameStateDescriptions(_offscreenBuffer, kScreenWidth, menuData, _saveLoadCurrentPage, _saveLoadCurrentSlot);
+ drawSaveGameStateDescriptions(_offscreenBuffer, kScreenWidth, menu, _saveLoadCurrentPage, _saveLoadCurrentSlot);
break;
}
- for (uint i = 0; i < menuData->buttonsCount; ++i) {
- drawButton(&menuData->buttonsTable[i]);
+ for (uint i = 0; i < menu->buttonsCount; ++i) {
+ drawButton(&menu->buttonsTable[i]);
}
}
-void ToucheEngine::handleMenuAction(void *menu, int actionId) {
- MenuData *menuData = (MenuData *)menu;
+void ToucheEngine::handleMenuAction(MenuData *menu, int actionId) {
switch (actionId) {
case kActionLoadMenu:
- menuData->mode = kMenuLoadStateMode;
+ menu->mode = kMenuLoadStateMode;
break;
case kActionSaveMenu:
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
- menuData->mode = kMenuSaveStateMode;
+ menu->mode = kMenuSaveStateMode;
break;
case kActionRestartGame:
restart();
- menuData->quit = true;
+ menu->quit = true;
break;
case kActionPlayGame:
- menuData->quit = true;
+ menu->quit = true;
break;
case kActionQuitGame:
quitGame();
- menuData->quit = true;
+ menu->quit = true;
break;
case kActionTextOnly:
_talkTextMode = kTalkModeTextOnly;
@@ -327,23 +234,23 @@ void ToucheEngine::handleMenuAction(void *menu, int actionId) {
_saveLoadCurrentSlot = _saveLoadCurrentPage * 10 + (_saveLoadCurrentSlot % 10);
break;
case kActionPerformSaveLoad:
- if (menuData->mode == kMenuLoadStateMode) {
+ if (menu->mode == kMenuLoadStateMode) {
if (loadGameState(_saveLoadCurrentSlot).getCode() == Common::kNoError) {
- menuData->quit = true;
+ menu->quit = true;
}
- } else if (menuData->mode == kMenuSaveStateMode) {
+ } else if (menu->mode == kMenuSaveStateMode) {
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
- const char *description = menuData->saveLoadDescriptionsTable[_saveLoadCurrentSlot];
+ const char *description = menu->saveLoadDescriptionsTable[_saveLoadCurrentSlot];
if (strlen(description) > 0) {
if (saveGameState(_saveLoadCurrentSlot, description).getCode() == Common::kNoError) {
- menuData->quit = true;
+ menu->quit = true;
}
}
}
break;
case kActionCancelSaveLoad:
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
- menuData->mode = kMenuSettingsMode;
+ menu->mode = kMenuSettingsMode;
break;
default:
if (actionId >= kActionGameState1 && actionId <= kActionGameState10) {
diff --git a/engines/touche/resource.cpp b/engines/touche/resource.cpp
index 16a95d307f..467d2bed90 100644
--- a/engines/touche/resource.cpp
+++ b/engines/touche/resource.cpp
@@ -150,38 +150,38 @@ void ToucheEngine::res_allocateTables() {
void ToucheEngine::res_deallocateTables() {
free(_textData);
- _textData = 0;
+ _textData = nullptr;
free(_backdropBuffer);
- _backdropBuffer = 0;
+ _backdropBuffer = nullptr;
free(_menuKitData);
- _menuKitData = 0;
+ _menuKitData = nullptr;
free(_convKitData);
- _convKitData = 0;
+ _convKitData = nullptr;
for (int i = 0; i < NUM_SEQUENCES; ++i) {
free(_sequenceDataTable[i]);
- _sequenceDataTable[i] = 0;
+ _sequenceDataTable[i] = nullptr;
}
free(_programData);
- _programData = 0;
+ _programData = nullptr;
free(_mouseData);
- _mouseData = 0;
+ _mouseData = nullptr;
free(_iconData);
- _iconData = 0;
+ _iconData = nullptr;
for (int i = 0; i < NUM_SPRITES; ++i) {
free(_spritesTable[i].ptr);
- _spritesTable[i].ptr = 0;
+ _spritesTable[i].ptr = nullptr;
}
free(_offscreenBuffer);
- _offscreenBuffer = 0;
+ _offscreenBuffer = nullptr;
}
uint32 ToucheEngine::res_getDataOffset(ResourceType type, int num, uint32 *size) {
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index 09697d0e4a..ff4f41f44d 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -46,32 +46,32 @@
namespace Touche {
ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
- : Engine(system), _midiPlayer(0), _language(language), _rnd("touche") {
+ : Engine(system), _midiPlayer(nullptr), _language(language), _rnd("touche") {
_saveLoadCurrentPage = 0;
_saveLoadCurrentSlot = 0;
_hideInventoryTexts = false;
_numOpcodes = 0;
_compressedSpeechData = 0;
- _textData = 0;
- _backdropBuffer = 0;
- _menuKitData = 0;
- _convKitData = 0;
+ _textData = nullptr;
+ _backdropBuffer = nullptr;
+ _menuKitData = nullptr;
+ _convKitData = nullptr;
for (int i = 0; i < NUM_SEQUENCES; i++)
- _sequenceDataTable[i] = 0;
+ _sequenceDataTable[i] = nullptr;
- _programData = 0;
+ _programData = nullptr;
_programDataSize = 0;
- _mouseData = 0;
- _iconData = 0;
+ _mouseData = nullptr;
+ _iconData = nullptr;
_currentBitmapWidth = 0;
_currentBitmapHeight = 0;
_currentImageWidth = 0;
_currentImageHeight = 0;
_roomWidth = 0;
- _programTextDataPtr = 0;
- _offscreenBuffer = 0;
+ _programTextDataPtr = nullptr;
+ _offscreenBuffer = nullptr;
_screenRect = Common::Rect(kScreenWidth, kScreenHeight);
_roomAreaRect = Common::Rect(kScreenWidth, kRoomHeight);
@@ -124,11 +124,11 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
_script.opcodeNum = 0;
_script.dataOffset = 0;
_script.keyCharNum = 0;
- _script.dataPtr = 0;
- _script.stackDataPtr = 0;
- _script.stackDataBasePtr = 0;
+ _script.dataPtr = nullptr;
+ _script.stackDataPtr = nullptr;
+ _script.stackDataBasePtr = nullptr;
_script.quitFlag = 0;
- _opcodesTable = 0;
+ _opcodesTable = nullptr;
for (uint i = 0; i < NUM_SPRITES; i++)
memset(&_spritesTable[i], 0, sizeof(SpriteData));
@@ -138,10 +138,10 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
_talkListEnd = 0;
_talkListCurrent = 0;
- _talkTextRectDefined = 0;
- _talkTextDisplayed = 0;
- _talkTextInitialized = 0;
- _skipTalkText = 0;
+ _talkTextRectDefined = false;
+ _talkTextDisplayed = false;
+ _talkTextInitialized = false;
+ _skipTalkText = false;
_talkTextSpeed = 0;
_keyCharTalkCounter = 0;
_talkTableLastTalkingKeyChar = 0;
@@ -151,14 +151,14 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
for (uint i = 0; i < NUM_TALK_ENTRIES; i++)
memset(&_talkTable[i], 0, sizeof(TalkEntry));
- _conversationChoicesUpdated = 0;
+ _conversationChoicesUpdated = false;
_conversationReplyNum = 0;
- _conversationEnded = 0;
+ _conversationEnded = false;
_conversationNum = 0;
_scrollConversationChoiceOffset = 0;
_currentConversation = 0;
- _disableConversationScript = 0;
- _conversationAreaCleared = 0;
+ _disableConversationScript = false;
+ _conversationAreaCleared = false;
for (uint i = 0; i < NUM_CONVERSATION_CHOICES; i++)
memset(&_conversationChoicesTable[i], 0, sizeof(ConversationChoice));
@@ -167,6 +167,26 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
_sortedKeyCharsTable[i] = 0;
_currentKeyCharNum = 0;
+ _inp_leftMouseButtonPressed = false;
+ _inp_rightMouseButtonPressed = false;
+ _disabledInputCounter = 0;
+ _gameState = kGameStateNone;
+ _displayQuitDialog = false;
+ _newMusicNum = 0;
+ _currentMusicNum = 0;
+ _newSoundNum = 0;
+ _newSoundDelay = 0;
+ _newSoundPriority = 0;
+ for (int i = 0; i < 3; ++i) {
+ _inventoryStateTable[i].displayOffset = 0;
+ _inventoryStateTable[i].lastItem = 0;
+ _inventoryStateTable[i].itemsPerLine = 0;
+ _inventoryStateTable[i].itemsList = nullptr;
+ }
+ _inventoryVar1 = nullptr;
+ _inventoryVar2 = nullptr;
+ _currentCursorObject = 0;
+ _talkTextMode = 0;
}
ToucheEngine::~ToucheEngine() {
@@ -3094,12 +3114,12 @@ void ToucheEngine::buildWalkPath(int dstPosX, int dstPosY, int keyChar) {
for (uint i = 0; i < _programWalkTable.size(); ++i) {
const ProgramWalkData *pwd = &_programWalkTable[i];
if ((pwd->point1 & 0x4000) == 0) {
- int distance = 32000;
ProgramPointData *pts1 = &_programPointsTable[pwd->point1];
ProgramPointData *pts2 = &_programPointsTable[pwd->point2];
if (pts1->order != 0) {
int dx = pts2->x - pts1->x;
int dy = pts2->y - pts1->y;
+ int distance = 32000;
if (dx == 0) {
if (dstPosY > MIN(pts2->y, pts1->y) && dstPosY < MAX(pts2->y, pts1->y)) {
int d = ABS(dstPosX - pts1->x);
diff --git a/engines/touche/touche.h b/engines/touche/touche.h
index 3da33f593b..20bf723553 100644
--- a/engines/touche/touche.h
+++ b/engines/touche/touche.h
@@ -346,16 +346,108 @@ enum StringType {
kStringTypeConversation
};
-void readGameStateDescription(Common::ReadStream *f, char *description, int len);
-Common::String generateGameStateFileName(const char *target, int slot, bool prefixOnly = false);
-int getGameStateFileSlot(const char *filename);
-
enum GameState {
kGameStateGameLoop,
kGameStateOptionsDialog,
- kGameStateQuitDialog
+ kGameStateQuitDialog,
+ kGameStateNone
+};
+
+enum ActionId {
+ kActionNone,
+
+ // settings menu
+ kActionLoadMenu,
+ kActionSaveMenu,
+ kActionRestartGame,
+ kActionPlayGame,
+ kActionQuitGame,
+ kActionTextOnly,
+ kActionVoiceOnly,
+ kActionTextAndVoice,
+ kActionLowerVolume,
+ kActionUpperVolume,
+
+ // saveLoad menu
+ kActionGameState1,
+ kActionGameState2,
+ kActionGameState3,
+ kActionGameState4,
+ kActionGameState5,
+ kActionGameState6,
+ kActionGameState7,
+ kActionGameState8,
+ kActionGameState9,
+ kActionGameState10,
+ kActionScrollUpSaves,
+ kActionScrollDownSaves,
+ kActionPerformSaveLoad,
+ kActionCancelSaveLoad
+};
+
+enum MenuMode {
+ kMenuSettingsMode = 0,
+ kMenuLoadStateMode,
+ kMenuSaveStateMode
+};
+
+enum ButtonFlags {
+ kButtonBorder = 1 << 0,
+ kButtonText = 1 << 1,
+ kButtonArrow = 1 << 2
};
+struct Button {
+ int x, y;
+ int w, h;
+ ActionId action;
+ int data;
+ uint8 flags;
+};
+
+struct MenuData {
+ MenuMode mode;
+ Button *buttonsTable;
+ uint buttonsCount;
+ bool quit;
+ bool exit;
+ char saveLoadDescriptionsTable[kMaxSaveStates][33];
+
+ void removeLastCharFromDescription(int slot) {
+ char *description = saveLoadDescriptionsTable[slot];
+ int descriptionLen = strlen(description);
+ if (descriptionLen > 0) {
+ --descriptionLen;
+ description[descriptionLen] = 0;
+ }
+ }
+
+ void addCharToDescription(int slot, char chr) {
+ char *description = saveLoadDescriptionsTable[slot];
+ int descriptionLen = strlen(description);
+ if (descriptionLen < 32 && Common::isPrint(chr)) {
+ description[descriptionLen] = chr;
+ description[descriptionLen + 1] = 0;
+ }
+ }
+
+ const Button *findButtonUnderCursor(int cursorX, int cursorY) const {
+ for (uint i = 0; i < buttonsCount; ++i) {
+ const Button *button = &buttonsTable[i];
+ if (cursorX >= button->x && cursorX < button->x + button->w &&
+ cursorY >= button->y && cursorY < button->y + button->h) {
+ return button;
+ }
+ }
+ return 0;
+ }
+};
+
+
+void readGameStateDescription(Common::ReadStream *f, char *description, int len);
+Common::String generateGameStateFileName(const char *target, int slot, bool prefixOnly = false);
+int getGameStateFileSlot(const char *filename);
+
class MidiPlayer;
class ToucheEngine: public Engine {
@@ -631,9 +723,9 @@ protected:
void res_loadSpeechSegment(int num);
void res_stopSpeech();
- void drawButton(void *button);
- void redrawMenu(void *menu);
- void handleMenuAction(void *menu, int actionId);
+ void drawButton(Button *button);
+ void redrawMenu(MenuData *menu);
+ void handleMenuAction(MenuData *menu, int actionId);
void handleOptions(int forceDisplay);
void drawActionsPanel(int dstX, int dstY, int deltaX, int deltaY);
void drawConversationPanelBorder(int dstY, int srcX, int srcY);
diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp
index 5a520b0e89..b647807f8a 100644
--- a/engines/tsage/debugger.cpp
+++ b/engines/tsage/debugger.cpp
@@ -30,19 +30,19 @@
namespace TsAGE {
Debugger::Debugger() : GUI::Debugger() {
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("scene", WRAP_METHOD(Debugger, Cmd_Scene));
- DCmd_Register("walk_regions", WRAP_METHOD(Debugger, Cmd_WalkRegions));
- DCmd_Register("priority_regions", WRAP_METHOD(Debugger, Cmd_PriorityRegions));
- DCmd_Register("scene_regions", WRAP_METHOD(Debugger, Cmd_SceneRegions));
- DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag));
- DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag));
- DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag));
- DCmd_Register("listobjects", WRAP_METHOD(Debugger, Cmd_ListObjects));
- DCmd_Register("moveobject", WRAP_METHOD(Debugger, Cmd_MoveObject));
- DCmd_Register("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots));
- DCmd_Register("sound", WRAP_METHOD(Debugger, Cmd_Sound));
- DCmd_Register("setdebug", WRAP_METHOD(Debugger, Cmd_SetDebug));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("scene", WRAP_METHOD(Debugger, Cmd_Scene));
+ registerCmd("walk_regions", WRAP_METHOD(Debugger, Cmd_WalkRegions));
+ registerCmd("priority_regions", WRAP_METHOD(Debugger, Cmd_PriorityRegions));
+ registerCmd("scene_regions", WRAP_METHOD(Debugger, Cmd_SceneRegions));
+ registerCmd("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag));
+ registerCmd("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag));
+ registerCmd("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag));
+ registerCmd("listobjects", WRAP_METHOD(Debugger, Cmd_ListObjects));
+ registerCmd("moveobject", WRAP_METHOD(Debugger, Cmd_MoveObject));
+ registerCmd("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots));
+ registerCmd("sound", WRAP_METHOD(Debugger, Cmd_Sound));
+ registerCmd("setdebug", WRAP_METHOD(Debugger, Cmd_SetDebug));
}
static int strToInt(const char *s) {
@@ -66,7 +66,7 @@ static int strToInt(const char *s) {
*/
bool Debugger::Cmd_Scene(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Usage: %s <scene number> [prior scene #]\n", argv[0]);
+ debugPrintf("Usage: %s <scene number> [prior scene #]\n", argv[0]);
return true;
}
@@ -82,7 +82,7 @@ bool Debugger::Cmd_Scene(int argc, const char **argv) {
*/
bool Debugger::Cmd_WalkRegions(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
@@ -120,8 +120,8 @@ bool Debugger::Cmd_WalkRegions(int argc, const char **argv) {
// Mark the scene as requiring a full redraw
g_globals->_paneRefreshFlag[0] = 2;
- DebugPrintf("Total regions = %d\n", g_globals->_walkRegions._regionList.size());
- DebugPrintf("%s\n", regionsDesc.c_str());
+ debugPrintf("Total regions = %d\n", g_globals->_walkRegions._regionList.size());
+ debugPrintf("%s\n", regionsDesc.c_str());
return false;
}
@@ -172,8 +172,8 @@ bool Debugger::Cmd_PriorityRegions(int argc, const char **argv) {
// Mark the scene as requiring a full redraw
g_globals->_paneRefreshFlag[0] = 2;
- DebugPrintf("Total regions = %d\n", count);
- DebugPrintf("%s", regionsDesc.c_str());
+ debugPrintf("Total regions = %d\n", count);
+ debugPrintf("%s", regionsDesc.c_str());
return true;
}
@@ -225,8 +225,8 @@ bool Debugger::Cmd_SceneRegions(int argc, const char **argv) {
// Mark the scene as requiring a full redraw
g_globals->_paneRefreshFlag[0] = 2;
- DebugPrintf("Total regions = %d\n", count);
- DebugPrintf("%s", regionsDesc.c_str());
+ debugPrintf("Total regions = %d\n", count);
+ debugPrintf("%s", regionsDesc.c_str());
return true;
}
@@ -237,7 +237,7 @@ bool Debugger::Cmd_SceneRegions(int argc, const char **argv) {
bool Debugger::Cmd_SetFlag(int argc, const char **argv) {
// Check for a flag to set
if (argc != 2) {
- DebugPrintf("Usage: %s <flag number>\n", argv[0]);
+ debugPrintf("Usage: %s <flag number>\n", argv[0]);
return true;
}
@@ -252,12 +252,12 @@ bool Debugger::Cmd_SetFlag(int argc, const char **argv) {
bool Debugger::Cmd_GetFlag(int argc, const char **argv) {
// Check for an flag to display
if (argc != 2) {
- DebugPrintf("Usage: %s <flag number>\n", argv[0]);
+ debugPrintf("Usage: %s <flag number>\n", argv[0]);
return true;
}
int flagNum = strToInt(argv[1]);
- DebugPrintf("Value: %d\n", g_globals->getFlag(flagNum));
+ debugPrintf("Value: %d\n", g_globals->getFlag(flagNum));
return true;
}
@@ -267,7 +267,7 @@ bool Debugger::Cmd_GetFlag(int argc, const char **argv) {
bool Debugger::Cmd_ClearFlag(int argc, const char **argv) {
// Check for a flag to clear
if (argc != 2) {
- DebugPrintf("Usage: %s <flag number>\n", argv[0]);
+ debugPrintf("Usage: %s <flag number>\n", argv[0]);
return true;
}
@@ -332,7 +332,7 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
*/
bool Debugger::Cmd_Sound(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Usage: %s <sound number>\n", argv[0]);
+ debugPrintf("Usage: %s <sound number>\n", argv[0]);
return true;
}
@@ -345,7 +345,7 @@ bool Debugger::Cmd_Sound(int argc, const char **argv) {
* Activate internal debugger, when available
*/
bool Debugger::Cmd_SetDebug(int argc, const char **argv) {
- DebugPrintf("Not available in this game\n");
+ debugPrintf("Not available in this game\n");
return true;
}
@@ -353,12 +353,12 @@ bool Debugger::Cmd_SetDebug(int argc, const char **argv) {
* This command lists the objects available, and their ID
*/
bool DemoDebugger::Cmd_ListObjects(int argc, const char **argv) {
- DebugPrintf("Not available in Demo\n");
+ debugPrintf("Not available in Demo\n");
return true;
}
bool DemoDebugger::Cmd_MoveObject(int argc, const char **argv) {
- DebugPrintf("Not available in Demo\n");
+ debugPrintf("Not available in Demo\n");
return true;
}
@@ -367,44 +367,44 @@ bool DemoDebugger::Cmd_MoveObject(int argc, const char **argv) {
*/
bool RingworldDebugger::Cmd_ListObjects(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
- DebugPrintf("Available objects for this game are:\n");
- DebugPrintf("0 - Stunner\n");
- DebugPrintf("1 - Scanner\n");
- DebugPrintf("2 - Stasis Box\n");
- DebugPrintf("3 - Info Disk\n");
- DebugPrintf("4 - Stasis Negator\n");
- DebugPrintf("5 - Key Device\n");
- DebugPrintf("6 - Medkit\n");
- DebugPrintf("7 - Ladder\n");
- DebugPrintf("8 - Rope\n");
- DebugPrintf("9 - Key\n");
- DebugPrintf("10 - Translator\n");
- DebugPrintf("11 - Ale\n");
- DebugPrintf("12 - Paper\n");
- DebugPrintf("13 - Waldos\n");
- DebugPrintf("14 - Stasis Box 2\n");
- DebugPrintf("15 - Ring\n");
- DebugPrintf("16 - Cloak\n");
- DebugPrintf("17 - Tunic\n");
- DebugPrintf("18 - Candle\n");
- DebugPrintf("19 - Straw\n");
- DebugPrintf("20 - Scimitar\n");
- DebugPrintf("21 - Sword\n");
- DebugPrintf("22 - Helmet\n");
- DebugPrintf("23 - Items\n");
- DebugPrintf("24 - Concentrator\n");
- DebugPrintf("25 - Nullifier\n");
- DebugPrintf("26 - Peg\n");
- DebugPrintf("27 - Vial\n");
- DebugPrintf("28 - Jacket\n");
- DebugPrintf("29 - Tunic 2\n");
- DebugPrintf("30 - Bone\n");
- DebugPrintf("31 - Empty Jar\n");
- DebugPrintf("32 - Jar\n");
+ debugPrintf("Available objects for this game are:\n");
+ debugPrintf("0 - Stunner\n");
+ debugPrintf("1 - Scanner\n");
+ debugPrintf("2 - Stasis Box\n");
+ debugPrintf("3 - Info Disk\n");
+ debugPrintf("4 - Stasis Negator\n");
+ debugPrintf("5 - Key Device\n");
+ debugPrintf("6 - Medkit\n");
+ debugPrintf("7 - Ladder\n");
+ debugPrintf("8 - Rope\n");
+ debugPrintf("9 - Key\n");
+ debugPrintf("10 - Translator\n");
+ debugPrintf("11 - Ale\n");
+ debugPrintf("12 - Paper\n");
+ debugPrintf("13 - Waldos\n");
+ debugPrintf("14 - Stasis Box 2\n");
+ debugPrintf("15 - Ring\n");
+ debugPrintf("16 - Cloak\n");
+ debugPrintf("17 - Tunic\n");
+ debugPrintf("18 - Candle\n");
+ debugPrintf("19 - Straw\n");
+ debugPrintf("20 - Scimitar\n");
+ debugPrintf("21 - Sword\n");
+ debugPrintf("22 - Helmet\n");
+ debugPrintf("23 - Items\n");
+ debugPrintf("24 - Concentrator\n");
+ debugPrintf("25 - Nullifier\n");
+ debugPrintf("26 - Peg\n");
+ debugPrintf("27 - Vial\n");
+ debugPrintf("28 - Jacket\n");
+ debugPrintf("29 - Tunic 2\n");
+ debugPrintf("30 - Bone\n");
+ debugPrintf("31 - Empty Jar\n");
+ debugPrintf("32 - Jar\n");
return true;
}
@@ -414,8 +414,8 @@ bool RingworldDebugger::Cmd_ListObjects(int argc, const char **argv) {
bool RingworldDebugger::Cmd_MoveObject(int argc, const char **argv) {
// Check for a flag to clear
if ((argc < 2) || (argc > 3)){
- DebugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
- DebugPrintf("If no scene is specified, the object will be added to inventory\n");
+ debugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
+ debugPrintf("If no scene is specified, the object will be added to inventory\n");
return true;
}
@@ -525,7 +525,7 @@ bool RingworldDebugger::Cmd_MoveObject(int argc, const char **argv) {
RING_INVENTORY._jar._sceneNumber = sceneNum;
break;
default:
- DebugPrintf("Invalid object Id %s\n", argv[1]);
+ debugPrintf("Invalid object Id %s\n", argv[1]);
break;
}
@@ -537,83 +537,83 @@ bool RingworldDebugger::Cmd_MoveObject(int argc, const char **argv) {
*/
bool BlueForceDebugger::Cmd_ListObjects(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
- DebugPrintf("Available objects for this game are:\n");
- DebugPrintf("1 - INV_COLT45\n");
- DebugPrintf("2 - INV_AMMO_CLIP\n");
- DebugPrintf("3 - INV_SPARE_CLIP\n");
- DebugPrintf("4 - INV_HANDCUFFS\n");
- DebugPrintf("5 - INV_GREENS_GUN\n");
- DebugPrintf("6 - INV_TICKET_BOOK\n");
- DebugPrintf("7 - INV_MIRANDA_CARD\n");
- DebugPrintf("8 - INV_FOREST_RAP\n");
- DebugPrintf("9 - INV_GREEN_ID\n");
- DebugPrintf("10 - INV_BASEBALL_CARD\n");
- DebugPrintf("11 - INV_BOOKING_GREEN\n");
- DebugPrintf("12 - INV_FLARE\n");
- DebugPrintf("13 - INV_COBB_RAP\n");
- DebugPrintf("14 - INV_22_BULLET\n");
- DebugPrintf("15 - INV_AUTO_RIFLE\n");
- DebugPrintf("16 - INV_WIG\n");
- DebugPrintf("17 - INV_FRANKIE_ID\n");
- DebugPrintf("18 - INV_TYRONE_ID\n");
- DebugPrintf("19 - INV_22_SNUB\n");
- DebugPrintf("20 - INV_BOOKING_FRANKIE\n");
- DebugPrintf("21 - INV_BOOKING_GANG\n");
- DebugPrintf("22 - INV_FBI_TELETYPE\n");
- DebugPrintf("23 - INV_DA_NOTE\n");
- DebugPrintf("24 - INV_PRINT_OUT\n");
- DebugPrintf("25 - INV_WAREHOUSE_KEYS\n");
- DebugPrintf("26 - INV_CENTER_PUNCH\n");
- DebugPrintf("27 - INV_TRANQ_GUN\n");
- DebugPrintf("28 - INV_HOOK\n");
- DebugPrintf("29 - INV_RAGS\n");
- DebugPrintf("30 - INV_JAR\n");
- DebugPrintf("31 - INV_SCREWDRIVER\n");
- DebugPrintf("32 - INV_D_FLOPPY\n");
- DebugPrintf("33 - INV_BLANK_DISK\n");
- DebugPrintf("34 - INV_STICK\n");
- DebugPrintf("35 - INV_CRATE1\n");
- DebugPrintf("36 - INV_CRATE2\n");
- DebugPrintf("37 - INV_SHOEBOX\n");
- DebugPrintf("38 - INV_BADGE\n");
- DebugPrintf("39 - INV_RENTAL_COUPON\n");
- DebugPrintf("40 - INV_NICKEL\n");
- DebugPrintf("41 - INV_LYLE_CARD\n");
- DebugPrintf("42 - INV_CARTER_NOTE\n");
- DebugPrintf("43 - INV_MUG_SHOT\n");
- DebugPrintf("44 - INV_CLIPPING\n");
- DebugPrintf("45 - INV_MICROFILM \n");
- DebugPrintf("46 - INV_WAVE_KEYS\n");
- DebugPrintf("47 - INV_RENTAL_KEYS\n");
- DebugPrintf("48 - INV_NAPKIN\n");
- DebugPrintf("49 - INV_DMV_PRINTOUT\n");
- DebugPrintf("50 - INV_FISHING_NET\n");
- DebugPrintf("51 - INV_ID\n");
- DebugPrintf("52 - INV_9MM_BULLETS\n");
- DebugPrintf("53 - INV_SCHEDULE\n");
- DebugPrintf("54 - INV_GRENADES\n");
- DebugPrintf("55 - INV_YELLOW_CORD\n");
- DebugPrintf("56 - INV_HALF_YELLOW_CORD\n");
- DebugPrintf("57 - INV_BLACK_CORD\n");
- DebugPrintf("58 - INV_HALF_BLACK_CORD\n");
- DebugPrintf("59 - INV_WARRANT\n");
- DebugPrintf("60 - INV_JACKET\n");
- DebugPrintf("61 - INV_GREENS_KNIFE\n");
- DebugPrintf("62 - INV_DOG_WHISTLE\n");
- DebugPrintf("63 - INV_AMMO_BELT\n");
- DebugPrintf("64 - INV_CARAVAN_KEY\n");
+ debugPrintf("Available objects for this game are:\n");
+ debugPrintf("1 - INV_COLT45\n");
+ debugPrintf("2 - INV_AMMO_CLIP\n");
+ debugPrintf("3 - INV_SPARE_CLIP\n");
+ debugPrintf("4 - INV_HANDCUFFS\n");
+ debugPrintf("5 - INV_GREENS_GUN\n");
+ debugPrintf("6 - INV_TICKET_BOOK\n");
+ debugPrintf("7 - INV_MIRANDA_CARD\n");
+ debugPrintf("8 - INV_FOREST_RAP\n");
+ debugPrintf("9 - INV_GREEN_ID\n");
+ debugPrintf("10 - INV_BASEBALL_CARD\n");
+ debugPrintf("11 - INV_BOOKING_GREEN\n");
+ debugPrintf("12 - INV_FLARE\n");
+ debugPrintf("13 - INV_COBB_RAP\n");
+ debugPrintf("14 - INV_22_BULLET\n");
+ debugPrintf("15 - INV_AUTO_RIFLE\n");
+ debugPrintf("16 - INV_WIG\n");
+ debugPrintf("17 - INV_FRANKIE_ID\n");
+ debugPrintf("18 - INV_TYRONE_ID\n");
+ debugPrintf("19 - INV_22_SNUB\n");
+ debugPrintf("20 - INV_BOOKING_FRANKIE\n");
+ debugPrintf("21 - INV_BOOKING_GANG\n");
+ debugPrintf("22 - INV_FBI_TELETYPE\n");
+ debugPrintf("23 - INV_DA_NOTE\n");
+ debugPrintf("24 - INV_PRINT_OUT\n");
+ debugPrintf("25 - INV_WAREHOUSE_KEYS\n");
+ debugPrintf("26 - INV_CENTER_PUNCH\n");
+ debugPrintf("27 - INV_TRANQ_GUN\n");
+ debugPrintf("28 - INV_HOOK\n");
+ debugPrintf("29 - INV_RAGS\n");
+ debugPrintf("30 - INV_JAR\n");
+ debugPrintf("31 - INV_SCREWDRIVER\n");
+ debugPrintf("32 - INV_D_FLOPPY\n");
+ debugPrintf("33 - INV_BLANK_DISK\n");
+ debugPrintf("34 - INV_STICK\n");
+ debugPrintf("35 - INV_CRATE1\n");
+ debugPrintf("36 - INV_CRATE2\n");
+ debugPrintf("37 - INV_SHOEBOX\n");
+ debugPrintf("38 - INV_BADGE\n");
+ debugPrintf("39 - INV_RENTAL_COUPON\n");
+ debugPrintf("40 - INV_NICKEL\n");
+ debugPrintf("41 - INV_LYLE_CARD\n");
+ debugPrintf("42 - INV_CARTER_NOTE\n");
+ debugPrintf("43 - INV_MUG_SHOT\n");
+ debugPrintf("44 - INV_CLIPPING\n");
+ debugPrintf("45 - INV_MICROFILM \n");
+ debugPrintf("46 - INV_WAVE_KEYS\n");
+ debugPrintf("47 - INV_RENTAL_KEYS\n");
+ debugPrintf("48 - INV_NAPKIN\n");
+ debugPrintf("49 - INV_DMV_PRINTOUT\n");
+ debugPrintf("50 - INV_FISHING_NET\n");
+ debugPrintf("51 - INV_ID\n");
+ debugPrintf("52 - INV_9MM_BULLETS\n");
+ debugPrintf("53 - INV_SCHEDULE\n");
+ debugPrintf("54 - INV_GRENADES\n");
+ debugPrintf("55 - INV_YELLOW_CORD\n");
+ debugPrintf("56 - INV_HALF_YELLOW_CORD\n");
+ debugPrintf("57 - INV_BLACK_CORD\n");
+ debugPrintf("58 - INV_HALF_BLACK_CORD\n");
+ debugPrintf("59 - INV_WARRANT\n");
+ debugPrintf("60 - INV_JACKET\n");
+ debugPrintf("61 - INV_GREENS_KNIFE\n");
+ debugPrintf("62 - INV_DOG_WHISTLE\n");
+ debugPrintf("63 - INV_AMMO_BELT\n");
+ debugPrintf("64 - INV_CARAVAN_KEY\n");
return true;
}
bool BlueForceDebugger::Cmd_MoveObject(int argc, const char **argv) {
// Check for a flag to clear
if ((argc < 2) || (argc > 3)){
- DebugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
- DebugPrintf("If no scene is specified, the object will be added to inventory\n");
+ debugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
+ debugPrintf("If no scene is specified, the object will be added to inventory\n");
return true;
}
@@ -625,7 +625,7 @@ bool BlueForceDebugger::Cmd_MoveObject(int argc, const char **argv) {
if ((objNum > 0) && (objNum < 65))
BF_INVENTORY.setObjectScene(objNum, sceneNum);
else
- DebugPrintf("Invalid object Id %s\n", argv[1]);
+ debugPrintf("Invalid object Id %s\n", argv[1]);
return true;
}
@@ -635,63 +635,63 @@ bool BlueForceDebugger::Cmd_MoveObject(int argc, const char **argv) {
*/
bool Ringworld2Debugger::Cmd_ListObjects(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
- DebugPrintf("Available objects for this game are:\n");
- DebugPrintf("1 - Scene %d - R2_OPTO_DISK\n", BF_INVENTORY.getObjectScene(1));
- DebugPrintf("2 - Scene %d - R2_READER\n", BF_INVENTORY.getObjectScene(2));
- DebugPrintf("3 - Scene %d - R2_NEGATOR_GUN\n", BF_INVENTORY.getObjectScene(3));
- DebugPrintf("4 - Scene %d - R2_STEPPING_DISKS\n", BF_INVENTORY.getObjectScene(4));
- DebugPrintf("5 - Scene %d - R2_ATTRACTOR_UNIT\n", BF_INVENTORY.getObjectScene(5));
- DebugPrintf("6 - Scene %d - R2_SENSOR_PROBE\n", BF_INVENTORY.getObjectScene(6));
- DebugPrintf("7 - Scene %d - R2_SONIC_STUNNER\n", BF_INVENTORY.getObjectScene(7));
- DebugPrintf("8 - Scene %d - R2_CABLE_HARNESS\n", BF_INVENTORY.getObjectScene(8));
- DebugPrintf("9 - Scene %d - R2_COM_SCANNER\n", BF_INVENTORY.getObjectScene(9));
- DebugPrintf("10 - Scene %d - R2_SPENT_POWER_CAPSULE\n", BF_INVENTORY.getObjectScene(10));
- DebugPrintf("11 - Scene %d - R2_CHARGED_POWER_CAPSULE\n", BF_INVENTORY.getObjectScene(11));
- DebugPrintf("12 - Scene %d - R2_AEROSOL\n", BF_INVENTORY.getObjectScene(12));
- DebugPrintf("13 - Scene %d - R2_REMOTE_CONTROL\n", BF_INVENTORY.getObjectScene(13));
- DebugPrintf("14 - Scene %d - R2_OPTICAL_FIBER\n", BF_INVENTORY.getObjectScene(14));
- DebugPrintf("15 - Scene %d - R2_CLAMP\n", BF_INVENTORY.getObjectScene(15));
- DebugPrintf("16 - Scene %d - R2_ATTRACTOR_CABLE_HARNESS\n", BF_INVENTORY.getObjectScene(16));
- DebugPrintf("17 - Scene %d - R2_FUEL_CELL\n", BF_INVENTORY.getObjectScene(17));
- DebugPrintf("18 - Scene %d - R2_GYROSCOPE\n", BF_INVENTORY.getObjectScene(18));
- DebugPrintf("19 - Scene %d - R2_AIRBAG\n", BF_INVENTORY.getObjectScene(19));
- DebugPrintf("20 - Scene %d - R2_REBREATHER_TANK\n", BF_INVENTORY.getObjectScene(20));
- DebugPrintf("21 - Scene %d - R2_RESERVE_REBREATHER_TANK\n", BF_INVENTORY.getObjectScene(21));
- DebugPrintf("22 - Scene %d - R2_GUIDANCE_MODULE\n", BF_INVENTORY.getObjectScene(22));
- DebugPrintf("23 - Scene %d - R2_THRUSTER_VALVE\n", BF_INVENTORY.getObjectScene(23));
- DebugPrintf("24 - Scene %d - R2_BALLOON_BACKPACK\n", BF_INVENTORY.getObjectScene(24));
- DebugPrintf("25 - Scene %d - R2_RADAR_MECHANISM\n", BF_INVENTORY.getObjectScene(25));
- DebugPrintf("26 - Scene %d - R2_JOYSTICK\n", BF_INVENTORY.getObjectScene(26));
- DebugPrintf("27 - Scene %d - R2_IGNITOR\n", BF_INVENTORY.getObjectScene(27));
- DebugPrintf("28 - Scene %d - R2_DIAGNOSTICS_DISPLAY\n", BF_INVENTORY.getObjectScene(28));
- DebugPrintf("29 - Scene %d - R2_GLASS_DOME\n", BF_INVENTORY.getObjectScene(29));
- DebugPrintf("30 - Scene %d - R2_WICK_LAMP\n", BF_INVENTORY.getObjectScene(30));
- DebugPrintf("31 - Scene %d - R2_SCRITH_KEY\n", BF_INVENTORY.getObjectScene(31));
- DebugPrintf("32 - Scene %d - R2_TANNER_MASK\n", BF_INVENTORY.getObjectScene(32));
- DebugPrintf("33 - Scene %d - R2_PURE_GRAIN_ALCOHOL\n", BF_INVENTORY.getObjectScene(33));
- DebugPrintf("34 - Scene %d - R2_SAPPHIRE_BLUE\n", BF_INVENTORY.getObjectScene(34));
- DebugPrintf("35 - Scene %d - R2_ANCIENT_SCROLLS\n", BF_INVENTORY.getObjectScene(35));
- DebugPrintf("36 - Scene %d - R2_FLUTE\n", BF_INVENTORY.getObjectScene(36));
- DebugPrintf("37 - Scene %d - R2_GUNPOWDER\n", BF_INVENTORY.getObjectScene(37));
- DebugPrintf("38 - Scene %d - R2_NONAME\n", BF_INVENTORY.getObjectScene(38));
- DebugPrintf("39 - Scene %d - R2_COM_SCANNER_2\n", BF_INVENTORY.getObjectScene(39));
- DebugPrintf("40 - Scene %d - R2_SUPERCONDUCTOR_WIRE\n", BF_INVENTORY.getObjectScene(40));
- DebugPrintf("41 - Scene %d - R2_PILLOW\n", BF_INVENTORY.getObjectScene(41));
- DebugPrintf("42 - Scene %d - R2_FOOD_TRAY\n", BF_INVENTORY.getObjectScene(42));
- DebugPrintf("43 - Scene %d - R2_LASER_HACKSAW\n", BF_INVENTORY.getObjectScene(43));
- DebugPrintf("44 - Scene %d - R2_PHOTON_STUNNER\n", BF_INVENTORY.getObjectScene(44));
- DebugPrintf("45 - Scene %d - R2_BATTERY\n", BF_INVENTORY.getObjectScene(45));
- DebugPrintf("46 - Scene %d - R2_SOAKED_FACEMASK\n", BF_INVENTORY.getObjectScene(46));
- DebugPrintf("47 - Scene %d - R2_LIGHT_BULB\n", BF_INVENTORY.getObjectScene(47));
- DebugPrintf("48 - Scene %d - R2_ALCOHOL_LAMP\n", BF_INVENTORY.getObjectScene(48));
- DebugPrintf("49 - Scene %d - R2_ALCOHOL_LAMP_2\n", BF_INVENTORY.getObjectScene(49));
- DebugPrintf("50 - Scene %d - R2_ALCOHOL_LAMP_3\n", BF_INVENTORY.getObjectScene(50));
- DebugPrintf("51 - Scene %d - R2_BROKEN_DISPLAY\n", BF_INVENTORY.getObjectScene(51));
- DebugPrintf("52 - Scene %d - R2_TOOLBOX\n", BF_INVENTORY.getObjectScene(52));
+ debugPrintf("Available objects for this game are:\n");
+ debugPrintf("1 - Scene %d - R2_OPTO_DISK\n", BF_INVENTORY.getObjectScene(1));
+ debugPrintf("2 - Scene %d - R2_READER\n", BF_INVENTORY.getObjectScene(2));
+ debugPrintf("3 - Scene %d - R2_NEGATOR_GUN\n", BF_INVENTORY.getObjectScene(3));
+ debugPrintf("4 - Scene %d - R2_STEPPING_DISKS\n", BF_INVENTORY.getObjectScene(4));
+ debugPrintf("5 - Scene %d - R2_ATTRACTOR_UNIT\n", BF_INVENTORY.getObjectScene(5));
+ debugPrintf("6 - Scene %d - R2_SENSOR_PROBE\n", BF_INVENTORY.getObjectScene(6));
+ debugPrintf("7 - Scene %d - R2_SONIC_STUNNER\n", BF_INVENTORY.getObjectScene(7));
+ debugPrintf("8 - Scene %d - R2_CABLE_HARNESS\n", BF_INVENTORY.getObjectScene(8));
+ debugPrintf("9 - Scene %d - R2_COM_SCANNER\n", BF_INVENTORY.getObjectScene(9));
+ debugPrintf("10 - Scene %d - R2_SPENT_POWER_CAPSULE\n", BF_INVENTORY.getObjectScene(10));
+ debugPrintf("11 - Scene %d - R2_CHARGED_POWER_CAPSULE\n", BF_INVENTORY.getObjectScene(11));
+ debugPrintf("12 - Scene %d - R2_AEROSOL\n", BF_INVENTORY.getObjectScene(12));
+ debugPrintf("13 - Scene %d - R2_REMOTE_CONTROL\n", BF_INVENTORY.getObjectScene(13));
+ debugPrintf("14 - Scene %d - R2_OPTICAL_FIBER\n", BF_INVENTORY.getObjectScene(14));
+ debugPrintf("15 - Scene %d - R2_CLAMP\n", BF_INVENTORY.getObjectScene(15));
+ debugPrintf("16 - Scene %d - R2_ATTRACTOR_CABLE_HARNESS\n", BF_INVENTORY.getObjectScene(16));
+ debugPrintf("17 - Scene %d - R2_FUEL_CELL\n", BF_INVENTORY.getObjectScene(17));
+ debugPrintf("18 - Scene %d - R2_GYROSCOPE\n", BF_INVENTORY.getObjectScene(18));
+ debugPrintf("19 - Scene %d - R2_AIRBAG\n", BF_INVENTORY.getObjectScene(19));
+ debugPrintf("20 - Scene %d - R2_REBREATHER_TANK\n", BF_INVENTORY.getObjectScene(20));
+ debugPrintf("21 - Scene %d - R2_RESERVE_REBREATHER_TANK\n", BF_INVENTORY.getObjectScene(21));
+ debugPrintf("22 - Scene %d - R2_GUIDANCE_MODULE\n", BF_INVENTORY.getObjectScene(22));
+ debugPrintf("23 - Scene %d - R2_THRUSTER_VALVE\n", BF_INVENTORY.getObjectScene(23));
+ debugPrintf("24 - Scene %d - R2_BALLOON_BACKPACK\n", BF_INVENTORY.getObjectScene(24));
+ debugPrintf("25 - Scene %d - R2_RADAR_MECHANISM\n", BF_INVENTORY.getObjectScene(25));
+ debugPrintf("26 - Scene %d - R2_JOYSTICK\n", BF_INVENTORY.getObjectScene(26));
+ debugPrintf("27 - Scene %d - R2_IGNITOR\n", BF_INVENTORY.getObjectScene(27));
+ debugPrintf("28 - Scene %d - R2_DIAGNOSTICS_DISPLAY\n", BF_INVENTORY.getObjectScene(28));
+ debugPrintf("29 - Scene %d - R2_GLASS_DOME\n", BF_INVENTORY.getObjectScene(29));
+ debugPrintf("30 - Scene %d - R2_WICK_LAMP\n", BF_INVENTORY.getObjectScene(30));
+ debugPrintf("31 - Scene %d - R2_SCRITH_KEY\n", BF_INVENTORY.getObjectScene(31));
+ debugPrintf("32 - Scene %d - R2_TANNER_MASK\n", BF_INVENTORY.getObjectScene(32));
+ debugPrintf("33 - Scene %d - R2_PURE_GRAIN_ALCOHOL\n", BF_INVENTORY.getObjectScene(33));
+ debugPrintf("34 - Scene %d - R2_SAPPHIRE_BLUE\n", BF_INVENTORY.getObjectScene(34));
+ debugPrintf("35 - Scene %d - R2_ANCIENT_SCROLLS\n", BF_INVENTORY.getObjectScene(35));
+ debugPrintf("36 - Scene %d - R2_FLUTE\n", BF_INVENTORY.getObjectScene(36));
+ debugPrintf("37 - Scene %d - R2_GUNPOWDER\n", BF_INVENTORY.getObjectScene(37));
+ debugPrintf("38 - Scene %d - R2_NONAME\n", BF_INVENTORY.getObjectScene(38));
+ debugPrintf("39 - Scene %d - R2_COM_SCANNER_2\n", BF_INVENTORY.getObjectScene(39));
+ debugPrintf("40 - Scene %d - R2_SUPERCONDUCTOR_WIRE\n", BF_INVENTORY.getObjectScene(40));
+ debugPrintf("41 - Scene %d - R2_PILLOW\n", BF_INVENTORY.getObjectScene(41));
+ debugPrintf("42 - Scene %d - R2_FOOD_TRAY\n", BF_INVENTORY.getObjectScene(42));
+ debugPrintf("43 - Scene %d - R2_LASER_HACKSAW\n", BF_INVENTORY.getObjectScene(43));
+ debugPrintf("44 - Scene %d - R2_PHOTON_STUNNER\n", BF_INVENTORY.getObjectScene(44));
+ debugPrintf("45 - Scene %d - R2_BATTERY\n", BF_INVENTORY.getObjectScene(45));
+ debugPrintf("46 - Scene %d - R2_SOAKED_FACEMASK\n", BF_INVENTORY.getObjectScene(46));
+ debugPrintf("47 - Scene %d - R2_LIGHT_BULB\n", BF_INVENTORY.getObjectScene(47));
+ debugPrintf("48 - Scene %d - R2_ALCOHOL_LAMP\n", BF_INVENTORY.getObjectScene(48));
+ debugPrintf("49 - Scene %d - R2_ALCOHOL_LAMP_2\n", BF_INVENTORY.getObjectScene(49));
+ debugPrintf("50 - Scene %d - R2_ALCOHOL_LAMP_3\n", BF_INVENTORY.getObjectScene(50));
+ debugPrintf("51 - Scene %d - R2_BROKEN_DISPLAY\n", BF_INVENTORY.getObjectScene(51));
+ debugPrintf("52 - Scene %d - R2_TOOLBOX\n", BF_INVENTORY.getObjectScene(52));
return true;
}
@@ -699,8 +699,8 @@ bool Ringworld2Debugger::Cmd_ListObjects(int argc, const char **argv) {
bool Ringworld2Debugger::Cmd_MoveObject(int argc, const char **argv) {
// Check for a flag to clear
if ((argc < 2) || (argc > 3)){
- DebugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
- DebugPrintf("If no scene is specified, the object will be added to inventory\n");
+ debugPrintf("Usage: %s <object number> [<scene number>]\n", argv[0]);
+ debugPrintf("If no scene is specified, the object will be added to inventory\n");
return true;
}
@@ -712,7 +712,7 @@ bool Ringworld2Debugger::Cmd_MoveObject(int argc, const char **argv) {
if ((objNum > 0) && (objNum < 53))
R2_INVENTORY.setObjectScene(objNum, sceneNum);
else
- DebugPrintf("Invalid object Id %s\n", argv[1]);
+ debugPrintf("Invalid object Id %s\n", argv[1]);
return true;
}
@@ -722,7 +722,7 @@ bool Ringworld2Debugger::Cmd_MoveObject(int argc, const char **argv) {
*/
bool Ringworld2Debugger::Cmd_SetDebug(int argc, const char **argv) {
if (argc != 1) {
- DebugPrintf("Usage: %s\n", argv[0]);
+ debugPrintf("Usage: %s\n", argv[0]);
return true;
}
diff --git a/engines/tucker/resource.cpp b/engines/tucker/resource.cpp
index 5f06334720..9cba7b523d 100644
--- a/engines/tucker/resource.cpp
+++ b/engines/tucker/resource.cpp
@@ -535,7 +535,10 @@ void TuckerEngine::loadObj() {
return;
}
debug(2, "loadObj() partNum %d locationNum %d", _partNum, _locationNum);
- if ((_gameFlags & kGameFlagDemo) == 0) {
+ // If a savegame is loaded from the launcher, skip the display chapter
+ if (_startSlot != -1)
+ _startSlot = -1;
+ else if ((_gameFlags & kGameFlagDemo) == 0) {
handleNewPartSequence();
}
_currentPartNum = _partNum;
@@ -662,15 +665,13 @@ void TuckerEngine::loadData4() {
t.findNextToken(kDataTokenDw);
_gameDebug = t.getNextInteger() != 0;
_displayGameHints = t.getNextInteger() != 0;
- // forces game hints feature
-// _displayGameHints = true;
_locationObjectsCount = 0;
if (t.findIndex(_locationNum)) {
while (t.findNextToken(kDataTokenDw)) {
int i = t.getNextInteger();
- if (i < 0) {
+ if (i < 0)
break;
- }
+
assert(_locationObjectsCount < kLocationObjectsTableSize);
LocationObject *d = &_locationObjectsTable[_locationObjectsCount++];
d->_xPos = i;
@@ -851,60 +852,63 @@ void TuckerEngine::unloadSprC02_01() {
void TuckerEngine::loadFx() {
loadFile("fx.c", _loadTempBuf);
DataTokenizer t(_loadTempBuf, _fileLoadSize);
- t.findIndex(_locationNum);
- t.findNextToken(kDataTokenDw);
- _locationSoundsCount = t.getNextInteger();
- _currentFxSet = 0;
- for (int i = 0; i < _locationSoundsCount; ++i) {
- LocationSound *s = &_locationSoundsTable[i];
- s->_offset = 0;
- s->_num = t.getNextInteger();
- s->_volume = t.getNextInteger();
- s->_type = t.getNextInteger();
- switch (s->_type) {
- case 5:
- _currentFxSet = 1;
- _currentFxIndex = i;
- _currentFxVolume = s->_volume;
- _currentFxDist = t.getNextInteger();
- _currentFxScale = t.getNextInteger();
- break;
- case 6:
- case 7:
- case 8:
- s->_startFxSpriteState = t.getNextInteger();
- s->_startFxSpriteNum = t.getNextInteger();
- s->_updateType = t.getNextInteger();
- if (s->_type == 7) {
- s->_flagNum = t.getNextInteger();
- s->_flagValueStartFx = t.getNextInteger();
- s->_stopFxSpriteState = t.getNextInteger();
- s->_stopFxSpriteNum = t.getNextInteger();
- s->_flagValueStopFx = t.getNextInteger();
+ if (t.findIndex(_locationNum)) {
+ t.findNextToken(kDataTokenDw);
+ _locationSoundsCount = t.getNextInteger();
+ _currentFxSet = 0;
+ for (int i = 0; i < _locationSoundsCount; ++i) {
+ LocationSound *s = &_locationSoundsTable[i];
+ s->_offset = 0;
+ s->_num = t.getNextInteger();
+ s->_volume = t.getNextInteger();
+ s->_type = t.getNextInteger();
+ switch (s->_type) {
+ case 5:
+ _currentFxSet = 1;
+ _currentFxIndex = i;
+ _currentFxVolume = s->_volume;
+ _currentFxDist = t.getNextInteger();
+ _currentFxScale = t.getNextInteger();
+ break;
+ case 6:
+ case 7:
+ case 8:
+ s->_startFxSpriteState = t.getNextInteger();
+ s->_startFxSpriteNum = t.getNextInteger();
+ s->_updateType = t.getNextInteger();
+ if (s->_type == 7) {
+ s->_flagNum = t.getNextInteger();
+ s->_flagValueStartFx = t.getNextInteger();
+ s->_stopFxSpriteState = t.getNextInteger();
+ s->_stopFxSpriteNum = t.getNextInteger();
+ s->_flagValueStopFx = t.getNextInteger();
+ }
+ break;
+ }
+ if (s->_type == 8) {
+ s->_type = 6;
}
- break;
- }
- if (s->_type == 8) {
- s->_type = 6;
}
- }
- t.findNextToken(kDataTokenDw);
- int count = t.getNextInteger();
- _locationMusicsCount = 0;
- for (int i = 0; i < count; ++i) {
- int flagNum = t.getNextInteger();
- int flagValue = t.getNextInteger();
- if (flagValue == _flagsTable[flagNum]) {
- LocationMusic *m = &_locationMusicsTable[_locationMusicsCount++];
- m->_offset = 0;
- m->_num = t.getNextInteger();
- m->_volume = t.getNextInteger();
- m->_flag = t.getNextInteger();
- } else {
- for (int j = 0; j < 3; ++j) {
- t.getNextInteger();
+ t.findNextToken(kDataTokenDw);
+ int count = t.getNextInteger();
+ _locationMusicsCount = 0;
+ for (int i = 0; i < count; ++i) {
+ int flagNum = t.getNextInteger();
+ int flagValue = t.getNextInteger();
+ if (flagValue == _flagsTable[flagNum]) {
+ LocationMusic *m = &_locationMusicsTable[_locationMusicsCount++];
+ m->_offset = 0;
+ m->_num = t.getNextInteger();
+ m->_volume = t.getNextInteger();
+ m->_flag = t.getNextInteger();
+ } else {
+ for (int j = 0; j < 3; ++j) {
+ t.getNextInteger();
+ }
}
}
+ } else {
+ error("loadFx() - Index not found for location %d", _locationNum);
}
}
diff --git a/engines/tucker/sequences.cpp b/engines/tucker/sequences.cpp
index 2fb881f77e..d9f284e443 100644
--- a/engines/tucker/sequences.cpp
+++ b/engines/tucker/sequences.cpp
@@ -40,7 +40,7 @@ void TuckerEngine::handleIntroSequence() {
_player = new AnimationSequencePlayer(_system, _mixer, _eventMan, &_compressedSound, firstSequence);
_player->mainLoop();
delete _player;
- _player = 0;
+ _player = nullptr;
}
void TuckerEngine::handleCreditsSequence() {
@@ -115,7 +115,8 @@ void TuckerEngine::handleCreditsSequence() {
if (counter4 == _creditsSequenceTimecounts[num]) {
_fadePaletteCounter = 0;
clearSprites();
- ++num;
+ if (num < 6)
+ ++num;
Common::String filename;
if (num == 6) {
for (int i = 0; i < 16; ++i) {
@@ -123,6 +124,7 @@ void TuckerEngine::handleCreditsSequence() {
loadImage(filename.c_str(), imgBuf + i * 64000, 2);
}
} else {
+ filename = "";
switch (num) {
case 1:
filename = "loc75.pcx";
@@ -140,7 +142,8 @@ void TuckerEngine::handleCreditsSequence() {
filename = "loc78.pcx";
break;
}
- loadImage(filename.c_str(), _quadBackgroundGfxBuf, 2);
+ if (filename != "")
+ loadImage(filename.c_str(), _quadBackgroundGfxBuf, 2);
}
_spritesCount = _creditsSequenceSpriteCounts[num];
++_flagsTable[236];
diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp
index adf4be6b65..de555cd7b6 100644
--- a/engines/tucker/tucker.cpp
+++ b/engines/tucker/tucker.cpp
@@ -50,6 +50,7 @@ TuckerEngine::TuckerEngine(OSystem *system, Common::Language language, uint32 fl
_currentSaveLoadGameState = 1;
_fileLoadSize = 0;
_csDataSize = 0;
+ _startSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
_player = nullptr;
_loadTempBuf = nullptr;
@@ -91,7 +92,8 @@ Common::Error TuckerEngine::run() {
initGraphics(kScreenWidth, kScreenHeight, false);
syncSoundSettings();
_compressedSound.openFile();
- handleIntroSequence();
+ if (_startSlot == -1)
+ handleIntroSequence();
if ((_gameFlags & kGameFlagIntroOnly) == 0 && !shouldQuit()) {
mainLoop();
}
@@ -604,6 +606,7 @@ void TuckerEngine::mainLoop() {
_flagsTable[236] = 74;
}
}
+
if (_flagsTable[236] > 70) {
handleCreditsSequence();
_quitGame = true;
@@ -890,9 +893,8 @@ void TuckerEngine::updateCharPosition() {
if (action->_testFlag1Num < 500) {
if (action->_testFlag1Num >= 300)
error("updateCharPosition() - Unexpected value for _testFlag1Num : %d", action->_testFlag1Num);
- if (_flagsTable[action->_testFlag1Num] != action->_testFlag1Value) {
+ if (_flagsTable[action->_testFlag1Num] != action->_testFlag1Value)
skip = false;
- }
} else if (_inventoryItemsState[action->_testFlag1Num - 500] != action->_testFlag1Value) {
skip = false;
}
@@ -900,9 +902,10 @@ void TuckerEngine::updateCharPosition() {
}
if (action->_testFlag2Num != 0) {
if (action->_testFlag2Num < 500) {
- if (_flagsTable[action->_testFlag2Num] != action->_testFlag2Value) {
+ if (action->_testFlag2Num >= 300)
+ error("updateCharPosition() - Unexpected value for _testFlag1Num : %d", action->_testFlag1Num);
+ if (_flagsTable[action->_testFlag2Num] != action->_testFlag2Value)
skip = false;
- }
} else if (_inventoryItemsState[action->_testFlag2Num - 500] != action->_testFlag2Value) {
skip = false;
}
diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h
index adcd02b2fe..a423915a5f 100644
--- a/engines/tucker/tucker.h
+++ b/engines/tucker/tucker.h
@@ -613,6 +613,7 @@ protected:
CompressedSound _compressedSound;
Common::Language _gameLang;
uint32 _gameFlags;
+ int _startSlot;
bool _quitGame;
bool _fastMode;
diff --git a/engines/voyeur/animation.cpp b/engines/voyeur/animation.cpp
index c1ded75f02..62b37346da 100644
--- a/engines/voyeur/animation.cpp
+++ b/engines/voyeur/animation.cpp
@@ -48,7 +48,7 @@ RL2Decoder::~RL2Decoder() {
}
bool RL2Decoder::loadVideo(int videoId) {
- Common::String filename = Common::String::format("%s.rl2",
+ Common::String filename = Common::String::format("%s.rl2",
::Voyeur::SZ_FILENAMES[videoId * 2]);
return loadRL2File(filename, false);
}
@@ -121,7 +121,7 @@ void RL2Decoder::readNextPacket() {
if (_soundFrameNumber == -1)
_soundFrameNumber = (frameNumber == -1) ? 0 : frameNumber;
- while (audioTrack->numQueuedStreams() < SOUND_FRAMES_READAHEAD &&
+ while (audioTrack->numQueuedStreams() < SOUND_FRAMES_READAHEAD &&
(_soundFrameNumber < (int)_soundFrames.size())) {
_fileStream->seek(_soundFrames[_soundFrameNumber]._offset);
audioTrack->queueSound(_fileStream, _soundFrames[_soundFrameNumber]._size);
@@ -217,13 +217,13 @@ bool RL2Decoder::RL2FileHeader::isValid() const {
}
Common::Rational RL2Decoder::RL2FileHeader::getFrameRate() const {
- return (_soundRate > 0) ? Common::Rational(_rate, _defSoundSize) :
+ return (_soundRate > 0) ? Common::Rational(_rate, _defSoundSize) :
Common::Rational(11025, 1103);
}
/*------------------------------------------------------------------------*/
-RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTrack *audioTrack,
+RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTrack *audioTrack,
Common::SeekableReadStream *stream): _header(header), _fileStream(stream) {
_frameOffsets = nullptr;
@@ -261,7 +261,7 @@ void RL2Decoder::RL2VideoTrack::initBackSurface() {
bool RL2Decoder::RL2VideoTrack::seek(const Audio::Timestamp &time) {
int frame = getFrameAtTime(time);
-
+
if (frame < 0 || frame >= _header._numFrames)
return false;
@@ -287,7 +287,7 @@ const Graphics::Surface *RL2Decoder::RL2VideoTrack::decodeNextFrame() {
_fileStream->seek(0x324);
rl2DecodeFrameWithoutTransparency(0);
- Common::copy((byte *)_surface->getPixels(), (byte *)_surface->getPixels() + (320 * 200),
+ Common::copy((byte *)_surface->getPixels(), (byte *)_surface->getPixels() + (320 * 200),
(byte *)_backSurface->getPixels());
_dirtyRects.push_back(Common::Rect(0, 0, _surface->w, _surface->h));
_initialFrame = false;
@@ -433,7 +433,7 @@ Graphics::Surface *RL2Decoder::RL2VideoTrack::getBackSurface() {
/*------------------------------------------------------------------------*/
-RL2Decoder::RL2AudioTrack::RL2AudioTrack(const RL2FileHeader &header, Common::SeekableReadStream *stream, Audio::Mixer::SoundType soundType):
+RL2Decoder::RL2AudioTrack::RL2AudioTrack(const RL2FileHeader &header, Common::SeekableReadStream *stream, Audio::Mixer::SoundType soundType):
_header(header), _soundType(soundType) {
// Create audio straem for the audio track
_audStream = Audio::makeQueuingAudioStream(_header._rate, _header._channels == 2);
@@ -450,7 +450,7 @@ void RL2Decoder::RL2AudioTrack::queueSound(Common::SeekableReadStream *stream, i
Common::MemoryReadStream *memoryStream = new Common::MemoryReadStream(data, size,
DisposeAfterUse::YES);
- _audStream->queueAudioStream(Audio::makeRawStream(memoryStream, _header._rate,
+ _audStream->queueAudioStream(Audio::makeRawStream(memoryStream, _header._rate,
Audio::FLAG_UNSIGNED, DisposeAfterUse::YES), DisposeAfterUse::YES);
}
@@ -458,7 +458,7 @@ Audio::AudioStream *RL2Decoder::RL2AudioTrack::getAudioStream() const {
return _audStream;
}
-void RL2Decoder::play(VoyeurEngine *vm, int resourceOffset,
+void RL2Decoder::play(VoyeurEngine *vm, int resourceOffset,
byte *frames, byte *imgPos) {
vm->flipPageAndWait();
int paletteStart = getPaletteStart();
@@ -472,14 +472,14 @@ void RL2Decoder::play(VoyeurEngine *vm, int resourceOffset,
vm->_graphicsManager->setPalette128(palette, paletteStart, paletteCount);
}
-
+
if (needsUpdate()) {
if (frames) {
// If reached a point where a new background is needed, load it
// and copy over to the video decoder
if (getCurFrame() >= READ_LE_UINT16(frames + picCtr * 4)) {
PictureResource *newPic = vm->_bVoy->boltEntry(0x302 + picCtr)._picResource;
- Common::Point pt(READ_LE_UINT16(imgPos + 4 * picCtr) - 32,
+ Common::Point pt(READ_LE_UINT16(imgPos + 4 * picCtr) - 32,
READ_LE_UINT16(imgPos + 4 * picCtr + 2) - 20);
vm->_graphicsManager->sDrawPic(newPic, &videoFrame, pt);
@@ -492,7 +492,7 @@ void RL2Decoder::play(VoyeurEngine *vm, int resourceOffset,
Common::copy((const byte *)frame->getPixels(), (const byte *)frame->getPixels() + 320 * 200,
(byte *)vm->_graphicsManager->_screenSurface.getPixels());
}
-
+
vm->_eventsManager->getMouseInfo();
g_system->delayMillis(10);
}
diff --git a/engines/voyeur/animation.h b/engines/voyeur/animation.h
index b17e998214..bc6d8a361a 100644
--- a/engines/voyeur/animation.h
+++ b/engines/voyeur/animation.h
@@ -105,7 +105,7 @@ private:
class RL2VideoTrack : public FixedRateVideoTrack {
public:
- RL2VideoTrack(const RL2FileHeader &header, RL2AudioTrack *audioTrack,
+ RL2VideoTrack(const RL2FileHeader &header, RL2AudioTrack *audioTrack,
Common::SeekableReadStream *stream);
~RL2VideoTrack();
diff --git a/engines/voyeur/data.cpp b/engines/voyeur/data.cpp
index cc0b81a313..b8c987f18b 100644
--- a/engines/voyeur/data.cpp
+++ b/engines/voyeur/data.cpp
@@ -94,7 +94,7 @@ SVoy::SVoy(VoyeurEngine *vm):_vm(vm) {
_evCmPtrs[i] = nullptr;
}
-void SVoy::addEvent(int hour, int minute, VoyeurEventType type, int audioVideoId,
+void SVoy::addEvent(int hour, int minute, VoyeurEventType type, int audioVideoId,
int on, int off, int dead) {
VoyeurEvent &e = _events[_eventCount++];
@@ -309,7 +309,7 @@ bool SVoy::checkForKey() {
if (e._audioVideoId == 40 && e._computerOn < 2 && e._computerOff > 6)
state->_victimEvidenceIndex = 4;
break;
-
+
default:
break;
}
@@ -321,7 +321,7 @@ bool SVoy::checkForKey() {
if (e._audioVideoId == 8 && e._computerOn < 2 && e._computerOff > 26)
state->_victimEvidenceIndex = 1;
break;
-
+
case 3:
if (e._audioVideoId == 20 && e._computerOn < 2 && e._computerOff > 28)
state->_victimEvidenceIndex = 3;
diff --git a/engines/voyeur/data.h b/engines/voyeur/data.h
index 98c884d0c1..a18ad84f51 100644
--- a/engines/voyeur/data.h
+++ b/engines/voyeur/data.h
@@ -101,7 +101,7 @@ public:
*/
bool isInRange(int slotIndex, int hotspotIndex, int v) const {
return _min[slotIndex][hotspotIndex] <= v &&
- v < _max[slotIndex][hotspotIndex];
+ v < _max[slotIndex][hotspotIndex];
}
};
@@ -164,7 +164,7 @@ public:
/**
* Add an event to the list of game events that have occurred
*/
- void addEvent(int hour, int minute, VoyeurEventType type, int audioVideoId,
+ void addEvent(int hour, int minute, VoyeurEventType type, int audioVideoId,
int on, int off, int dead);
/**
@@ -181,7 +181,7 @@ public:
* Adds the start of an audio event happening
*/
void addAudioEventStart();
-
+
/**
* Adsd the finish of an audio event happening
*/
@@ -191,17 +191,17 @@ public:
* Adds the start of an evidence event happening
*/
void addEvidEventStart(int v);
-
+
/**
* Adds the finish of an evidence event happening
*/
void addEvidEventEnd(int totalPages);
-
+
/**
* Adds the start of a computer event happening
*/
void addComputerEventStart();
-
+
/**
* Adds the finish of a computer event happening
*/
diff --git a/engines/voyeur/debugger.cpp b/engines/voyeur/debugger.cpp
index 234300bce5..e9a12180da 100644
--- a/engines/voyeur/debugger.cpp
+++ b/engines/voyeur/debugger.cpp
@@ -29,11 +29,10 @@ namespace Voyeur {
Debugger::Debugger(VoyeurEngine *vm) : GUI::Debugger(), _vm(vm) {
// Register methods
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("exit", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("time", WRAP_METHOD(Debugger, Cmd_Time));
- DCmd_Register("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots));
- DCmd_Register("mouse", WRAP_METHOD(Debugger, Cmd_Mouse));
+ registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
+ registerCmd("time", WRAP_METHOD(Debugger, Cmd_Time));
+ registerCmd("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots));
+ registerCmd("mouse", WRAP_METHOD(Debugger, Cmd_Mouse));
// Set fields
_isTimeActive = true;
@@ -46,44 +45,44 @@ static const int TIME_STATES[] = {
bool Debugger::Cmd_Time(int argc, const char **argv) {
if (argc < 2) {
- // Get the current day and time of day
+ // Get the current day and time of day
Common::String dtString = _vm->getDayName();
Common::String timeString = _vm->getTimeOfDay();
if (!timeString.empty())
dtString += " " + timeString;
- DebugPrintf("Time period = %d, date/time is: %s, time is %s\n",
+ debugPrintf("Time period = %d, date/time is: %s, time is %s\n",
_vm->_voy->_transitionId, dtString.c_str(), _isTimeActive ? "on" : "off");
- DebugPrintf("Format: %s [on | off | 1..17 | val <amount>]\n\n", argv[0]);
+ debugPrintf("Format: %s [on | off | 1..17 | val <amount>]\n\n", argv[0]);
} else {
if (!strcmp(argv[1], "on")) {
_isTimeActive = true;
- DebugPrintf("Time is now on\n\n");
+ debugPrintf("Time is now on\n\n");
} else if (!strcmp(argv[1], "off")) {
_isTimeActive = false;
- DebugPrintf("Time is now off\n\n");
+ debugPrintf("Time is now off\n\n");
} else if (!strcmp(argv[1], "val")) {
if (argc < 3) {
- DebugPrintf("Time expired is currently %d.\n", _vm->_voy->_RTVNum);
+ debugPrintf("Time expired is currently %d.\n", _vm->_voy->_RTVNum);
} else {
_vm->_voy->_RTVNum = atoi(argv[2]);
- DebugPrintf("Time expired is now %d.\n", _vm->_voy->_RTVNum);
+ debugPrintf("Time expired is now %d.\n", _vm->_voy->_RTVNum);
}
} else {
int timeId = atoi(argv[1]);
if (timeId >= 1 && timeId < 17) {
int stateId = TIME_STATES[timeId - 1];
if (!stateId) {
- DebugPrintf("Given time period is not used in-game\n");
+ debugPrintf("Given time period is not used in-game\n");
} else {
- DebugPrintf("Changing to time period: %d\n", timeId);
+ debugPrintf("Changing to time period: %d\n", timeId);
if (_vm->_mainThread->goToState(-1, stateId))
_vm->_mainThread->parsePlayCommands();
return false;
}
} else {
- DebugPrintf("Unknown parameter\n\n");
+ debugPrintf("Unknown parameter\n\n");
}
}
}
@@ -93,7 +92,7 @@ bool Debugger::Cmd_Time(int argc, const char **argv) {
bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
if (_vm->_voy->_computerTextId >= 0) {
- DebugPrintf("Hotspot Computer Screen %d - %d,%d->%d,%d\n",
+ debugPrintf("Hotspot Computer Screen %d - %d,%d->%d,%d\n",
_vm->_voy->_computerTextId,
_vm->_voy->_computerScreenRect.left,
_vm->_voy->_computerScreenRect.top,
@@ -112,9 +111,9 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
hotspots[hotspotIdx].right, hotspots[hotspotIdx].bottom);
int arrIndex = hotspots[hotspotIdx]._arrIndex;
if (_vm->_voy->_roomHotspotsEnabled[arrIndex - 1]) {
- DebugPrintf("Hotspot Room %d - %s - Enabled\n", arrIndex, pos);
+ debugPrintf("Hotspot Room %d - %s - Enabled\n", arrIndex, pos);
} else {
- DebugPrintf("Hotspot Room - %s - Disabled\n", pos);
+ debugPrintf("Hotspot Room - %s - Disabled\n", pos);
}
}
}
@@ -132,14 +131,14 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
for (int arrIndex = 0; arrIndex < 3; ++arrIndex) {
if (_vm->_voy->_audioHotspotTimes._min[arrIndex][hotspotIdx] != 9999) {
- DebugPrintf("Hotspot %d %s Audio slot %d, time: %d to %d\n",
+ debugPrintf("Hotspot %d %s Audio slot %d, time: %d to %d\n",
hotspotIdx, pos.c_str(), arrIndex,
_vm->_voy->_audioHotspotTimes._min[arrIndex][hotspotIdx],
_vm->_voy->_audioHotspotTimes._max[arrIndex][hotspotIdx]);
}
if (_vm->_voy->_evidenceHotspotTimes._min[arrIndex][hotspotIdx] != 9999) {
- DebugPrintf("Hotspot %d %s Evidence slot %d, time: %d to %d\n",
+ debugPrintf("Hotspot %d %s Evidence slot %d, time: %d to %d\n",
hotspotIdx, pos.c_str(), arrIndex,
_vm->_voy->_evidenceHotspotTimes._min[arrIndex][hotspotIdx],
_vm->_voy->_evidenceHotspotTimes._max[arrIndex][hotspotIdx]);
@@ -148,7 +147,7 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
for (int arrIndex = 0; arrIndex < 8; ++arrIndex) {
if (_vm->_voy->_videoHotspotTimes._min[arrIndex][hotspotIdx] != 9999) {
- DebugPrintf("Hotspot %d %s Video slot %d, time: %d to %d\n",
+ debugPrintf("Hotspot %d %s Video slot %d, time: %d to %d\n",
hotspotIdx, pos.c_str(), arrIndex,
_vm->_voy->_videoHotspotTimes._min[arrIndex][hotspotIdx],
_vm->_voy->_videoHotspotTimes._max[arrIndex][hotspotIdx]);
@@ -157,16 +156,16 @@ bool Debugger::Cmd_Hotspots(int argc, const char **argv) {
}
}
- DebugPrintf("\nEnd of list\n");
+ debugPrintf("\nEnd of list\n");
return true;
}
bool Debugger::Cmd_Mouse(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("mouse [ on | off ]\n");
+ debugPrintf("mouse [ on | off ]\n");
} else {
_showMousePosition = !strcmp(argv[1], "on");
- DebugPrintf("Mouse position is now %s\n", _showMousePosition ? "on" : "off");
+ debugPrintf("Mouse position is now %s\n", _showMousePosition ? "on" : "off");
}
return true;
diff --git a/engines/voyeur/events.cpp b/engines/voyeur/events.cpp
index 9a3c6d00ff..7ce7351e65 100644
--- a/engines/voyeur/events.cpp
+++ b/engines/voyeur/events.cpp
@@ -73,7 +73,7 @@ EventsManager::EventsManager(VoyeurEngine *vm) : _intPtr(_gameData),
Common::fill(&_cycleTime[0], &_cycleTime[4], 0);
Common::fill(&_cycleNext[0], &_cycleNext[4], (byte *)nullptr);
_cyclePtr = NULL;
-
+
_leftClick = _rightClick = false;
_mouseClicked = _newMouseClicked = false;
_newLeftClick = _newRightClick = false;;
@@ -158,7 +158,7 @@ void EventsManager::checkForNextFrameCounter() {
showMousePosition();
// Display the frame
- g_system->copyRectToScreen((byte *)_vm->_graphicsManager->_screenSurface.getPixels(),
+ g_system->copyRectToScreen((byte *)_vm->_graphicsManager->_screenSurface.getPixels(),
SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
g_system->updateScreen();
@@ -218,7 +218,7 @@ void EventsManager::videoTimer() {
_gameData._hasPalette = false;
g_system->getPaletteManager()->setPalette(_gameData._palette +
- _gameData._palStartIndex * 3, _gameData._palStartIndex,
+ _gameData._palStartIndex * 3, _gameData._palStartIndex,
_gameData._palEndIndex - _gameData._palStartIndex + 1);
}
}
@@ -241,7 +241,7 @@ void EventsManager::delayClick(int cycles) {
do {
g_system->delayMillis(10);
getMouseInfo();
- } while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd
+ } while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd
&& !_vm->_eventsManager->_mouseClicked);
}
@@ -315,7 +315,7 @@ void EventsManager::startFade(CMapResource *cMap) {
palEntry._bEntry = vgaP[2] << 8;
int bDiff = (cMap->_entries[mapIndex * 3 + 2] << 8) - palEntry._bEntry;
palEntry._bChange = bDiff / cMap->_steps;
-
+
palEntry._palIndex = idx;
if (!(cMap->_fadeStatus & 1))
++mapIndex;
@@ -431,12 +431,12 @@ void EventsManager::vDoCycleInt() {
byte b = pPal[start * 3 + 2];
Common::copy(&pPal[start * 3 + 3], &pPal[end * 3 + 3], &pPal[start * 3]);
-
+
// Place the original saved entry at the end of the range
pPal[end * 3] = r;
pPal[end * 3 + 1] = g;
pPal[end * 3 + 2] = b;
-
+
if (_fadeStatus & 1) {
//dx = start, di = end
warning("TODO: Adjustment of ViewPortListResource");
@@ -454,12 +454,12 @@ void EventsManager::vDoCycleInt() {
// Move the remainder of the range forwards one entry
Common::copy_backward(&pPal[start * 3], &pPal[end * 3], &pPal[end * 3 + 3]);
-
+
// Place the original saved entry at the end of the range
pPal[start * 3] = r;
pPal[start * 3 + 1] = g;
pPal[start * 3 + 2] = b;
-
+
if (_fadeStatus & 1) {
//dx = start, di = end
warning("TODO: Adjustment of ViewPortListResource");
diff --git a/engines/voyeur/events.h b/engines/voyeur/events.h
index 5e0bfe6404..0c1cef0955 100644
--- a/engines/voyeur/events.h
+++ b/engines/voyeur/events.h
@@ -38,7 +38,7 @@ class CMapResource;
#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
typedef void (EventsManager::*EventMethodPtr)();
-
+
class IntNode {
public:
EventMethodPtr _intFunc;
diff --git a/engines/voyeur/files.cpp b/engines/voyeur/files.cpp
index 7369d9280e..346fd2419e 100644
--- a/engines/voyeur/files.cpp
+++ b/engines/voyeur/files.cpp
@@ -421,8 +421,8 @@ byte *BoltFile::getBoltMember(uint32 id) {
}
void BoltFile::initDefault() {
- _state._curMemberPtr->_data = _state.decompress(NULL, _state._curMemberPtr->_size,
- _state._curMemberPtr->_mode);
+ _state._curMemberPtr->_data = _state.decompress(NULL, _state._curMemberPtr->_size,
+ _state._curMemberPtr->_mode);
}
/*------------------------------------------------------------------------*/
@@ -505,7 +505,7 @@ void BVoyBoltFile::initSoundMap() {
}
void BVoyBoltFile::sInitRect() {
- _state._curMemberPtr->_data = _state.decompress(NULL, _state._curMemberPtr->_size,
+ _state._curMemberPtr->_data = _state.decompress(NULL, _state._curMemberPtr->_size,
_state._curMemberPtr->_mode);
// Check whether the resource Id is in the list of extended rects
@@ -522,7 +522,7 @@ void BVoyBoltFile::sInitRect() {
void BVoyBoltFile::sInitPic() {
// Read in the header data
_state._curMemberPtr->_data = _state.decompress(NULL, 24, _state._curMemberPtr->_mode);
- _state._curMemberPtr->_picResource = new PictureResource(_state,
+ _state._curMemberPtr->_picResource = new PictureResource(_state,
_state._curMemberPtr->_data);
}
@@ -567,14 +567,14 @@ void StampBoltFile::initResource(int resType) {
void StampBoltFile::initThread() {
initDefault();
- _state._curMemberPtr->_threadResource = new ThreadResource(_state,
+ _state._curMemberPtr->_threadResource = new ThreadResource(_state,
_state._curMemberPtr->_data);
}
void StampBoltFile::initPtr() {
initDefault();
- _state._curMemberPtr->_ptrResource = new PtrResource(_state,
+ _state._curMemberPtr->_ptrResource = new PtrResource(_state,
_state._curMemberPtr->_data);
}
@@ -585,7 +585,7 @@ void StampBoltFile::initControl() {
initDefault();
ControlResource *res;
- _state._curMemberPtr->_controlResource = res = new ControlResource(_state,
+ _state._curMemberPtr->_controlResource = res = new ControlResource(_state,
_state._curMemberPtr->_data);
_state._vm->_controlGroupPtr = _state._curGroupPtr;
@@ -596,7 +596,7 @@ void StampBoltFile::initState() {
initDefault();
assert(_state._curMemberPtr->_size == 16);
- _state._curMemberPtr->_stateResource = new StateResource(_state,
+ _state._curMemberPtr->_stateResource = new StateResource(_state,
_state._curMemberPtr->_data);
}
@@ -658,7 +658,7 @@ BoltEntry::BoltEntry(Common::SeekableReadStream *f, uint16 id): _file(f), _id(id
_mode = buffer[0];
_initMethod = buffer[3];
_size = READ_LE_UINT32(&buffer[4]) & 0xffffff;
- _fileOffset = READ_LE_UINT32(&buffer[8]);
+ _fileOffset = READ_LE_UINT32(&buffer[8]);
}
BoltEntry::~BoltEntry() {
@@ -687,7 +687,7 @@ void BoltEntry::load() {
*/
bool BoltEntry::hasResource() const {
return _rectResource || _picResource || _viewPortResource || _viewPortListResource
- || _fontResource || _fontInfoResource || _cMapResource || _vInitCycleResource
+ || _fontResource || _fontInfoResource || _cMapResource || _vInitCycleResource
|| _ptrResource || _controlResource || _stateResource || _threadResource;
}
@@ -719,7 +719,7 @@ RectResource::RectResource(const byte *src, int size, bool isExtendedRects) {
int x1 = READ_LE_UINT16(src);
int y1 = READ_LE_UINT16(src + 2);
- int x2 = READ_LE_UINT16(src + 4);
+ int x2 = READ_LE_UINT16(src + 4);
int y2 = READ_LE_UINT16(src + 6);
_entries.push_back(RectEntry(x1, y1, x2, y2, arrIndex, rectCount));
@@ -896,7 +896,7 @@ int DisplayResource::drawText(const Common::String &msg) {
viewPort->_fontRect.top -= fontInfo._shadow.y;
}
}
- }
+ }
if (gfxManager._saveBack && fontInfo._fontSaveBack && (_flags & DISPFLAG_VIEWPORT)) {
viewPort->addSaveRect(viewPort->_pageIndex, viewPort->_fontRect);
@@ -971,7 +971,7 @@ int DisplayResource::drawText(const Common::String &msg) {
fontChar._imgData = fontData._charImages + offset * 2;
gfxManager.sDrawPic(&fontChar, this, Common::Point(xp, yp));
-
+
fontChar._imgData = NULL;
xp += charWidth + padding;
msgWidth += charWidth + padding;
@@ -1056,7 +1056,7 @@ PictureResource::PictureResource(BoltFilesState &state, const byte *src):
byte *imgData = state._curLibPtr->boltEntry(id)._picResource->_imgData;
_freeImgData = DisposeAfterUse::NO;
- // TODO: Double check code below. Despite different coding in the
+ // TODO: Double check code below. Despite different coding in the
// original, both looked like they do the same formula
if (_flags & PICFLAG_PIC_OFFSET) {
_imgData = imgData + (READ_LE_UINT32(&src[18]) & 0xffff);
@@ -1082,7 +1082,7 @@ PictureResource::PictureResource(BoltFilesState &state, const byte *src):
if (mode != state._vm->_graphicsManager->_SVGAMode) {
state._vm->_graphicsManager->_SVGAMode = mode;
- state._vm->_graphicsManager->clearPalette();
+ state._vm->_graphicsManager->clearPalette();
}
int screenOffset = READ_LE_UINT32(&src[18]) & 0xffff;
@@ -1118,7 +1118,7 @@ PictureResource::PictureResource(BoltFilesState &state, const byte *src):
_imgData = new byte[nbytes];
Common::fill(_imgData, _imgData + nbytes, 0);
} else {
- _imgData = state.decompress(NULL, nbytes, state._curMemberPtr->_mode);
+ _imgData = state.decompress(NULL, nbytes, state._curMemberPtr->_mode);
}
}
}
@@ -1131,7 +1131,7 @@ PictureResource::PictureResource(Graphics::Surface *surface) {
_maskData = 0;
_planeSize = 0;
_keyColor = 0;
-
+
_bounds = Common::Rect(0, 0, surface->w, surface->h);
_imgData = (byte *)surface->getPixels();
_freeImgData = DisposeAfterUse::NO;
@@ -1150,7 +1150,7 @@ PictureResource::PictureResource() {
_freeImgData = DisposeAfterUse::NO;
}
-PictureResource::PictureResource(int flags, int select, int pick, int onOff,
+PictureResource::PictureResource(int flags, int select, int pick, int onOff,
const Common::Rect &bounds, int maskData, byte *imgData, int planeSize) {
_flags = flags;
_select = select;
@@ -1189,7 +1189,7 @@ void PictureResource::flipVertical(const byte *data) {
for (int y = 0; y < _bounds.height(); ++y) {
Common::copy(srcP, srcP + _bounds.width(), destP);
srcP += _bounds.width();
- destP -= _bounds.width();
+ destP -= _bounds.width();
}
}
@@ -1205,7 +1205,7 @@ ViewPortResource::ViewPortResource(BoltFilesState &state, const byte *src):
int xs = READ_LE_UINT16(src + 12);
int ys = READ_LE_UINT16(src + 14);
- _bounds = Common::Rect(xs, ys, xs + READ_LE_UINT16(src + 16),
+ _bounds = Common::Rect(xs, ys, xs + READ_LE_UINT16(src + 16),
ys + READ_LE_UINT16(src + 18));
_currentPic = state._curLibPtr->getPictureResource(READ_LE_UINT32(src + 0x20));
@@ -1285,7 +1285,7 @@ void ViewPortResource::setupViewPort(PictureResource *page, Common::Rect *clippi
yDiff = r.bottom - page->_bounds.bottom;
if (xDiff > 0)
- r.setWidth(xDiff <= r.width() ? r.width() - xDiff : 0);
+ r.setWidth(xDiff <= r.width() ? r.width() - xDiff : 0);
if (yDiff > 0)
r.setHeight(yDiff <= r.height() ? r.height() - yDiff : 0);
}
@@ -1305,7 +1305,7 @@ void ViewPortResource::setupViewPort(PictureResource *page, Common::Rect *clippi
r.top = clippingRect->top;
r.setHeight(yDiff <= height ? height - yDiff : 0);
}
-
+
xDiff = r.right - clippingRect->right;
yDiff = r.bottom - clippingRect->bottom;
@@ -1339,7 +1339,7 @@ void ViewPortResource::setupViewPort(PictureResource *pic, Common::Rect *clippin
void ViewPortResource::addSaveRect(int pageIndex, const Common::Rect &r) {
Common::Rect rect = r;
-
+
if (clipRect(rect)) {
if (_addFn) {
(_state._vm->_graphicsManager->*_addFn)(this, pageIndex, rect);
@@ -1355,21 +1355,21 @@ void ViewPortResource::fillPic(byte onOff) {
void ViewPortResource::drawIfaceTime() {
// Hour display
- _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
+ _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
(_state._vm->_gameHour / 10) == 0 ? 10 : _state._vm->_gameHour / 10,
Common::Point(161, 25));
- _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
+ _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
_state._vm->_gameHour % 10, Common::Point(172, 25));
// Minute display
- _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
+ _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
_state._vm->_gameMinute / 10, Common::Point(190, 25));
- _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
+ _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort,
_state._vm->_gameMinute % 10, Common::Point(201, 25));
// AM/PM indicator
PictureResource *pic = _state._vm->_bVoy->boltEntry(_state._vm->_voy->_isAM ? 272 : 273)._picResource;
- _state._vm->_graphicsManager->sDrawPic(pic, _state._vm->_graphicsManager->_vPort,
+ _state._vm->_graphicsManager->sDrawPic(pic, _state._vm->_graphicsManager->_vPort,
Common::Point(215, 27));
}
@@ -1488,9 +1488,9 @@ FontInfoResource::FontInfoResource() {
_shadowColor = 0;
}
-FontInfoResource::FontInfoResource(byte picFlags, byte picSelect, byte picPick, byte picOnOff,
- byte fontFlags, FontJustify justify, int fontSaveBack, const Common::Point &pos,
- int justifyWidth, int justifyHeight, const Common::Point &shadow, int foreColor,
+FontInfoResource::FontInfoResource(byte picFlags, byte picSelect, byte picPick, byte picOnOff,
+ byte fontFlags, FontJustify justify, int fontSaveBack, const Common::Point &pos,
+ int justifyWidth, int justifyHeight, const Common::Point &shadow, int foreColor,
int backColor, int shadowColor) {
_curFont = NULL;
_picFlags = picFlags;
@@ -1516,7 +1516,7 @@ CMapResource::CMapResource(BoltFilesState &state, const byte *src): _vm(state._v
_fadeStatus = src[1];
_start = READ_LE_UINT16(src + 2);
_end = READ_LE_UINT16(src + 4);
-
+
int count = _end - _start + 1;
_entries = new byte[count * 3];
Common::copy(src + 6, src + 6 + 3 * count, _entries);
@@ -1607,7 +1607,7 @@ ControlResource::ControlResource(BoltFilesState &state, const byte *src) {
/*------------------------------------------------------------------------*/
StateResource::StateResource(BoltFilesState &state, const byte *src):
- _victimIndex(_vals[1]), _victimEvidenceIndex(_vals[2]),
+ _victimIndex(_vals[1]), _victimEvidenceIndex(_vals[2]),
_victimMurderIndex(_vals[3]) {
for (int i = 0; i < 4; ++i)
_vals[i] = READ_LE_UINT32(src + i * 4);
diff --git a/engines/voyeur/files.h b/engines/voyeur/files.h
index 49c0b2c8a4..eef5df497c 100644
--- a/engines/voyeur/files.h
+++ b/engines/voyeur/files.h
@@ -114,7 +114,7 @@ public:
void resolveIt(uint32 id, byte **p);
void resolveFunction(uint32 id, GraphicMethodPtr *fn);
- BoltEntry &boltEntry(uint16 id);
+ BoltEntry &boltEntry(uint16 id);
BoltEntry &getBoltEntryFromLong(uint32 id);
PictureResource *getPictureResource(uint32 id);
CMapResource *getCMapResource(uint32 id);
@@ -160,7 +160,7 @@ public:
int _fileOffset;
Common::Array<BoltEntry> _entries;
public:
- BoltGroup(Common::SeekableReadStream *f);
+ BoltGroup(Common::SeekableReadStream *f);
virtual ~BoltGroup();
void load(uint16 groupId);
@@ -234,15 +234,15 @@ public:
/* bvoy.blt resource types */
enum PictureFlag {
- PICFLAG_2 = 2, PICFLAG_PIC_OFFSET = 8, PICFLAG_CLEAR_SCREEN = 0x10,
+ PICFLAG_2 = 2, PICFLAG_PIC_OFFSET = 8, PICFLAG_CLEAR_SCREEN = 0x10,
PICFLAG_20 = 0x20, PICFLAG_HFLIP = 0x40, PICFLAG_VFLIP = 0x80, PICFLAG_100 = 0x100,
- PICFLAG_CLEAR_SCREEN00 = 0x1000
+ PICFLAG_CLEAR_SCREEN00 = 0x1000
};
enum DisplayFlag {
- DISPFLAG_1 = 1, DISPFLAG_2 = 2, DISPFLAG_4 = 4, DISPFLAG_8 = 8,
+ DISPFLAG_1 = 1, DISPFLAG_2 = 2, DISPFLAG_4 = 4, DISPFLAG_8 = 8,
DISPFLAG_10 = 0x10, DISPFLAG_20 = 0x20, DISPFLAG_40 = 0x40, DISPFLAG_80 = 0x80,
- DISPFLAG_100 = 0x100, DISPFLAG_200 = 0x200, DISPFLAG_400 = 0x400,
+ DISPFLAG_100 = 0x100, DISPFLAG_200 = 0x200, DISPFLAG_400 = 0x400,
DISPFLAG_800 = 0x800, DISPFLAG_1000 = 0x1000, DISPFLAG_2000 = 0x2000,
DISPFLAG_4000 = 0x4000, DISPFLAG_VIEWPORT = 0x8000, DISPFLAG_CURSOR = 0x10000,
DISPFLAG_NONE = 0};
@@ -256,7 +256,7 @@ public:
DisplayResource();
DisplayResource(VoyeurEngine *vm);
- /**
+ /**
* Fill a box of the given size at the current _drawPtr location
*/
void sFillBox(int width, int height);
@@ -308,7 +308,7 @@ public:
DisposeAfterUse::Flag _freeImgData;
public:
PictureResource(BoltFilesState &state, const byte *src);
- PictureResource(int flags, int select, int pick, int onOff,
+ PictureResource(int flags, int select, int pick, int onOff,
const Common::Rect &bounds, int maskData, byte *imgData, int planeSize);
PictureResource(Graphics::Surface *surface);
PictureResource();
@@ -334,7 +334,7 @@ public:
PictureResource *_pages[2];
// Rect lists and counts. Note that _rectListCount values of '-1' seem to have
- // special significance, which is why I'm not making them redundant in favor
+ // special significance, which is why I'm not making them redundant in favor
// of the arrays' .size() method
Common::Array<Common::Rect> *_rectListPtr[3];
int _rectListCount[3];
@@ -413,9 +413,9 @@ public:
public:
FontInfoResource(BoltFilesState &state, const byte *src);
FontInfoResource();
- FontInfoResource(byte picFlags, byte picSelect, byte picPick, byte picOnOff, byte fontFlags,
- FontJustify justify, int fontSaveBack, const Common::Point &pos, int justifyWidth,
- int justifyHeight, const Common::Point &shadow, int foreColor, int backColor,
+ FontInfoResource(byte picFlags, byte picSelect, byte picPick, byte picOnOff, byte fontFlags,
+ FontJustify justify, int fontSaveBack, const Common::Point &pos, int justifyWidth,
+ int justifyHeight, const Common::Point &shadow, int foreColor, int backColor,
int shadowColor);
};
diff --git a/engines/voyeur/files_threads.cpp b/engines/voyeur/files_threads.cpp
index 700944f7ef..b1960a23ac 100644
--- a/engines/voyeur/files_threads.cpp
+++ b/engines/voyeur/files_threads.cpp
@@ -97,7 +97,7 @@ void ThreadResource::unloadAStack(int stackId) {
}
bool ThreadResource::doState() {
- if (!getStateInfo())
+ if (!getStateInfo())
return false;
getButtonsFlags();
@@ -122,7 +122,7 @@ bool ThreadResource::getStateInfo() {
uint32 fld = READ_LE_UINT32(_ctlPtr + 2);
fld += _stateId << 3;
_nextStateId = READ_LE_UINT32(_ctlPtr + fld + 4);
-
+
fld = READ_LE_UINT32(_ctlPtr + fld);
byte *baseP = _ctlPtr + fld;
_stateCount = READ_LE_UINT16(baseP);
@@ -133,7 +133,7 @@ bool ThreadResource::getStateInfo() {
_playCommandsPtr += (READ_LE_UINT32(baseP + 6) / 2) << 1;
_threadInfoPtr = baseP + 10;
-
+
getButtonsText();
return true;
}
@@ -146,7 +146,7 @@ byte *ThreadResource::getDataOffset() {
void ThreadResource::getButtonsText() {
int idx = 0;
-
+
for (const byte *p = _threadInfoPtr; *p != 0x49; p = getNextRecord(p)) {
if (*p == 0xC0) {
++p;
@@ -162,7 +162,7 @@ void ThreadResource::getButtonsText() {
void ThreadResource::getButtonsFlags() {
int idx = 0;
-
+
for (const byte *p = _threadInfoPtr; *p != 0x49; p = getNextRecord(p)) {
if (*p == 0xC0) {
if (*++p & 0x20)
@@ -379,9 +379,9 @@ void ThreadResource::parsePlayCommands() {
_vm->_eventsManager->incrementTime(1);
_vm->_audioVideoId = -1;
parseIndex = 999;
- }
- }
-
+ }
+ }
+
dataP += 8;
break;
@@ -408,7 +408,7 @@ void ThreadResource::parsePlayCommands() {
_vm->_voy->_eventFlags |= EVTFLAG_TIME_DISABLED;
_vm->_voy->addVideoEventEnd();
_vm->_eventsManager->incrementTime(1);
-
+
_vm->_audioVideoId = -1;
_vm->_playStampGroupId = -1;
@@ -494,7 +494,7 @@ void ThreadResource::parsePlayCommands() {
_vm->_audioVideoId = -1;
parseIndex = 999;
}
- break;
+ break;
case 5:
// Check whether transition to a given time period is allowed, and
@@ -587,8 +587,8 @@ void ThreadResource::parsePlayCommands() {
case 10:
// Pick the person who is to die, during startup
if (_vm->_iForceDeath == -1) {
- // No specific person has been preset to be killed, so pick one randomly.
- // The loop below was used because the victim was persisted from the previous
+ // No specific person has been preset to be killed, so pick one randomly.
+ // The loop below was used because the victim was persisted from the previous
// play-through, so it ensured that a different victim is picked.
int randomVal;
do {
@@ -663,7 +663,7 @@ void ThreadResource::parsePlayCommands() {
if (v2 == 0 || _vm->_controlPtr->_state->_victimIndex == v2)
_vm->_voy->_murderThreshold = v3;
-
+
dataP += 4;
break;
@@ -819,7 +819,7 @@ const byte *ThreadResource::cardPerform(const byte *card) {
case 24:
case 27:
case 28:
- subId -= 3;
+ subId -= 3;
// Deliberate fall-through
case 21:
@@ -858,13 +858,13 @@ const byte *ThreadResource::cardPerform(const byte *card) {
++count;
}
}
-
+
++card;
} else {
if (cardPerform2(card, id)) {
card += subId;
card = cardPerform(card);
- while (*card++ != 61) ;
+ while (*card++ != 61) ;
} else {
card += subId;
while (*card != 61 && *card != 29)
@@ -878,7 +878,7 @@ const byte *ThreadResource::cardPerform(const byte *card) {
assert(bVal < 8);
card += 6;
break;
-
+
case 45:
_newStateId = _nextStateId;
_newStackId = _stackId;
@@ -929,12 +929,12 @@ bool ThreadResource::cardPerform2(const byte *pSrc, int cardCmdId) {
return vLong != vLong2;
case 25:
- vLong = _vm->_controlPtr->_state->_vals[*pSrc];
+ vLong = _vm->_controlPtr->_state->_vals[*pSrc];
vLong2 = (int32)READ_LE_UINT32(pSrc + 1);
return vLong < vLong2;
case 26:
- vLong = _vm->_controlPtr->_state->_vals[*pSrc];
+ vLong = _vm->_controlPtr->_state->_vals[*pSrc];
vLong2 = (int32)READ_LE_UINT32(pSrc + 1);
return vLong > vLong2;
@@ -951,13 +951,13 @@ bool ThreadResource::cardPerform2(const byte *pSrc, int cardCmdId) {
default:
return false;
}
-}
+}
int ThreadResource::doApt() {
loadTheApt();
_vm->_currentVocId = 151;
- _vm->_voy->_viewBounds = _vm->_bVoy->boltEntry(_vm->_playStampGroupId)._rectResource;
+ _vm->_voy->_viewBounds = _vm->_bVoy->boltEntry(_vm->_playStampGroupId)._rectResource;
Common::Array<RectEntry> &hotspots = _vm->_bVoy->boltEntry(
_vm->_playStampGroupId + 1)._rectResource->_entries;
_vm->_eventsManager->getMouseInfo();
@@ -1039,7 +1039,7 @@ int ThreadResource::doApt() {
hotspotId = 5;
// Draw the text description for the highlighted hotspot
- pic = _vm->_bVoy->boltEntry(_vm->_playStampGroupId +
+ pic = _vm->_bVoy->boltEntry(_vm->_playStampGroupId +
hotspotId + 6)._picResource;
_vm->_graphicsManager->sDrawPic(pic, _vm->_graphicsManager->_vPort,
Common::Point(106, 200));
@@ -1101,10 +1101,10 @@ int ThreadResource::doApt() {
void ThreadResource::doRoom() {
VoyeurEngine &vm = *_vm;
SVoy voy = *vm._voy;
-
+
vm.makeViewFinderP();
voy._fadingType = 0;
-
+
if (!vm._bVoy->getBoltGroup(vm._playStampGroupId))
return;
@@ -1116,7 +1116,7 @@ void ThreadResource::doRoom() {
voy._fadingStep1 = 2;
voy._fadingStep2 = 0;
voy._fadingType = 1;
-
+
Common::Array<RectEntry> &hotspots = vm._bVoy->boltEntry(vm._playStampGroupId + 4)._rectResource->_entries;
int hotspotId = -1;
@@ -1214,7 +1214,7 @@ void ThreadResource::doRoom() {
vm._eventsManager->_mouseClicked = false;
vm._eventsManager->startCursorBlink();
- int totalChars = vm.doComputerText(9999);
+ int totalChars = vm.doComputerText(9999);
if (totalChars)
vm._voy->addComputerEventEnd(totalChars);
@@ -1345,12 +1345,12 @@ int ThreadResource::doInterface() {
Common::String fname = _vm->_soundManager->getVOCFileName(_vm->_currentVocId);
_vm->_soundManager->startVOCPlay(fname);
_vm->_eventsManager->getMouseInfo();
-
+
_vm->_graphicsManager->setColor(240, 220, 220, 220);
_vm->_eventsManager->_intPtr._hasPalette = true;
_vm->_voy->_eventFlags &= ~EVTFLAG_TIME_DISABLED;
- // Set the cusor
+ // Set the cusor
PictureResource *crosshairsCursor = _vm->_bVoy->boltEntry(0x112)._picResource;
PictureResource *eyeCursor = _vm->_bVoy->boltEntry(0x113)._picResource;
PictureResource *listenCursor = _vm->_bVoy->boltEntry(0x114)._picResource;
@@ -1382,7 +1382,7 @@ int ThreadResource::doInterface() {
if (!mansionViewBounds.contains(pt))
pt = Common::Point(-1, -1);
else
- pt = _vm->_mansionViewPos +
+ pt = _vm->_mansionViewPos +
Common::Point(pt.x - MANSION_VIEW_X, pt.y - MANSION_VIEW_Y);
regionIndex = -1;
@@ -1420,20 +1420,20 @@ int ThreadResource::doInterface() {
// Regularly update the time display
if (_vm->_voy->_RTANum & 2) {
- _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
+ _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
_vm->_gameMinute / 10, Common::Point(190, 25));
- _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
+ _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
_vm->_gameMinute % 10, Common::Point(201, 25));
if (_vm->_voy->_RTANum & 4) {
int v = _vm->_gameHour / 10;
- _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
+ _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
v == 0 ? 10 : v, Common::Point(161, 25));
- _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
+ _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort,
_vm->_gameHour % 10, Common::Point(172, 25));
pic = _vm->_bVoy->boltEntry(_vm->_voy->_isAM ? 272 : 273)._picResource;
- _vm->_graphicsManager->sDrawPic(pic, _vm->_graphicsManager->_vPort,
+ _vm->_graphicsManager->sDrawPic(pic, _vm->_graphicsManager->_vPort,
Common::Point(215, 27));
}
}
@@ -1462,7 +1462,7 @@ int ThreadResource::doInterface() {
_vm->makeViewFinder();
_vm->initIFace();
-
+
hotspots = &_vm->_bVoy->boltEntry(_vm->_playStampGroupId + 1)._rectResource->_entries;
_vm->_eventsManager->getMouseInfo();
@@ -1471,7 +1471,7 @@ int ThreadResource::doInterface() {
_vm->_eventsManager->_intPtr._flashTimer = 0;
}
}
- } while (!_vm->_eventsManager->_rightClick && !_vm->shouldQuit() &&
+ } while (!_vm->_eventsManager->_rightClick && !_vm->shouldQuit() &&
(!_vm->_eventsManager->_leftClick || regionIndex == -1));
_vm->_eventsManager->hideCursor();
@@ -1612,7 +1612,7 @@ void ThreadResource::loadTheApt() {
}
CMapResource *pal = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + 4)._cMapResource;
- pal->_steps = 1;
+ pal->_steps = 1;
pal->startFade();
_vm->flipPageAndWaitForFade();
}
@@ -1715,7 +1715,7 @@ void ThreadResource::doAptAnim(int mode) {
void ThreadResource::synchronize(Common::Serializer &s) {
s.syncAsSint16LE(_aptPos.x);
s.syncAsSint16LE(_aptPos.y);
-
+
int stateId = _stateId;
int stackId = _stackId;
s.syncAsSint16LE(stateId);
diff --git a/engines/voyeur/graphics.cpp b/engines/voyeur/graphics.cpp
index f756b9cc85..68a30e41f4 100644
--- a/engines/voyeur/graphics.cpp
+++ b/engines/voyeur/graphics.cpp
@@ -97,9 +97,9 @@ void GraphicsManager::restoreMCGASaveRect(ViewPortResource *viewPort) {
restoreBack(*viewPort->_rectListPtr[1], viewPort->_rectListCount[1], viewPort->_pages[0],
viewPort->_pages[1]);
-
+
int count = viewPort->_rectListCount[0];
- restoreBack(*viewPort->_rectListPtr[0], viewPort->_rectListCount[0],
+ restoreBack(*viewPort->_rectListPtr[0], viewPort->_rectListCount[0],
viewPort->_activePage, viewPort->_currentPic);
SWAP(viewPort->_rectListPtr[0], viewPort->_rectListPtr[1]);
@@ -150,7 +150,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
destPic = (PictureResource *)destDisplay;
}
- Common::Point offset = Common::Point(initialOffset.x + srcPic->_bounds.left - destPic->_bounds.left,
+ Common::Point offset = Common::Point(initialOffset.x + srcPic->_bounds.left - destPic->_bounds.left,
initialOffset.y + srcPic->_bounds.top - destPic->_bounds.top);
width1 = width2 = srcPic->_bounds.width();
height1 = srcPic->_bounds.height();
@@ -178,7 +178,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
srcOffset -= tmpHeight * width2;
height1 += tmpHeight;
offset.y = newBounds.top;
-
+
if (height1 <= 0)
return;
@@ -258,7 +258,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
for (uint idx = 0; idx < srcPic->_maskData; ++idx) {
if (imageDataShift < 4)
++imageDataShift;
- }
+ }
} else {
srcImgData = srcPic->_imgData;
destImgData = destPic->_imgData;
@@ -367,7 +367,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
width2 = srcPic->_bounds.width();
height1 = tmpHeight + height1;
-
+
for (int yp = 0; yp < height1; ++yp) {
runLength = 0;
@@ -509,7 +509,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
if (srcFlags & DISPFLAG_2) {
if (!(srcFlags & DISPFLAG_8)) {
srcP = srcImgData + srcOffset;
-
+
if (destFlags & DISPFLAG_8) {
// loc_272C3
error("TODO: sDrawPic variation");
@@ -786,7 +786,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des
} else {
// loc_271F0
srcP = srcImgData;
-
+
if (isClipped) {
// loc_2700A
tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
@@ -886,7 +886,7 @@ void GraphicsManager::flipPage() {
for (uint idx = 0; idx < viewPorts.size(); ++idx) {
if (viewPorts[idx]->_flags & DISPFLAG_20) {
- if ((viewPorts[idx]->_flags & (DISPFLAG_8 || DISPFLAG_1))
+ if ((viewPorts[idx]->_flags & (DISPFLAG_8 || DISPFLAG_1))
== (DISPFLAG_8 || DISPFLAG_1)) {
if (_planeSelect == idx)
sDisplayPic(viewPorts[idx]->_currentPic);
@@ -992,7 +992,7 @@ void GraphicsManager::screenReset() {
_backgroundPage = NULL;
_vPort->setupViewPort(NULL);
- fillPic(_vPort, 0);
+ fillPic(_vPort, 0);
_vm->flipPageAndWait();
}
diff --git a/engines/voyeur/graphics.h b/engines/voyeur/graphics.h
index 221d31061d..e4d0b38650 100644
--- a/engines/voyeur/graphics.h
+++ b/engines/voyeur/graphics.h
@@ -54,14 +54,13 @@ public:
DrawInfo(int penColor, const Common::Point &pos);
};
-typedef void (GraphicsManager::*GraphicMethodPtr)();
+typedef void (GraphicsManager::*GraphicMethodPtr)();
typedef void (GraphicsManager::*ViewPortSetupPtr)(ViewPortResource *);
typedef void (GraphicsManager::*ViewPortAddPtr)(ViewPortResource *, int idx, const Common::Rect &bounds);
typedef void (GraphicsManager::*ViewPortRestorePtr)(ViewPortResource *);
class GraphicsManager {
public:
- VoyeurEngine *_vm;
byte _VGAColors[PALETTE_SIZE];
PictureResource *_backgroundPage;
int _SVGAMode;
@@ -77,6 +76,8 @@ public:
DrawInfo *_drawPtr;
DrawInfo _defaultDrawInfo;
private:
+ VoyeurEngine *_vm;
+
void restoreBack(Common::Array<Common::Rect> &rectList, int rectListCount,
PictureResource *srcPic, PictureResource *destPic);
public:
@@ -86,7 +87,7 @@ public:
void sInitGraphics();
void setupMCGASaveRect(ViewPortResource *viewPort);
- void addRectOptSaveRect(ViewPortResource *viewPort, int idx, const Common::Rect &bounds);
+ void addRectOptSaveRect(ViewPortResource *viewPort, int idx, const Common::Rect &bounds);
void restoreMCGASaveRect(ViewPortResource *viewPort);
void addRectNoSaveBack(ViewPortResource *viewPort, int idx, const Common::Rect &bounds);
@@ -101,7 +102,7 @@ public:
void resetPalette();
void setColor(int idx, byte r, byte g, byte b);
void setOneColor(int idx, byte r, byte g, byte b);
- void setColors(int start, int count, const byte *pal);
+ void setColors(int start, int count, const byte *pal);
void screenReset();
void fadeDownICF1(int steps);
void fadeUpICF1(int steps = 0);
diff --git a/engines/voyeur/sound.cpp b/engines/voyeur/sound.cpp
index 26145bd743..c0e5a043cd 100644
--- a/engines/voyeur/sound.cpp
+++ b/engines/voyeur/sound.cpp
@@ -62,7 +62,7 @@ void SoundManager::startVOCPlay(const Common::String &filename) {
if (!f.open(filename))
error("Could not find voc file - %s", filename.c_str());
- Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(f.readStream(f.size()),
+ Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(f.readStream(f.size()),
Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, audioStream);
diff --git a/engines/voyeur/staticres.cpp b/engines/voyeur/staticres.cpp
index 7016793ddc..372da508f1 100644
--- a/engines/voyeur/staticres.cpp
+++ b/engines/voyeur/staticres.cpp
@@ -43,7 +43,7 @@ const int RESOLVE_TABLE[] = {
0x7500
};
-const int LEVEL_H[] = {
+const int LEVEL_H[] = {
4, 7, 7, 8, 9, 10, 2, 2, 4, 8, 8, 9, 9, 10, 10, 11, 11
};
@@ -58,40 +58,40 @@ const int BLIND_TABLE[] = {
};
const int COMPUTER_SCREEN_TABLE[] = {
- 269, 128, 307, 163,
- 269, 128, 307, 163,
- 68, 79, 98, 102,
- 68, 79, 98, 102,
- 68, 79, 98, 102,
+ 269, 128, 307, 163,
+ 269, 128, 307, 163,
+ 68, 79, 98, 102,
+ 68, 79, 98, 102,
+ 68, 79, 98, 102,
+ 68, 79, 98, 102,
+ 248, 138, 291, 163,
+ 83, 132, 143, 156,
+ 248, 138, 291, 163,
+ 83, 132, 143, 156,
+ 83, 132, 143, 156,
+ 248, 138, 291, 163,
68, 79, 98, 102,
- 248, 138, 291, 163,
- 83, 132, 143, 156,
- 248, 138, 291, 163,
- 83, 132, 143, 156,
- 83, 132, 143, 156,
- 248, 138, 291, 163,
- 68, 79, 98, 102,
68, 79, 98, 102
};
const char *const SZ_FILENAMES[] = {
- "A2110100", nullptr, "A2300100", nullptr, "B1220100", nullptr, "C1220100", nullptr,
- "C1290100", nullptr, "D1220100", nullptr, "D1270100", nullptr, "E1210100", nullptr,
+ "A2110100", nullptr, "A2300100", nullptr, "B1220100", nullptr, "C1220100", nullptr,
+ "C1290100", nullptr, "D1220100", nullptr, "D1270100", nullptr, "E1210100", nullptr,
"E1260100", nullptr, "E1280100", nullptr, "E1325100", nullptr, "F1200100", nullptr,
- "G1250100", nullptr, "G1260100", nullptr, "H1200100", nullptr, "H1230100", nullptr,
- "H1310100", nullptr, "I1300100", nullptr, "J1220100", nullptr, "J1230100", nullptr,
+ "G1250100", nullptr, "G1260100", nullptr, "H1200100", nullptr, "H1230100", nullptr,
+ "H1310100", nullptr, "I1300100", nullptr, "J1220100", nullptr, "J1230100", nullptr,
"J1320100", nullptr, "K1260100", nullptr, "K1280100", nullptr, "K1325100", nullptr,
- "L1210100", nullptr, "L1280100", nullptr, "L1290100", nullptr, "L1300100", nullptr,
- "L1310100", nullptr, "M1260100", nullptr, "M1310100", nullptr, "N1210100", nullptr,
+ "L1210100", nullptr, "L1280100", nullptr, "L1290100", nullptr, "L1300100", nullptr,
+ "L1310100", nullptr, "M1260100", nullptr, "M1310100", nullptr, "N1210100", nullptr,
"N1225100", nullptr, "N1275510", nullptr, "N1280510", nullptr, "N1325100", nullptr,
- "O1230100", nullptr, "O1260100", nullptr, "O1260520", nullptr, "O1280100", nullptr,
- "O1325540", nullptr, "P1276710", nullptr, "P1280540", nullptr, "P1280740", nullptr,
+ "O1230100", nullptr, "O1260100", nullptr, "O1260520", nullptr, "O1280100", nullptr,
+ "O1325540", nullptr, "P1276710", nullptr, "P1280540", nullptr, "P1280740", nullptr,
"P1290510", nullptr, "P1325100", nullptr, "P1325300", nullptr, "P1325520", nullptr,
- "Q1230100", nullptr, "Q1240530", nullptr, "Q1240730", nullptr, "Q1260100", nullptr,
- "Q1260520", nullptr, "Q1260720", nullptr, "Q1325100", nullptr, "R1280540", nullptr,
+ "Q1230100", nullptr, "Q1240530", nullptr, "Q1240730", nullptr, "Q1260100", nullptr,
+ "Q1260520", nullptr, "Q1260720", nullptr, "Q1325100", nullptr, "R1280540", nullptr,
"Z1110510", nullptr, "Z1110520", nullptr, "Z1110530", nullptr, "Z1110540", nullptr,
- "Z1110545", nullptr, "Z2320100", nullptr, "Z2905300", nullptr, "Z3110100", nullptr,
- "Z3115510", nullptr, "Z3115520", nullptr, "Z3115530", nullptr, "Z3115540", nullptr,
+ "Z1110545", nullptr, "Z2320100", nullptr, "Z2905300", nullptr, "Z3110100", nullptr,
+ "Z3115510", nullptr, "Z3115520", nullptr, "Z3115530", nullptr, "Z3115540", nullptr,
"Z4915100", nullptr, "Z4915200", nullptr, "Z4915300",
nullptr, nullptr, nullptr, nullptr, nullptr,
"MMARG", "MZACK", "MREED", "MJESSI", "MCHLOE", "MCAMERA", "MENDCRED",
diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp
index 9843930bd3..8edacc5883 100644
--- a/engines/voyeur/voyeur.cpp
+++ b/engines/voyeur/voyeur.cpp
@@ -37,7 +37,7 @@ VoyeurEngine *g_vm;
VoyeurEngine::VoyeurEngine(OSystem *syst, const VoyeurGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _randomSource("Voyeur"),
- _defaultFontInfo(3, 0xff, 0xff, 0, 0, ALIGN_LEFT, 0, Common::Point(), 1, 1,
+ _defaultFontInfo(3, 0xff, 0xff, 0, 0, ALIGN_LEFT, 0, Common::Point(), 1, 1,
Common::Point(1, 1), 1, 0, 0) {
_debugger = nullptr;
_eventsManager = nullptr;
@@ -158,7 +158,7 @@ void VoyeurEngine::initInput() {
bool VoyeurEngine::doHeadTitle() {
// char dest[144];
-
+
_eventsManager->startMainClockInt();
if (_loadGameSlot == -1) {
@@ -205,7 +205,7 @@ bool VoyeurEngine::doHeadTitle() {
_voy->addEvent(18, 7, EVTYPE_VIDEO, 40, 0, 998, -1);
_voy->addEvent(18, 8, EVTYPE_VIDEO, 43, 0, 998, -1);
_voy->addEvent(19, 1, EVTYPE_AUDIO, 20, 0, 998, -1);
- }
+ }
}
_voy->_aptLoadMode = 140;
@@ -271,7 +271,7 @@ bool VoyeurEngine::doLock() {
_graphicsManager->setColor(2, 96, 96, 96);
_graphicsManager->setColor(3, 160, 160, 160);
_graphicsManager->setColor(4, 224, 224, 224);
-
+
// Set up the cursor
_eventsManager->setCursor(cursorPic);
_eventsManager->showCursor();
@@ -464,11 +464,11 @@ void VoyeurEngine::doOpening() {
_eventsManager->_intPtr._hasPalette = true;
_graphicsManager->_vPort->setupViewPort();
flipPageAndWait();
-
+
RL2Decoder decoder;
decoder.loadRL2File("a2300100.rl2", false);
decoder.start();
-
+
while (!shouldQuit() && !decoder.endOfVideo() && !_eventsManager->_mouseClicked) {
if (decoder.hasDirtyPalette()) {
const byte *palette = decoder.getPalette();
@@ -487,7 +487,7 @@ void VoyeurEngine::doOpening() {
textPic = _bVoy->boltEntry(frameIndex / 2 + 0x202)._picResource;
textPos = Common::Point(READ_LE_UINT16(xyTable + frameIndex * 2),
READ_LE_UINT16(xyTable + (frameIndex + 1) * 2));
-
+
creditShow = false;
} else {
textPic = nullptr;
@@ -500,8 +500,9 @@ void VoyeurEngine::doOpening() {
if (textPic) {
_graphicsManager->sDrawPic(textPic, _graphicsManager->_vPort, textPos);
- flipPageAndWait();
}
+
+ flipPageAndWait();
}
_eventsManager->getMouseInfo();
@@ -560,9 +561,9 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) {
RL2Decoder decoder;
decoder.loadVideo(videoId);
- decoder.seek(Audio::Timestamp(_voy->_vocSecondsOffset * 1000));
+ decoder.seek(Audio::Timestamp(_voy->_vocSecondsOffset * 1000));
decoder.start();
- int endFrame = decoder.getCurFrame() + totalFrames;
+ int endFrame = decoder.getCurFrame() + totalFrames;
_eventsManager->getMouseInfo();
_eventsManager->startCursorBlink();
@@ -603,9 +604,9 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) {
void VoyeurEngine::playAudio(int audioId) {
_bVoy->getBoltGroup(0x7F00);
- _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x7F00 +
+ _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x7F00 +
BLIND_TABLE[audioId] * 2)._picResource;
- _graphicsManager->_backColors = _bVoy->boltEntry(0x7F01 +
+ _graphicsManager->_backColors = _bVoy->boltEntry(0x7F01 +
BLIND_TABLE[audioId] * 2)._cMapResource;
_graphicsManager->_vPort->setupViewPort();
@@ -620,7 +621,7 @@ void VoyeurEngine::playAudio(int audioId) {
_voy->_eventFlags |= EVTFLAG_RECORDING;
_eventsManager->startCursorBlink();
- while (!shouldQuit() && !_eventsManager->_mouseClicked &&
+ while (!shouldQuit() && !_eventsManager->_mouseClicked &&
_soundManager->getVOCStatus())
_eventsManager->delayClick(1);
@@ -657,7 +658,7 @@ void VoyeurEngine::doTransitionCard(const Common::String &time, const Common::St
fi._justifyHeight = 120;
_graphicsManager->_vPort->drawText(time);
-
+
if (!location.empty()) {
fi._pos = Common::Point(0, 138);
fi._justify = ALIGN_CENTER;
@@ -723,7 +724,7 @@ void VoyeurEngine::showEndingNews() {
_soundManager->startVOCPlay(fname);
_eventsManager->getMouseInfo();
- while (!shouldQuit() && !_eventsManager->_mouseClicked &&
+ while (!shouldQuit() && !_eventsManager->_mouseClicked &&
_soundManager->getVOCStatus()) {
_eventsManager->delay(1);
_eventsManager->getMouseInfo();
@@ -901,7 +902,7 @@ void VoyeurSavegameHeader::write(Common::OutSaveFile *f, VoyeurEngine *vm, const
// Create a thumbnail and save it
Graphics::Surface *thumb = new Graphics::Surface();
- ::createThumbnail(thumb, (byte *)vm->_graphicsManager->_screenSurface.getPixels(),
+ ::createThumbnail(thumb, (byte *)vm->_graphicsManager->_screenSurface.getPixels(),
SCREEN_WIDTH, SCREEN_HEIGHT, vm->_graphicsManager->_VGAColors);
Graphics::saveThumbnail(*f, *thumb);
thumb->free();
diff --git a/engines/voyeur/voyeur_game.cpp b/engines/voyeur/voyeur_game.cpp
index a6564c32ba..34ad62a88d 100644
--- a/engines/voyeur/voyeur_game.cpp
+++ b/engines/voyeur/voyeur_game.cpp
@@ -33,7 +33,7 @@ void VoyeurEngine::playStamp() {
_stampLibPtr->getBoltGroup(0);
_controlPtr->_state = _stampLibPtr->boltEntry(_controlPtr->_stateId >> 16)._stateResource;
assert(_controlPtr->_state);
-
+
_resolvePtr = &RESOLVE_TABLE[0];
initStamp();
@@ -57,11 +57,11 @@ void VoyeurEngine::playStamp() {
_mainThread->parsePlayCommands();
bool flag = breakFlag = (_voy->_eventFlags & EVTFLAG_2) != 0;
-
+
switch (_voy->_playStampMode) {
case 5:
buttonId = _mainThread->doInterface();
-
+
if (buttonId == -2) {
switch (_mainThread->doApt()) {
case 0:
@@ -110,7 +110,7 @@ void VoyeurEngine::playStamp() {
case 16:
_voy->_transitionId = 17;
buttonId = _mainThread->doApt();
-
+
switch (buttonId) {
case 1:
_mainThread->chooseSTAMPButton(22);
@@ -234,19 +234,19 @@ void VoyeurEngine::closeStamp() {
void VoyeurEngine::doTailTitle() {
_graphicsManager->_vPort->setupViewPort(NULL);
_graphicsManager->screenReset();
-
+
if (_bVoy->getBoltGroup(0x600)) {
RL2Decoder decoder;
decoder.loadRL2File("a1100200.rl2", false);
decoder.start();
decoder.play(this);
-
+
if (!shouldQuit() && !_eventsManager->_mouseClicked) {
doClosingCredits();
if (!shouldQuit() && !_eventsManager->_mouseClicked) {
_graphicsManager->screenReset();
-
+
PictureResource *pic = _bVoy->boltEntry(0x602)._picResource;
CMapResource *pal = _bVoy->boltEntry(0x603)._cMapResource;
@@ -315,7 +315,7 @@ void VoyeurEngine::doClosingCredits() {
_graphicsManager->_vPort->drawText(msg);
msg += strlen(msg) + 1;
}
-
+
if (flags & 0x40) {
fi._foreColor = 2;
fi._curFont = _bVoy->boltEntry(0x400)._fontResource;
@@ -345,7 +345,7 @@ void VoyeurEngine::doClosingCredits() {
fi._justifyHeight = 240;
fi._pos = Common::Point(198, READ_LE_UINT16(entry));
- _graphicsManager->_vPort->drawText(msg);
+ _graphicsManager->_vPort->drawText(msg);
msg += strlen(msg) + 1;
}
@@ -500,7 +500,7 @@ void VoyeurEngine::reviewTape() {
Common::String msg = _eventsManager->getEvidString(eventNum);
_graphicsManager->_backgroundPage->drawText(msg);
-
+
yp += 15;
}
@@ -527,7 +527,7 @@ void VoyeurEngine::reviewTape() {
break;
}
}
-
+
pt = _eventsManager->getMousePos();
if (tempPos.x >= 68 && tempPos.x <= 277 && tempPos.y >= 31 && tempPos.y <= 154) {
tempPos.y -= 2;
@@ -545,7 +545,7 @@ void VoyeurEngine::reviewTape() {
flipPageAndWait();
_graphicsManager->_drawPtr->_penColor = 0;
- _graphicsManager->_drawPtr->_pos = Common::Point(tempRect.left, tempRect.top);
+ _graphicsManager->_drawPtr->_pos = Common::Point(tempRect.left, tempRect.top);
_graphicsManager->_backgroundPage->sFillBox(tempRect.width(), tempRect.height());
int yp = 45;
@@ -642,7 +642,7 @@ void VoyeurEngine::reviewTape() {
foundIndex = -1;
_eventsManager->_rightClick = 0;
}
-
+
if (_eventsManager->_rightClick)
foundIndex = 0;
@@ -652,7 +652,7 @@ void VoyeurEngine::reviewTape() {
_voy->_fadingType = 0;
_voy->_viewBounds = nullptr;
_graphicsManager->_vPort->setupViewPort(NULL);
-
+
if (_currentVocId != -1) {
_voy->_vocSecondsOffset = _voy->_RTVNum - _voy->_musicStartTime;
_soundManager->stopVOCPlay();
@@ -693,7 +693,7 @@ void VoyeurEngine::reviewTape() {
uint32 secondsDuration = e._computerOff;
_eventsManager->getMouseInfo();
- while (!_eventsManager->_mouseClicked && _soundManager->getVOCStatus() &&
+ while (!_eventsManager->_mouseClicked && _soundManager->getVOCStatus() &&
_soundManager->getVOCFrame() < secondsDuration) {
_eventsManager->getMouseInfo();
_eventsManager->delay(10);
@@ -707,7 +707,7 @@ void VoyeurEngine::reviewTape() {
case EVTYPE_EVID:
_voy->reviewAnEvidEvent(eventIndex);
-
+
_voy->_vocSecondsOffset = _voy->_RTVNum - _voy->_musicStartTime;
_soundManager->stopVOCPlay();
_bVoy->getBoltGroup(0x900);
@@ -715,7 +715,7 @@ void VoyeurEngine::reviewTape() {
case EVTYPE_COMPUTER:
_voy->reviewComputerEvent(eventIndex);
-
+
_voy->_vocSecondsOffset = _voy->_RTVNum - _voy->_musicStartTime;
_soundManager->stopVOCPlay();
_bVoy->getBoltGroup(0x900);
@@ -863,7 +863,7 @@ bool VoyeurEngine::checkForIncriminate() {
for (int idx = 0; idx < _voy->_eventCount; ++idx) {
VoyeurEvent &evt = _voy->_events[idx];
-
+
if (evt._type == EVTYPE_VIDEO) {
if (evt._audioVideoId == 44 && evt._computerOn <= 40 &&
(evt._computerOff + evt._computerOn) >= 70) {
@@ -908,7 +908,7 @@ void VoyeurEngine::playAVideoEvent(int eventIndex) {
_voy->_vocSecondsOffset = evt._computerOn;
_eventsManager->_videoDead = evt._dead;
_voy->_eventFlags &= ~EVTFLAG_TIME_DISABLED;
-
+
playAVideoDuration(_audioVideoId, evt._computerOff);
_voy->_eventFlags |= EVTFLAG_TIME_DISABLED;
@@ -929,7 +929,7 @@ void VoyeurEngine::playAVideoEvent(int eventIndex) {
int VoyeurEngine::getChooseButton() {
int prevIndex = -2;
- Common::Array<RectEntry> &hotspots = _bVoy->boltEntry(_playStampGroupId
+ Common::Array<RectEntry> &hotspots = _bVoy->boltEntry(_playStampGroupId
+ 6)._rectResource->_entries;
int selectedIndex = -1;
@@ -949,7 +949,7 @@ int VoyeurEngine::getChooseButton() {
_eventsManager->getMouseInfo();
selectedIndex = -1;
Common::Point pt = _eventsManager->getMousePos();
-
+
for (uint idx = 0; idx < hotspots.size(); ++idx) {
if (hotspots[idx].contains(pt)) {
if (!_voy->_victimMurdered || ((int)idx + 1) != _controlPtr->_state->_victimIndex) {
@@ -984,7 +984,7 @@ int VoyeurEngine::getChooseButton() {
void VoyeurEngine::makeViewFinder() {
_graphicsManager->_backgroundPage = _bVoy->boltEntry(0x103)._picResource;
- _graphicsManager->sDrawPic(_graphicsManager->_backgroundPage,
+ _graphicsManager->sDrawPic(_graphicsManager->_backgroundPage,
_graphicsManager->_vPort, Common::Point(0, 0));
CMapResource *pal = _bVoy->boltEntry(0x104)._cMapResource;
@@ -1067,7 +1067,7 @@ void VoyeurEngine::initIFace() {
_mansionViewPos = Common::Point((MANSION_MAX_X - MANSION_VIEW_WIDTH) / 2,
(MANSION_MAX_Y - MANSION_VIEW_HEIGHT) / 2);
doScroll(_mansionViewPos);
-
+
_voy->_viewBounds = _bVoy->boltEntry(_playStampGroupId)._rectResource;
// Show the cursor using ScummVM functionality
@@ -1150,7 +1150,7 @@ Common::String VoyeurEngine::getDayName() {
case 3:
case 4:
return SATURDAY;
- case 17:
+ case 17:
return MONDAY;
default:
return SUNDAY;
@@ -1277,7 +1277,7 @@ void VoyeurEngine::doTimeBar() {
if (_voy->_RTVLimit > 0) {
if (_voy->_RTVNum > _voy->_RTVLimit || _voy->_RTVNum < 0)
_voy->_RTVNum = _voy->_RTVLimit - 1;
-
+
_timeBarVal = _voy->_RTVNum;
int height = ((_voy->_RTVLimit - _voy->_RTVNum) * 59) / _voy->_RTVLimit;
int fullHeight = MAX(151 - height, 93);
@@ -1308,14 +1308,14 @@ void VoyeurEngine::flashTimeBar() {
_graphicsManager->setColor(240, 220, 20, 20);
else
_graphicsManager->setColor(240, 220, 220, 220);
-
+
_eventsManager->_intPtr._hasPalette = true;
_flashTimeFlag = !_flashTimeFlag;
}
}
void VoyeurEngine::checkPhoneCall() {
- if ((_voy->_RTVLimit - _voy->_RTVNum) >= 36 && _voy->_totalPhoneCalls < 5 &&
+ if ((_voy->_RTVLimit - _voy->_RTVNum) >= 36 && _voy->_totalPhoneCalls < 5 &&
_currentVocId <= 151 && _currentVocId > 146) {
if ((_voy->_switchBGNum < _checkPhoneVal || _checkPhoneVal > 180) &&
!_soundManager->getVOCStatus()) {
@@ -1361,9 +1361,9 @@ void VoyeurEngine::doEvidDisplay(int evidId, int eventId) {
if (count > 0) {
for (int idx = 1; idx <= count; ++idx) {
- _voy->_evPicPtrs[idx - 1] = _bVoy->boltEntry(_voy->_boltGroupId2 +
+ _voy->_evPicPtrs[idx - 1] = _bVoy->boltEntry(_voy->_boltGroupId2 +
(evidId + idx) * 2)._picResource;
- _voy->_evCmPtrs[idx - 1] = _bVoy->boltEntry(_voy->_boltGroupId2 +
+ _voy->_evCmPtrs[idx - 1] = _bVoy->boltEntry(_voy->_boltGroupId2 +
(evidId + idx) * 2 + 1)._cMapResource;
}
}
@@ -1394,7 +1394,7 @@ void VoyeurEngine::doEvidDisplay(int evidId, int eventId) {
break;
if (count == 0 || evidIdx >= eventId)
continue;
-
+
pic = _voy->_evPicPtrs[arrIndex];
_graphicsManager->sDrawPic(pic, _graphicsManager->_vPort,
Common::Point((384 - pic->_bounds.width()) / 2,
diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp
index 51fd74e300..a313314a8b 100644
--- a/engines/wintermute/debugger.cpp
+++ b/engines/wintermute/debugger.cpp
@@ -29,8 +29,8 @@
namespace Wintermute {
Console::Console(WintermuteEngine *vm) : GUI::Debugger(), _engineRef(vm) {
- DCmd_Register("show_fps", WRAP_METHOD(Console, Cmd_ShowFps));
- DCmd_Register("dump_file", WRAP_METHOD(Console, Cmd_DumpFile));
+ registerCmd("show_fps", WRAP_METHOD(Console, Cmd_ShowFps));
+ registerCmd("dump_file", WRAP_METHOD(Console, Cmd_DumpFile));
}
Console::~Console(void) {
@@ -50,7 +50,7 @@ bool Console::Cmd_ShowFps(int argc, const char **argv) {
bool Console::Cmd_DumpFile(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Usage: %s <file path> <output file name>\n", argv[0]);
+ debugPrintf("Usage: %s <file path> <output file name>\n", argv[0]);
return true;
}
@@ -60,7 +60,7 @@ bool Console::Cmd_DumpFile(int argc, const char **argv) {
BaseFileManager *fileManager = BaseEngine::instance().getFileManager();
Common::SeekableReadStream *inFile = fileManager->openFile(filePath);
if (!inFile) {
- DebugPrintf("File '%s' not found\n", argv[1]);
+ debugPrintf("File '%s' not found\n", argv[1]);
return true;
}
@@ -77,7 +77,7 @@ bool Console::Cmd_DumpFile(int argc, const char **argv) {
delete outFile;
delete inFile;
- DebugPrintf("Resource file '%s' dumped to file '%s'\n", argv[1], argv[2]);
+ debugPrintf("Resource file '%s' dumped to file '%s'\n", argv[1], argv[2]);
return true;
}
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
index 22382bc264..e610f34474 100644
--- a/engines/zvision/core/console.cpp
+++ b/engines/zvision/core/console.cpp
@@ -45,25 +45,25 @@
namespace ZVision {
Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
- DCmd_Register("loadimage", WRAP_METHOD(Console, cmdLoadImage));
- DCmd_Register("loadvideo", WRAP_METHOD(Console, cmdLoadVideo));
- DCmd_Register("loadsound", WRAP_METHOD(Console, cmdLoadSound));
- DCmd_Register("raw2wav", WRAP_METHOD(Console, cmdRawToWav));
- DCmd_Register("setrenderstate", WRAP_METHOD(Console, cmdSetRenderState));
- DCmd_Register("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable));
- DCmd_Register("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV));
- DCmd_Register("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
- DCmd_Register("changelocation", WRAP_METHOD(Console, cmdChangeLocation));
- DCmd_Register("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
- DCmd_Register("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles));
- DCmd_Register("rendertext", WRAP_METHOD(Console, cmdRenderText));
+ registerCmd("loadimage", WRAP_METHOD(Console, cmdLoadImage));
+ registerCmd("loadvideo", WRAP_METHOD(Console, cmdLoadVideo));
+ registerCmd("loadsound", WRAP_METHOD(Console, cmdLoadSound));
+ registerCmd("raw2wav", WRAP_METHOD(Console, cmdRawToWav));
+ registerCmd("setrenderstate", WRAP_METHOD(Console, cmdSetRenderState));
+ registerCmd("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable));
+ registerCmd("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV));
+ registerCmd("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
+ registerCmd("changelocation", WRAP_METHOD(Console, cmdChangeLocation));
+ registerCmd("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
+ registerCmd("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles));
+ registerCmd("rendertext", WRAP_METHOD(Console, cmdRenderText));
}
bool Console::cmdLoadImage(int argc, const char **argv) {
if (argc == 4)
_engine->getRenderManager()->renderImageToScreen(argv[1], atoi(argv[2]), atoi(argv[3]));
else {
- DebugPrintf("Use loadimage <fileName> <destinationX> <destinationY> to load an image to the screen\n");
+ debugPrintf("Use loadimage <fileName> <destinationX> <destinationY> to load an image to the screen\n");
return true;
}
@@ -72,7 +72,7 @@ bool Console::cmdLoadImage(int argc, const char **argv) {
bool Console::cmdLoadVideo(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Use loadvideo <fileName> to load a video to the screen\n");
+ debugPrintf("Use loadvideo <fileName> to load a video to the screen\n");
return true;
}
@@ -86,7 +86,7 @@ bool Console::cmdLoadVideo(int argc, const char **argv) {
bool Console::cmdLoadSound(int argc, const char **argv) {
if (!Common::File::exists(argv[1])) {
- DebugPrintf("File does not exist\n");
+ debugPrintf("File does not exist\n");
return true;
}
@@ -105,7 +105,7 @@ bool Console::cmdLoadSound(int argc, const char **argv) {
Audio::SoundHandle handle;
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false);
} else {
- DebugPrintf("Use loadsound <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n");
+ debugPrintf("Use loadsound <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n");
return true;
}
@@ -114,7 +114,7 @@ bool Console::cmdLoadSound(int argc, const char **argv) {
bool Console::cmdRawToWav(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n");
+ debugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n");
return true;
}
@@ -124,7 +124,7 @@ bool Console::cmdRawToWav(int argc, const char **argv) {
bool Console::cmdSetRenderState(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
+ debugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
return true;
}
@@ -137,7 +137,7 @@ bool Console::cmdSetRenderState(int argc, const char **argv) {
else if (renderState.matchString("flat", true))
_engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::FLAT);
else
- DebugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
+ debugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n");
return true;
}
@@ -150,7 +150,7 @@ bool Console::cmdGenerateRenderTable(int argc, const char **argv) {
bool Console::cmdSetPanoramaFoV(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n");
+ debugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n");
return true;
}
@@ -161,7 +161,7 @@ bool Console::cmdSetPanoramaFoV(int argc, const char **argv) {
bool Console::cmdSetPanoramaScale(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n");
+ debugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n");
return true;
}
@@ -172,7 +172,7 @@ bool Console::cmdSetPanoramaScale(int argc, const char **argv) {
bool Console::cmdChangeLocation(int argc, const char **argv) {
if (argc != 6) {
- DebugPrintf("Use changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n");
+ debugPrintf("Use changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n");
return true;
}
@@ -183,7 +183,7 @@ bool Console::cmdChangeLocation(int argc, const char **argv) {
bool Console::cmdDumpFile(int argc, const char **argv) {
if (argc != 2) {
- DebugPrintf("Use dumpfile <fileName> to dump a file\n");
+ debugPrintf("Use dumpfile <fileName> to dump a file\n");
return true;
}
@@ -205,7 +205,7 @@ bool Console::cmdParseAllScrFiles(int argc, const char **argv) {
bool Console::cmdRenderText(int argc, const char **argv) {
if (argc != 7) {
- DebugPrintf("Use rendertext <text> <fontNumber> <destX> <destY> <maxWidth> <1 or 0: wrap> to render text\n");
+ debugPrintf("Use rendertext <text> <fontNumber> <destX> <destY> <maxWidth> <1 or 0: wrap> to render text\n");
return true;
}
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
index 55353acbb9..edee1fd16e 100644
--- a/engines/zvision/sound/zork_raw.cpp
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -185,14 +185,14 @@ Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath,
char fileIdentifier = (engine->getGameId() == GID_NEMESIS) ? fileName[6] : fileName[7];
if (engine->getGameId() == GID_NEMESIS) {
- for (int i = 0; i < 6; ++i) {
+ for (uint i = 0; i < ARRAYSIZE(RawZorkStream::_zNemSoundParamLookupTable); ++i) {
if (RawZorkStream::_zNemSoundParamLookupTable[i].identifier == fileIdentifier) {
soundParams = RawZorkStream::_zNemSoundParamLookupTable[i];
foundParams = true;
}
}
} else if (engine->getGameId() == GID_GRANDINQUISITOR) {
- for (int i = 0; i < 6; ++i) {
+ for (uint i = 0; i < ARRAYSIZE(RawZorkStream::_zgiSoundParamLookupTable); ++i) {
if (RawZorkStream::_zgiSoundParamLookupTable[i].identifier == fileIdentifier) {
soundParams = RawZorkStream::_zgiSoundParamLookupTable[i];
foundParams = true;