diff options
Diffstat (limited to 'engines')
52 files changed, 2045 insertions, 994 deletions
diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp index 2d7075cba1..10906480fe 100644 --- a/engines/composer/composer.cpp +++ b/engines/composer/composer.cpp @@ -42,6 +42,7 @@ #include "composer/composer.h" #include "composer/graphics.h" #include "composer/resource.h" +#include "composer/console.h" namespace Composer { @@ -57,6 +58,7 @@ ComposerEngine::ComposerEngine(OSystem *syst, const ComposerGameDescription *gam _mouseEnabled = false; _mouseSpriteId = 0; _lastButton = NULL; + _console = NULL; } ComposerEngine::~ComposerEngine() { @@ -73,6 +75,7 @@ ComposerEngine::~ComposerEngine() { i->_surface.free(); delete _rnd; + delete _console; } Common::Error ComposerEngine::run() { @@ -113,6 +116,8 @@ Common::Error ComposerEngine::run() { CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount()); delete cursor; + _console = new Console(this); + loadLibrary(0); uint fps = atoi(getStringFromConfig("Common", "FPS").c_str()); @@ -190,11 +195,11 @@ Common::Error ComposerEngine::run() { case Common::EVENT_KEYDOWN: switch (event.kbd.keycode) { case Common::KEYCODE_d: - /*if (event.kbd.hasFlags(Common::KBD_CTRL)) { + if (event.kbd.hasFlags(Common::KBD_CTRL)) { // Start the debugger getDebugger()->attach(); getDebugger()->onFrame(); - }*/ + } break; case Common::KEYCODE_q: diff --git a/engines/composer/composer.h b/engines/composer/composer.h index 7d8022455a..f945df8bb1 100644 --- a/engines/composer/composer.h +++ b/engines/composer/composer.h @@ -34,11 +34,14 @@ #include "engines/engine.h" #include "engines/util.h" +#include "gui/debugger.h" + #include "graphics/surface.h" #include "audio/mixer.h" #include "composer/resource.h" +#include "composer/console.h" namespace Audio { class QueuingAudioStream; @@ -159,6 +162,9 @@ public: const ComposerGameDescription *_gameDescription; + Console *_console; + GUI::Debugger *getDebugger() { return _console; } + private: Common::RandomSource *_rnd; diff --git a/engines/composer/console.cpp b/engines/composer/console.cpp new file mode 100644 index 0000000000..8c68b3205b --- /dev/null +++ b/engines/composer/console.cpp @@ -0,0 +1,31 @@ +/* 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 "composer/composer.h" + +namespace Composer { + +Console::Console(ComposerEngine *vm) : GUI::Debugger() { + _vm = vm; +} + +} // End of namespace Composer diff --git a/engines/composer/console.h b/engines/composer/console.h new file mode 100644 index 0000000000..0567d8bc6f --- /dev/null +++ b/engines/composer/console.h @@ -0,0 +1,40 @@ +/* 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 COMPOSER_CONSOLE_H +#define COMPOSER_CONSOLE_H + +namespace Composer { + +class ComposerEngine; + +class Console : public GUI::Debugger { +public: + Console(ComposerEngine *vm); + +private: + ComposerEngine *_vm; +}; + +} // End of namespace Composer + +#endif /* COMPOSER_CONSOLE_H */ diff --git a/engines/composer/module.mk b/engines/composer/module.mk index 8bfaf932e8..c879d53630 100644 --- a/engines/composer/module.mk +++ b/engines/composer/module.mk @@ -1,6 +1,7 @@ MODULE := engines/composer MODULE_OBJS = \ + console.o \ composer.o \ detection.o \ graphics.o \ diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp index 163f0077fc..14cb4be5a0 100644 --- a/engines/drascula/drascula.cpp +++ b/engines/drascula/drascula.cpp @@ -864,6 +864,11 @@ void DrasculaEngine::updateEvents() { #endif switch (event.type) { case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) { + // Start the debugger + getDebugger()->attach(); + getDebugger()->onFrame(); + } addKeyToBuffer(event.kbd); break; case Common::EVENT_KEYUP: diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h index 944191b5fb..53fce9c212 100644 --- a/engines/drascula/drascula.h +++ b/engines/drascula/drascula.h @@ -38,6 +38,8 @@ #include "engines/savestate.h" +#include "drascula/console.h" + #include "audio/mixer.h" #include "engines/engine.h" @@ -313,8 +315,6 @@ static const int interf_y[] = { 51, 51, 51, 51, 83, 83, 83 }; struct RoomHandlers; -class Console; - class DrasculaEngine : public Engine { protected: // Engine APIs @@ -724,11 +724,12 @@ public: void update_62_pre(); void update_102(); + Console *_console; + GUI::Debugger *getDebugger() { return _console; } + private: int _lang; - Console *_console; - CharInfo *_charMap; int _charMapSize; diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h index 010f3883b0..87a9f5423f 100644 --- a/engines/dreamweb/dreamweb.h +++ b/engines/dreamweb/dreamweb.h @@ -110,6 +110,8 @@ protected: virtual Common::Error run(); virtual bool hasFeature(EngineFeature f) const; + GUI::Debugger *getDebugger() { return _console; } + public: DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gameDesc); virtual ~DreamWebEngine(); diff --git a/engines/fullpipe/console.cpp b/engines/fullpipe/console.cpp new file mode 100644 index 0000000000..587f3dc6e6 --- /dev/null +++ b/engines/fullpipe/console.cpp @@ -0,0 +1,31 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "fullpipe/fullpipe.h" + +namespace Fullpipe { + +Console::Console(FullpipeEngine *vm) : GUI::Debugger() { + _vm = vm; +} + +} // End of namespace Fullpipe diff --git a/engines/fullpipe/console.h b/engines/fullpipe/console.h new file mode 100644 index 0000000000..9c03081b2b --- /dev/null +++ b/engines/fullpipe/console.h @@ -0,0 +1,40 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef FULLPIPE_CONSOLE_H +#define FULLPIPE_CONSOLE_H + +namespace Fullpipe { + +class FullpipeEngine; + +class Console : public GUI::Debugger { +public: + Console(FullpipeEngine *vm); + +private: + FullpipeEngine *_vm; +}; + +} // End of namespace Fullpipe + +#endif /* FULLPIPE_CONSOLE_H */ diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h index 76739b6632..b774c89ed0 100644 --- a/engines/fullpipe/constants.h +++ b/engines/fullpipe/constants.h @@ -96,7 +96,6 @@ namespace Fullpipe { #define MSG_SC4_KOZAWFALL 2858 #define MSG_SC4_MANFROMBOTTLE 2854 #define MSG_SC4_MANTOBOTTLE 2852 -#define PIC_SC4_LADDER 1438 #define MSG_GOTOLADDER 618 #define MSG_SHAKEBOTTLE 584 #define MSG_SHOOTKOZAW 557 @@ -110,6 +109,8 @@ namespace Fullpipe { #define MV_IN1MAN_SLEEP 5111 #define MV_KZW_JUMP 558 #define MV_KZW_JUMPROTATE 561 +#define MV_KZW_TOHOLERV 537 +#define MV_KZW_WALKPLANK 500 #define MV_BDG_OPEN 1379 #define MV_BTN_CLICK 599 #define MV_CLK_GO 589 @@ -118,6 +119,8 @@ namespace Fullpipe { #define MV_MAN_GOLADDER 451 #define MV_MAN_GOLADDER2 2844 #define MV_MAN_GOU 460 +#define MV_MAN_JUMPONPLANK 551 +#define MV_MAN_LOOKLADDER 520 #define MV_MAN_LOOKUP 4773 #define MV_MAN_STARTLADDER 452 #define MV_MAN_STARTLADDER2 2842 @@ -184,9 +187,14 @@ namespace Fullpipe { #define PIC_SC4_MASK 585 #define PIC_SC4_PLANK 5183 #define PIC_SCD_SEL 734 +#define QU_BALL_WALKL 4920 +#define QU_BALL_WALKR 4919 #define QU_EGTR_MD2_SHOW 4698 #define QU_EGTR_MD1_SHOW 4697 #define QU_EGTR_SLIMSHOW 4883 +#define QU_HND_TAKE0 1440 +#define QU_HND_TAKE1 1441 +#define QU_HND_TAKE2 1442 #define QU_HND_TAKEBOTTLE 1443 #define QU_IN2_DO 5144 #define QU_INTR_FINISH 5138 @@ -196,6 +204,7 @@ namespace Fullpipe { #define QU_PNK_CLICK 550 #define QU_SC3_ENTERLIFT 2779 #define QU_SC3_EXITLIFT 2808 +#define QU_SC4_GOCLOCK 595 #define QU_SC4_MANFROMBOTTLE 2851 #define SC_1 301 #define SC_10 653 @@ -284,8 +293,12 @@ namespace Fullpipe { #define ST_LBN_9N 2777 #define ST_LBN_9P 2778 #define ST_MAN_EMPTY 476 +#define ST_MAN_LADDERDOWN 521 +#define ST_MAN_ONPLANK 552 #define ST_MAN_RIGHT 325 #define ST_MAN_SIT 1164 +#define ST_MAN_STANDLADDER 453 +#define ST_PNK_WEIGHTLEFT 503 #define TrubaDown 697 #define TrubaLeft 474 #define TrubaRight 696 diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp index 7dedaf3109..a254ea642d 100644 --- a/engines/fullpipe/fullpipe.cpp +++ b/engines/fullpipe/fullpipe.cpp @@ -35,6 +35,7 @@ #include "fullpipe/input.h" #include "fullpipe/scenes.h" #include "fullpipe/floaters.h" +#include "fullpipe/console.h" namespace Fullpipe { @@ -51,6 +52,7 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); _rnd = new Common::RandomSource("fullpipe"); + _console = 0; _gameProjectVersion = 0; _pictureScale = 8; @@ -152,6 +154,7 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) FullpipeEngine::~FullpipeEngine() { delete _rnd; + delete _console; delete _globalMessageQueueList; } @@ -174,6 +177,8 @@ Common::Error FullpipeEngine::run() { _backgroundSurface.create(800, 600, format); + _console = new Console(this); + initialize(); _isSaveAllowed = false; @@ -272,6 +277,11 @@ void FullpipeEngine::updateEvents() { return; break; default: + if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) { + // Start the debugger + getDebugger()->attach(); + getDebugger()->onFrame(); + } ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0); ex->_keyCode = event.kbd.keycode; ex->_excFlags |= 3; diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h index 00d2863c94..ca025a48a2 100644 --- a/engines/fullpipe/fullpipe.h +++ b/engines/fullpipe/fullpipe.h @@ -36,6 +36,9 @@ #include "engines/engine.h" +#include "gui/debugger.h" +#include "fullpipe/console.h" + struct ADGameDescription; namespace Fullpipe { @@ -80,6 +83,9 @@ public: FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc); virtual ~FullpipeEngine(); + Console *_console; + GUI::Debugger *getDebugger() { return _console; } + void initialize(); void setMusicAllowed(int val) { _musicAllowed = val; } @@ -143,6 +149,7 @@ public: void playSound(int id, int flag); void startSceneTrack(); void stopSoundStream2(); + void stopAllSoundStreams(); int _sfxVolume; diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp index fba7e402d2..a4dbc30669 100644 --- a/engines/fullpipe/gfx.cpp +++ b/engines/fullpipe/gfx.cpp @@ -596,7 +596,7 @@ void Picture::draw(int x, int y, int style, int angle) { int x1 = x; int y1 = y; - debug(0, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename); + debug(7, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename); if (x != -1) x1 = x; @@ -611,7 +611,7 @@ void Picture::draw(int x, int y, int style, int angle) { return; if ((_alpha & 0xff) < 0xff) { - debug(0, "Picture:draw: alpha = %0x", _alpha); + debug(7, "Picture:draw: alpha = %0x", _alpha); } byte *pal = _paletteData; @@ -783,7 +783,7 @@ bool Bitmap::isPixelAtHitPosRB(int x, int y) { } void Bitmap::putDib(int x, int y, int32 *palette) { - debug(0, "Bitmap::putDib(%d, %d)", x, y); + debug(7, "Bitmap::putDib(%d, %d)", x, y); _x = x - g_fullpipe->_sceneRect.left; _y = y - g_fullpipe->_sceneRect.top; diff --git a/engines/fullpipe/init.cpp b/engines/fullpipe/init.cpp index 49bf72ac91..eb109e11ec 100644 --- a/engines/fullpipe/init.cpp +++ b/engines/fullpipe/init.cpp @@ -65,7 +65,7 @@ void FullpipeEngine::initObjectStates() { setObjectState(sO_Guardian, getObjectEnumState(sO_Guardian, sO_OnRight)); setObjectState(sO_Grandma, getObjectEnumState(sO_Grandma, sO_In_14)); setObjectState(sO_Boot_15, getObjectEnumState(sO_Boot_15, sO_NotPresent)); - setObjectState(sO_LeftPipe_15, getObjectEnumState(sO_LeftPipe_15, sO_OpenedShe)); + setObjectState(sO_LeftPipe_15, getObjectEnumState(sO_LeftPipe_15, sO_IsOpened)); setObjectState(sO_Pedestal_16, getObjectEnumState(sO_Pedestal_16, sO_IsFree)); setObjectState(sO_Cup, getObjectEnumState(sO_Cup, sO_InSmokeRoom)); setObjectState(sO_Pedestal_17, getObjectEnumState(sO_Pedestal_17, sO_IsFree)); @@ -84,7 +84,7 @@ void FullpipeEngine::initObjectStates() { setObjectState(sO_Lever_23, getObjectEnumState(sO_Lever_23, sO_NotTaken)); setObjectState(sO_LeverHandle_23, getObjectEnumState(sO_LeverHandle_23, sO_WithoutStool)); setObjectState(sO_LowerPipe_21, getObjectEnumState(sO_LowerPipe_21, sO_IsClosed)); - setObjectState(sO_StarsDown_24, getObjectEnumState(sO_StarsDown_24, sO_OpenedShe)); + setObjectState(sO_StarsDown_24, getObjectEnumState(sO_StarsDown_24, sO_IsOpened)); setObjectState(sO_Hatch_26, getObjectEnumState(sO_Hatch_26, sO_Closed)); setObjectState(sO_Sock_26, getObjectEnumState(sO_Sock_26, sO_NotHanging)); setObjectState(sO_LeftPipe_26, getObjectEnumState(sO_LeftPipe_26, sO_IsClosed)); diff --git a/engines/fullpipe/module.mk b/engines/fullpipe/module.mk index 88e3ac5d02..bd948b7ab4 100644 --- a/engines/fullpipe/module.mk +++ b/engines/fullpipe/module.mk @@ -2,6 +2,7 @@ MODULE := engines/fullpipe MODULE_OBJS = \ behavior.o \ + console.o \ detection.o \ floaters.o \ fullpipe.o \ diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp index f67011a50f..20b710d7df 100644 --- a/engines/fullpipe/motion.cpp +++ b/engines/fullpipe/motion.cpp @@ -28,9 +28,9 @@ #include "fullpipe/objects.h" #include "fullpipe/statics.h" +#include "fullpipe/gameloader.h" #include "fullpipe/motion.h" #include "fullpipe/messages.h" -#include "fullpipe/gameloader.h" namespace Fullpipe { @@ -185,6 +185,130 @@ MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, return mq; } +MctlLadder::MctlLadder() { + _ladder_field_18 = 0; + _objId = 0; + _height = 0; + _ladderY = 0; + _ladder_field_14 = 0; + + _ladder_field_20 = 0; + _ladder_field_24 = 0; +} + +MctlLadder::~MctlLadder() { + freeItems(); +} + +int MctlLadder::collisionDetection(StaticANIObject *man) { + if (findObjectPos(man) < 0) + return 0; + + double delta; + + if ((double)(man->_oy - _ladderY) / (double)_height < 0.0) + delta = -0.5; + else + delta = 0.5; + + int res = (int)((double)(man->_oy - _ladderY) / (double)_height + delta); + + if (res < 0) + return 0; + + return res; +} + +void MctlLadder::addObject(StaticANIObject *obj) { + if (findObjectPos(obj) < 0) { + MctlLadderMovement *movement = new MctlLadderMovement; + + if (initMovement(obj, movement)) { + _mgm.addItem(obj->_id); + _movements.push_back(movement); + } else { + delete movement; + } + } +} + +int MctlLadder::findObjectPos(StaticANIObject *obj) { + int res = -1; + + for (Common::List<MctlLadderMovement *>::iterator it = _movements.begin(); it != _movements.end(); ++it, ++res) + if ((*it)->objId == obj->_id) + break; + + return res; +} + +bool MctlLadder::initMovement(StaticANIObject *ani, MctlLadderMovement *movement) { + GameVar *v = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(ani->getName()); + + if (!v) + return false; + + v = v->getSubVarByName("Test_Ladder"); + + if (!v) + return false; + + movement->staticIdsSize = 6; + movement->movVars = new MctlLadderMovementVars; + movement->staticIds = new int[movement->staticIdsSize]; + + v = v->getSubVarByName("Up"); + + if (!v) + return false; + + movement->movVars->varUpStart = v->getSubVarAsInt("Start"); + movement->movVars->varUpGo = v->getSubVarAsInt("Go"); + movement->movVars->varUpStop = v->getSubVarAsInt("Stop"); + + movement->staticIds[0] = ani->getMovementById(movement->movVars->varUpStart)->_staticsObj1->_staticsId; + movement->staticIds[2] = ani->getMovementById(movement->movVars->varUpGo)->_staticsObj1->_staticsId; + + v = v->getSubVarByName("Down"); + + if (!v) + return false; + + movement->movVars->varDownStart = v->getSubVarAsInt("Start"); + movement->movVars->varDownGo = v->getSubVarAsInt("Go"); + movement->movVars->varDownStop = v->getSubVarAsInt("Stop"); + + movement->staticIds[1] = ani->getMovementById(movement->movVars->varDownStart)->_staticsObj1->_staticsId; + movement->staticIds[3] = ani->getMovementById(movement->movVars->varDownGo)->_staticsObj1->_staticsId; + + movement->objId = ani->_id; + + return true; +} + +void MctlLadder::freeItems() { + _mgm.clear(); + + for (Common::List<MctlLadderMovement *>::iterator it = _movements.begin(); it != _movements.end(); ++it) { + delete (*it)->movVars; + delete [] (*it)->staticIds; + } + + _movements.clear(); +} + +MessageQueue *MctlLadder::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { + warning("STUB: MctlLadder::method34()"); + + return 0; +} + +MessageQueue *MctlLadder::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { + warning("STUB: MctlLadder::doWalkTo()"); + + return 0; +} + MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr) { warning("STUB: MctlCompound::findClosestConnectionPoint()"); diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h index bab0ffc8ca..5842b296da 100644 --- a/engines/fullpipe/motion.h +++ b/engines/fullpipe/motion.h @@ -161,6 +161,50 @@ public: MessageQueue *genMovement(MGMInfo *mgminfo); }; +struct MctlLadderMovementVars { + int varUpGo; + int varDownGo; + int varUpStop; + int varDownStop; + int varUpStart; + int varDownStart; +}; + +struct MctlLadderMovement { + int objId; + int staticIdsSize; + MctlLadderMovementVars *movVars; + int *staticIds; +}; + +class MctlLadder : public MotionController { +public: + int _objId; + int _ladderY; + int _ladder_field_14; + int _ladder_field_18; + int _height; + int _ladder_field_20; + int _ladder_field_24; + Common::List<MctlLadderMovement *> _movements; + MGM _mgm; + +public: + MctlLadder(); + virtual ~MctlLadder(); + int collisionDetection(StaticANIObject *man); + + virtual void addObject(StaticANIObject *obj); + virtual int removeObject(StaticANIObject *obj) { return 1; } + virtual void freeItems(); + virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId); + virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId); + +private: + int findObjectPos(StaticANIObject *obj); + bool initMovement(StaticANIObject *ani, MctlLadderMovement *movement); +}; + class MovGraphNode : public CObject { public: int _x; diff --git a/engines/fullpipe/objectnames.h b/engines/fullpipe/objectnames.h index 241e31b165..b8696ec672 100644 --- a/engines/fullpipe/objectnames.h +++ b/engines/fullpipe/objectnames.h @@ -148,7 +148,7 @@ namespace Fullpipe { #define sO_ClockAxis "\xce\xf1\xfc \xf7\xe0\xf1\xee\xe2" // "Ось часов" #define sO_Opened "\xce\xf2\xea\xf0\xfb\xf2" // "Открыт" #define sO_OpenedWithBoot "\xce\xf2\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Открыта с ботинком" -#define sO_OpenedShe "\xce\xf2\xea\xf0\xfb\xf2\xe0" // "Открыта" +#define sO_IsOpened "\xce\xf2\xea\xf0\xfb\xf2\xe0" // "Открыта" #define sO_WeirdWacko "\xce\xf2\xec\xee\xf0\xee\xe6\xe5\xed\xed\xfb\xe9" // "Отмороженный" #define sO_NotPresent "\xce\xf2\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "Отсутствует" #define sO_Error "\xce\xf8\xe8\xe1\xea\xe0" // "Ошибка" diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp index 3831831866..61ff3457a7 100644 --- a/engines/fullpipe/scene.cpp +++ b/engines/fullpipe/scene.cpp @@ -447,7 +447,7 @@ void Scene::objectList_sortByPriority(PtrList &list) { } void Scene::draw() { - debug(0, ">>>>> Scene::draw()"); + debug(6, ">>>>> Scene::draw()"); updateScrolling(); drawContent(60000, 0, true); @@ -470,11 +470,74 @@ void Scene::draw() { } void Scene::updateScrolling() { - debug(0, "STUB Scene::updateScrolling()"); + if (_messageQueueId && !_x && !_y) { + MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId); + + if (mq) + mq->update(); + + _messageQueueId = 0; + } + + if (_x || _y) { + int offsetX = 0; + int offsetY = 0; + + if (_x < 0) { + if (!g_fullpipe->_sceneRect.left && !(((PictureObject *)_picObjList[0])->_flags & 2)) + _x = 0; + + if (_x <= -g_fullpipe->_scrollSpeed) { + offsetX = -g_fullpipe->_scrollSpeed; + _x += g_fullpipe->_scrollSpeed; + } + } else if (_x >= g_fullpipe->_scrollSpeed) { + offsetX = g_fullpipe->_scrollSpeed; + _x -= g_fullpipe->_scrollSpeed; + } else { + _x = 0; + } + + if (_y > 0) { + offsetY = g_fullpipe->_scrollSpeed; + _y -= g_fullpipe->_scrollSpeed; + } + + if (_y < 0) { + offsetY -= g_fullpipe->_scrollSpeed; + _y += g_fullpipe->_scrollSpeed; + } + + g_fullpipe->_sceneRect.translate(offsetX, offsetY); + } + + updateScrolling2(); } void Scene::updateScrolling2() { - warning("STUB Scene::updateScrolling2()"); + if (_picObjList.size()) { + Common::Point point; + int offsetY = 0; + int offsetX = 0; + + ((PictureObject *)_picObjList[0])->getDimensions(&point); + + int flags = ((PictureObject *)_picObjList[0])->_flags; + + if (g_fullpipe->_sceneRect.left < 0 && !(flags & 2)) + offsetX = -g_fullpipe->_sceneRect.left; + + if (g_fullpipe->_sceneRect.top < 0 && !(flags & 0x20)) + offsetY = -g_fullpipe->_sceneRect.top; + + if (g_fullpipe->_sceneRect.right > point.x - 1 && g_fullpipe->_sceneRect.left > 0 && !(flags & 2)) + offsetX = point.x - g_fullpipe->_sceneRect.right - 1; + + if (g_fullpipe->_sceneRect.bottom > point.y - 1 && g_fullpipe->_sceneRect.top > 0 && !(flags & 0x20)) + offsetY = point.y - g_fullpipe->_sceneRect.bottom - 1; + + g_fullpipe->_sceneRect.translate(offsetX, offsetY); + } } StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) { @@ -525,7 +588,7 @@ int Scene::getPictureObjectIdAtPos(int x, int y) { } void Scene::update(int counterdiff) { - debug(0, "Scene::update(%d)", counterdiff); + debug(6, "Scene::update(%d)", counterdiff); for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s) ((StaticANIObject *)*s)->update(counterdiff); @@ -603,7 +666,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) { } } _bigPictureArray[bgNumX][0]->getDimensions(&point); - int v32 = point.x + bgPosX; + int oldx = point.x + bgPosX; bgPosX += point.x; bgNumX++; @@ -612,7 +675,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) { break; bgNumX = 0; } - if (v32 >= g_fullpipe->_sceneRect.right - 1) + if (oldx >= g_fullpipe->_sceneRect.right - 1) break; } } diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp index 014459e847..9dc4c74b15 100644 --- a/engines/fullpipe/scenes.cpp +++ b/engines/fullpipe/scenes.cpp @@ -72,6 +72,7 @@ Vars::Vars() { scene04_coinPut = false; scene04_soundPlaying = false; scene04_dynamicPhaseIndex = 0; + scene04_needJumping = false; scene04_sceneClickX = 0; scene04_sceneClickY = 0; @@ -79,7 +80,6 @@ Vars::Vars() { scene04_dudePosX = 0; scene04_dudePosY = 0; - scene04_var01 = 0; scene04_var02 = 0; scene04_var04 = 0; scene04_walkingKozyawka = 0; @@ -100,6 +100,7 @@ Vars::Vars() { scene04_var20 = 0; scene04_var24 = 0; scene04_bottleY = 0; + scene04_ladderOffset = 0; selector = 0; } diff --git a/engines/fullpipe/scenes.h b/engines/fullpipe/scenes.h index 670b94a839..e7960fe010 100644 --- a/engines/fullpipe/scenes.h +++ b/engines/fullpipe/scenes.h @@ -26,6 +26,7 @@ namespace Fullpipe { class StaticANIObject; + class MctlLadder; int defaultUpdateCursor(); @@ -93,19 +94,27 @@ public: Common::List<GameObject *> scene04_bottleObjList; Common::List<StaticANIObject *> scene04_kozyawkiAni; - int scene04_ladder; + MctlLadder *scene04_ladder; + int scene04_ladderOffset; + bool scene04_coinPut; bool scene04_soundPlaying; + bool scene04_needJumping; + int scene04_dynamicPhaseIndex; int scene04_sceneClickX; int scene04_sceneClickY; int scene04_dudePosX; int scene04_dudePosY; + int scene04_bottleY; + + StaticANIObject *scene04_walkingKozyawka; + + int scene04_speakerVariant; + int scene04_speakerPhase; - int scene04_var01; int scene04_var02; int scene04_var04; - StaticANIObject *scene04_walkingKozyawka; int scene04_var06; int scene04_var07; int scene04_var08; @@ -116,13 +125,10 @@ public: int scene04_var13; int scene04_var14; int scene04_var15; - int scene04_speakerVariant; - int scene04_speakerPhase; int scene04_var18; int scene04_var19; int scene04_var20; StaticANIObject *scene04_var24; - int scene04_bottleY; PictureObject *selector; }; diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp index d642ebfcd2..3c2c02298a 100644 --- a/engines/fullpipe/scenes/scene04.cpp +++ b/engines/fullpipe/scenes/scene04.cpp @@ -61,7 +61,7 @@ void scene04_speakerCallback(int *phase) { } void scene04_initScene(Scene *sc) { - g_vars->scene04_var01 = 0; + g_vars->scene04_needJumping = false; g_vars->scene04_bottle = sc->getPictureObjectById(PIC_SC4_BOTTLE, 0); g_vars->scene04_hand = sc->getStaticANIObject1ById(ANI_HAND, -1); g_vars->scene04_plank = sc->getStaticANIObject1ById(ANI_PLANK, -1); @@ -196,7 +196,19 @@ void scene04_initScene(Scene *sc) { } bool sceneHandler04_friesAreWalking() { - warning("STUB: sceneHandler04_friesAreWalking()"); + if (g_vars->scene04_needJumping && g_fullpipe->_aniMan->isIdle() && !(g_fullpipe->_aniMan->_flags & 0x100)) { + int col = g_vars->scene04_ladder->collisionDetection(g_fullpipe->_aniMan); + if (col >= 3 && col <= 6 ) { + Movement *koz; + + if (!g_vars->scene04_walkingKozyawka + || (koz = g_vars->scene04_walkingKozyawka->_movement) == 0 + || koz->_id != MV_KZW_WALKPLANK + || koz->_currDynamicPhaseIndex < 10 + || koz->_currDynamicPhaseIndex > 41) + return true; + } + } return false; } @@ -233,7 +245,7 @@ int scene04_updateCursor() { } void sceneHandlers_sub01(ExCommand *ex) { - warning("sceneHandlers_sub01()"); + warning("STUB: sceneHandlers_sub01()"); } void sceneHandler04_checkBigBallClick() { @@ -267,17 +279,52 @@ void sceneHandler04_clickButton() { } void sceneHandler04_clickLadder() { - warning("sceneHandler04_clickLadder()"); + warning("STUB: sceneHandler04_clickLadder()"); } -void sceneHandler04_sub13() { - warning("sceneHandler04_sub13()"); +void sceneHandler04_jumpOnLadder() { + if (g_fullpipe->_aniMan->_movement && g_fullpipe->_aniMan->_movement->_id != MV_MAN_LOOKLADDER) + return; + + if (g_fullpipe->_aniMan->_statics->_staticsId != ST_MAN_STANDLADDER && g_fullpipe->_aniMan->_statics->_staticsId != ST_MAN_LADDERDOWN) + return; + + g_fullpipe->_aniMan->changeStatics2(ST_MAN_LADDERDOWN); + + g_fullpipe->_aniMan->_flags |= 1; + + MGM mgm; + MGMInfo mgminfo; + + mgm.addItem(ANI_MAN); + + mgminfo.ani = g_fullpipe->_aniMan; + mgminfo.staticsId2 = ST_MAN_ONPLANK; + mgminfo.x1 = 938; + mgminfo.y1 = 442; + mgminfo.field_1C = 10; + mgminfo.field_10 = 1; + mgminfo.flags = 78; + mgminfo.movementId = MV_MAN_JUMPONPLANK; + + MessageQueue *mq = mgm.genMovement(&mgminfo); + + if (mq) { + mq->_flags |= 1; + + if (!mq->chain(g_fullpipe->_aniMan)) + delete mq; + + g_fullpipe->_aniMan->_priority = 10; + } + + g_vars->scene04_ladderOffset = g_vars->scene04_ladder->collisionDetection(g_fullpipe->_aniMan); } void sceneHandler04_clickPlank() { if (sceneHandler04_friesAreWalking()) - sceneHandler04_sub13(); - else if (g_vars->scene04_var01) + sceneHandler04_jumpOnLadder(); + else if (g_vars->scene04_needJumping) g_fullpipe->playSound(SND_4_033, 0); else if (!g_vars->scene04_soundPlaying) chainQueue(QU_PNK_CLICK, 0); @@ -311,7 +358,7 @@ void sceneHandler04_dropBottle() { } void sceneHandler04_gotoLadder(int par) { - warning("sceneHandler04_gotoLadder()"); + warning("STUB: sceneHandler04_gotoLadder()"); } void sceneHandler04_lowerPlank() { @@ -319,7 +366,20 @@ void sceneHandler04_lowerPlank() { } void sceneHandler04_manFromBottle() { - warning("sceneHandler04_manFromBottle()"); + for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it) + if (*it == g_fullpipe->_aniMan) { + g_vars->scene04_bottleObjList.erase(it); + g_vars->scene04_var06 -= 9; + break; + } + + if (g_vars->scene04_ladder) + delete g_vars->scene04_ladder; + + g_vars->scene04_ladder = 0; + + getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->setEnabled(); + getGameLoaderInteractionController()->enableFlag24(); } void sceneHandler04_manToBottle() { @@ -335,7 +395,7 @@ void sceneHandler04_raisePlank() { } void sceneHandler04_shootKozyawka() { - warning("sceneHandler04_shootKozyawka()"); + warning("STUB: sceneHandler04_shootKozyawka()"); } void sceneHandler04_showCoin() { @@ -349,7 +409,7 @@ void sceneHandler04_showCoin() { } void sceneHandler04_stopSound() { - warning("sceneHandler04_stopSound()"); + warning("STUB: sceneHandler04_stopSound()"); } void sceneHandler04_sub1(ExCommand *ex) { @@ -382,11 +442,78 @@ void sceneHandler04_walkKozyawka() { } void sceneHandler04_sub4() { - warning("sceneHandler04_sub4()"); +#if 0 + int var20 = g_vars->scene04_var20; + int oldDynIndex = g_vars->scene04_dynamicPhaseIndex; + v2 = g_vars->scene04_var20 + g_vars->scene04_dynamicPhaseIndex; + g_vars->scene04_dynamicPhaseIndex += g_vars->scene04_var20; + + if (g_vars->scene04_var20 + g_vars->scene04_dynamicPhaseIndex < 0) { + v2 = 0; + var20 = 0; + g_vars->scene04_dynamicPhaseIndex = 0; + g_vars->scene04_var20 = 0; + } + + if (v2 > 14) { + v2 = 14; + var20 = 0; + g_vars->scene04_dynamicPhaseIndex = 14; + g_vars->scene04_var20 = 0; + } + + v4 = __OFSUB__(g_vars->scene04_var06, v2); + v3 = g_vars->scene04_var06 - v2 < 0; + + if (g_vars->scene04_var06 > v2) { + ++var20; + v4 = __OFSUB__(g_vars->scene04_var06, v2); + v3 = g_vars->scene04_var06 - v2 < 0; + g_vars->scene04_var20 = var20; + } + + if (v3 ^ v4) { + --var20; + g_vars->scene04_var20 = var20; + } + + if (oldDynIndex <= g_vars->scene04_var06) + if (v2 <= g_vars->scene04_var06) + goto LABEL_16; + } else if (v2 > g_vars->scene04_var06) { + goto LABEL_16; + } + + g_vars->scene04_var25++; + + if (var20 && g_vars->scene04_var25 > 1) { + g_vars->scene04_var25 = 0; + g_vars->scene04_var20--; + } + LABEL_16: + + Common::Point point; + + int curdelta = g_vars->scene04_spring->getCurrDimensions(&point)->y - g_vars->scene04_dynamicPhaseIndex; + + if (g_vars->scene04_dynamicPhaseIndex) { + if (!g_vars->scene04_spring->_movement) + g_vars->scene04_spring->startAnim(MV_SPR_LOWER, 0, -1); + + g_vars->scene04_spring->_movement->setDynamicPhaseIndex(g_vars->scene04_dynamicPhaseIndex); + } else { + g_vars->scene04_spring->changeStatics2(ST_SPR_UP); + } + + if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex) + sceneHandler04_bottleUpdateObjects(curdelta - (g_vars->scene04_spring->getCurrDimensions(&point)->y - g_vars->scene04_dynamicPhaseIndex)); +#endif + + warning("STUB: sceneHandler04_sub4()"); } void sceneHandler04_sub5() { - warning("sceneHandler04_sub5()"); + warning("STUB: sceneHandler04_sub5()"); } void sceneHandler04_bottleUpdateObjects(int off) { @@ -421,36 +548,138 @@ void sceneHandler04_liftBottle() { } } -void sceneHandler04_sub7() { - warning("sceneHandler04_sub7()"); +void sceneHandler04_startSounds(const char *snd1, const char *snd2, const char *snd3) { + warning("STUB: sceneHandler04_startSounds()"); +} + +void sceneHandler04_goClock() { + sceneHandler04_walkKozyawka(); + chainQueue(QU_SC4_GOCLOCK, 0); + g_vars->scene04_soundPlaying = 1; + g_vars->scene04_coinPut = 0; + + g_fullpipe->stopAllSoundStreams(); + + sceneHandler04_startSounds("sc4_start.ogg", "sc4_loop.ogg", "sc4_stop2.ogg"); + + g_vars->scene04_var14 = 0; } void sceneHandler04_sub8(ExCommand *ex) { - warning("sceneHandler04_sub8()"); + warning("STUB: sceneHandler04_sub8()"); } -void sceneHandler04_sub9(StaticANIObject *ani) { - warning("sceneHandler04_sub9()"); +void sceneHandler04_sub12() { + StaticANIObject *ball = g_fullpipe->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1); + + if (ball && ball->_flags & 4) + for (uint i = 0; i < ball->_movements.size(); i++) + ((Movement *)ball->_movements[i])->_counterMax = 0; + + g_vars->scene04_var13 = 0; +} + +void sceneHandler04_handTake() { + g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED); + + if (g_vars->scene04_kozyawkiAni.size()) { + if (g_vars->scene04_kozyawkiAni.size() == 1) { + chainQueue(QU_HND_TAKE1, 0); + g_vars->scene04_var19 = 0; + } else { + chainQueue((g_vars->scene04_kozyawkiAni.size() != 2) ? QU_HND_TAKEBOTTLE : QU_HND_TAKE2, 0); + g_vars->scene04_var19 = 0; + } + } else { + chainQueue(QU_HND_TAKE0, 0); + g_vars->scene04_var19 = 0; + } } -void sceneHandler04_sub15() { - warning("sceneHandler04_sub15()"); +void sceneHandler04_sub9(StaticANIObject *ani) { + g_vars->scene04_bottleObjList.push_back(ani); + g_vars->scene04_kozyawkiAni.push_back(ani); + + g_vars->scene04_var06 += 2; + g_vars->scene04_walkingKozyawka = 0; + g_vars->scene04_var24 = 0; + + if (g_vars->scene04_kozyawkiAni.size() > 1 ) + g_vars->scene04_var19 = 0; + + if (g_vars->scene04_kozyawkiAni.size() <= 2 || g_vars->scene04_hand->_movement) { + sceneHandler04_walkKozyawka(); + } else { + sceneHandler04_handTake(); + sceneHandler04_stopSound(); + } } void sceneHandler04_sub17() { - warning("sceneHandler04_sub17()"); + StaticANIObject *ball = g_fullpipe->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1); + + if (g_vars->scene04_needJumping + && (!ball || !(ball->_flags & 4)) + && g_vars->scene04_ladder->collisionDetection(g_fullpipe->_aniMan) > 3) { + + if (!g_fullpipe->_rnd->getRandomNumber(49)) { + if (g_vars->scene04_var15) + chainQueue(QU_BALL_WALKR, 0); + else + chainQueue(QU_BALL_WALKL, 0); + + g_vars->scene04_var15 = !g_vars->scene04_var15; + + sceneHandler04_checkBigBallClick(); + + g_vars->scene04_var14 = 0; + } + } } void sceneHandler04_takeBottle() { - warning("sceneHandler04_takeBottle()"); + g_vars->scene04_var02 = 1; + g_vars->scene04_hand->_priority = 5; + + g_fullpipe->setObjectState(sO_LowerPipe, g_fullpipe->getObjectEnumState(sO_LowerPipe, sO_IsOpened)); } void sceneHandler04_takeKozyawka() { - warning("sceneHandler04_takeKozyawka()"); + if (g_vars->scene04_kozyawkiAni.size() > 0) { + if (g_vars->scene04_kozyawkiAni.size() == 1) + g_vars->scene04_var19 = 1; + + StaticANIObject *koz = g_vars->scene04_kozyawkiAni.front(); + g_vars->scene04_kozyawkiAni.pop_front(); + + if (koz) { + koz->queueMessageQueue(0); + koz->hide(); + + g_vars->scene04_kozyawkiObjList.push_back(koz); + + for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it) + if (*it == koz) { + g_vars->scene04_bottleObjList.erase(it); + break; + } + + g_vars->scene04_var06 -= 2; + } + } } void sceneHandler04_testPlank(ExCommand *ex) { - warning("sceneHandler04_testPlank()"); + MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex->_parId); + + if (!mq) + return; + + if (g_vars->scene04_plank->_movement || !g_vars->scene04_plank->_statics || g_vars->scene04_plank->_statics->_staticsId != ST_PNK_WEIGHTLEFT) { + mq->getExCommandByIndex(0)->_messageNum = MV_KZW_TOHOLERV; + } else { + mq->getExCommandByIndex(0)->_messageNum = MV_KZW_WALKPLANK; + } } void sceneHandler04_updateBottle() { @@ -526,7 +755,7 @@ int sceneHandler04(ExCommand *ex) { if (g_vars->scene04_var10) sceneHandler04_sub1(0); - sceneHandler04_sub15(); + sceneHandler04_handTake(); sceneHandler04_stopSound(); break; @@ -614,9 +843,9 @@ int sceneHandler04(ExCommand *ex) { sceneHandler04_sub1(0); if (g_vars->scene04_coinPut && g_vars->scene04_var18 && !g_vars->scene04_var09 && !g_vars->scene04_soundPlaying) - sceneHandler04_sub7(); + sceneHandler04_goClock(); - if (g_vars->scene04_var01) { + if (g_vars->scene04_needJumping) { if (!g_vars->scene04_soundPlaying) { g_fullpipe->startSceneTrack(); @@ -676,7 +905,7 @@ int sceneHandler04(ExCommand *ex) { sceneHandler04_clickPlank(); ex->_messageKind = 0; - } else if (g_vars->scene04_var01) { + } else if (g_vars->scene04_needJumping) { sceneHandler04_sub8(ex); } else if (!ani || !canInteractAny(g_fullpipe->_aniMan, ani, ex->_keyCode)) { PictureObject *pic = g_fullpipe->_currentScene->getPictureObjectById(picid, 0); @@ -719,7 +948,7 @@ int sceneHandler04(ExCommand *ex) { if (g_vars->scene04_var10) sceneHandler04_sub1(0); - sceneHandler04_sub15(); + sceneHandler04_handTake(); } break; diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp index b4a864d164..147d6218c6 100644 --- a/engines/fullpipe/sound.cpp +++ b/engines/fullpipe/sound.cpp @@ -139,5 +139,9 @@ void FullpipeEngine::stopSoundStream2() { warning("STUB: FullpipeEngine::stopSoundStream2()"); } +void FullpipeEngine::stopAllSoundStreams() { + warning("STUB: FullpipeEngine::stopAllSoundStreams()"); +} + } // End of namespace Fullpipe diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp index b82875f638..8324e0f322 100644 --- a/engines/fullpipe/statics.cpp +++ b/engines/fullpipe/statics.cpp @@ -496,7 +496,7 @@ void StaticANIObject::draw() { Common::Point point; Common::Rect rect; - debug(0, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); + debug(6, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); if (_shadowsOn && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_shadows && (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) { @@ -556,7 +556,7 @@ void StaticANIObject::draw() { } void StaticANIObject::draw2() { - debug(0, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); + debug(6, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy); if ((_flags & 4) && (_flags & 0x10)) { if (_movement) { @@ -891,7 +891,7 @@ void StaticANIObject::hide() { } void StaticANIObject::show1(int x, int y, int movId, int mqId) { - debug(0, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId); + debug(6, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId); if (_messageQueueId) return; @@ -998,20 +998,17 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase int newy = _oy; Common::Point point; - debug(0, "0 %d %d", newx, newy); if (_movement) { _movement->getCurrDynamicPhaseXY(point); newx -= point.x; newy -= point.y; - debug(0, "1 %d %d", newx, newy); } else if (_statics) { _statics->getSomeXY(point); newx -= point.x; newy -= point.y; - debug(0, "2 %d %d - %d %d assa", newx, newy, point.x, point.y); } _movement = mov; @@ -1029,7 +1026,6 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase newx += point.x + _movement->_mx; newy += point.y + _movement->_my; - debug(0, "3 %d %d", newx, newy); _stepArray.gotoNextPoint(); ExCommand *ex = _movement->_currDynamicPhase->getExCommand(); @@ -1794,7 +1790,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) { _field_7E = 0; _rect = new Common::Rect(); - debug(0, "DynamicPhase::DynamicPhase(src, %d)", reverse); + debug(1, "DynamicPhase::DynamicPhase(src, %d)", reverse); if (reverse) { if (!src->_bitmap) diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h index d8c30e5004..b7c6a9b5a9 100644 --- a/engines/hopkins/hopkins.h +++ b/engines/hopkins/hopkins.h @@ -48,6 +48,7 @@ #include "common/util.h" #include "engines/engine.h" #include "graphics/surface.h" +#include "gui/debugger.h" /** * This is the namespace of the Hopkins engine. @@ -136,6 +137,8 @@ protected: virtual Common::Error run(); virtual bool hasFeature(EngineFeature f) const; + GUI::Debugger *getDebugger() { return _debug; } + public: AnimationManager *_animMan; ComputerManager *_computer; diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h index 0561aa251e..4d923d1f0e 100644 --- a/engines/neverhood/neverhood.h +++ b/engines/neverhood/neverhood.h @@ -32,6 +32,8 @@ #include "common/system.h" #include "audio/mixer.h" #include "engines/engine.h" +#include "gui/debugger.h" +#include "neverhood/console.h" #include "neverhood/messages.h" namespace Neverhood { @@ -48,7 +50,6 @@ class Screen; class SoundMan; class AudioResourceMan; class StaticData; -class Console; struct NPoint; struct GameState { @@ -90,6 +91,7 @@ public: GameModule *_gameModule; StaticData *_staticData; Console *_console; + GUI::Debugger *getDebugger() { return _console; } SoundMan *_soundMan; AudioResourceMan *_audioResourceMan; diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp index 0b3e1ee040..0707a83e87 100644 --- a/engines/pegasus/neighborhood/caldoria/caldoria.cpp +++ b/engines/pegasus/neighborhood/caldoria/caldoria.cpp @@ -386,54 +386,72 @@ void Caldoria::startSpotOnceOnly(TimeValue startTime, TimeValue stopTime) { if (!_privateFlags.getFlag(kCaldoriaPrivateSeen13CarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen13CarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria14, kEast): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen14CarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen14CarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria18, kWest): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen18CarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen18CarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria23, kSouth): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen23CarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen23CarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria33, kSouth): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen33CarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen33CarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria36, kNorth): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen36CarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen36CarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria41, kNorth): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41NorthCarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen41NorthCarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria41, kEast): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41EastCarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen41EastCarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; case MakeRoomView(kCaldoria41, kWest): if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41WestCarFlag) && _vm->getRandomBit() == 0) { _privateFlags.setFlag(kCaldoriaPrivateSeen41WestCarFlag, true); Neighborhood::startSpotOnceOnly(startTime, stopTime); + } else { + showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection())); } break; default: diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 80d8ab8257..e7cbde6cbb 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -2980,7 +2980,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) { Script *script; // Create a custom segment manager here, so that the game's segment // manager won't be affected by loading and unloading scripts here. - SegManager *customSegMan = new SegManager(_engine->getResMan()); + SegManager *customSegMan = new SegManager(_engine->getResMan(), _engine->getScriptPatcher()); Common::List<ResourceId>::iterator itr; for (itr = resources.begin(); itr != resources.end(); ++itr) { diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 6955225fe5..16b88b5672 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -484,7 +484,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_nr); if (s.isLoading()) - load(_nr, g_sci->getResMan()); + load(_nr, g_sci->getResMan(), g_sci->getScriptPatcher()); s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _bufSize s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _scriptSize s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _heapSize diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 6616a0ee13..c661a00185 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -32,7 +32,8 @@ namespace Sci { -Script::Script() : SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) { +Script::Script() + : SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) { freeScript(); } @@ -65,7 +66,7 @@ void Script::freeScript() { _objects.clear(); } -void Script::load(int script_nr, ResourceManager *resMan) { +void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher) { freeScript(); Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0); @@ -136,7 +137,7 @@ void Script::load(int script_nr, ResourceManager *resMan) { memcpy(_buf, script->data, script->size); // Check scripts for matching signatures and patch those, if found - patcherProcessScript(_nr, _buf, script->size); + scriptPatcher->processScript(_nr, _buf, script->size); if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, _nr), 0); diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 6a27dc7f64..9e016156b8 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -25,6 +25,7 @@ #include "common/str.h" #include "sci/engine/segment.h" +#include "sci/engine/script_patches.h" namespace Sci { @@ -96,13 +97,7 @@ public: ~Script(); void freeScript(); - void load(int script_nr, ResourceManager *resMan); - - void patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize); - void patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11); - void patcherEnablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription); - int32 patcherFindSignature(const SciScriptPatcherEntry *patchEntry, const byte *scriptData, const uint32 scriptSize, bool isMacSci11); - void patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, bool isMacSci11); + void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher); virtual bool isValidOffset(uint16 offset) const; virtual SegmentRef dereference(reg_t pointer); diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 6293fb42ae..e776c8fb3a 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -25,6 +25,7 @@ #include "sci/engine/script.h" #include "sci/engine/state.h" #include "sci/engine/features.h" +#include "sci/engine/script_patches.h" #include "common/util.h" @@ -76,72 +77,27 @@ namespace Sci { // You have to use the exact same order in both the table and the enum, otherwise // it won't work. -#define SIG_END 0xFFFF -#define SIG_MISMATCH 0xFFFE -#define SIG_COMMANDMASK 0xF000 -#define SIG_VALUEMASK 0x0FFF -#define SIG_BYTEMASK 0x00FF -#define SIG_MAGICDWORD 0xF000 -#define SIG_ADDTOOFFSET 0xE000 -#define SIG_SELECTOR16 0x9000 -#define SIG_SELECTOR8 0x8000 -#define SIG_UINT16 0x1000 -#define SIG_BYTE 0x0000 - -#define PATCH_END SIG_END -#define PATCH_COMMANDMASK SIG_COMMANDMASK -#define PATCH_VALUEMASK SIG_VALUEMASK -#define PATCH_BYTEMASK SIG_BYTEMASK -#define PATCH_ADDTOOFFSET SIG_ADDTOOFFSET -#define PATCH_GETORIGINALBYTE 0xD000 -#define PATCH_GETORIGINALBYTEADJUST 0xC000 -#define PATCH_SELECTOR16 SIG_SELECTOR16 -#define PATCH_SELECTOR8 SIG_SELECTOR8 -#define PATCH_UINT16 SIG_UINT16 -#define PATCH_BYTE SIG_BYTE - -// defines maximum scratch area for getting original bytes from unpatched script data -#define PATCH_VALUELIMIT 4096 - -struct SciScriptPatcherEntry { - bool active; - uint16 scriptNr; - const char *description; - int16 applyCount; - uint32 magicDWord; - int magicOffset; - const uint16 *signatureData; - const uint16 *patchData; -}; - -#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL } - -struct SciScriptPatcherSelector { - const char *name; - int16 id; -}; - -SciScriptPatcherSelector selectorTable[] = { - { "cycles", -1, }, // system selector - { "seconds", -1, }, // system selector - { "init", -1, }, // system selector - { "dispose", -1, }, // system selector - { "new", -1, }, // system selector - { "curEvent", -1, }, // system selector - { "disable", -1, }, // system selector - { "show", -1, }, // system selector - { "x", -1, }, // system selector - { "cel", -1, }, // system selector - { "setMotion", -1, }, // system selector - { "deskSarg", -1, }, // Gabriel Knight - { "localize", -1, }, // Freddy Pharkas - { "put", -1, }, // Police Quest 1 VGA - { "solvePuzzle", -1, }, // Quest For Glory 3 - { "timesShownID", -1, }, // Space Quest 1 VGA - { "startText", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support - { "startAudio", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support - { "modNum", -1, }, // King's Quest 6 CD / Laura Bow 2 CD for audio+text support - { NULL, -1 } +static const char *const selectorNameTable[] = { + "cycles", // system selector + "seconds", // system selector + "init", // system selector + "dispose", // system selector + "new", // system selector + "curEvent", // system selector + "disable", // system selector + "show", // system selector + "x", // system selector + "cel", // system selector + "setMotion", // system selector + "deskSarg", // Gabriel Knight + "localize", // Freddy Pharkas + "put", // Police Quest 1 VGA + "solvePuzzle", // Quest For Glory 3 + "timesShownID", // Space Quest 1 VGA + "startText", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support + "startAudio", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support + "modNum", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support + NULL }; enum ScriptPatcherSelectors { @@ -186,7 +142,7 @@ enum ScriptPatcherSelectors { // We fix the script by patching in a jump to the proper code inside fawaz::doit. // Responsible method: fawaz::handleEvent // Fixes bug: #6402 -const uint16 camelotSignaturePeepingTom[] = { +static const uint16 camelotSignaturePeepingTom[] = { 0x72, SIG_MAGICDWORD, SIG_UINT16 + 0x7e, 0x07, // lofsa fawaz <-- start of proper initializion code 0xa1, 0xb9, // sag b9h SIG_ADDTOOFFSET +571, // skip 571 bytes @@ -203,15 +159,15 @@ const uint16 camelotSignaturePeepingTom[] = { SIG_END }; -const uint16 camelotPatchPeepingTom[] = { +static const uint16 camelotPatchPeepingTom[] = { PATCH_ADDTOOFFSET +576, 0x32, PATCH_UINT16 + 0xbd, 0xfd, // jmp to fawaz::doit / properly init peepingTom code PATCH_END }; -// script, description, signature patch -SciScriptPatcherEntry camelotSignatures[] = { - { true, 62, "fix peepingTom Sierra bug", 1, 0, 0, camelotSignaturePeepingTom, camelotPatchPeepingTom }, +// script, description, signature patch +static const SciScriptPatcherEntry camelotSignatures[] = { + { true, 62, "fix peepingTom Sierra bug", 1, camelotSignaturePeepingTom, camelotPatchPeepingTom }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -224,7 +180,7 @@ SciScriptPatcherEntry camelotSignatures[] = { // Applies to at least: PC-CD // Responsible method: stayAndHelp::changeState // Fixes bug: #5107 -const uint16 ecoquest1SignatureStayAndHelp[] = { +static const uint16 ecoquest1SignatureStayAndHelp[] = { 0x3f, 0x01, // link 01 0x87, 0x01, // lap param[1] 0x65, 0x14, // aTop state @@ -253,7 +209,7 @@ const uint16 ecoquest1SignatureStayAndHelp[] = { SIG_END }; -const uint16 ecoquest1PatchStayAndHelp[] = { +static const uint16 ecoquest1PatchStayAndHelp[] = { 0x87, 0x01, // lap param[1] 0x65, 0x14, // aTop state 0x36, // push @@ -278,9 +234,9 @@ const uint16 ecoquest1PatchStayAndHelp[] = { PATCH_END }; -// script, description, signature patch -SciScriptPatcherEntry ecoquest1Signatures[] = { - { true, 660, "CD: bad messagebox and freeze", 1, 0, 0, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp }, +// script, description, signature patch +static const SciScriptPatcherEntry ecoquest1Signatures[] = { + { true, 660, "CD: bad messagebox and freeze", 1, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -291,7 +247,7 @@ SciScriptPatcherEntry ecoquest1Signatures[] = { // is resetted every time, which means the previous text isn't available // anymore. We have to patch the code because of that. // Fixes bug: #4993 -const uint16 ecoquest2SignatureEcorder[] = { +static const uint16 ecoquest2SignatureEcorder[] = { 0x31, 0x22, // bnt [next state] 0x39, 0x0a, // pushi 0a 0x5b, 0x04, 0x1e, // lea temp[1e] @@ -318,7 +274,7 @@ const uint16 ecoquest2SignatureEcorder[] = { SIG_END }; -const uint16 ecoquest2PatchEcorder[] = { +static const uint16 ecoquest2PatchEcorder[] = { 0x2f, 0x02, // bt [to pushi 07] 0x3a, // toss 0x48, // ret @@ -347,7 +303,7 @@ const uint16 ecoquest2PatchEcorder[] = { // kGraphFillBoxAny and kGraphUpdateBox), as there isn't enough space to patch // the function otherwise. // Fixes bug: #6467 -const uint16 ecoquest2SignatureEcorderTutorial[] = { +static const uint16 ecoquest2SignatureEcorderTutorial[] = { 0x30, SIG_UINT16 + 0x23, 0x00, // bnt [next state] 0x39, 0x0a, // pushi 0a 0x5b, 0x04, 0x1f, // lea temp[1f] @@ -370,7 +326,7 @@ const uint16 ecoquest2SignatureEcorderTutorial[] = { SIG_END }; -const uint16 ecoquest2PatchEcorderTutorial[] = { +static const uint16 ecoquest2PatchEcorderTutorial[] = { 0x31, 0x23, // bnt [next state] (save 1 byte) // The parameter count below should be 7, but we're out of bytes // to patch! A workaround has been added because of this @@ -403,10 +359,10 @@ const uint16 ecoquest2PatchEcorderTutorial[] = { PATCH_END }; -// script, description, signature patch -SciScriptPatcherEntry ecoquest2Signatures[] = { - { true, 50, "initial text not removed on ecorder", 1, 0, 0, ecoquest2SignatureEcorder, ecoquest2PatchEcorder }, - { true, 333, "initial text not removed on ecorder tutorial",1, 0, 0, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial }, +// script, description, signature patch +static const SciScriptPatcherEntry ecoquest2Signatures[] = { + { true, 50, "initial text not removed on ecorder", 1, ecoquest2SignatureEcorder, ecoquest2PatchEcorder }, + { true, 333, "initial text not removed on ecorder tutorial", 1, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -416,26 +372,26 @@ SciScriptPatcherEntry ecoquest2Signatures[] = { // infinite loop. This script bug was not apparent in SSCI, probably because // event handling was slightly different there, so it was never discovered. // Fixes bug: #5120 -const uint16 fanmadeSignatureInfiniteLoop[] = { +static const uint16 fanmadeSignatureInfiniteLoop[] = { 0x38, SIG_UINT16 + 0x4c, 0x00, // pushi 004c 0x39, 0x00, // pushi 00 0x87, 0x01, // lap 01 0x4b, 0x04, // send 04 SIG_MAGICDWORD, 0x18, // not - 0x30, SIG_UINT16 + 0x2f, 0x00, // bnt 002f [06a5] --> jmp ffbc [0664] --> BUG! infinite loop + 0x30, SIG_UINT16 + 0x2f, 0x00, // bnt 002f [06a5] --> jmp ffbc [0664] --> BUG! infinite loop SIG_END }; -const uint16 fanmadePatchInfiniteLoop[] = { +static const uint16 fanmadePatchInfiniteLoop[] = { PATCH_ADDTOOFFSET | +10, 0x30, SIG_UINT16 + 0x32, 0x00, // bnt 0032 [06a8] --> pushi 004c PATCH_END }; -// script, description, signature patch -SciScriptPatcherEntry fanmadeSignatures[] = { - { true, 999, "infinite loop on typo", 1, 0, 0, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop }, +// script, description, signature patch +static const SciScriptPatcherEntry fanmadeSignatures[] = { + { true, 999, "infinite loop on typo", 1, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -449,7 +405,7 @@ SciScriptPatcherEntry fanmadeSignatures[] = { // The "score" code is already buggy and sets volume to 0 when playing // Applies to at least: English PC-CD // Responsible method: unknown -const uint16 freddypharkasSignatureScoreDisposal[] = { +static const uint16 freddypharkasSignatureScoreDisposal[] = { 0x67, 0x32, // pTos 32 (selector theAudCount) 0x78, // push1 SIG_MAGICDWORD, @@ -460,7 +416,7 @@ const uint16 freddypharkasSignatureScoreDisposal[] = { SIG_END }; -const uint16 freddypharkasPatchScoreDisposal[] = { +static const uint16 freddypharkasPatchScoreDisposal[] = { 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 @@ -475,7 +431,7 @@ const uint16 freddypharkasPatchScoreDisposal[] = { // this fixes the issue. // Applies to at least: English PC-CD // Responsible method: rm235::init and sEnterFrom500::changeState -const uint16 freddypharkasSignatureCanisterHang[] = { +static const uint16 freddypharkasSignatureCanisterHang[] = { 0x38, SIG_SELECTOR16 + SELECTOR_disable, // pushi disable 0x7a, // push2 SIG_MAGICDWORD, @@ -486,7 +442,7 @@ const uint16 freddypharkasSignatureCanisterHang[] = { SIG_END }; -const uint16 freddypharkasPatchCanisterHang[] = { +static const uint16 freddypharkasPatchCanisterHang[] = { PATCH_ADDTOOFFSET | +3, 0x78, // push1 PATCH_ADDTOOFFSET | +2, @@ -506,7 +462,7 @@ const uint16 freddypharkasPatchCanisterHang[] = { // We just reuse the active event, thus removing the duplicate kGetEvent call. // Applies to at least: English PC-CD, German Floppy, English Mac // Responsible method: lowerLadder::doit and highLadder::doit -const uint16 freddypharkasSignatureLadderEvent[] = { +static const uint16 freddypharkasSignatureLadderEvent[] = { 0x39, SIG_MAGICDWORD, SIG_SELECTOR8 + SELECTOR_new, // pushi new 0x76, // push0 @@ -522,7 +478,7 @@ const uint16 freddypharkasSignatureLadderEvent[] = { SIG_END }; -const uint16 freddypharkasPatchLadderEvent[] = { +static const uint16 freddypharkasPatchLadderEvent[] = { 0x34, 0x00, 0x00, // ldi 0000 (waste 3 bytes, overwrites first 2 pushes) PATCH_ADDTOOFFSET | +8, 0xa5, 0x00, // sat temp[0] (waste 2 bytes, overwrites 2nd send) @@ -537,7 +493,7 @@ const uint16 freddypharkasPatchLadderEvent[] = { // so we revert the script back to using the values of the DOS script. // Applies to at least: English Mac // Responsible method: unknown -const uint16 freddypharkasSignatureMacInventory[] = { +static const uint16 freddypharkasSignatureMacInventory[] = { SIG_MAGICDWORD, 0x39, 0x23, // pushi 23 0x39, 0x74, // pushi 74 @@ -547,7 +503,7 @@ const uint16 freddypharkasSignatureMacInventory[] = { SIG_END }; -const uint16 freddypharkasPatchMacInventory[] = { +static const uint16 freddypharkasPatchMacInventory[] = { 0x39, 0x02, // pushi 02 (now matches the DOS version) PATCH_ADDTOOFFSET +23, 0x39, 0x04, // pushi 04 (now matches the DOS version) @@ -555,11 +511,11 @@ const uint16 freddypharkasPatchMacInventory[] = { }; // script, description, signature patch -SciScriptPatcherEntry freddypharkasSignatures[] = { - { true, 0, "CD: score early disposal", 1, 0, 0, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal }, - { true, 15, "Mac: broken inventory", 1, 0, 0, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory }, - { true, 235, "CD: canister pickup hang", 3, 0, 0, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang }, - { true, 320, "ladder event issue", 2, 0, 0, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent }, +static const SciScriptPatcherEntry freddypharkasSignatures[] = { + { true, 0, "CD: score early disposal", 1, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal }, + { true, 15, "Mac: broken inventory", 1, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory }, + { true, 235, "CD: canister pickup hang", 3, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang }, + { true, 320, "ladder event issue", 2, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -568,7 +524,7 @@ SciScriptPatcherEntry freddypharkasSignatures[] = { // this is not enough time to get to the door, so we patch that to 23 seconds // Applies to at least: English PC-CD, German PC-CD, English Mac // Responsible method: daySixBeignet::changeState -const uint16 gk1SignatureDay6PoliceBeignet[] = { +static const uint16 gk1SignatureDay6PoliceBeignet[] = { 0x35, 0x04, // ldi 04 0x1a, // eq? 0x30, SIG_ADDTOOFFSET +2, // bnt [next state check] @@ -583,7 +539,7 @@ const uint16 gk1SignatureDay6PoliceBeignet[] = { SIG_END }; -const uint16 gk1PatchDay6PoliceBeignet[] = { +static const uint16 gk1PatchDay6PoliceBeignet[] = { PATCH_ADDTOOFFSET +16, 0x34, PATCH_UINT16 + 0x17, 0x00, // ldi 23 0x65, PATCH_GETORIGINALBYTEADJUST +20, +2, // aTop seconds (1c for PC, 1e for Mac) @@ -594,7 +550,7 @@ const uint16 gk1PatchDay6PoliceBeignet[] = { // this is not enough time to get to the door, so we patch it to 42 seconds // Applies to at least: English PC-CD, German PC-CD, English Mac // Responsible method: sargSleeping::changeState -const uint16 gk1SignatureDay6PoliceSleep[] = { +static const uint16 gk1SignatureDay6PoliceSleep[] = { 0x35, 0x08, // ldi 08 0x1a, // eq? 0x31, SIG_ADDTOOFFSET +1, // bnt [next state check] @@ -605,7 +561,7 @@ const uint16 gk1SignatureDay6PoliceSleep[] = { 0 }; -const uint16 gk1PatchDay6PoliceSleep[] = { +static const uint16 gk1PatchDay6PoliceSleep[] = { PATCH_ADDTOOFFSET +5, 0x34, SIG_UINT16 + 0x2a, 0x00, // ldi 42 0x65, PATCH_GETORIGINALBYTEADJUST +9, +2, // aTop seconds (1c for PC, 1e for Mac) @@ -615,7 +571,7 @@ const uint16 gk1PatchDay6PoliceSleep[] = { // startOfDay5::changeState (20h) - when gabriel goes to the phone the script will hang // Applies to at least: English PC-CD, German PC-CD, English Mac // Responsible method: startOfDay5::changeState -const uint16 gk1SignatureDay5PhoneFreeze[] = { +static const uint16 gk1SignatureDay5PhoneFreeze[] = { 0x4a, SIG_MAGICDWORD, SIG_UINT16 + 0x0c, 0x00, // send 0c 0x35, 0x03, // ldi 03 @@ -626,7 +582,7 @@ const uint16 gk1SignatureDay5PhoneFreeze[] = { SIG_END }; -const uint16 gk1PatchDay5PhoneFreeze[] = { +static const uint16 gk1PatchDay5PhoneFreeze[] = { PATCH_ADDTOOFFSET +3, 0x35, 0x06, // ldi 01 0x65, PATCH_GETORIGINALBYTEADJUST +6, +6, // aTop ticks @@ -644,7 +600,7 @@ const uint16 gk1PatchDay5PhoneFreeze[] = { // Applies to at least: English Floppy // Responsible method: Interrogation::dispose // TODO: Check, if English Mac is affected too and if this patch applies -const uint16 gk1SignatureInterrogationBug[] = { +static const uint16 gk1SignatureInterrogationBug[] = { SIG_MAGICDWORD, 0x65, 0x4c, // aTop 4c 0x67, 0x50, // pTos 50 @@ -670,7 +626,7 @@ const uint16 gk1SignatureInterrogationBug[] = { SIG_END }; -const uint16 gk1PatchInterrogationBug[] = { +static const uint16 gk1PatchInterrogationBug[] = { 0x65, 0x4c, // aTop 4c 0x63, 0x50, // pToa 50 0x31, 0x15, // bnt 15 [05b9] @@ -696,11 +652,11 @@ const uint16 gk1PatchInterrogationBug[] = { }; // script, description, signature patch -SciScriptPatcherEntry gk1Signatures[] = { - { true, 51, "interrogation bug", 1, 0, 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug }, - { true, 212, "day 5 phone freeze", 1, 0, 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze }, - { true, 230, "day 6 police beignet timer issue", 1, 0, 0, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet }, - { true, 230, "day 6 police sleep timer issue", 1, 0, 0, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep }, +static const SciScriptPatcherEntry gk1Signatures[] = { + { true, 51, "interrogation bug", 1, gk1SignatureInterrogationBug, gk1PatchInterrogationBug }, + { true, 212, "day 5 phone freeze", 1, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze }, + { true, 230, "day 6 police beignet timer issue", 1, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet }, + { true, 230, "day 6 police sleep timer issue", 1, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -710,7 +666,7 @@ SciScriptPatcherEntry gk1Signatures[] = { // is later used to set master volume. This issue makes sierra sci set // the volume to max. We fix the export, so volume won't get modified in // those cases. -const uint16 kq5SignatureCdHarpyVolume[] = { +static const uint16 kq5SignatureCdHarpyVolume[] = { SIG_MAGICDWORD, 0x80, SIG_UINT16 + 0x91, 0x01, // lag global[191h] 0x18, // not @@ -732,7 +688,7 @@ const uint16 kq5SignatureCdHarpyVolume[] = { SIG_END }; -const uint16 kq5PatchCdHarpyVolume[] = { +static const uint16 kq5PatchCdHarpyVolume[] = { 0x38, PATCH_UINT16 + 0x2f, 0x02, // pushi 022f (selector theVol) (3 new bytes) 0x76, // push0 (1 new byte) 0x51, 0x88, // class SpeakTimer (2 new bytes) @@ -770,24 +726,24 @@ const uint16 kq5PatchCdHarpyVolume[] = { // See also the warning+comment in Object::initBaseObject // // Fixes bug: #4964 -const uint16 kq5SignatureWitchCageInit[] = { - SIG_UINT16 + 0x00, 0x00, // top - SIG_UINT16 + 0x00, 0x00, // left - SIG_UINT16 + 0x00, 0x00, // bottom - SIG_UINT16 + 0x00, 0x00, // right - SIG_UINT16 + 0x00, 0x00, // extra property #1 +static const uint16 kq5SignatureWitchCageInit[] = { + SIG_UINT16 + 0x00, 0x00, // top + SIG_UINT16 + 0x00, 0x00, // left + SIG_UINT16 + 0x00, 0x00, // bottom + SIG_UINT16 + 0x00, 0x00, // right + SIG_UINT16 + 0x00, 0x00, // extra property #1 SIG_MAGICDWORD, - SIG_UINT16 + 0x7a, 0x00, // extra property #2 - SIG_UINT16 + 0xc8, 0x00, // extra property #3 - SIG_UINT16 + 0xa3, 0x00, // extra property #4 + SIG_UINT16 + 0x7a, 0x00, // extra property #2 + SIG_UINT16 + 0xc8, 0x00, // extra property #3 + SIG_UINT16 + 0xa3, 0x00, // extra property #4 SIG_END }; -const uint16 kq5PatchWitchCageInit[] = { - PATCH_UINT16 + 0x00, 0x00, // top - PATCH_UINT16 + 0x7a, 0x00, // left - PATCH_UINT16 + 0xc8, 0x00, // bottom - PATCH_UINT16 + 0xa3, 0x00, // right +static const uint16 kq5PatchWitchCageInit[] = { + PATCH_UINT16 + 0x00, 0x00, // top + PATCH_UINT16 + 0x7a, 0x00, // left + PATCH_UINT16 + 0xc8, 0x00, // bottom + PATCH_UINT16 + 0xa3, 0x00, // right PATCH_END }; @@ -805,7 +761,7 @@ const uint16 kq5PatchWitchCageInit[] = { // changes to GameFeatures::detectsetCursorType() ) and breaking savegame // compatibilty between the DOS and Windows CD versions of KQ5. // TODO: Investigate these side effects more closely. -const uint16 kq5SignatureWinGMSignals[] = { +static const uint16 kq5SignatureWinGMSignals[] = { SIG_MAGICDWORD, 0x80, SIG_UINT16 + 0x90, 0x01, // lag 0x190 0x18, // not @@ -814,16 +770,16 @@ const uint16 kq5SignatureWinGMSignals[] = { SIG_END }; -const uint16 kq5PatchWinGMSignals[] = { +static const uint16 kq5PatchWinGMSignals[] = { 0x34, PATCH_UINT16 + 0x01, 0x00, // ldi 0x0001 PATCH_END }; // script, description, signature patch -SciScriptPatcherEntry kq5Signatures[] = { - { true, 0, "CD: harpy volume change", 1, 0, 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume }, - { true, 200, "CD: witch cage init", 1, 0, 0, kq5SignatureWitchCageInit, kq5PatchWitchCageInit }, - { false, 124, "Win: GM Music signal checks", 4, 0, 0, kq5SignatureWinGMSignals, kq5PatchWinGMSignals }, +static const SciScriptPatcherEntry kq5Signatures[] = { + { true, 0, "CD: harpy volume change", 1, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume }, + { true, 200, "CD: witch cage init", 1, kq5SignatureWitchCageInit, kq5PatchWitchCageInit }, + { false, 124, "Win: GM Music signal checks", 4, kq5SignatureWinGMSignals, kq5PatchWinGMSignals }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -837,7 +793,7 @@ SciScriptPatcherEntry kq5Signatures[] = { // constantly restarting (since it's being looped anyway), thus the normal // game speech can work while the baby cry sound is heard. // Fixes bug: #4955 -const uint16 kq6SignatureDuplicateBabyCry[] = { +static const uint16 kq6SignatureDuplicateBabyCry[] = { SIG_MAGICDWORD, 0x83, 0x00, // lal 00 0x31, 0x1e, // bnt 1e [07f4] @@ -847,7 +803,7 @@ const uint16 kq6SignatureDuplicateBabyCry[] = { SIG_END }; -const uint16 kq6PatchDuplicateBabyCry[] = { +static const uint16 kq6PatchDuplicateBabyCry[] = { 0x48, // ret PATCH_END }; @@ -860,7 +816,7 @@ const uint16 kq6PatchDuplicateBabyCry[] = { // Applies to at least: PC-CD, English PC floppy, German PC floppy, English Mac // Responsible method: KqInv::showSelf // Fixes bug: #5681 -const uint16 kq6SignatureInventoryStackFix[] = { +static const uint16 kq6SignatureInventoryStackFix[] = { 0x67, 0x30, // pTos state 0x34, SIG_UINT16 + 0x00, 0x20, // ldi 2000 0x12, // and @@ -889,7 +845,7 @@ const uint16 kq6SignatureInventoryStackFix[] = { SIG_END // followed by jmp (0x32 for PC, 0x33 for mac) }; -const uint16 kq6PatchInventoryStackFix[] = { +static const uint16 kq6PatchInventoryStackFix[] = { 0x67, 0x30, // pTos state 0x3c, // dup (1 more byte, needed for patch) 0x3c, // dup (1 more byte, saves 1 byte later) @@ -926,7 +882,7 @@ const uint16 kq6PatchInventoryStackFix[] = { // this patch gets enabled, when the user selects "both" in the ScummVM "Speech + Subtitles" menu // We currently use global 98d to hold a kMemory pointer. // Patched method: Messager::sayNext / lb2Messager::sayNext (always use text branch) -const uint16 kq6laurabow2CDSignatureAudioTextSupport1[] = { +static const uint16 kq6laurabow2CDSignatureAudioTextSupport1[] = { 0x89, 0x5a, // lsg global[5a] 0x35, 0x02, // ldi 02 0x12, // and @@ -936,14 +892,14 @@ const uint16 kq6laurabow2CDSignatureAudioTextSupport1[] = { SIG_END }; -const uint16 kq6laurabow2CDPatchAudioTextSupport1[] = { +static const uint16 kq6laurabow2CDPatchAudioTextSupport1[] = { PATCH_ADDTOOFFSET +5, 0x33, 0x13, // jmp [audio call] PATCH_END }; // Patched method: Messager::sayNext / lb2Messager::sayNext (allocate audio memory) -const uint16 kq6laurabow2CDSignatureAudioTextSupport2[] = { +static const uint16 kq6laurabow2CDSignatureAudioTextSupport2[] = { 0x7a, // push2 0x78, // push1 0x39, 0x0c, // pushi 0c @@ -952,14 +908,14 @@ const uint16 kq6laurabow2CDSignatureAudioTextSupport2[] = { SIG_END }; -const uint16 kq6laurabow2CDPatchAudioTextSupport2[] = { +static const uint16 kq6laurabow2CDPatchAudioTextSupport2[] = { PATCH_ADDTOOFFSET +7, 0xa1, 98, // sag global[98d] PATCH_END }; // Patched method: Messager::sayNext / lb2Messager::sayNext (release audio memory) -const uint16 kq6laurabow2CDSignatureAudioTextSupport3[] = { +static const uint16 kq6laurabow2CDSignatureAudioTextSupport3[] = { 0x7a, // push2 0x39, 0x03, // pushi 03 SIG_MAGICDWORD, @@ -968,14 +924,14 @@ const uint16 kq6laurabow2CDSignatureAudioTextSupport3[] = { SIG_END }; -const uint16 kq6laurabow2CDPatchAudioTextSupport3[] = { +static const uint16 kq6laurabow2CDPatchAudioTextSupport3[] = { PATCH_ADDTOOFFSET +3, 0x89, 98, // lsg global[98d] PATCH_END }; // Patched method: Narrator::say (use audio memory) -const uint16 kq6laurabow2CDSignatureAudioTextSupport4[] = { +static const uint16 kq6laurabow2CDSignatureAudioTextSupport4[] = { 0x89, 0x5a, // lsg global[5a] 0x35, 0x01, // ldi 01 0x12, // and @@ -996,10 +952,11 @@ const uint16 kq6laurabow2CDSignatureAudioTextSupport4[] = { SIG_END }; -const uint16 kq6laurabow2CDPatchAudioTextSupport4[] = { - PATCH_ADDTOOFFSET +5, - 0x18, // not (never jump here) - 0x18, // not (never jump here) +static const uint16 kq6laurabow2CDPatchAudioTextSupport4[] = { + PATCH_ADDTOOFFSET +2, + 0x34, PATCH_UINT16 + 0x01, 0x00, // ldi 0001 (waste 1 byte) + 0x12, + 0x18, // not - prepares acc for KQ6 talker::startText PATCH_ADDTOOFFSET +19, 0x89, 98, // lsp global[98d] PATCH_END @@ -1007,31 +964,122 @@ const uint16 kq6laurabow2CDPatchAudioTextSupport4[] = { // Patched method: Talker::display/Narrator::say (remove reset saved mouse cursor code) // code would screw over mouse cursor -const uint16 kq6laurabow2CDSignatureAudioTextSupport5[] = { +static const uint16 kq6laurabow2CDSignatureAudioTextSupport5[] = { SIG_MAGICDWORD, 0x35, 0x00, // ldi 00 0x65, 0x82, // aTop saveCursor SIG_END }; -const uint16 kq6laurabow2CDPatchAudioTextSupport5[] = { +static const uint16 kq6laurabow2CDPatchAudioTextSupport5[] = { 0x18, 0x18, 0x18, 0x18, // waste bytes, do nothing PATCH_END }; -// script, description, signature patch -SciScriptPatcherEntry kq6Signatures[] = { - { true, 481, "duplicate baby cry", 1, 0, 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry }, - { true, 907, "inventory stack fix", 1, 0, 0, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix }, +// Additional patches specifically for King's Quest 6 +// Fixes text window placement, when portrait+text is shown +// Patched method: Kq6Talker::init +static const uint16 kq6CDSignatureAudioTextSupport1[] = { + SIG_MAGICDWORD, + 0x89, 0x5a, // lsg global[5a] + 0x35, 0x02, // ldi 02 + 0x1a, // eq? + 0x31, 0x32, // bnt [jump-for-text-code] + 0x87, 0x00, // lap param[0] + SIG_END +}; + +static const uint16 kq6CDPatchAudioTextSupport1[] = { + PATCH_ADDTOOFFSET +5, + 0x33, 0x32, // jmp [jump-for-text-code] + PATCH_END +}; + +// Additional patches specifically for King's Quest 6 +// Fixes low-res portrait staying on screen for hi-res mode +// Patched method: Talker::startText +// this method is called by Narrator::say and acc is 0 for text-only and true for audio+text +static const uint16 kq6CDSignatureAudioTextSupport2[] = { + SIG_MAGICDWORD, + 0x3f, 0x01, // link 01 + 0x63, 0x8a, // pToa viewInPrint + 0x18, // not + 0x31, 0x06, // bnt [skip following code] + 0x38, SIG_UINT16 + 0xe1, 0x00, // pushi 00e1 + 0x76, // push0 + 0x54, 0x04, // self 04 + SIG_END +}; + +static const uint16 kq6CDPatchAudioTextSupport2[] = { + PATCH_ADDTOOFFSET +2, + 0x67, 0x8a, // pTos viewInPrint + 0x14, // or + 0x2f, // bt [skip following code] + PATCH_END +}; + +// Fixes text window placement, when portrait+text is shown (Guard in room 220) +// Patched method: tlkGateGuard1::init & tlkGateGuard2::init +static const uint16 kq6CDSignatureAudioTextSupportGuards[] = { + SIG_MAGICDWORD, + 0x89, 0x5a, // lsg global[5a] + 0x35, 0x01, // ldi 01 + 0x1a, // eq? + SIG_END // followed by bnt for Guard1 and bt for Guard2 +}; + +static const uint16 kq6CDPatchAudioTextSupportGuards[] = { + PATCH_ADDTOOFFSET +2, + 0x34, PATCH_UINT16 + 0x01, 0x00, // ldi 0001 (waste 1 byte to overwrite eq?) + PATCH_END +}; + +// Fixes text window placement, when portrait+text is shown (Stepmother in room 250) +// Patched method: tlkStepmother::init +static const uint16 kq6CDSignatureAudioTextSupportStepmother[] = { + SIG_MAGICDWORD, + 0x89, 0x5a, // lsg global[5a] + 0x35, 0x02, // ldi 02 + 0x12, // and + 0x31, 0x1a, // bnt [jump-for-text-code] + SIG_END +}; + +static const uint16 kq6CDPatchAudioTextSupportJumpAlways[] = { + PATCH_ADDTOOFFSET +5, + 0x33, // jump always + PATCH_END +}; + +// Fixes text window placement, when portrait+text is shown (Gnomes in room 450) +// Patched method: GnomeTalker::init +static const uint16 kq6CDSignatureAudioTextSupportGnomes[] = { + SIG_MAGICDWORD, + 0x89, 0x5a, // lsg global[5a] + 0x35, 0x02, // ldi 02 + 0x1a, // eq? + 0x31, 0x16, // bnt [jump-for-text-code] + SIG_END +}; + +// script, description, signature patch +static const SciScriptPatcherEntry kq6Signatures[] = { + { true, 481, "duplicate baby cry", 1, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry }, + { true, 907, "inventory stack fix", 1, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix }, // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support - // *** King's Quest 6 audio + text support - CURRENTLY DISABLED *** - // TODO: fix window placement (currently part of the text windows go off-screen) - // TODO: fix hi-res portraits mode graphic glitches - { false, 924, "CD: audio + text support 1", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 }, - { false, 924, "CD: audio + text support 2", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 }, - { false, 924, "CD: audio + text support 3", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 }, - { false, 928, "CD: audio + text support 4", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 }, - { false, 928, "CD: audio + text support 5", 2, 0, 0, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 }, + // *** King's Quest 6 audio + text support *** + // TODO: all window placements seems to be fixed, game should be played through to check for any more issues + { false, 924, "CD: audio + text support KQ6&LB2 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 }, + { false, 924, "CD: audio + text support KQ6&LB2 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 }, + { false, 924, "CD: audio + text support KQ6&LB2 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 }, + { false, 928, "CD: audio + text support KQ6&LB2 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 }, + { false, 928, "CD: audio + text support KQ6&LB2 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 }, + { false, 909, "CD: audio + text support KQ6 1", 1, kq6CDSignatureAudioTextSupport1, kq6CDPatchAudioTextSupport1 }, + { false, 928, "CD: audio + text support KQ6 2", 1, kq6CDSignatureAudioTextSupport2, kq6CDPatchAudioTextSupport2 }, + { false, 1009, "CD: audio + text support KQ6 Guards", 2, kq6CDSignatureAudioTextSupportGuards, kq6CDPatchAudioTextSupportGuards }, + { false, 1027, "CD: audio + text support KQ6 Stepmother", 1, kq6CDSignatureAudioTextSupportStepmother, kq6CDPatchAudioTextSupportJumpAlways }, + { false, 1037, "CD: audio + text support KQ6 Gnomes", 1, kq6CDSignatureAudioTextSupportGnomes, kq6CDPatchAudioTextSupportJumpAlways }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1048,7 +1096,7 @@ SciScriptPatcherEntry kq6Signatures[] = { // Applies to at least: German floppy // Responsible method: unknown // Fixes bug: #5264 -const uint16 longbowSignatureShowHandCode[] = { +static const uint16 longbowSignatureShowHandCode[] = { 0x78, // push1 0x78, // push1 0x72, SIG_ADDTOOFFSET +2, // lofsa (letter, that was typed) @@ -1065,7 +1113,7 @@ const uint16 longbowSignatureShowHandCode[] = { SIG_END }; -const uint16 longbowPatchShowHandCode[] = { +static const uint16 longbowPatchShowHandCode[] = { 0x39, 0x01, // pushi 1 (combine the two push1's in one, like in the English version) PATCH_ADDTOOFFSET +3, // leave the lofsa call untouched // The following will remove the duplicate call @@ -1075,9 +1123,9 @@ const uint16 longbowPatchShowHandCode[] = { PATCH_END }; -// script, description, signature patch -SciScriptPatcherEntry longbowSignatures[] = { - { true, 210, "hand code crash", 5, 0, 0, longbowSignatureShowHandCode, longbowPatchShowHandCode }, +// script, description, signature patch +static const SciScriptPatcherEntry longbowSignatures[] = { + { true, 210, "hand code crash", 5, longbowSignatureShowHandCode, longbowPatchShowHandCode }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1098,7 +1146,7 @@ SciScriptPatcherEntry longbowSignatures[] = { // Applies to at least: English floppy // Responsible method: rm63Script::handleEvent // Fixes bug: #6346 -const uint16 larry2SignatureWearParachutePoints[] = { +static const uint16 larry2SignatureWearParachutePoints[] = { 0x35, 0x01, // ldi 01 0xa1, SIG_MAGICDWORD, 0x8e, // sag 8e 0x80, SIG_UINT16 + 0xe0, 0x01, // lag 1e0 @@ -1109,7 +1157,7 @@ const uint16 larry2SignatureWearParachutePoints[] = { SIG_END }; -const uint16 larry2PatchWearParachutePoints[] = { +static const uint16 larry2PatchWearParachutePoints[] = { PATCH_ADDTOOFFSET +4, 0x80, PATCH_UINT16 + 0x5a, 0x00, // lag 5a (global 90) PATCH_ADDTOOFFSET +6, @@ -1118,8 +1166,8 @@ const uint16 larry2PatchWearParachutePoints[] = { }; // script, description, signature patch -SciScriptPatcherEntry larry2Signatures[] = { - { true, 63, "plane: no points for wearing plane", 1, 0, 0, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints }, +static const SciScriptPatcherEntry larry2Signatures[] = { + { true, 63, "plane: no points for wearing plane", 1, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1131,7 +1179,7 @@ SciScriptPatcherEntry larry2Signatures[] = { // Because of that the talking head of Patti is drawn over the textbox. A translation oversight. // Applies to at least: German floppy // Responsible method: none, position of talker object on screen needs to get modified -const uint16 larry5SignatureGermanEndingPattiTalker[] = { +static const uint16 larry5SignatureGermanEndingPattiTalker[] = { SIG_MAGICDWORD, SIG_UINT16 + 0x6e, 0x00, // object pattiTalker::x (110) SIG_UINT16 + 0xb4, 0x00, // object pattiTalker::y (180) @@ -1141,14 +1189,14 @@ const uint16 larry5SignatureGermanEndingPattiTalker[] = { SIG_END }; -const uint16 larry5PatchGermanEndingPattiTalker[] = { +static const uint16 larry5PatchGermanEndingPattiTalker[] = { PATCH_UINT16 + 0x5a, 0x00, // change pattiTalker::x to 90 PATCH_END }; // script, description, signature patch -SciScriptPatcherEntry larry5Signatures[] = { - { true, 380, "German-only: Enlarge Patti Textbox", 1, 0, 0, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker }, +static const SciScriptPatcherEntry larry5Signatures[] = { + { true, 380, "German-only: Enlarge Patti Textbox", 1, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1162,7 +1210,7 @@ SciScriptPatcherEntry larry5Signatures[] = { // in sierra sci) // Applies to at least: German PC-CD // Responsible method: unknown -const uint16 larry6SignatureDeathDialog[] = { +static const uint16 larry6SignatureDeathDialog[] = { SIG_MAGICDWORD, 0x3e, SIG_UINT16 + 0x33, 0x01, // link 0133 (offset 0x20) 0x35, 0xff, // ldi ff @@ -1186,7 +1234,7 @@ const uint16 larry6SignatureDeathDialog[] = { SIG_END }; -const uint16 larry6PatchDeathDialog[] = { +static const uint16 larry6PatchDeathDialog[] = { 0x3e, 0x00, 0x02, // link 0200 PATCH_ADDTOOFFSET +687, 0x5a, PATCH_UINT16 + 0x04, 0x00, PATCH_UINT16 + 0x40, 0x01, // lea 0004 0140 @@ -1198,14 +1246,14 @@ const uint16 larry6PatchDeathDialog[] = { }; // script, description, signature patch -SciScriptPatcherEntry larry6Signatures[] = { - { true, 82, "death dialog memory corruption", 1, 0, 0, larry6SignatureDeathDialog, larry6PatchDeathDialog }, +static const SciScriptPatcherEntry larry6Signatures[] = { + { true, 82, "death dialog memory corruption", 1, larry6SignatureDeathDialog, larry6PatchDeathDialog }, SCI_SIGNATUREENTRY_TERMINATOR }; // =========================================================================== // Laura Bow 2 -// +// // Moving away the painting in the room with the hidden safe is problematic // for the CD version of the game. safePic::doVerb gets triggered by the mouse-click. // This method sets local 0 as signal, which is only meant to get handled, when @@ -1230,7 +1278,7 @@ SciScriptPatcherEntry larry6Signatures[] = { // Applies to at least: English PC-CD // Responsible method: rm560::doit // Fixes bug: #6460 -const uint16 laurabow2CDSignaturePaintingClosing[] = { +static const uint16 laurabow2CDSignaturePaintingClosing[] = { 0x39, 0x04, // pushi 04 (cel) 0x76, // push0 SIG_MAGICDWORD, @@ -1257,7 +1305,7 @@ const uint16 laurabow2CDSignaturePaintingClosing[] = { SIG_END }; -const uint16 laurabow2CDPatchPaintingClosing[] = { +static const uint16 laurabow2CDPatchPaintingClosing[] = { PATCH_ADDTOOFFSET +2, 0x3c, // dup (1 additional byte) 0x76, // push0 @@ -1303,7 +1351,7 @@ const uint16 laurabow2CDPatchPaintingClosing[] = { // Applies to at least: English PC-CD // Responsible method: LB2::newRoom, LB2::handsOff, LB2::handsOn // Fixes bug: #6440 -const uint16 laurabow2CDSignatureFixProblematicIconBar[] = { +static const uint16 laurabow2CDSignatureFixProblematicIconBar[] = { SIG_MAGICDWORD, 0x38, SIG_UINT16 + 0xf1, 0x00, // pushi 00f1 (disable) - hardcoded, we only want to patch the CD version 0x76, // push0 @@ -1312,7 +1360,7 @@ const uint16 laurabow2CDSignatureFixProblematicIconBar[] = { SIG_END }; -const uint16 laurabow2CDPatchFixProblematicIconBar[] = { +static const uint16 laurabow2CDPatchFixProblematicIconBar[] = { 0x35, 0x00, // ldi 00 0xa1, 0x74, // sag 74h 0x35, 0x00, // ldi 00 (waste bytes) @@ -1322,15 +1370,15 @@ const uint16 laurabow2CDPatchFixProblematicIconBar[] = { // script, description, signature patch -SciScriptPatcherEntry laurabow2Signatures[] = { - { true, 560, "CD: painting closing immediately", 1, 0, 0, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing }, - { true, 0, "CD: fix problematic icon bar", 1, 0, 0, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar }, +static const SciScriptPatcherEntry laurabow2Signatures[] = { + { true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing }, + { true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar }, // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support - { false, 924, "CD: audio + text support 1", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 }, - { false, 924, "CD: audio + text support 2", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 }, - { false, 924, "CD: audio + text support 3", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 }, - { false, 928, "CD: audio + text support 4", 1, 0, 0, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 }, - { false, 928, "CD: audio + text support 5", 2, 0, 0, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 }, + { false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 }, + { false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 }, + { false, 924, "CD: audio + text support 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 }, + { false, 928, "CD: audio + text support 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 }, + { false, 928, "CD: audio + text support 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1339,7 +1387,7 @@ SciScriptPatcherEntry laurabow2Signatures[] = { // MG::replay somewhat calculates the savedgame-id used when saving again // this doesn't work right and we remove the code completely. // We set the savedgame-id directly right after restoring in kRestoreGame. -const uint16 mothergoose256SignatureReplay[] = { +static const uint16 mothergoose256SignatureReplay[] = { 0x36, // push 0x35, SIG_MAGICDWORD, 0x20, // ldi 20 0x04, // sub @@ -1347,7 +1395,7 @@ const uint16 mothergoose256SignatureReplay[] = { SIG_END }; -const uint16 mothergoose256PatchReplay[] = { +static const uint16 mothergoose256PatchReplay[] = { 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 (dummy) 0x34, PATCH_UINT16 + 0x00, 0x00, // ldi 0000 (dummy) PATCH_END @@ -1355,24 +1403,24 @@ const uint16 mothergoose256PatchReplay[] = { // when saving, it also checks if the savegame ID is below 13. // we change this to check if below 113 instead -const uint16 mothergoose256SignatureSaveLimit[] = { +static const uint16 mothergoose256SignatureSaveLimit[] = { 0x89, SIG_MAGICDWORD, 0xb3, // lsg global[b3] 0x35, 0x0d, // ldi 0d 0x20, // ge? SIG_END }; -const uint16 mothergoose256PatchSaveLimit[] = { +static const uint16 mothergoose256PatchSaveLimit[] = { PATCH_ADDTOOFFSET | +2, 0x35, 0x0d + SAVEGAMEID_OFFICIALRANGE_START, // ldi 113d PATCH_END }; // script, description, signature patch -SciScriptPatcherEntry mothergoose256Signatures[] = { - { true, 0, "replay save issue", 1, 0, 0, mothergoose256SignatureReplay, mothergoose256PatchReplay }, - { true, 0, "save limit dialog (SCI1.1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit }, - { true, 994, "save limit dialog (SCI1)", 1, 0, 0, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit }, +static const SciScriptPatcherEntry mothergoose256Signatures[] = { + { true, 0, "replay save issue", 1, mothergoose256SignatureReplay, mothergoose256PatchReplay }, + { true, 0, "save limit dialog (SCI1.1)", 1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit }, + { true, 994, "save limit dialog (SCI1)", 1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1389,7 +1437,7 @@ SciScriptPatcherEntry mothergoose256Signatures[] = { // Applies to at least: English floppy // Responsible method: putGun::changeState (script 341) // Fixes bug: #5705 / #6400 -const uint16 pq1vgaSignaturePutGunInLockerBug[] = { +static const uint16 pq1vgaSignaturePutGunInLockerBug[] = { 0x35, 0x00, // ldi 00 0x1a, // eq? 0x31, 0x25, // bnt [next state check] @@ -1414,7 +1462,7 @@ const uint16 pq1vgaSignaturePutGunInLockerBug[] = { SIG_END }; -const uint16 pq1vgaPatchPutGunInLockerBug[] = { +static const uint16 pq1vgaPatchPutGunInLockerBug[] = { PATCH_ADDTOOFFSET +3, 0x31, 0x1c, // bnt [next state check] PATCH_ADDTOOFFSET +22, @@ -1434,8 +1482,8 @@ const uint16 pq1vgaPatchPutGunInLockerBug[] = { }; // script, description, signature patch -SciScriptPatcherEntry pq1vgaSignatures[] = { - { true, 341, "put gun in locker bug", 1, 0, 0, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug }, +static const SciScriptPatcherEntry pq1vgaSignatures[] = { + { true, 341, "put gun in locker bug", 1, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1450,7 +1498,7 @@ SciScriptPatcherEntry pq1vgaSignatures[] = { // We just reuse the active event, thus removing the duplicate kGetEvent call. // Applies to at least: English floppy // Responsible method: pointBox::doit -const uint16 qfg1vgaSignatureFightEvents[] = { +static const uint16 qfg1vgaSignatureFightEvents[] = { 0x39, SIG_MAGICDWORD, SIG_SELECTOR8 + SELECTOR_new, // pushi "new" 0x76, // push0 @@ -1471,7 +1519,7 @@ const uint16 qfg1vgaSignatureFightEvents[] = { SIG_END }; -const uint16 qfg1vgaPatchFightEvents[] = { +static const uint16 qfg1vgaPatchFightEvents[] = { 0x38, PATCH_SELECTOR16 + SELECTOR_curEvent, // pushi 15a (selector curEvent) 0x76, // push0 0x81, 0x50, // lag global[50] @@ -1500,27 +1548,27 @@ const uint16 qfg1vgaPatchFightEvents[] = { // Fixes bug: #6139. // Patch 1: Increase temp space -const uint16 qfg1vgaSignatureTempSpace[] = { +static const uint16 qfg1vgaSignatureTempSpace[] = { SIG_MAGICDWORD, 0x3f, 0xba, // link 0xba 0x87, 0x00, // lap 0 SIG_END }; -const uint16 qfg1vgaPatchTempSpace[] = { +static const uint16 qfg1vgaPatchTempSpace[] = { 0x3f, 0xca, // link 0xca PATCH_END }; // Patch 2: Move the pointer used for the window header a little bit -const uint16 qfg1vgaSignatureDialogHeader[] = { +static const uint16 qfg1vgaSignatureDialogHeader[] = { SIG_MAGICDWORD, 0x5b, 0x04, 0x80, // lea temp[0x80] 0x36, // push SIG_END }; -const uint16 qfg1vgaPatchDialogHeader[] = { +static const uint16 qfg1vgaPatchDialogHeader[] = { 0x5b, 0x04, 0x90, // lea temp[0x90] PATCH_END }; @@ -1534,7 +1582,7 @@ const uint16 qfg1vgaPatchDialogHeader[] = { // the crusher, ego is supposed to move close to position 79, 165. We change it // to 85, 165, which is not an edge case thus the freeze is avoided. // Fixes bug: #6180 -const uint16 qfg1vgaSignatureMoveToCrusher[] = { +static const uint16 qfg1vgaSignatureMoveToCrusher[] = { SIG_MAGICDWORD, 0x51, 0x1f, // class Motion 0x36, // push @@ -1544,7 +1592,7 @@ const uint16 qfg1vgaSignatureMoveToCrusher[] = { SIG_END }; -const uint16 qfg1vgaPatchMoveToCrusher[] = { +static const uint16 qfg1vgaPatchMoveToCrusher[] = { PATCH_ADDTOOFFSET +3, 0x39, 0x55, // pushi 55 (85 - x) PATCH_END @@ -1554,7 +1602,7 @@ const uint16 qfg1vgaPatchMoveToCrusher[] = { // spot when sneaking. In GuardsTrumpet::changeState, we change the final // location where Ego is moved from 111, 111 to 114, 114. // Fixes bug: #6248 -const uint16 qfg1vgaSignatureMoveToCastleGate[] = { +static const uint16 qfg1vgaSignatureMoveToCastleGate[] = { SIG_MAGICDWORD, 0x51, 0x1f, // class MoveTo 0x36, // push @@ -1564,7 +1612,7 @@ const uint16 qfg1vgaSignatureMoveToCastleGate[] = { SIG_END }; -const uint16 qfg1vgaPatchMoveToCastleGate[] = { +static const uint16 qfg1vgaPatchMoveToCastleGate[] = { PATCH_ADDTOOFFSET +3, 0x39, 0x72, // pushi 72 (114 - x) PATCH_END @@ -1576,7 +1624,7 @@ const uint16 qfg1vgaPatchMoveToCastleGate[] = { // Applies to at least: English floppy // Responsible method: smallMonster::doVerb // Fixes bug #6249 -const uint16 qfg1vgaSignatureCheetaurDescription[] = { +static const uint16 qfg1vgaSignatureCheetaurDescription[] = { SIG_MAGICDWORD, 0x34, SIG_UINT16 + 0xb8, 0x01, // ldi 01b8 0x1a, // eq? @@ -1589,7 +1637,7 @@ const uint16 qfg1vgaSignatureCheetaurDescription[] = { SIG_END }; -const uint16 qfg1vgaPatchCheetaurDescription[] = { +static const uint16 qfg1vgaPatchCheetaurDescription[] = { PATCH_ADDTOOFFSET +14, 0x39, 0x11, // pushi 11 -> monster type cheetaur PATCH_END @@ -1608,7 +1656,7 @@ const uint16 qfg1vgaPatchCheetaurDescription[] = { // Applies to at least: English floppy // Responsible method: happyFace::changeState, door11::doit // Fixes bug #6181 -const uint16 qfg1vgaSignatureFunnyRoomFix[] = { +static const uint16 qfg1vgaSignatureFunnyRoomFix[] = { 0x65, 0x14, // aTop 14 (state) 0x36, // push 0x3c, // dup @@ -1621,7 +1669,7 @@ const uint16 qfg1vgaSignatureFunnyRoomFix[] = { SIG_END }; -const uint16 qfg1vgaPatchFunnyRoomFix[] = { +static const uint16 qfg1vgaPatchFunnyRoomFix[] = { PATCH_ADDTOOFFSET +3, 0x2e, PATCH_UINT16 + 0x29, 0x00, // bt 0029 [-> next state] - saves 4 bytes 0x35, 0x01, // ldi 01 @@ -1632,15 +1680,15 @@ const uint16 qfg1vgaPatchFunnyRoomFix[] = { }; // script, description, signature patch -SciScriptPatcherEntry qfg1vgaSignatures[] = { - { true, 215, "fight event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, - { true, 216, "weapon master event issue", 1, 0, 0, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, - { true, 814, "window text temp space", 1, 0, 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace }, - { true, 814, "dialog header offset", 3, 0, 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader }, - { true, 331, "moving to crusher", 1, 0, 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher }, - { true, 41, "moving to castle gate", 1, 0, 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate }, - { true, 210, "cheetaur description fixed", 1, 0, 0, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription }, - { true, 96, "funny room script bug fixed", 1, 0, 0, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix }, +static const SciScriptPatcherEntry qfg1vgaSignatures[] = { + { true, 215, "fight event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, + { true, 216, "weapon master event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents }, + { true, 814, "window text temp space", 1, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace }, + { true, 814, "dialog header offset", 3, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader }, + { true, 331, "moving to crusher", 1, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher }, + { true, 41, "moving to castle gate", 1, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate }, + { true, 210, "cheetaur description fixed", 1, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription }, + { true, 96, "funny room script bug fixed", 1, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1658,7 +1706,7 @@ SciScriptPatcherEntry qfg1vgaSignatures[] = { // and text entry refreshes whenever a button is pressed, and prevent possible // crashes because of these constant quick object reallocations. // Fixes bug: #5096 -const uint16 qfg2SignatureImportDialog[] = { +static const uint16 qfg2SignatureImportDialog[] = { 0x63, SIG_MAGICDWORD, 0x20, // pToa text 0x30, SIG_UINT16 + 0x0b, 0x00, // bnt [next state] 0x7a, // push2 @@ -1670,21 +1718,21 @@ const uint16 qfg2SignatureImportDialog[] = { SIG_END }; -const uint16 qfg2PatchImportDialog[] = { +static const uint16 qfg2PatchImportDialog[] = { PATCH_ADDTOOFFSET +5, 0x48, // ret PATCH_END }; // script, description, signature patch -SciScriptPatcherEntry qfg2Signatures[] = { - { true, 944, "import dialog continuous calls", 1, 0, 0, qfg2SignatureImportDialog, qfg2PatchImportDialog }, +static const SciScriptPatcherEntry qfg2Signatures[] = { + { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog }, SCI_SIGNATUREENTRY_TERMINATOR }; // =========================================================================== // Patch for the import screen in QFG3, same as the one for QFG2 above -const uint16 qfg3SignatureImportDialog[] = { +static const uint16 qfg3SignatureImportDialog[] = { 0x63, SIG_MAGICDWORD, 0x2a, // pToa text 0x31, 0x0b, // bnt [next state] 0x7a, // push2 @@ -1696,7 +1744,7 @@ const uint16 qfg3SignatureImportDialog[] = { SIG_END }; -const uint16 qfg3PatchImportDialog[] = { +static const uint16 qfg3PatchImportDialog[] = { PATCH_ADDTOOFFSET +4, 0x48, // ret PATCH_END @@ -1720,7 +1768,7 @@ const uint16 qfg3PatchImportDialog[] = { // Applies to at least: English, German, Italian, French, Spanish Floppy // Responsible method: unknown // Fixes bug: #5172 -const uint16 qfg3SignatureWooDialog[] = { +static const uint16 qfg3SignatureWooDialog[] = { SIG_MAGICDWORD, 0x67, 0x12, // pTos 12 (query) 0x35, 0xb6, // ldi b6 @@ -1741,16 +1789,16 @@ const uint16 qfg3SignatureWooDialog[] = { SIG_END }; -const uint16 qfg3PatchWooDialog[] = { +static const uint16 qfg3PatchWooDialog[] = { PATCH_ADDTOOFFSET +0x29, 0x33, 0x11, // jmp to 0x6a2, the call to hero::solvePuzzle for 0xFFFC PATCH_END }; // script, description, signature patch -SciScriptPatcherEntry qfg3Signatures[] = { - { true, 944, "import dialog continuous calls", 1, 0, 0, qfg3SignatureImportDialog, qfg3PatchImportDialog }, - { true, 440, "dialog crash when asking about Woo", 1, 0, 0, qfg3SignatureWooDialog, qfg3PatchWooDialog }, +static const SciScriptPatcherEntry qfg3Signatures[] = { + { true, 944, "import dialog continuous calls", 1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, + { true, 440, "dialog crash when asking about Woo", 1, qfg3SignatureWooDialog, qfg3PatchWooDialog }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1762,7 +1810,7 @@ SciScriptPatcherEntry qfg3Signatures[] = { // we could either calculate property count differently somehow fixing this // but I think just patching it out is cleaner. // Fixes bug: #5093 -const uint16 sq4FloppySignatureEndlessFlight[] = { +static const uint16 sq4FloppySignatureEndlessFlight[] = { 0x39, 0x04, // pushi 04 (selector x) SIG_MAGICDWORD, 0x78, // push1 @@ -1772,7 +1820,7 @@ const uint16 sq4FloppySignatureEndlessFlight[] = { SIG_END }; -const uint16 sq4FloppyPatchEndlessFlight[] = { +static const uint16 sq4FloppyPatchEndlessFlight[] = { PATCH_ADDTOOFFSET +5, 0x35, 0x03, // ldi 03 (which would be the content of the property) PATCH_END @@ -1784,7 +1832,7 @@ const uint16 sq4FloppyPatchEndlessFlight[] = { // Patch 1: iconTextSwitch::show, called when the text options button is shown. // This is patched to add the "Both" text resource (i.e. we end up with // "Speech", "Text" and "Both") -const uint16 sq4CdSignatureTextOptionsButton[] = { +static const uint16 sq4CdSignatureTextOptionsButton[] = { SIG_MAGICDWORD, 0x35, 0x01, // ldi 0x01 0xa1, 0x53, // sag 0x53 @@ -1795,7 +1843,7 @@ const uint16 sq4CdSignatureTextOptionsButton[] = { SIG_END }; -const uint16 sq4CdPatchTextOptionsButton[] = { +static const uint16 sq4CdPatchTextOptionsButton[] = { PATCH_ADDTOOFFSET +7, 0x39, 0x0b, // pushi 0x0b PATCH_END @@ -1804,7 +1852,7 @@ const uint16 sq4CdPatchTextOptionsButton[] = { // Patch 2: Adjust a check in babbleIcon::init, which handles the babble icon // (e.g. the two guys from Andromeda) shown when dying/quitting. // Fixes bug: #6068 -const uint16 sq4CdSignatureBabbleIcon[] = { +static const uint16 sq4CdSignatureBabbleIcon[] = { SIG_MAGICDWORD, 0x89, 0x5a, // lsg 5a 0x35, 0x02, // ldi 02 @@ -1813,7 +1861,7 @@ const uint16 sq4CdSignatureBabbleIcon[] = { SIG_END }; -const uint16 sq4CdPatchBabbleIcon[] = { +static const uint16 sq4CdPatchBabbleIcon[] = { 0x89, 0x5a, // lsg 5a 0x35, 0x01, // ldi 01 0x1a, // eq? @@ -1825,7 +1873,7 @@ const uint16 sq4CdPatchBabbleIcon[] = { // when the text options button is clicked: "Speech", "Text" and "Both". // Refer to the patch above for additional details. // iconTextSwitch::doit (called when the text options button is clicked) -const uint16 sq4CdSignatureTextOptions[] = { +static const uint16 sq4CdSignatureTextOptions[] = { SIG_MAGICDWORD, 0x89, 0x5a, // lsg 0x5a (load global 90 to stack) 0x3c, // dup @@ -1849,7 +1897,7 @@ const uint16 sq4CdSignatureTextOptions[] = { SIG_END }; -const uint16 sq4CdPatchTextOptions[] = { +static const uint16 sq4CdPatchTextOptions[] = { 0x89, 0x5a, // lsg 0x5a (load global 90 to stack) 0x3c, // dup 0x35, 0x03, // ldi 0x03 (acc = 3) @@ -1869,11 +1917,11 @@ const uint16 sq4CdPatchTextOptions[] = { }; // script, description, signature patch -SciScriptPatcherEntry sq4Signatures[] = { - { true, 298, "Floppy: endless flight", 1, 0, 0, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight }, - { true, 818, "CD: Speech and subtitles option", 1, 0, 0, sq4CdSignatureTextOptions, sq4CdPatchTextOptions }, - { true, 0, "CD: Babble icon speech and subtitles fix", 1, 0, 0, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon }, - { true, 818, "CD: Speech and subtitles option button", 1, 0, 0, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton }, +static const SciScriptPatcherEntry sq4Signatures[] = { + { true, 298, "Floppy: endless flight", 1, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight }, + { true, 818, "CD: Speech and subtitles option", 1, sq4CdSignatureTextOptions, sq4CdPatchTextOptions }, + { true, 0, "CD: Babble icon speech and subtitles fix", 1, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon }, + { true, 818, "CD: Speech and subtitles option button", 1, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton }, SCI_SIGNATUREENTRY_TERMINATOR }; @@ -1888,8 +1936,8 @@ SciScriptPatcherEntry sq4Signatures[] = { // The same issue happens in Sierra SCI. // We simply set the correct starting cel number to fix the bug. // Responsible method: robotIntoShip::changeState(9) -const uint16 sq1vgaSignatureUlenceFlatsTimepodGfxGlitch[] = { - 0x39, +static const uint16 sq1vgaSignatureUlenceFlatsTimepodGfxGlitch[] = { + 0x39, SIG_MAGICDWORD, SIG_SELECTOR8 + SELECTOR_cel, // pushi "cel" 0x78, // push1 0x39, 0x0a, // pushi 0x0a (set ship::cel to 10) @@ -1897,13 +1945,13 @@ const uint16 sq1vgaSignatureUlenceFlatsTimepodGfxGlitch[] = { SIG_END }; -const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = { +static const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = { PATCH_ADDTOOFFSET +3, 0x39, 0x09, // pushi 0x09 (set ship::cel to 9) PATCH_END }; -const uint16 sq1vgaSignatureEgoShowsCard[] = { +static const uint16 sq1vgaSignatureEgoShowsCard[] = { SIG_MAGICDWORD, 0x38, SIG_SELECTOR16 + SELECTOR_timesShownID, // push "timesShownID" 0x78, // push1 @@ -1925,7 +1973,7 @@ const uint16 sq1vgaSignatureEgoShowsCard[] = { // Note that this script patch is merely a reordering of the // instructions in the original script. -const uint16 sq1vgaPatchEgoShowsCard[] = { +static const uint16 sq1vgaPatchEgoShowsCard[] = { 0x38, PATCH_SELECTOR16 + SELECTOR_timesShownID, // push "timesShownID" 0x76, // push0 0x51, 0x7c, // class DeltaurRegion @@ -1946,10 +1994,11 @@ const uint16 sq1vgaPatchEgoShowsCard[] = { // script, description, signature patch -SciScriptPatcherEntry sq1vgaSignatures[] = { - { true, 45, "Ulence Flats: timepod graphic glitch", 1, 0, 0, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch }, - { true, 58, "Sarien armory droid zapping ego first time", 1, 0, 0, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard }, - SCI_SIGNATUREENTRY_TERMINATOR}; +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 }, + SCI_SIGNATUREENTRY_TERMINATOR +}; // =========================================================================== // The toolbox in sq5 is buggy. When you click on the upper part of the "put @@ -1973,7 +2022,7 @@ SciScriptPatcherEntry sq1vgaSignatures[] = { // Applies to at least: English/German/French PC floppy // Responsible method: takeTool::changeState // Fixes bug: #6457 -const uint16 sq5SignatureToolboxFix[] = { +static const uint16 sq5SignatureToolboxFix[] = { 0x31, 0x13, // bnt [check for state 1] SIG_MAGICDWORD, 0x38, SIG_UINT16 + 0xaa, 0x00, // pushi 00aa @@ -1993,7 +2042,7 @@ const uint16 sq5SignatureToolboxFix[] = { SIG_END }; -const uint16 sq5PatchToolboxFix[] = { +static const uint16 sq5PatchToolboxFix[] = { 0x31, 0x41, // bnt [check for state 2] PATCH_ADDTOOFFSET +16, // skip to jmp offset 0x35, 0x01, // ldi 01 @@ -2004,14 +2053,32 @@ const uint16 sq5PatchToolboxFix[] = { }; // script, description, signature patch -SciScriptPatcherEntry sq5Signatures[] = { - { true, 226, "toolbox fix", 1, 0, 0, sq5SignatureToolboxFix, sq5PatchToolboxFix }, +static const SciScriptPatcherEntry sq5Signatures[] = { + { true, 226, "toolbox fix", 1, sq5SignatureToolboxFix, sq5PatchToolboxFix }, SCI_SIGNATUREENTRY_TERMINATOR }; +// ================================================================================= + +ScriptPatcher::ScriptPatcher() { + int selectorCount = ARRAYSIZE(selectorNameTable); + int selectorNr; + + // Allocate table for selector-IDs and initialize that table as well + _selectorIdTable = new Selector[ selectorCount ]; + for (selectorNr = 0; selectorNr < selectorCount; selectorNr++) + _selectorIdTable[selectorNr] = -1; + + _runtimeTable = NULL; +} + +ScriptPatcher::~ScriptPatcher() { + delete[] _runtimeTable; + delete[] _selectorIdTable; +} // will actually patch previously found signature area -void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) { +void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) { const uint16 *patchData = patchEntry->patchData; byte orgData[PATCH_VALUELIMIT]; int32 offset = signatureOffset; @@ -2056,7 +2123,7 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc case PATCH_SELECTOR16: { byte byte1; byte byte2; - + switch (patchCommand) { case PATCH_UINT16: { byte1 = patchValue & PATCH_BYTEMASK; @@ -2067,7 +2134,7 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc break; } case PATCH_SELECTOR16: { - patchSelector = selectorTable[patchValue].id; + patchSelector = _selectorIdTable[patchValue]; byte1 = patchSelector & 0xFF; byte2 = patchSelector >> 8; break; @@ -2086,7 +2153,7 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc break; } case PATCH_SELECTOR8: { - patchSelector = selectorTable[patchValue].id; + patchSelector = _selectorIdTable[patchValue]; if (patchSelector & 0xFF00) error("Script-Patcher: 8 bit selector required, game uses 16 bit selector"); scriptData[offset] = patchSelector & 0xFF; @@ -2103,18 +2170,18 @@ void Script::patcherApplyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc } // will return -1 if no match was found, otherwise an offset to the start of the signature match -int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) { +int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) { if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay return -1; - const uint32 magicDWord = patchEntry->magicDWord; // is platform-specific BE/LE form, so that the later match will work + const uint32 magicDWord = runtimeEntry->magicDWord; // is platform-specific BE/LE form, so that the later match will work const uint32 searchLimit = scriptSize - 3; uint32 DWordOffset = 0; // first search for the magic DWORD while (DWordOffset < searchLimit) { if (magicDWord == READ_UINT32(scriptData + DWordOffset)) { // magic DWORD found, check if actual signature matches - uint32 offset = DWordOffset + patchEntry->magicOffset; + uint32 offset = DWordOffset + runtimeEntry->magicOffset; uint32 byteOffset = offset; const uint16 *signatureData = patchEntry->signatureData; uint16 sigSelector = 0; @@ -2145,7 +2212,7 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons break; } case SIG_SELECTOR16: { - sigSelector = selectorTable[sigValue].id; + sigSelector = _selectorIdTable[sigValue]; byte1 = sigSelector & 0xFF; byte2 = sigSelector >> 8; break; @@ -2169,7 +2236,7 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons } case SIG_SELECTOR8: { if (byteOffset < scriptSize) { - sigSelector = selectorTable[sigValue].id; + sigSelector = _selectorIdTable[sigValue]; if (sigSelector & 0xFF00) error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", patchEntry->description); if (scriptData[byteOffset] != (sigSelector & 0xFF)) @@ -2189,14 +2256,14 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons sigWord = SIG_MISMATCH; // out of bounds } } - + if (sigWord == SIG_MISMATCH) break; - + signatureData++; sigWord = *signatureData; } - + if (sigWord == SIG_END) // signature fully matched? return offset; } @@ -2208,30 +2275,45 @@ int32 Script::patcherFindSignature(const SciScriptPatcherEntry *patchEntry, cons // This method calculates the magic DWORD for each entry in the signature table // and it also initializes the selector table for selectors used in the signatures/patches of the current game -void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacSci11) { - SciScriptPatcherEntry *curEntry = patchTable; - SciScriptPatcherSelector *curSelector = NULL; +void ScriptPatcher::initSignature(const SciScriptPatcherEntry *patchTable, bool isMacSci11) { + const SciScriptPatcherEntry *curEntry = patchTable; + SciScriptPatcherRuntimeEntry *curRuntimeEntry; + Selector curSelector = -1; int step; int magicOffset; byte magicDWord[4]; int magicDWordLeft = 0; - const uint16 *curData; - uint16 curWord; - uint16 curCommand; - uint32 curValue; - byte byte1; - byte byte2; - - while (curEntry->signatureData) { + const uint16 *curData; + uint16 curWord; + uint16 curCommand; + uint32 curValue; + byte byte1; + byte byte2; + int patchEntryCount = 0; + + // Count entries and allocate runtime data + while (curEntry->signatureData) { + patchEntryCount++; curEntry++; + } + _runtimeTable = new SciScriptPatcherRuntimeEntry[patchEntryCount]; + memset(_runtimeTable, 0, sizeof(SciScriptPatcherRuntimeEntry) * patchEntryCount); + + curEntry = patchTable; + curRuntimeEntry = _runtimeTable; + while (curEntry->signatureData) { // process signature memset(magicDWord, 0, sizeof(magicDWord)); + curRuntimeEntry->active = curEntry->defaultActive; + curRuntimeEntry->magicDWord = 0; + curRuntimeEntry->magicOffset = 0; + for (step = 0; step < 2; step++) { switch (step) { case 0: curData = curEntry->signatureData; break; case 1: curData = curEntry->patchData; break; } - + curWord = *curData; magicOffset = 0; while (curWord != SIG_END) { @@ -2240,10 +2322,10 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS switch (curCommand) { case SIG_MAGICDWORD: { if (step == 0) { - if ((curEntry->magicDWord) || (magicDWordLeft)) + if ((curRuntimeEntry->magicDWord) || (magicDWordLeft)) error("Script-Patcher: Magic-DWORD specified multiple times in signature\nFaulty patch: '%s'", curEntry->description); magicDWordLeft = 4; - curEntry->magicOffset = magicOffset; + curRuntimeEntry->magicOffset = magicOffset; } break; } @@ -2271,15 +2353,17 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS break; } case SIG_SELECTOR16: { - curSelector = &selectorTable[curValue]; - if (curSelector->id == -1) - curSelector->id = g_sci->getKernel()->findSelector(curSelector->name); + curSelector = _selectorIdTable[curValue]; + if (curSelector == -1) { + curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]); + _selectorIdTable[curValue] = curSelector; + } if (!isMacSci11) { - byte1 = curSelector->id & 0x00FF; - byte2 = curSelector->id >> 8; + byte1 = curSelector & 0x00FF; + byte2 = curSelector >> 8; } else { - byte1 = curSelector->id >> 8; - byte2 = curSelector->id & 0x00FF; + byte1 = curSelector >> 8; + byte2 = curSelector & 0x00FF; } break; } @@ -2294,7 +2378,7 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS magicDWordLeft--; } if (!magicDWordLeft) { - curEntry->magicDWord = READ_LE_UINT32(magicDWord); + curRuntimeEntry->magicDWord = READ_LE_UINT32(magicDWord); } } break; @@ -2302,15 +2386,16 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS case SIG_BYTE: case SIG_SELECTOR8: { if (curCommand == SIG_SELECTOR8) { - curSelector = &selectorTable[curValue]; - if (curSelector->id == -1) { - curSelector->id = g_sci->getKernel()->findSelector(curSelector->name); - if (curSelector->id != -1) { - if (curSelector->id & 0xFF00) + curSelector = _selectorIdTable[curValue]; + if (curSelector == -1) { + curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]); + _selectorIdTable[curValue] = curSelector; + if (curSelector != -1) { + if (curSelector & 0xFF00) error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", curEntry->description); } } - curValue = curSelector->id; + curValue = curSelector; } magicOffset--; if (magicDWordLeft) { @@ -2318,7 +2403,7 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS magicDWord[4 - magicDWordLeft] = (byte)curValue; magicDWordLeft--; if (!magicDWordLeft) { - curEntry->magicDWord = READ_LE_UINT32(magicDWord); + curRuntimeEntry->magicDWord = READ_LE_UINT32(magicDWord); } } } @@ -2329,35 +2414,38 @@ void Script::patcherInitSignature(SciScriptPatcherEntry *patchTable, bool isMacS } if (magicDWordLeft) error("Script-Patcher: Magic-DWORD beyond End-Of-Signature\nFaulty patch: '%s'", curEntry->description); - if (!curEntry->magicDWord) + if (!curRuntimeEntry->magicDWord) error("Script-Patcher: Magic-DWORD not specified in signature\nFaulty patch: '%s'", curEntry->description); - - curEntry++; - } + + curEntry++; curRuntimeEntry++; + } } // This method enables certain patches // It's used for patches, which are not meant to get applied all the time -void Script::patcherEnablePatch(SciScriptPatcherEntry *patchTable, const char *searchDescription) { - SciScriptPatcherEntry *curEntry = patchTable; - int searchDescriptionLen = strlen( searchDescription ); +void ScriptPatcher::enablePatch(const SciScriptPatcherEntry *patchTable, const char *searchDescription) { + const SciScriptPatcherEntry *curEntry = patchTable; + SciScriptPatcherRuntimeEntry *runtimeEntry = _runtimeTable; + int searchDescriptionLen = strlen(searchDescription); int matchCount = 0; - - while (curEntry->signatureData) { + + while (curEntry->signatureData) { if (strncmp(curEntry->description, searchDescription, searchDescriptionLen) == 0) { // match found, enable patch - curEntry->active = true; + runtimeEntry->active = true; matchCount++; } - curEntry++; - } - - if (!matchCount) + curEntry++; runtimeEntry++; + } + + if (!matchCount) error("Script-Patcher: no patch found to enable"); } -void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) { - SciScriptPatcherEntry *signatureTable = NULL; +void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) { + const SciScriptPatcherEntry *signatureTable = NULL; + const SciScriptPatcherEntry *curEntry = NULL; + SciScriptPatcherRuntimeEntry *curRuntimeEntry = NULL; const Sci::SciGameId gameId = g_sci->getGameId(); switch (gameId) { @@ -2431,48 +2519,57 @@ void Script::patcherProcessScript(uint16 scriptNr, byte *scriptData, const uint3 if (signatureTable) { bool isMacSci11 = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1); - if (!signatureTable->magicDWord) { + if (!_runtimeTable) { // Abort, in case selectors are not yet initialized (happens for games w/o selector-dictionary) if (!g_sci->getKernel()->selectorNamesAvailable()) return; - + // signature table needs to get initialized (Magic DWORD set, selector table set) - patcherInitSignature(signatureTable, isMacSci11); - + initSignature(signatureTable, isMacSci11); + // Do additional game-specific initialization switch (gameId) { case GID_KQ5: if (g_sci->_features->useAltWinGMSound()) { // See the explanation in the kq5SignatureWinGMSignals comment - patcherEnablePatch(signatureTable, "Win: GM Music signal checks"); + enablePatch(signatureTable, "Win: GM Music signal checks"); + } + break; + case GID_KQ6: + if (g_sci->speechAndSubtitlesEnabled()) { + // Enables Audio + subtitles patches for King's Quest 6, when "Text and Speech: Both" is selected + enablePatch(signatureTable, "CD: audio + text support"); } break; case GID_LAURABOW2: if (g_sci->speechAndSubtitlesEnabled()) { // Enables Audio + subtitles patches for Laura Bow 2, when "Text and Speech: Both" is selected - patcherEnablePatch(signatureTable, "CD: audio + text support"); + enablePatch(signatureTable, "CD: audio + text support"); } break; default: break; } } - - while (signatureTable->signatureData) { - if ( (scriptNr == signatureTable->scriptNr) && (signatureTable->active) ) { + + curEntry = signatureTable; + curRuntimeEntry = _runtimeTable; + + while (curEntry->signatureData) { + if ((scriptNr == curEntry->scriptNr) && (curRuntimeEntry->active)) { int32 foundOffset = 0; - int16 applyCount = signatureTable->applyCount; + int16 applyCount = curEntry->applyCount; do { - foundOffset = patcherFindSignature(signatureTable, scriptData, scriptSize, isMacSci11); + foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize, isMacSci11); if (foundOffset != -1) { // found, so apply the patch - debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", signatureTable->description, scriptNr, foundOffset); - patcherApplyPatch(signatureTable, scriptData, scriptSize, foundOffset, isMacSci11); + debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", curEntry->description, scriptNr, foundOffset); + applyPatch(curEntry, scriptData, scriptSize, foundOffset, isMacSci11); } applyCount--; } while ((foundOffset != -1) && (applyCount)); } - signatureTable++; + curEntry++; curRuntimeEntry++; } } } diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h new file mode 100644 index 0000000000..5d3ee22f7a --- /dev/null +++ b/engines/sci/engine/script_patches.h @@ -0,0 +1,100 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCI_ENGINE_SCRIPT_PATCHES_H +#define SCI_ENGINE_SCRIPT_PATCHES_H + +#include "sci/sci.h" + +namespace Sci { + +#define SIG_END 0xFFFF +#define SIG_MISMATCH 0xFFFE +#define SIG_COMMANDMASK 0xF000 +#define SIG_VALUEMASK 0x0FFF +#define SIG_BYTEMASK 0x00FF +#define SIG_MAGICDWORD 0xF000 +#define SIG_ADDTOOFFSET 0xE000 +#define SIG_SELECTOR16 0x9000 +#define SIG_SELECTOR8 0x8000 +#define SIG_UINT16 0x1000 +#define SIG_BYTE 0x0000 + +#define PATCH_END SIG_END +#define PATCH_COMMANDMASK SIG_COMMANDMASK +#define PATCH_VALUEMASK SIG_VALUEMASK +#define PATCH_BYTEMASK SIG_BYTEMASK +#define PATCH_ADDTOOFFSET SIG_ADDTOOFFSET +#define PATCH_GETORIGINALBYTE 0xD000 +#define PATCH_GETORIGINALBYTEADJUST 0xC000 +#define PATCH_SELECTOR16 SIG_SELECTOR16 +#define PATCH_SELECTOR8 SIG_SELECTOR8 +#define PATCH_UINT16 SIG_UINT16 +#define PATCH_BYTE SIG_BYTE + +// defines maximum scratch area for getting original bytes from unpatched script data +#define PATCH_VALUELIMIT 4096 + +struct SciScriptPatcherEntry { + bool defaultActive; +// bool active; + uint16 scriptNr; + const char *description; + int16 applyCount; +// uint32 magicDWord; +// int magicOffset; + const uint16 *signatureData; + const uint16 *patchData; +}; + +//#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, 0, 0, NULL, NULL } +#define SCI_SIGNATUREENTRY_TERMINATOR { false, 0, NULL, 0, NULL, NULL } + +struct SciScriptPatcherRuntimeEntry { + bool active; + uint32 magicDWord; + int magicOffset; +}; + +/** + * ScriptPatcher class, handles on-the-fly patching of script data + */ +class ScriptPatcher { +public: + ScriptPatcher(); + ~ScriptPatcher(); + + void processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize); + +private: + void initSignature(const SciScriptPatcherEntry *patchTable, bool isMacSci11); + void enablePatch(const SciScriptPatcherEntry *patchTable, const char *searchDescription); + int32 findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, bool isMacSci11); + void applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, bool isMacSci11); + + Selector *_selectorIdTable; + SciScriptPatcherRuntimeEntry *_runtimeTable; +}; + +} // End of namespace Sci + +#endif // SCI_ENGINE_WORKAROUNDS_H diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index a059bee74e..161a4f5c79 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -28,7 +28,8 @@ namespace Sci { -SegManager::SegManager(ResourceManager *resMan) { +SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher) + : _resMan(resMan), _scriptPatcher(scriptPatcher) { _heap.push_back(0); _clonesSegId = 0; @@ -44,8 +45,6 @@ SegManager::SegManager(ResourceManager *resMan) { _stringSegId = 0; #endif - _resMan = resMan; - createClassTable(); } @@ -983,7 +982,7 @@ int SegManager::instantiateScript(int scriptNum) { scr = allocateScript(scriptNum, &segmentId); } - scr->load(scriptNum, _resMan); + scr->load(scriptNum, _resMan, _scriptPatcher); scr->initializeLocals(this); scr->initializeClasses(this); scr->initializeObjects(this, segmentId); diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 0667b75651..b587f4991a 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -49,7 +49,7 @@ public: /** * Initialize the segment manager. */ - SegManager(ResourceManager *resMan); + SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher); /** * Deallocate all memory associated with the segment manager. @@ -448,6 +448,7 @@ private: Common::HashMap<int, SegmentId> _scriptSegMap; ResourceManager *_resMan; + ScriptPatcher *_scriptPatcher; SegmentId _clonesSegId; ///< ID of the (a) clones segment SegmentId _listsSegId; ///< ID of the (a) list segment diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 065565d8de..ae1d3ebdc5 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -38,6 +38,7 @@ #include "sci/engine/state.h" #include "sci/engine/kernel.h" #include "sci/engine/script.h" // for script_adjust_opcode_formats +#include "sci/engine/script_patches.h" #include "sci/engine/selector.h" // for SELECTOR #include "sci/sound/audio.h" @@ -184,6 +185,7 @@ SciEngine::~SciEngine() { delete[] _opcode_formats; + delete _scriptPatcher; delete _resMan; // should be deleted last g_sci = 0; } @@ -217,8 +219,9 @@ Common::Error SciEngine::run() { // Add the after market GM patches for the specified game, if they exist _resMan->addNewGMPatch(_gameId); _gameObjectAddress = _resMan->findGameObject(); - - SegManager *segMan = new SegManager(_resMan); + + _scriptPatcher = new ScriptPatcher(); + SegManager *segMan = new SegManager(_resMan, _scriptPatcher); // Initialize the game screen _gfxScreen = new GfxScreen(_resMan); @@ -883,12 +886,12 @@ void SciEngine::syncSoundSettings() { } } -// used by Script Patcher. Used to find out, if Laura Bow 2 needs patching for Speech+Subtitles - or not +// used by Script Patcher. Used to find out, if Laura Bow 2/King's Quest 6 need patching for Speech+Subtitles - or not bool SciEngine::speechAndSubtitlesEnabled() { bool subtitlesOn = ConfMan.getBool("subtitles"); bool speechOn = !ConfMan.getBool("speech_mute"); - if (subtitlesOn && speechOn) + if (isCD() && subtitlesOn && speechOn) return true; return false; } @@ -910,13 +913,12 @@ void SciEngine::syncIngameAudioOptions() { case GID_FREDDYPHARKAS: case GID_ECOQUEST: case GID_LSL6: - // TODO: The following need script patches for simultaneous speech and subtitles - // GID_KQ6 _gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 3); // speech + subtitles break; case GID_LAURABOW2: - // Laura Bow 2 gets patched when speech and subtitles are enabled - // It then does both, when the user has "speech" selected. That's why we select speech here + case GID_KQ6: + // Laura Bow 2 + King's Quest 6 get patched when speech and subtitles are enabled + // When the user has "speech" selected, the game will then do both That's why we select speech here default: // Game does not support speech and subtitles, set it to speech _gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech @@ -943,6 +945,7 @@ void SciEngine::updateScummVMAudioOptions() { // speech switch (_gameId) { case GID_LAURABOW2: + case GID_KQ6: // We don't sync "speech" for Laura Bow 2 in case the user choose "both" in the setting // Because "speech" (2) within SCI means "speech + subtitles" for Laura Bow 2 if (subtitlesOn && speechOn) diff --git a/engines/sci/sci.h b/engines/sci/sci.h index c91606fbc9..418f8c5e50 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -55,6 +55,7 @@ class AudioPlayer; class SoundCommandParser; class EventManager; class SegManager; +class ScriptPatcher; class GfxAnimate; class GfxCache; @@ -269,6 +270,7 @@ public: bool hasMacIconBar() const; inline ResourceManager *getResMan() const { return _resMan; } + inline ScriptPatcher *getScriptPatcher() const { return _scriptPatcher; } inline Kernel *getKernel() const { return _kernel; } inline EngineState *getEngineState() const { return _gamestate; } inline Vocabulary *getVocabulary() const { return _vocabulary; } @@ -400,6 +402,7 @@ private: const ADGameDescription *_gameDescription; const SciGameId _gameId; ResourceManager *_resMan; /**< The resource manager */ + ScriptPatcher *_scriptPatcher; /**< The script patcher */ EngineState *_gamestate; Kernel *_kernel; Vocabulary *_vocabulary; diff --git a/engines/teenagent/teenagent.h b/engines/teenagent/teenagent.h index d6a2c0d3c6..3c3bc25e56 100644 --- a/engines/teenagent/teenagent.h +++ b/engines/teenagent/teenagent.h @@ -31,6 +31,9 @@ #include "common/rect.h" #include "common/array.h" +#include "gui/debugger.h" + +#include "teenagent/console.h" #include "teenagent/dialog.h" struct ADGameDescription; @@ -50,7 +53,6 @@ struct UseHotspot; class Scene; class MusicPlayer; class Dialog; -class Console; class Resources; class Inventory; @@ -84,6 +86,8 @@ public: virtual bool canSaveGameStateCurrently() { return !_sceneBusy; } virtual bool hasFeature(EngineFeature f) const; + GUI::Debugger *getDebugger() { return console; } + void init(); enum Action { kActionNone, kActionExamine, kActionUse }; diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp index 043b18b8c5..6b6f4a5cd3 100644 --- a/engines/tinsel/scene.cpp +++ b/engines/tinsel/scene.cpp @@ -130,14 +130,14 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) { const byte *p = pStruc; memset(&g_tempStruc, 0, sizeof(SCENE_STRUC)); - g_tempStruc.numEntrance = READ_32(p); p += sizeof(uint32); - g_tempStruc.numPoly = READ_32(p); p += sizeof(uint32); - g_tempStruc.numTaggedActor = READ_32(p); p += sizeof(uint32); - g_tempStruc.defRefer = READ_32(p); p += sizeof(uint32); - g_tempStruc.hSceneScript = READ_32(p); p += sizeof(uint32); - g_tempStruc.hEntrance = READ_32(p); p += sizeof(uint32); - g_tempStruc.hPoly = READ_32(p); p += sizeof(uint32); - g_tempStruc.hTaggedActor = READ_32(p); p += sizeof(uint32); + g_tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.defRefer = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.hSceneScript = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.hEntrance = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.hPoly = READ_UINT32(p); p += sizeof(uint32); + g_tempStruc.hTaggedActor = READ_UINT32(p); p += sizeof(uint32); return &g_tempStruc; } @@ -168,7 +168,7 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) { assert(_ctx->pInit->hTinselCode); // Must have some code to run _ctx->pic = InitInterpretContext(GS_SCENE, - _ctx->pInit->hTinselCode, + FROM_32(_ctx->pInit->hTinselCode), TinselV2 ? _ctx->pInit->event : NOEVENT, NOPOLY, // No polygon 0, // No actor @@ -210,7 +210,7 @@ void SendSceneTinselProcess(TINSEL_EVENT event) { */ static void LoadScene(SCNHANDLE scene, int entry) { - int32 i; + uint32 i; TP_INIT init; const SCENE_STRUC *ss; const ENTRANCE_STRUC *es; @@ -239,17 +239,17 @@ static void LoadScene(SCNHANDLE scene, int entry) { // Music stuff char *cptr = (char *)FindChunk(scene, CHUNK_MUSIC_FILENAME); assert(cptr); - _vm->_pcmMusic->setMusicSceneDetails(ss->hMusicScript, ss->hMusicSegment, cptr); + _vm->_pcmMusic->setMusicSceneDetails(FROM_32(ss->hMusicScript), FROM_32(ss->hMusicSegment), cptr); } if (entry == NO_ENTRY_NUM) { // Restoring scene // Initialize all the polygons for this scene - InitPolygons(ss->hPoly, ss->numPoly, true); + InitPolygons(FROM_32(ss->hPoly), FROM_32(ss->numPoly), true); // Initialize the actors for this scene - StartTaggedActors(ss->hTaggedActor, ss->numTaggedActor, false); + StartTaggedActors(FROM_32(ss->hTaggedActor), FROM_32(ss->numTaggedActor), false); if (TinselV2) // Returning from cutscene @@ -259,18 +259,18 @@ static void LoadScene(SCNHANDLE scene, int entry) { // Genuine new scene // Initialize all the polygons for this scene - InitPolygons(ss->hPoly, ss->numPoly, false); + InitPolygons(FROM_32(ss->hPoly), FROM_32(ss->numPoly), false); // Initialize the actors for this scene - StartTaggedActors(ss->hTaggedActor, ss->numTaggedActor, true); + StartTaggedActors(FROM_32(ss->hTaggedActor), FROM_32(ss->numTaggedActor), true); // Run the appropriate entrance code (if any) - es = (const ENTRANCE_STRUC *)LockMem(ss->hEntrance); - for (i = 0; i < ss->numEntrance; i++) { + es = (const ENTRANCE_STRUC *)LockMem(FROM_32(ss->hEntrance)); + for (i = 0; i < FROM_32(ss->numEntrance); i++) { if (FROM_32(es->eNumber) == (uint)entry) { if (es->hScript) { init.event = STARTUP; - init.hTinselCode = FROM_32(es->hScript); + init.hTinselCode = es->hScript; CoroScheduler.createProcess(PID_TCODE, SceneTinselProcess, &init, sizeof(init)); } @@ -285,7 +285,7 @@ static void LoadScene(SCNHANDLE scene, int entry) { } - if (i == ss->numEntrance) + if (i == FROM_32(ss->numEntrance)) error("Non-existent scene entry number"); if (ss->hSceneScript) { @@ -297,10 +297,10 @@ static void LoadScene(SCNHANDLE scene, int entry) { } // Default refer type - SetDefaultRefer(ss->defRefer); + SetDefaultRefer(FROM_32(ss->defRefer)); // Scene's processes - SceneProcesses(ss->numProcess, ss->hProcess); + SceneProcesses(FROM_32(ss->numProcess), FROM_32(ss->hProcess)); } diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h index 5eb3b7d7b8..d26153245d 100644 --- a/engines/tinsel/tinsel.h +++ b/engines/tinsel/tinsel.h @@ -32,6 +32,8 @@ #include "common/util.h" #include "engines/engine.h" +#include "gui/debugger.h" + #include "tinsel/debugger.h" #include "tinsel/graphics.h" #include "tinsel/sound.h" @@ -150,6 +152,7 @@ class TinselEngine : public Engine { Common::Point _mousePos; uint8 _dosPlayerDir; Console *_console; + GUI::Debugger *getDebugger() { return _console; } static const char *const _sampleIndices[][3]; static const char *const _sampleFiles[][3]; diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h index 0be2d2a646..b405d099c4 100644 --- a/engines/toltecs/toltecs.h +++ b/engines/toltecs/toltecs.h @@ -36,13 +36,16 @@ #include "graphics/surface.h" +#include "gui/debugger.h" + +#include "toltecs/console.h" + namespace Toltecs { struct ToltecsGameDescription; class AnimationPlayer; class ArchiveReader; -class Console; class Input; class MenuSystem; class MoviePlayer; @@ -110,6 +113,8 @@ public: const Common::String& getTargetName() const { return _targetName; } void syncSoundSettings(); + GUI::Debugger *getDebugger() { return _console; } + void setupSysStrings(); void requestSavegame(int slotNum, Common::String &description); void requestLoadgame(int slotNum); diff --git a/engines/tony/tony.h b/engines/tony/tony.h index 750673061d..cdc7d7e20a 100644 --- a/engines/tony/tony.h +++ b/engines/tony/tony.h @@ -31,6 +31,7 @@ #include "common/random.h" #include "common/util.h" #include "engines/engine.h" +#include "gui/debugger.h" #include "tony/mpal/mpal.h" #include "tony/mpal/memory.h" @@ -108,6 +109,7 @@ public: Common::List<FPSfx *> _activeSfx; Globals _globals; Debugger *_debugger; + GUI::Debugger *getDebugger() { return _debugger; } int16 _cTableDialog[256]; int16 _lTableDialog[256]; diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 596f056bfe..0b3eb53268 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -2888,6 +2888,8 @@ void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum, setFrame(frameNum); setPosition(Common::Point(posX, posY)); fixPriority(priority); + + _effect = effect; } void BackgroundSceneObject::copySceneToBackground() { diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index 0f271649b3..50d4b4e008 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -443,7 +443,7 @@ Ringworld2Globals::Ringworld2Globals() { _scene180Mode = -1; _v57709 = 0; _v5780C = 0; - _v5780E = 0; + _mouseCursorId = 0; _v57810 = 0; _fadePaletteFlag = false; @@ -557,7 +557,7 @@ void Ringworld2Globals::reset() { _scene180Mode = -1; _v57709 = 0; _v5780C = 0; - _v5780E = 0; + _mouseCursorId = 0; _v57810 = 0; _s1550PlayerArea[R2_QUINN] = Common::Point(27, 4); _s1550PlayerArea[R2_SEEKER] = Common::Point(27, 4); @@ -611,7 +611,7 @@ void Ringworld2Globals::synchronize(Serializer &s) { s.syncAsSint16LE(_scene180Mode); s.syncAsSint16LE(_v57709); s.syncAsSint16LE(_v5780C); - s.syncAsSint16LE(_v5780E); + s.syncAsSint16LE(_mouseCursorId); s.syncAsSint16LE(_v57810); s.syncAsByte(_s1550PlayerArea[R2_QUINN].x); diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index f5543af345..777697edbd 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -284,7 +284,7 @@ public: int _scene180Mode; // _v575f7 int _v57709; int _v5780C; - int _v5780E; + int _mouseCursorId; int _v57810; int _speechSubtitles; Common::Point _s1550PlayerArea[3]; // only used for Quinn and Seeker diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp index d174d6fa4d..adb5e7f8a8 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp @@ -876,8 +876,8 @@ void Scene1100::postInit(SceneObjectList *OwnerList) { R2_GLOBALS._player._moveRate = 30; R2_GLOBALS._player._moveDiff = Common::Point(16, 2); - _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, 1); - _purplePlant.setup2(1102, 5, 1, 216, 167, 1, 0); + _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, EFFECT_SHADED); + _purplePlant.setup2(1102, 5, 1, 216, 167, 1, EFFECT_NONE); _leftImpacts.postInit(); _leftImpacts.setup(1113, 2, 1); @@ -2212,31 +2212,41 @@ void Scene1200::startCrawling(CrawlDirection dir) { * *--------------------------------------------------------------------------*/ -Scene1337::unkObj1337sub1::unkObj1337sub1() { +Scene1337::Card::Card() { _cardId = 0; _stationPos = Common::Point(0, 0); } -void Scene1337::unkObj1337sub1::synchronize(Serializer &s) { - warning("STUBBED: unkObj1337sub1::synchronize()"); +void Scene1337::Card::synchronize(Serializer &s) { + warning("STUBBED: Card::synchronize()"); } -Scene1337::unkObj1337_1::unkObj1337_1() { - _fieldB94 = Common::Point(0, 0); - _fieldB98 = Common::Point(0, 0); - _fieldB9C = Common::Point(0, 0); - _fieldBA0 = Common::Point(0, 0); - _fieldBA4 = 0; +bool Scene1337::Card::isIn(Common::Point pt) { + if ((_stationPos.x > pt.x) || (_stationPos.x + 24 < pt.x)) + return false; + + if ((_stationPos.y > pt.y) || (_stationPos.y + 24 < pt.y)) + return false; + + return true; +} + +Scene1337::GameBoardSide::GameBoardSide() { + _card1Pos = Common::Point(0, 0); + _card2Pos = Common::Point(0, 0); + _card3Pos = Common::Point(0, 0); + _card4Pos = Common::Point(0, 0); + _frameNum = 0; } -void Scene1337::unkObj1337_1::synchronize(Serializer &s) { - warning("STUBBED: unkObj1337_1::synchronize()"); +void Scene1337::GameBoardSide::synchronize(Serializer &s) { + warning("STUBBED: GameBoardSide::synchronize()"); } Scene1337::Scene1337() { _autoplay = false; _cardsAvailableNumb = 0; - _field3E26 = 0; + _currentDiscardIndex = 0; for (int i = 0; i < 100; i++) _availableCardsPile[i] = 0; @@ -2245,14 +2255,14 @@ Scene1337::Scene1337() { _currentPlayerNumb = 0; _field4240 = 0; _field4242 = 0; - _field4244 = false; + _showPlayerTurn = false; _field4246 = false; _field424A = 0; - _instructionsDisplayedFl = 0; + _instructionsDisplayedFl = false; _instructionsWaitCount = 0; _unkFctPtr412 = nullptr; - _field3EF0 = nullptr; + _discardCard = nullptr; _field3EF4 = nullptr; _field3EF8 = nullptr; @@ -2455,7 +2465,11 @@ void Scene1337::Action1::signal() { scene->_gameBoardSide[0]._outpostStation[0]._card.remove(); scene->_gameBoardSide[0]._outpostStation[1]._card.remove(); - scene->_background2.setup2(1332, 5, 1, 165, 95, 110, 1); + scene->_stockPile.setup(1332, 5, 1); + scene->_stockPile.setPosition(Common::Point(165, 95)); + scene->_stockPile.setPriority(110); + scene->_stockPile._effect = EFFECT_SHADED; + scene->_stockPile.show(); scene->_gameBoardSide[1]._handCard[0]._card.postInit(); scene->_gameBoardSide[1]._handCard[0]._card.setVisage(1332); @@ -2654,10 +2668,10 @@ void Scene1337::Action1::signal() { waitFrames(60); scene->actionDisplay(1331, 14, 159, 10, 1, 200, 0, 7, 0, 154, 154); - scene->_gameBoardSide[2]._delayPile[0]._card.postInit(); - scene->_gameBoardSide[2]._delayPile[0]._card.setVisage(1332); - scene->_gameBoardSide[2]._delayPile[0]._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0); - scene->_gameBoardSide[2]._delayPile[0]._card.hide(); + scene->_gameBoardSide[2]._delayCard._card.postInit(); + scene->_gameBoardSide[2]._delayCard._card.setVisage(1332); + scene->_gameBoardSide[2]._delayCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0); + scene->_gameBoardSide[2]._delayCard._card.hide(); scene->_gameBoardSide[3]._handCard[2]._cardId = 0; scene->_gameBoardSide[3]._handCard[2].remove(); @@ -2666,13 +2680,13 @@ void Scene1337::Action1::signal() { scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayPile[0]._stationPos, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayCard._stationPos, this); } break; case 6: { scene->_animatedCard._card.hide(); - scene->_gameBoardSide[2]._delayPile[0]._cardId = 21; - scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayPile[0]); + scene->_gameBoardSide[2]._delayCard._cardId = 21; + scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayCard); scene->_aSound1.play(57); R2_GLOBALS._sceneObjects->draw(); @@ -2731,12 +2745,12 @@ void Scene1337::Action1::signal() { scene->_lowerDisplayCard[6].remove(); scene->_lowerDisplayCard[7].remove(); - scene->_discardPile._cardId = scene->_gameBoardSide[2]._delayPile[0]._cardId; + scene->_discardPile._cardId = scene->_gameBoardSide[2]._delayCard._cardId; - scene->_gameBoardSide[2]._delayPile[0]._cardId = 0; - scene->_gameBoardSide[2]._delayPile[0]._card.remove(); + scene->_gameBoardSide[2]._delayCard._cardId = 0; + scene->_gameBoardSide[2]._delayCard._card.remove(); - scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -2750,10 +2764,10 @@ void Scene1337::Action1::signal() { R2_GLOBALS._sceneObjects->draw(); - scene->_gameBoardSide[2]._delayPile[0]._card.postInit(); - scene->_gameBoardSide[2]._delayPile[0]._card.setVisage(1332); - scene->_gameBoardSide[2]._delayPile[0]._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0); - scene->_gameBoardSide[2]._delayPile[0]._card.hide(); + scene->_gameBoardSide[2]._delayCard._card.postInit(); + scene->_gameBoardSide[2]._delayCard._card.setVisage(1332); + scene->_gameBoardSide[2]._delayCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0); + scene->_gameBoardSide[2]._delayCard._card.hide(); scene->_gameBoardSide[3]._handCard[1]._cardId = 0; scene->_gameBoardSide[3]._handCard[1].remove(); @@ -2762,13 +2776,13 @@ void Scene1337::Action1::signal() { scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayPile[0]._stationPos, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayCard._stationPos, this); } break; case 8: { scene->_animatedCard._card.hide(); - scene->_gameBoardSide[2]._delayPile[0]._cardId = 14; - scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayPile[0]); + scene->_gameBoardSide[2]._delayCard._cardId = 14; + scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayCard); scene->_aSound1.play(57); R2_GLOBALS._sceneObjects->draw(); @@ -2861,17 +2875,17 @@ void Scene1337::Action1::signal() { scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayPile[0]._stationPos, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayCard._stationPos, this); } break; case 9: { scene->_aSound1.play(58); - scene->_gameBoardSide[2]._delayPile[0]._cardId = 0; - scene->_gameBoardSide[2]._delayPile[0].remove(); + scene->_gameBoardSide[2]._delayCard._cardId = 0; + scene->_gameBoardSide[2]._delayCard.remove(); scene->_animatedCard._card.setStrip(5); scene->_animatedCard._card.setFrame(1); scene->_animatedCard._card.animate(ANIM_MODE_2, NULL); - scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayPile[0]._stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -3026,13 +3040,13 @@ void Scene1337::Action1::signal() { scene->_gameBoardSide[1]._outpostStation[i]._card.remove(); } - scene->_gameBoardSide[2]._delayPile[0]._cardId = 0; - scene->_gameBoardSide[2]._delayPile[0]._card.remove(); + scene->_gameBoardSide[2]._delayCard._cardId = 0; + scene->_gameBoardSide[2]._delayCard._card.remove(); scene->_discardPile._cardId = 0; scene->_discardPile._card.remove(); - scene->_background2.remove(); + scene->_stockPile.remove(); } // No break on purpose case 0: @@ -3083,7 +3097,11 @@ void Scene1337::Action2::signal() { break; case 3: scene->_shuffleAnimation._card.remove(); - scene->_background2.setup2(1332, 5, 1, 162, 95, 110, 1); + scene->_stockPile.setup(1332, 5, 1); + scene->_stockPile.setPosition(Common::Point(162, 95)); + scene->_stockPile.setPriority(110); + scene->_stockPile._effect = EFFECT_SHADED; + scene->_stockPile.show(); scene->_shuffleEndedFl = true; break; default: @@ -3091,6 +3109,9 @@ void Scene1337::Action2::signal() { } } +/** + * Deal cards + */ void Scene1337::Action3::signal() { Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene; @@ -3343,7 +3364,7 @@ void Scene1337::Action3::signal() { scene->_gameBoardSide[0]._handCard[2]._card.setStrip(5); scene->_gameBoardSide[0]._handCard[2]._card.setFrame(1); scene->_gameBoardSide[0]._handCard[2]._card.fixPriority(170); - scene->_gameBoardSide[0]._handCard[2]._card.hide(); + scene->_animatedCard._card.hide(); default: break; } @@ -3359,41 +3380,44 @@ void Scene1337::Action3::signal() { } } +/** + * Action used to handle the other players' turn + */ void Scene1337::Action4::signal() { Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene; switch (_actionIndex++) { case 0: - if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId))) { + if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId))) { if (scene->_cardsAvailableNumb < 0) - scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId); + scene->shuffleCards(); scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0); scene->_animatedCard._card.show(); scene->_aSound2.play(61); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB94, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card1Pos, this); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb]; scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0; scene->_cardsAvailableNumb--; if (scene->_cardsAvailableNumb < 0) - scene->_background2.remove(); + scene->_stockPile.remove(); } else { // Self call, forcing next actionIndex signal(); } break; case 1: - if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB94.x) - && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB94.y) ) { + if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card1Pos.x) + && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card1Pos.y) ) { scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.postInit(); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card._moveDiff = Common::Point(30, 30); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setVisage(1332); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._stationPos, 0); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setStrip(1); - scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4); + scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.fixPriority(170); } @@ -3401,7 +3425,7 @@ void Scene1337::Action4::signal() { scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]); scene->_animatedCard._card.hide(); - if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId == 0))) { + if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId == 0))) { if (scene->_cardsAvailableNumb < 0) scene->shuffleCards(); scene->_animatedCard._card.setPosition(Common::Point(162, 95)); @@ -3410,25 +3434,25 @@ void Scene1337::Action4::signal() { scene->_aSound2.play(61); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB98, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card2Pos, this); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb]; scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0; scene->_cardsAvailableNumb--; if (scene->_cardsAvailableNumb < 0) - scene->_background2.remove(); + scene->_stockPile.remove(); } else signal(); break; case 2: - if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB98.x) - && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB98.y) ) { + if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card2Pos.x) + && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card2Pos.y) ) { scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.postInit(); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card._moveDiff = Common::Point(30, 30); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setVisage(1332); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._stationPos, 0); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setStrip(1); - scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4); + scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.fixPriority(170); } @@ -3436,7 +3460,7 @@ void Scene1337::Action4::signal() { scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]); scene->_animatedCard._card.hide(); - if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId == 0))) { + if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId == 0))) { if (scene->_cardsAvailableNumb < 0) scene->shuffleCards(); scene->_animatedCard._card.setPosition(Common::Point(162, 95)); @@ -3445,25 +3469,25 @@ void Scene1337::Action4::signal() { scene->_aSound2.play(61); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB9C, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card3Pos, this); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb]; scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0; scene->_cardsAvailableNumb--; if (scene->_cardsAvailableNumb < 0) - scene->_background2.remove(); + scene->_stockPile.remove(); } else signal(); break; case 3: - if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB9C.x) - && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldB9C.y) ) { + if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card3Pos.x) + && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card3Pos.y) ) { scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.postInit(); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card._moveDiff = Common::Point(30, 30); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setVisage(1332); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._stationPos, 0); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setStrip(1); - scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4); + scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.fixPriority(170); } @@ -3471,7 +3495,7 @@ void Scene1337::Action4::signal() { scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]); scene->_animatedCard._card.hide(); - if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayPile[0]._cardId == 0))) { + if ((scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId == 0) && (scene->subC264B(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId == 0))) { if (scene->_cardsAvailableNumb < 0) scene->shuffleCards(); scene->_animatedCard._card.setPosition(Common::Point(162, 95)); @@ -3480,25 +3504,25 @@ void Scene1337::Action4::signal() { scene->_aSound2.play(61); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA0, this); + scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card4Pos, this); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb]; scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0; scene->_cardsAvailableNumb--; if (scene->_cardsAvailableNumb < 0) - scene->_background2.remove(); + scene->_stockPile.remove(); } else signal(); break; case 4: - if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA0.x) - && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA0.y) ) { + if ( ( scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card4Pos.x) + && ( scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card4Pos.y) ) { scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.postInit(); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card._moveDiff = Common::Point(30, 30); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setVisage(1332); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._stationPos, 0); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setStrip(1); - scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._fieldBA4); + scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum); scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.fixPriority(170); } @@ -3528,14 +3552,18 @@ void Scene1337::Action4::signal() { } } +/** + * Animations for discarding a card + */ void Scene1337::Action5::signal() { Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene; switch (_actionIndex++) { case 0: { - scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF0->_cardId; - scene->_field3E26--; + scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_discardCard->_cardId; + scene->_currentDiscardIndex--; if (!g_globals->_sceneObjects->contains(&scene->_discardPile._card)) { + // The first discarded card makes the pile appear scene->_discardPile._card.postInit(); scene->_discardPile._card.hide(); scene->_discardPile._card.setVisage(1332); @@ -3543,15 +3571,15 @@ void Scene1337::Action5::signal() { scene->_discardPile._card.fixPriority(170); } - scene->_discardPile._cardId = scene->_field3EF0->_cardId; - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); + scene->_discardPile._cardId = scene->_discardCard->_cardId; + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); - if (scene->_field3EF0 == &scene->_item6) { + if (scene->_discardCard == &scene->_selectedCard) { scene->setCursorData(5, 1, 4); scene->subC4CEC(); } - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); Common::Point pt(128, 95); NpcMover *mover = new NpcMover(); @@ -3581,10 +3609,10 @@ void Scene1337::Action6::signal() { scene->_field3EF4->_card.setPosition(scene->_field3EF4->_stationPos); scene->_field3EF4->_card.fixPriority(170); - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -3595,7 +3623,7 @@ void Scene1337::Action6::signal() { scene->_animatedCard._card.hide(); scene->setAnimationInfo(scene->_field3EF4); scene->_aSound1.play(59); - if (scene->_field3EF0 == &scene->_item6) { + if (scene->_discardCard == &scene->_selectedCard) { scene->setCursorData(5, 1, 4); scene->subC4CEC(); } @@ -3611,32 +3639,31 @@ void Scene1337::Action7::signal() { switch (_actionIndex++) { case 0: { - scene->_field3EF4->_cardId = scene->_field3EF0->_cardId; + scene->_field3EF4->_cardId = scene->_discardCard->_cardId; - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); scene->_animatedCard._card.addMover(mover, &scene->_field3EF4->_stationPos, this); } break; case 1: - if (scene->_field3EF0 == &scene->_item6) { + if (scene->_discardCard == &scene->_selectedCard) { scene->setCursorData(5, 1, 4); scene->subC4CEC(); } scene->setAnimationInfo(scene->_field3EF4); scene->_aSound1.play(59); scene->_item5._cardId = 1; - scene->_item5._stationPos.x = scene->_field3EF4->_stationPos.x; - scene->_item5._stationPos.y = scene->_field3EF4->_stationPos.y; + scene->_item5._stationPos = scene->_field3EF4->_stationPos; scene->_item5._card.postInit(); scene->_item5._card.hide(); - scene->_item5._card._flags = 0x200; + scene->_item5._card._flags = OBJFLAG_HIDING; - scene->subC4A39(&scene->_item5); + scene->discardCard(&scene->_item5); break; default: break; @@ -3648,13 +3675,13 @@ void Scene1337::Action8::signal() { switch (_actionIndex++) { case 0: { - scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId; - scene->_field3E26--; + scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_field3EF4->_cardId; + scene->_currentDiscardIndex--; - scene->_field3EF4->_cardId = scene->_field3EF0->_cardId; - scene->_field3EF0->_card.remove(); + scene->_field3EF4->_cardId = scene->_discardCard->_cardId; + scene->_discardCard->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -3664,13 +3691,13 @@ void Scene1337::Action8::signal() { case 1: scene->_animatedCard._card.hide(); - if (scene->_field3EF0 == &scene->_item6) { + if (scene->_discardCard == &scene->_selectedCard) { scene->setCursorData(5, 1, 4); scene->subC4CEC(); } scene->setAnimationInfo(scene->_field3EF4); scene->_aSound1.play(58); - scene->subC4A39(scene->_field3EF4); + scene->discardCard(scene->_field3EF4); break; default: break; @@ -3682,17 +3709,17 @@ void Scene1337::Action9::signal() { switch (_actionIndex++) { case 0: { - scene->_field3EF4->_cardId = scene->_field3EF0->_cardId; + scene->_field3EF4->_cardId = scene->_discardCard->_cardId; scene->_field3EF4->_card.postInit(); scene->_field3EF4->_card.hide(); scene->_field3EF4->_card.setVisage(1332); scene->_field3EF4->_card.setPosition(scene->_field3EF4->_stationPos, 0); scene->_field3EF4->_card.fixPriority(170); - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -3704,7 +3731,7 @@ void Scene1337::Action9::signal() { scene->setAnimationInfo(scene->_field3EF4); scene->_aSound1.play(57); - if (scene->_field3EF0 == &scene->_item6) { + if (scene->_discardCard == &scene->_selectedCard) { scene->setCursorData(5, 1, 4); scene->subC4CEC(); } @@ -3726,17 +3753,17 @@ void Scene1337::Action10::signal() { scene->_field3EF8->_card.setVisage(1332); scene->_field3EF8->_card.setPosition(scene->_field3EF8->_stationPos, 0); scene->_field3EF8->_card.fixPriority(170); - scene->_field3EF8->_cardId = scene->_field3EF0->_cardId; + scene->_field3EF8->_cardId = scene->_discardCard->_cardId; - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); - if (scene->_field3EF0 == &scene->_item6) { + if (scene->_discardCard == &scene->_selectedCard) { scene->setCursorData(5, 1, 4); scene->subC4CEC(); } - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); scene->_animatedCard._card.addMover(mover, &scene->_field3EF8->_stationPos, this); @@ -3849,10 +3876,10 @@ void Scene1337::Action10::signal() { g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks); } - scene->_item6._stationPos = event.mousePos; + scene->_selectedCard._stationPos = event.mousePos; for (int i = 0; i <= 7; i++) { - if ((scene->subC2BF8(&scene->_gameBoardSide[2]._outpostStation[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0)) { + if (scene->_gameBoardSide[2]._outpostStation[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0)) { scene->_field3EF4 = &scene->_gameBoardSide[2]._outpostStation[0]; found2 = true; break; @@ -3863,8 +3890,8 @@ void Scene1337::Action10::signal() { } } - scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId; - scene->_field3E26--; + scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_field3EF4->_cardId; + scene->_currentDiscardIndex--; scene->_field3EF4->_cardId = 0; scene->_field3EF4->_card.remove(); @@ -3877,7 +3904,7 @@ void Scene1337::Action10::signal() { break; case 2: scene->_animatedCard._card.hide(); - scene->subC4A39(scene->_field3EF8); + scene->discardCard(scene->_field3EF8); break; default: break; @@ -3902,9 +3929,9 @@ void Scene1337::Action11::signal() { scene->_animatedCard._card.setPosition(scene->_field3EF4->_stationPos, 0); scene->setCursorData(5, 1, 4); } else { - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); } scene->_animatedCard._card.show(); @@ -3930,8 +3957,8 @@ void Scene1337::Action11::signal() { } if ((found) && (scene->subC3E92(scene->_field4240) != -1)) { - scene->_field3EF0 = &scene->_gameBoardSide[0]._handCard[i]; - scene->_field3EF4 = &scene->_gameBoardSide[0]._arr4[0]; + scene->_discardCard = &scene->_gameBoardSide[0]._handCard[i]; + scene->_field3EF4 = &scene->_gameBoardSide[0]._emptyStationPos; if (scene->_field4240 != 0) { int tmpVal = scene->subC3E92(scene->_field4240); scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal]; @@ -3949,8 +3976,8 @@ void Scene1337::Action11::signal() { } if ((found) && (scene->subC3E92(scene->_field4240) != -1)) { - scene->_field3EF0 = &scene->_gameBoardSide[1]._handCard[i]; - scene->_field3EF4 = &scene->_gameBoardSide[1]._arr4[0]; + scene->_discardCard = &scene->_gameBoardSide[1]._handCard[i]; + scene->_field3EF4 = &scene->_gameBoardSide[1]._emptyStationPos; if (scene->_field4240 != 1) { int tmpVal = scene->subC3E92(scene->_field4240); scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal]; @@ -3973,8 +4000,8 @@ void Scene1337::Action11::signal() { scene->subC4CEC(); else { scene->subC4CEC(); - scene->_field3EF0 = &scene->_gameBoardSide[2]._handCard[i]; - scene->_field3EF4 = &scene->_gameBoardSide[2]._arr4[0]; + scene->_discardCard = &scene->_gameBoardSide[2]._handCard[i]; + scene->_field3EF4 = &scene->_gameBoardSide[2]._emptyStationPos; if (scene->_field4240 != 2) { int tmpVal = scene->subC3E92(scene->_field4240); scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal]; @@ -3993,8 +4020,8 @@ void Scene1337::Action11::signal() { } if ((found) && (scene->subC3E92(scene->_field4240) != -1)) { - scene->_field3EF0 = &scene->_gameBoardSide[3]._handCard[i]; - scene->_field3EF4 = &scene->_gameBoardSide[3]._arr4[0]; + scene->_discardCard = &scene->_gameBoardSide[3]._handCard[i]; + scene->_field3EF4 = &scene->_gameBoardSide[3]._emptyStationPos; if (scene->_field4240 != 3) { int tmpVal = scene->subC3E92(scene->_field4240); scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4240]._handCard[tmpVal]; @@ -4045,13 +4072,13 @@ void Scene1337::Action11::signal() { g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks); } - scene->_item6._stationPos = event.mousePos; + scene->_selectedCard._stationPos = event.mousePos; found = false; if (scene->_field4242 != 2) { for (i = 0; i <= 3; i++) { - if ((scene->subC2BF8(&scene->_gameBoardSide[scene->_field4242]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[scene->_field4242]._handCard[i]._cardId != 0)) { + if (scene->_gameBoardSide[scene->_field4242]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[scene->_field4242]._handCard[i]._cardId != 0)) { scene->_field3EF8 = &scene->_gameBoardSide[scene->_field4242]._handCard[i]; found = true; break; @@ -4069,13 +4096,13 @@ void Scene1337::Action11::signal() { } } - scene->_field3EF0->_card.postInit(); - scene->_field3EF0->_card.hide(); - scene->_field3EF0->_card.setVisage(1332); - scene->_field3EF0->_card.setPosition(scene->_field3EF0->_stationPos, 0); - scene->_field3EF0->_card.fixPriority(170); - scene->_field3EF0->_card.setStrip2(1); - scene->_field3EF0->_cardId = scene->_field3EF8->_cardId; + scene->_discardCard->_card.postInit(); + scene->_discardCard->_card.hide(); + scene->_discardCard->_card.setVisage(1332); + scene->_discardCard->_card.setPosition(scene->_discardCard->_stationPos, 0); + scene->_discardCard->_card.fixPriority(170); + scene->_discardCard->_card.setStrip2(1); + scene->_discardCard->_cardId = scene->_field3EF8->_cardId; scene->_field3EF8->_cardId = 0; scene->_field3EF8->_card.remove(); @@ -4084,32 +4111,32 @@ void Scene1337::Action11::signal() { scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_field3EF0->_stationPos, this); + scene->_animatedCard._card.addMover(mover, &scene->_discardCard->_stationPos, this); } break; case 2: scene->_animatedCard._card.hide(); switch (scene->_field4240) { case 0: - scene->_field3EF0->_card.setFrame(2); - scene->_field3EF0->_card.show(); + scene->_discardCard->_card.setFrame2(2); + scene->_discardCard->_card.show(); break; case 1: - scene->_field3EF0->_card.setFrame(4); - scene->_field3EF0->_card.show(); + scene->_discardCard->_card.setFrame2(4); + scene->_discardCard->_card.show(); break; case 3: - scene->_field3EF0->_card.setFrame(3); - scene->_field3EF0->_card.show(); + scene->_discardCard->_card.setFrame2(3); + scene->_discardCard->_card.show(); break; default: - scene->setAnimationInfo(scene->_field3EF0); + scene->setAnimationInfo(scene->_discardCard); break; } scene->_currentPlayerNumb--; - scene->_field4244 = false; - scene->subC4A39(scene->_field3EF4); + scene->_showPlayerTurn = false; + scene->discardCard(scene->_field3EF4); break; default: break; @@ -4124,11 +4151,12 @@ void Scene1337::Action12::signal() { signal(); break; case 1: { - scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId; - scene->_field3EF4->_cardId = scene->_field3EF0->_cardId; - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_field3EF4->_cardId; + scene->_currentDiscardIndex++; + scene->_field3EF4->_cardId = scene->_discardCard->_cardId; + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -4192,11 +4220,11 @@ void Scene1337::Action12::signal() { g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks); } - scene->_item6._stationPos = event.mousePos; + scene->_selectedCard._stationPos = event.mousePos; if (scene->_field4240 == 0) { for (i = 0; i <= 3; i++) { - if ((scene->subC2BF8(&scene->_gameBoardSide[0]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[0]._handCard[i]._cardId != 0)) { + if (scene->_gameBoardSide[0]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[0]._handCard[i]._cardId != 0)) { found = true; scene->_field3EF8 = &scene->_gameBoardSide[0]._handCard[i]; break; @@ -4206,7 +4234,7 @@ void Scene1337::Action12::signal() { if (scene->_field4240 == 3) { for (i = 0; i <= 3; i++) { - if ((scene->subC2BF8(&scene->_gameBoardSide[3]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)) { + if (scene->_gameBoardSide[3]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)) { found = true; scene->_field3EF8 = &scene->_gameBoardSide[3]._handCard[i]; break; @@ -4216,7 +4244,7 @@ void Scene1337::Action12::signal() { if (scene->_field4240 == 1) { for (i = 0; i <= 3; i++) { - if ((scene->subC2BF8(&scene->_gameBoardSide[1]._handCard[i], scene->_item6._stationPos) != 0) && (scene->_gameBoardSide[1]._handCard[i]._cardId != 0)) { + if (scene->_gameBoardSide[1]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[1]._handCard[i]._cardId != 0)) { found = true; scene->_field3EF8 = &scene->_gameBoardSide[1]._handCard[i]; break; @@ -4242,13 +4270,13 @@ void Scene1337::Action12::signal() { } } - scene->_field3EF0->_card.postInit(); - scene->_field3EF0->_card.hide(); - scene->_field3EF0->_card.setVisage(1332); - scene->_field3EF0->_card.setPosition(scene->_field3EF0->_stationPos); - scene->_field3EF0->_card.fixPriority(170); - scene->_field3EF0->_card.setStrip2(1); - scene->_field3EF0->_cardId = scene->_field3EF8->_cardId; + scene->_discardCard->_card.postInit(); + scene->_discardCard->_card.hide(); + scene->_discardCard->_card.setVisage(1332); + scene->_discardCard->_card.setPosition(scene->_discardCard->_stationPos); + scene->_discardCard->_card.fixPriority(170); + scene->_discardCard->_card.setStrip2(1); + scene->_discardCard->_cardId = scene->_field3EF8->_cardId; scene->_field3EF8->_cardId = 0; scene->_field3EF8->_card.remove(); @@ -4258,29 +4286,29 @@ void Scene1337::Action12::signal() { scene->_aSound1.play(57); NpcMover *mover = new NpcMover(); - scene->_animatedCard._card.addMover(mover, &scene->_field3EF0->_stationPos, this); + scene->_animatedCard._card.addMover(mover, &scene->_discardCard->_stationPos, this); } break; case 3: scene->_animatedCard._card.hide(); switch (scene->_field4242) { case 0: - scene->_field3EF0->_card.setFrame2(2); - scene->_field3EF0->_card.show(); + scene->_discardCard->_card.setFrame2(2); + scene->_discardCard->_card.show(); break; case 1: - scene->_field3EF0->_card.setFrame2(4); - scene->_field3EF0->_card.show(); + scene->_discardCard->_card.setFrame2(4); + scene->_discardCard->_card.show(); break; case 3: - scene->_field3EF0->_card.setFrame2(3); - scene->_field3EF0->_card.show(); + scene->_discardCard->_card.setFrame2(3); + scene->_discardCard->_card.show(); break; default: - scene->setAnimationInfo(scene->_field3EF0); + scene->setAnimationInfo(scene->_discardCard); break; } - scene->subC4A39(scene->_field3EF4); + scene->discardCard(scene->_field3EF4); break; default: break; @@ -4292,15 +4320,15 @@ void Scene1337::Action13::signal() { switch (_actionIndex++) { case 0: { - scene->_availableCardsPile[scene->_field3E26] = scene->_field3EF4->_cardId; - scene->_field3E26--; + scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_field3EF4->_cardId; + scene->_currentDiscardIndex--; - scene->_field3EF4->_cardId = scene->_field3EF0->_cardId; + scene->_field3EF4->_cardId = scene->_discardCard->_cardId; - scene->_field3EF0->_cardId = 0; - scene->_field3EF0->_card.remove(); + scene->_discardCard->_cardId = 0; + scene->_discardCard->_card.remove(); - scene->_animatedCard._card.setPosition(scene->_field3EF0->_stationPos, 0); + scene->_animatedCard._card.setPosition(scene->_discardCard->_stationPos, 0); scene->_animatedCard._card.show(); NpcMover *mover = new NpcMover(); @@ -4314,7 +4342,7 @@ void Scene1337::Action13::signal() { signal(); break; case 2: - scene->subC4A39(scene->_field3EF4); + scene->discardCard(scene->_field3EF4); break; default: break; @@ -4337,9 +4365,9 @@ void Scene1337::postInit(SceneObjectList *OwnerList) { _unkFctPtr412 = NULL; - _field3EF0 = NULL; - _field3EF4 = NULL; - _field3EF8 = NULL; + _discardCard = nullptr; + _field3EF4 = nullptr; + _field3EF8 = nullptr; _gameBoardSide[2]._handCard[0]._stationPos = Common::Point(10, 174); _gameBoardSide[2]._handCard[1]._stationPos = Common::Point(37, 174); @@ -4355,15 +4383,15 @@ void Scene1337::postInit(SceneObjectList *OwnerList) { _gameBoardSide[2]._outpostStation[6]._stationPos = Common::Point(171, 174); _gameBoardSide[2]._outpostStation[7]._stationPos = Common::Point(145, 174); - _gameBoardSide[2]._delayPile[0]._stationPos = Common::Point(199, 174); + _gameBoardSide[2]._delayCard._stationPos = Common::Point(199, 174); - _gameBoardSide[2]._arr4[0]._stationPos = Common::Point(145, 148); + _gameBoardSide[2]._emptyStationPos._stationPos = Common::Point(145, 148); - _gameBoardSide[2]._fieldB94 = Common::Point(10, 174); - _gameBoardSide[2]._fieldB98 = Common::Point(37, 174); - _gameBoardSide[2]._fieldB9C = Common::Point(64, 174); - _gameBoardSide[2]._fieldBA0 = Common::Point(91, 174); - _gameBoardSide[2]._fieldBA4 = 2; + _gameBoardSide[2]._card1Pos = Common::Point(10, 174); + _gameBoardSide[2]._card2Pos = Common::Point(37, 174); + _gameBoardSide[2]._card3Pos = Common::Point(64, 174); + _gameBoardSide[2]._card4Pos = Common::Point(91, 174); + _gameBoardSide[2]._frameNum = 2; _gameBoardSide[3]._handCard[0]._stationPos = Common::Point(14, 14); _gameBoardSide[3]._handCard[1]._stationPos = Common::Point(14, 36); @@ -4379,15 +4407,15 @@ void Scene1337::postInit(SceneObjectList *OwnerList) { _gameBoardSide[3]._outpostStation[6]._stationPos = Common::Point(37, 118); _gameBoardSide[3]._outpostStation[7]._stationPos = Common::Point(37, 92); - _gameBoardSide[3]._delayPile[0]._stationPos = Common::Point(37, 145); + _gameBoardSide[3]._delayCard._stationPos = Common::Point(37, 145); - _gameBoardSide[3]._arr4[0]._stationPos = Common::Point(63, 92); + _gameBoardSide[3]._emptyStationPos._stationPos = Common::Point(63, 92); - _gameBoardSide[3]._fieldB94 = Common::Point(14, 14); - _gameBoardSide[3]._fieldB98 = Common::Point(14, 36); - _gameBoardSide[3]._fieldB9C = Common::Point(14, 58); - _gameBoardSide[3]._fieldBA0 = Common::Point(14, 80); - _gameBoardSide[3]._fieldBA4 = 3; + _gameBoardSide[3]._card1Pos = Common::Point(14, 14); + _gameBoardSide[3]._card2Pos = Common::Point(14, 36); + _gameBoardSide[3]._card3Pos = Common::Point(14, 58); + _gameBoardSide[3]._card4Pos = Common::Point(14, 80); + _gameBoardSide[3]._frameNum = 3; _gameBoardSide[0]._handCard[0]._stationPos = Common::Point(280, 5); _gameBoardSide[0]._handCard[1]._stationPos = Common::Point(253, 5); @@ -4403,15 +4431,15 @@ void Scene1337::postInit(SceneObjectList *OwnerList) { _gameBoardSide[0]._outpostStation[6]._stationPos = Common::Point(119, 16); _gameBoardSide[0]._outpostStation[7]._stationPos = Common::Point(145, 16); - _gameBoardSide[0]._delayPile[0]._stationPos = Common::Point(91, 16); + _gameBoardSide[0]._delayCard._stationPos = Common::Point(91, 16); - _gameBoardSide[0]._arr4[0]._stationPos = Common::Point(145, 42); + _gameBoardSide[0]._emptyStationPos._stationPos = Common::Point(145, 42); - _gameBoardSide[0]._fieldB94 = Common::Point(280, 5); - _gameBoardSide[0]._fieldB98 = Common::Point(253, 5); - _gameBoardSide[0]._fieldB9C = Common::Point(226, 5); - _gameBoardSide[0]._fieldBA0 = Common::Point(199, 5); - _gameBoardSide[0]._fieldBA4 = 2; + _gameBoardSide[0]._card1Pos = Common::Point(280, 5); + _gameBoardSide[0]._card2Pos = Common::Point(253, 5); + _gameBoardSide[0]._card3Pos = Common::Point(226, 5); + _gameBoardSide[0]._card4Pos = Common::Point(199, 5); + _gameBoardSide[0]._frameNum = 2; _gameBoardSide[1]._handCard[0]._stationPos = Common::Point(283, 146); _gameBoardSide[1]._handCard[1]._stationPos = Common::Point(283, 124); @@ -4427,17 +4455,19 @@ void Scene1337::postInit(SceneObjectList *OwnerList) { _gameBoardSide[1]._outpostStation[6]._stationPos = Common::Point(253, 70); _gameBoardSide[1]._outpostStation[7]._stationPos = Common::Point(253, 96); - _gameBoardSide[1]._delayPile[0]._stationPos = Common::Point(253, 43); + _gameBoardSide[1]._delayCard._stationPos = Common::Point(253, 43); - _gameBoardSide[1]._arr4[0]._stationPos = Common::Point(227, 96); + _gameBoardSide[1]._emptyStationPos._stationPos = Common::Point(227, 96); - _gameBoardSide[1]._fieldB94 = Common::Point(283, 146); - _gameBoardSide[1]._fieldB98 = Common::Point(283, 124); - _gameBoardSide[1]._fieldB9C = Common::Point(283, 102); - _gameBoardSide[1]._fieldBA0 = Common::Point(283, 80); - _gameBoardSide[1]._fieldBA4 = 4; + _gameBoardSide[1]._card1Pos = Common::Point(283, 146); + _gameBoardSide[1]._card2Pos = Common::Point(283, 124); + _gameBoardSide[1]._card3Pos = Common::Point(283, 102); + _gameBoardSide[1]._card4Pos = Common::Point(283, 80); + _gameBoardSide[1]._frameNum = 4; subPostInit(); + + _stockPile.postInit(); } void Scene1337::remove() { @@ -4453,7 +4483,7 @@ void Scene1337::remove() { void Scene1337::process(Event &event) { if (event.eventType == EVENT_BUTTON_DOWN) { if (event.btnState != BTNSHIFT_RIGHT) { - subD183F(R2_GLOBALS._v5780E, 1); + updateCursorId(R2_GLOBALS._mouseCursorId, true); event.handled = true; } else if (_unkFctPtr412) { FunctionPtrType tmpFctPtr = _unkFctPtr412; @@ -4478,10 +4508,10 @@ void Scene1337::process(Event &event) { } void Scene1337::dispatch() { - if (_instructionsDisplayedFl == 0) { + if (!_instructionsDisplayedFl) { ++_instructionsWaitCount; if (_instructionsWaitCount == 4) { - _instructionsDisplayedFl = 1; + _instructionsDisplayedFl = true; suggestInstructions(); } } @@ -4494,14 +4524,17 @@ void Scene1337::dispatch() { Scene::dispatch(); } -void Scene1337::actionDisplay(int resNum, int lineNum, int x, int y, int arg5, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt) { +void Scene1337::actionDisplay(int resNum, int lineNum, int x, int y, int keepOnScreen, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt) { // TODO: Check if it's normal that arg5 is unused and replaced by an hardcoded 0 value // May hide an original bug - SceneItem::display(resNum, lineNum, SET_X, x, SET_Y, y, SET_KEEP_ONSCREEN, 0, SET_WIDTH, width, SET_POS_MODE, -1, SET_TEXT_MODE, textMode, SET_FONT, fontNum, SET_FG_COLOR, colFG, SET_EXT_BGCOLOR, colBGExt, SET_EXT_FGCOLOR, colFGExt, LIST_END); + SceneItem::display(resNum, lineNum, SET_X, x, SET_Y, y, SET_KEEP_ONSCREEN, 0, + SET_WIDTH, width, SET_POS_MODE, -1, SET_TEXT_MODE, textMode, + SET_FONT, fontNum, SET_FG_COLOR, colFG, SET_EXT_BGCOLOR, colBGExt, + SET_EXT_FGCOLOR, colFGExt, LIST_END); } -void Scene1337::setAnimationInfo(unkObj1337sub1 *subObj) { +void Scene1337::setAnimationInfo(Card *subObj) { if (!subObj) return; @@ -4533,7 +4566,7 @@ void Scene1337::subC20F9() { if (_currentPlayerNumb == 3) _currentPlayerNumb = 0; - if (_field4244) { + if (_showPlayerTurn) { _currentPlayerArrow.show(); switch (_currentPlayerNumb) { case 0: @@ -4604,7 +4637,7 @@ void Scene1337::subC20F9() { } void Scene1337::subC2586() { - if (_field4244) + if (_showPlayerTurn) _currentPlayerArrow.hide(); switch (_currentPlayerNumb) { @@ -4624,7 +4657,7 @@ void Scene1337::subC2586() { break; } - _field4244 = true; + _showPlayerTurn = true; } @@ -4886,24 +4919,14 @@ void Scene1337::subC2835(int arg1) { return; } - subC4A39(&_gameBoardSide[arg1]._handCard[i]); -} - -bool Scene1337::subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt) { - if ((subObj1->_stationPos.x > pt.x) || (subObj1->_stationPos.x + 24 < pt.x)) - return false; - - if ((subObj1->_stationPos.y > pt.y) || (subObj1->_stationPos.y + 24 < pt.y)) - return false; - - return true; + discardCard(&_gameBoardSide[arg1]._handCard[i]); } void Scene1337::subC2C2F() { bool found = true; - if (_gameBoardSide[3]._delayPile[0]._cardId != 0) { - switch (_gameBoardSide[3]._delayPile[0]._cardId) { + if (_gameBoardSide[3]._delayCard._cardId != 0) { + switch (_gameBoardSide[3]._delayCard._cardId) { case 10: // No break on purpose case 12: @@ -4919,14 +4942,14 @@ void Scene1337::subC2C2F() { case 20: // No break on purpose case 21: - subC4A39(&_gameBoardSide[3]._delayPile[0]); + discardCard(&_gameBoardSide[3]._delayCard); found = false; break; default: found = false; int i; for (i = 0; i <= 3; i++) { - if (subC3386(_gameBoardSide[3]._delayPile[0]._cardId, _gameBoardSide[3]._handCard[i]._cardId)) { + if (subC3386(_gameBoardSide[3]._delayCard._cardId, _gameBoardSide[3]._handCard[i]._cardId)) { found = true; break; } @@ -4934,7 +4957,7 @@ void Scene1337::subC2C2F() { if (found) { found = false; - subC34A1(&_gameBoardSide[3]._handCard[i], &_gameBoardSide[3]._delayPile[0]); + subC34A1(&_gameBoardSide[3]._handCard[i], &_gameBoardSide[3]._delayCard); } break; } @@ -4949,7 +4972,7 @@ void Scene1337::subC2C2F() { found = false; for (int i = 0; i <= 7; i++) { - if ((_gameBoardSide[3]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[3]._delayPile[0]._cardId))) { + if ((_gameBoardSide[3]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[3]._delayCard._cardId))) { subC340B(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[3]._outpostStation[i]); found = true; break; @@ -4971,7 +4994,7 @@ void Scene1337::subC2C2F() { if (!found) { for (int i = 0; i <= 7; i++) { - if ((_gameBoardSide[3]._outpostStation[i]._cardId == 1) && (!subC2687(_gameBoardSide[3]._delayPile[0]._cardId))) { + if ((_gameBoardSide[3]._outpostStation[i]._cardId == 1) && (!subC2687(_gameBoardSide[3]._delayCard._cardId))) { int tmpVal = 0; for (int j = 0; j <= 7; j++) { @@ -5055,7 +5078,7 @@ void Scene1337::subC2C2F() { // It's understandable for 'i', which helps making sure that tmpVal is used properly, // but it's suspect for j for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[tmpRandIndx]._delayPile[0]._cardId == 0) && (subC32B1(tmpRandIndx, _gameBoardSide[3]._handCard[randIndx]._cardId))) { + if ((_gameBoardSide[tmpRandIndx]._delayCard._cardId == 0) && (subC32B1(tmpRandIndx, _gameBoardSide[3]._handCard[randIndx]._cardId))) { tmpVal = j; } } @@ -5071,7 +5094,7 @@ void Scene1337::subC2C2F() { if (tmpVal != -1) { // Useless second identical check skipped - subC3456(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[tmpVal]._delayPile[0]); + subC3456(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[tmpVal]._delayCard); return; } } @@ -5080,10 +5103,10 @@ void Scene1337::subC2C2F() { } } - subC4A39(&_gameBoardSide[3]._handCard[randIndx]); + discardCard(&_gameBoardSide[3]._handCard[randIndx]); } -void Scene1337::subC318B(int arg1, unkObj1337sub1 *subObj1, int arg3) { +void Scene1337::subC318B(int arg1, Card *subObj1, int arg3) { _field4240 = arg1; _field4242 = arg3; @@ -5095,8 +5118,8 @@ void Scene1337::subC318B(int arg1, unkObj1337sub1 *subObj1, int arg3) { break; } - _field3EF0 = subObj1; - _field3EF4 = &_gameBoardSide[arg3]._arr4[0]; + _discardCard = subObj1; + _field3EF4 = &_gameBoardSide[arg3]._emptyStationPos; _field3EF8 = &_gameBoardSide[arg3]._handCard[randIndx]; _item1.setAction(&_action11); @@ -5189,9 +5212,9 @@ bool Scene1337::subC3386(int arg1, int arg2) { return false; } -void Scene1337::subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) { +void Scene1337::subC33C0(Card *subObj1, Card *subObj2) { _field3EF4 = subObj2; - _field3EF0 = subObj1; + _discardCard = subObj1; _item1.setAction(&_action7); } @@ -5212,28 +5235,28 @@ int Scene1337::subC3E92(int arg1) { return randIndx; } -void Scene1337::subC340B(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) { - _field3EF0 = subObj1; +void Scene1337::subC340B(Card *subObj1, Card *subObj2) { + _discardCard = subObj1; _field3EF4 = subObj2; _item1.setAction(&_action6); } -void Scene1337::subC3456(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) { - _field3EF0 = subObj1; +void Scene1337::subC3456(Card *subObj1, Card *subObj2) { + _discardCard = subObj1; _field3EF4 = subObj2; _item1.setAction(&_action9); } -void Scene1337::subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) { - _field3EF0 = subObj1; +void Scene1337::subC34A1(Card *subObj1, Card *subObj2) { + _discardCard = subObj1; _field3EF4 = subObj2; _item1.setAction(&_action8); } -Scene1337::unkObj1337sub1 *Scene1337::subC34EC(int arg1) { +Scene1337::Card *Scene1337::subC34EC(int arg1) { for (int i = 0; i <= 7; i++) { if (_gameBoardSide[arg1]._outpostStation[i]._cardId == 1) { return &_gameBoardSide[arg1]._outpostStation[i]; @@ -5249,16 +5272,16 @@ Scene1337::unkObj1337sub1 *Scene1337::subC34EC(int arg1) { return NULL; } -void Scene1337::subC358E(unkObj1337sub1 *subObj1, int arg2) { - _field3EF0 = subObj1; +void Scene1337::subC358E(Card *subObj1, int arg2) { + _discardCard = subObj1; _field3EF4 = subC34EC(arg2); - _field3EF8 = &_gameBoardSide[arg2]._arr4[0]; + _field3EF8 = &_gameBoardSide[arg2]._emptyStationPos; _field4240 = arg2; _item1.setAction(&_action10); } -void Scene1337::subC4A39(unkObj1337sub1 *subObj) { - _field3EF0 = subObj; +void Scene1337::discardCard(Card *card) { + _discardCard = card; _item1.setAction(&_action5); } @@ -5277,8 +5300,8 @@ void Scene1337::subC4CEC() { } } -void Scene1337::subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) { - _field3EF0 = subObj1; +void Scene1337::subC51A0(Card *subObj1, Card *subObj2) { + _discardCard = subObj1; _field3EF4 = subObj2; _item1.setAction(&_action13); @@ -5385,7 +5408,7 @@ void Scene1337::displayDialog(int dialogNumb) { void Scene1337::subPostInit() { R2_GLOBALS._v57709 = 0; R2_GLOBALS._v5780C = 0; - subD183F(1, 0); + updateCursorId(1, false); subD1940(true); // _v5780C++ subD18F5(); @@ -5496,15 +5519,15 @@ void Scene1337::subPostInit() { _availableCardsPile[99] = 0; _cardsAvailableNumb = 98; - _field3E26 = 98; + _currentDiscardIndex = 98; // CHECKME: Would make more sense at pos 99 _discardPile._cardId = 0; _discardPile._stationPos = Common::Point(128, 95); - _item8._cardId = 0; - _item8._stationPos = Common::Point(162, 95); + _stockCard._cardId = 0; + _stockCard._stationPos = Common::Point(162, 95); - _item6._cardId = 0; + _selectedCard._cardId = 0; _animatedCard._card.postInit(); _animatedCard._card.setVisage(1332); @@ -5526,14 +5549,19 @@ void Scene1337::subPostInit() { _currentPlayerArrow.animate(ANIM_MODE_2, NULL); _currentPlayerArrow.hide(); - _field4244 = true; + _showPlayerTurn = true; _field4246 = false; _field424A = -1; - _background1.setup2(9531, 1, 1, 249, 168, 155, 0); + _helpIcon.postInit(); + _helpIcon.setup(9531, 1, 1); + _helpIcon.setPosition(Common::Point(249, 168)); + _helpIcon.setPriority(155); + _helpIcon._effect = EFFECT_NONE; + _helpIcon.show(); _autoplay = false; - _instructionsDisplayedFl = 0; + _instructionsDisplayedFl = false; _instructionsWaitCount = 0; } @@ -5544,7 +5572,7 @@ void Scene1337::suggestInstructions() { if (MessageDialog::show(NEED_INSTRUCTIONS, NO_MSG, YES_MSG) == 0) { if (R2_GLOBALS._v57709 == 0) subD18F5(); - firstShuffle(); + dealCards(); } else { if (R2_GLOBALS._v57709 == 0) subD18F5(); @@ -5578,7 +5606,7 @@ void Scene1337::shuffleCards() { // CHECKME: This will fail if i == 0, which shouldn't happen // as we don't shuffle cards when no card is available. _cardsAvailableNumb = i - 1; - _field3E26 = 98; + _currentDiscardIndex = 98; // CHECKME: Would make more sense at pos 99 break; } } @@ -5591,6 +5619,8 @@ void Scene1337::shuffleCards() { } _shuffleEndedFl = false; + + // Shuffle cards _animatedCard._card.setAction(&_action2); while(!_shuffleEndedFl && !g_vm->shouldQuit()) { @@ -5601,9 +5631,11 @@ void Scene1337::shuffleCards() { } } -void Scene1337::firstShuffle() { +void Scene1337::dealCards() { _animatedCard._card._moveDiff = Common::Point(30, 30); shuffleCards(); + + // Deal cards _item1.setAction(&_action3); } void Scene1337::subCD193() { @@ -5611,17 +5643,17 @@ void Scene1337::subCD193() { warning("STUBBED: subCD193()"); } -void Scene1337::subCDB90(int arg1, Common::Point pt) { +void Scene1337::handleClick(int arg1, Common::Point pt) { bool found = false; int curReg = R2_GLOBALS._sceneRegions.indexOf(g_globals->_events._mousePos); if (arg1 == 3) { int i; for (i = 0; i <= 7; i++) { - if ( (subC2BF8(&_gameBoardSide[2]._outpostStation[i], pt)) - || (subC2BF8(&_gameBoardSide[0]._outpostStation[i], pt)) - || (subC2BF8(&_gameBoardSide[1]._outpostStation[i], pt)) - || (subC2BF8(&_gameBoardSide[3]._outpostStation[i], pt)) ) { + if ( _gameBoardSide[2]._outpostStation[i].isIn(pt) + || _gameBoardSide[0]._outpostStation[i].isIn(pt) + || _gameBoardSide[1]._outpostStation[i].isIn(pt) + || _gameBoardSide[3]._outpostStation[i].isIn(pt) ) { found = true; break; } @@ -5657,36 +5689,36 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { break; } } else { - if ( (subC2BF8(&_gameBoardSide[2]._delayPile[0], pt)) - || (subC2BF8(&_gameBoardSide[0]._delayPile[0], pt)) - || (subC2BF8(&_gameBoardSide[1]._delayPile[0], pt)) - || (subC2BF8(&_gameBoardSide[3]._delayPile[0], pt)) ) { + if ( _gameBoardSide[2]._delayCard.isIn(pt) + || _gameBoardSide[0]._delayCard.isIn(pt) + || _gameBoardSide[1]._delayCard.isIn(pt) + || _gameBoardSide[3]._delayCard.isIn(pt) ) { found = true; } if (found) { switch (curReg) { case 5: - if (_gameBoardSide[2]._delayPile[0]._cardId != 0) - displayDialog(_gameBoardSide[2]._delayPile[0]._cardId); + if (_gameBoardSide[2]._delayCard._cardId != 0) + displayDialog(_gameBoardSide[2]._delayCard._cardId); else actionDisplay(1330, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; case 10: - if (_gameBoardSide[3]._delayPile[0]._cardId != 0) - displayDialog(_gameBoardSide[3]._delayPile[0]._cardId); + if (_gameBoardSide[3]._delayCard._cardId != 0) + displayDialog(_gameBoardSide[3]._delayCard._cardId); else actionDisplay(1330, 16, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; case 15: - if (_gameBoardSide[0]._delayPile[0]._cardId != 0) - displayDialog(_gameBoardSide[3]._delayPile[0]._cardId); + if (_gameBoardSide[0]._delayCard._cardId != 0) + displayDialog(_gameBoardSide[3]._delayCard._cardId); else actionDisplay(1330, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; case 20: - if (_gameBoardSide[1]._delayPile[0]._cardId != 0) - displayDialog(_gameBoardSide[1]._delayPile[0]._cardId); + if (_gameBoardSide[1]._delayCard._cardId != 0) + displayDialog(_gameBoardSide[1]._delayCard._cardId); else actionDisplay(1330, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; @@ -5694,28 +5726,28 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { break; } } else { - if (subC2BF8(&_discardPile, pt)) { + if (_discardPile.isIn(pt)) { if (_discardPile._cardId != 0) displayDialog(_discardPile._cardId); else actionDisplay(1330, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (_background1._bounds.contains(pt)) { + } else if (_helpIcon._bounds.contains(pt)) { actionDisplay(1330, 43, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (subC2BF8(&_item8, pt)) { + } else if (_stockCard.isIn(pt)) { actionDisplay(1330, 4, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if ( (subC2BF8(&_gameBoardSide[2]._arr4[0], pt)) - || (subC2BF8(&_gameBoardSide[3]._arr4[0], pt)) - || (subC2BF8(&_gameBoardSide[0]._arr4[0], pt)) - || (subC2BF8(&_gameBoardSide[1]._arr4[0], pt)) ) { + } else if ( (_gameBoardSide[2]._emptyStationPos.isIn(pt)) + || (_gameBoardSide[3]._emptyStationPos.isIn(pt)) + || (_gameBoardSide[0]._emptyStationPos.isIn(pt)) + || (_gameBoardSide[1]._emptyStationPos.isIn(pt)) ) { actionDisplay(1330, 32, 159, 10, 1, 200, 0, 7, 0, 154, 154); } else { - if (subC2BF8(&_gameBoardSide[2]._handCard[0], pt)) + if (_gameBoardSide[2]._handCard[0].isIn(pt)) displayDialog(_gameBoardSide[2]._handCard[0]._cardId); - else if (subC2BF8(&_gameBoardSide[2]._handCard[1], pt)) + else if (_gameBoardSide[2]._handCard[1].isIn(pt)) displayDialog(_gameBoardSide[2]._handCard[1]._cardId); - else if (subC2BF8(&_gameBoardSide[2]._handCard[2], pt)) + else if (_gameBoardSide[2]._handCard[2].isIn(pt)) displayDialog(_gameBoardSide[2]._handCard[2]._cardId); - else if (subC2BF8(&_gameBoardSide[2]._handCard[3], pt)) + else if (_gameBoardSide[2]._handCard[3].isIn(pt)) displayDialog(_gameBoardSide[2]._handCard[3]._cardId); else if ((curReg >= 6) && (curReg <= 9)) actionDisplay(1330, 29, 159, 10, 1, 200, 0, 7, 0, 154, 154); @@ -5756,7 +5788,7 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { return; for (int i = 0; i <= 7; i++) { - if (subC2BF8(&_gameBoardSide[2]._outpostStation[i], pt)) { + if (_gameBoardSide[2]._outpostStation[i].isIn(pt)) { switch (_gameBoardSide[2]._outpostStation[i]._cardId) { case 0: actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154); @@ -5770,7 +5802,7 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { } found = true; break; - } else if (subC2BF8(&_gameBoardSide[0]._outpostStation[i], pt)) { + } else if (_gameBoardSide[0]._outpostStation[i].isIn(pt)) { switch (_gameBoardSide[0]._outpostStation[i]._cardId) { case 0: actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154); @@ -5781,7 +5813,7 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { } found = true; break; - } else if (subC2BF8(&_gameBoardSide[1]._outpostStation[i], pt)) { + } else if (_gameBoardSide[1]._outpostStation[i].isIn(pt)) { switch (_gameBoardSide[1]._outpostStation[i]._cardId) { case 0: actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117); @@ -5792,7 +5824,7 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { } found = true; break; - } else if (subC2BF8(&_gameBoardSide[3]._outpostStation[i], pt)) { + } else if (_gameBoardSide[3]._outpostStation[i].isIn(pt)) { switch (_gameBoardSide[3]._outpostStation[i]._cardId) { case 0: actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172); @@ -5806,8 +5838,9 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { } } - if (subC2BF8(&_gameBoardSide[2]._delayPile[0], pt)) { - if (_gameBoardSide[0]._delayPile[0]._cardId != 0) { + if (_gameBoardSide[2]._delayCard.isIn(pt)) { + // The original uses _gameBoardSide[0], which is obviously a bug. + if (_gameBoardSide[2]._delayCard._cardId != 0) { actionDisplay(1330, 39, 159, 10, 1, 200, 0, 7, 0, 154, 154); } else { actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154); @@ -5815,8 +5848,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { found = true; } - if (subC2BF8(&_gameBoardSide[3]._delayPile[0], pt)) { - if (_gameBoardSide[3]._delayPile[0]._cardId != 0) { + if (_gameBoardSide[3]._delayCard.isIn(pt)) { + if (_gameBoardSide[3]._delayCard._cardId != 0) { actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172); } else { actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172); @@ -5824,8 +5857,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { found = true; } - if (subC2BF8(&_gameBoardSide[1]._delayPile[0], pt)) { - if (_gameBoardSide[1]._delayPile[0]._cardId != 0) { + if (_gameBoardSide[1]._delayCard.isIn(pt)) { + if (_gameBoardSide[1]._delayCard._cardId != 0) { actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117); } else { actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117); @@ -5833,8 +5866,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { found = true; } - if (subC2BF8(&_gameBoardSide[0]._delayPile[0], pt)) { - if (_gameBoardSide[0]._delayPile[0]._cardId != 0) { + if (_gameBoardSide[0]._delayCard.isIn(pt)) { + if (_gameBoardSide[0]._delayCard._cardId != 0) { actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154); } else { actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154); @@ -5842,17 +5875,17 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { found = true; } - if (subC2BF8(&_gameBoardSide[3]._arr4[0], pt)) { + if (_gameBoardSide[3]._emptyStationPos.isIn(pt)) { actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172); found = true; } - if (subC2BF8(&_gameBoardSide[1]._arr4[0], pt)) { + if (_gameBoardSide[1]._emptyStationPos.isIn(pt)) { actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117); found = true; } - if (subC2BF8(&_gameBoardSide[0]._arr4[0], pt)) { + if (_gameBoardSide[0]._emptyStationPos.isIn(pt)) { actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154); found = true; } @@ -5860,14 +5893,14 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) { if (found) return; - if (_background1._bounds.contains(pt)) { + if (_helpIcon._bounds.contains(pt)) { subCD193(); return; } - if (subC2BF8(&_discardPile, pt)) + if (_discardPile.isIn(pt)) actionDisplay(1330, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154); - else if (subC2BF8(&_item8, pt)) + else if (_stockCard.isIn(pt)) actionDisplay(1330, 5, 159, 10, 1, 200, 0, 7, 0, 154, 154); else { switch (curReg) { @@ -5919,8 +5952,8 @@ void Scene1337::subCF31D() { bool found; int count; - if (this->_gameBoardSide[1]._delayPile[0]._cardId != 0) { - switch (_gameBoardSide[1]._delayPile[0]._cardId) { + if (this->_gameBoardSide[1]._delayCard._cardId != 0) { + switch (_gameBoardSide[1]._delayCard._cardId) { case 10: // No break on purpose case 12: @@ -5937,13 +5970,13 @@ void Scene1337::subCF31D() { // No break on purpose case 21: tmpVal = 0; - subC4A39(&_gameBoardSide[1]._delayPile[0]); + discardCard(&_gameBoardSide[1]._delayCard); break; default: found = false; int i; for (i = 0; i <= 3; i++) { - if (subC3386(_gameBoardSide[1]._delayPile[0]._cardId, _gameBoardSide[1]._handCard[i]._cardId)) { + if (subC3386(_gameBoardSide[1]._delayCard._cardId, _gameBoardSide[1]._handCard[i]._cardId)) { found = true; break; } @@ -5951,7 +5984,7 @@ void Scene1337::subCF31D() { if (found) { tmpVal = 0; - subC34A1(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[1]._delayPile[0]); + subC34A1(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[1]._delayCard); } } } @@ -5978,7 +6011,7 @@ void Scene1337::subCF31D() { for (int j = 0; j <= 7; j++) { if (_gameBoardSide[1]._outpostStation[j]._cardId == 1) { - if (!subC2687(_gameBoardSide[1]._delayPile[0]._cardId)) { + if (!subC2687(_gameBoardSide[1]._delayCard._cardId)) { count = 0; for (int k = 0; k <= 7; k++) { if ((_gameBoardSide[1]._outpostStation[k]._cardId > 1) && (_gameBoardSide[1]._outpostStation[k]._cardId <= 9)) @@ -6002,7 +6035,7 @@ void Scene1337::subCF31D() { tmpVal = subC2719(1); if (tmpVal != -1) { for (int i = 0; i <= 7; i++) { - if ((_gameBoardSide[1]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[1]._delayPile[0]._cardId))) { + if ((_gameBoardSide[1]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[1]._delayCard._cardId))) { subC340B(&_gameBoardSide[1]._handCard[tmpVal], &_gameBoardSide[1]._outpostStation[i]); found = true; break; @@ -6066,7 +6099,7 @@ void Scene1337::subCF31D() { for (int k = 0; k <= 7; k++) { // CHECKME: 'k' is not used in that loop. // It looks suspicious. - if ((_gameBoardSide[tmpVal]._delayPile[0]._cardId == 0) && (subC32B1(tmpVal, _gameBoardSide[1]._handCard[i]._cardId))) { + if ((_gameBoardSide[tmpVal]._delayCard._cardId == 0) && (subC32B1(tmpVal, _gameBoardSide[1]._handCard[i]._cardId))) { count = tmpVal; break; } @@ -6089,7 +6122,7 @@ void Scene1337::subCF31D() { } if (found) - subC3456(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[count]._delayPile[0]); + subC3456(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[count]._delayCard); else { int j; for (j = 0; j <= 3; j++) { @@ -6100,7 +6133,7 @@ void Scene1337::subCF31D() { if (rndVal != 1) { for (int m = 0; m <= 7; m++) { // 'm' is not used in that loop. It looks suspicious. - if ((_gameBoardSide[rndVal]._delayPile[0]._cardId == 0) && (_gameBoardSide[1]._handCard[j]._cardId == 1)) { + if ((_gameBoardSide[rndVal]._delayCard._cardId == 0) && (_gameBoardSide[1]._handCard[j]._cardId == 1)) { count = rndVal; break; } @@ -6121,7 +6154,7 @@ void Scene1337::subCF31D() { } if (found) - subC3456(&_gameBoardSide[1]._handCard[j], &_gameBoardSide[count]._delayPile[0]); + subC3456(&_gameBoardSide[1]._handCard[j], &_gameBoardSide[count]._delayCard); else subC2835(1); } @@ -6131,8 +6164,8 @@ void Scene1337::subCF31D() { void Scene1337::subCF979() { bool found = true; - if (_gameBoardSide[0]._delayPile[0]._cardId != 0) { - switch (_gameBoardSide[0]._delayPile[0]._cardId) { + if (_gameBoardSide[0]._delayCard._cardId != 0) { + switch (_gameBoardSide[0]._delayCard._cardId) { case 10: //No break on purpose case 12: @@ -6148,7 +6181,7 @@ void Scene1337::subCF979() { case 20: //No break on purpose case 21: - subC4A39(&_gameBoardSide[0]._delayPile[0]); + discardCard(&_gameBoardSide[0]._delayCard); found = false; break; default: @@ -6156,7 +6189,7 @@ void Scene1337::subCF979() { found = false; for (i = 0; i <= 3; i++) { - if (subC3386(_gameBoardSide[0]._delayPile[0]._cardId, _gameBoardSide[0]._handCard[i]._cardId)) { + if (subC3386(_gameBoardSide[0]._delayCard._cardId, _gameBoardSide[0]._handCard[i]._cardId)) { found = true; break; } @@ -6164,7 +6197,7 @@ void Scene1337::subCF979() { if (found) { found = false; - subC34A1(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[0]._delayPile[0]); + subC34A1(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[0]._delayCard); } break; } @@ -6189,7 +6222,7 @@ void Scene1337::subCF979() { if (!flag) { for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[0]._outpostStation[j]._cardId == 1) && (!subC2687(_gameBoardSide[0]._delayPile[0]._cardId))) { + if ((_gameBoardSide[0]._outpostStation[j]._cardId == 1) && (!subC2687(_gameBoardSide[0]._delayCard._cardId))) { int count = 0; for (int k = 0; k <= 7; k++) { if ((_gameBoardSide[0]._outpostStation[k]._cardId > 1) && (_gameBoardSide[0]._outpostStation[k]._cardId <= 9)) { @@ -6219,7 +6252,7 @@ void Scene1337::subCF979() { if (tmpVal != -1) { for (int i = 0; i <= 7; i++) { - if ((_gameBoardSide[0]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[0]._delayPile[0]._cardId))) { + if ((_gameBoardSide[0]._outpostStation[i]._cardId == 0) && (!subC2687(_gameBoardSide[0]._delayCard._cardId))) { subC340B(&_gameBoardSide[0]._handCard[tmpVal], &_gameBoardSide[0]._outpostStation[i]); found = true; break; @@ -6262,8 +6295,8 @@ void Scene1337::subCF979() { if (subC27B5(_gameBoardSide[0]._handCard[i]._cardId) != -1) { // The variable 'j' is not used in the inner code of the loop. It's suspect for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[2]._delayPile[0]._cardId == 0) && (subC32B1(2, _gameBoardSide[0]._handCard[i]._cardId))) { - subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayPile[0]); + if ((_gameBoardSide[2]._delayCard._cardId == 0) && (subC32B1(2, _gameBoardSide[0]._handCard[i]._cardId))) { + subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayCard); found = true; break; } @@ -6281,8 +6314,8 @@ void Scene1337::subCF979() { if (subC27F9(_gameBoardSide[0]._handCard[i]._cardId) != -1) { // The variable 'j' is not used in the inner code of the loop. It's suspect for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[2]._delayPile[0]._cardId == 0) && (subC32B1(2, _gameBoardSide[0]._handCard[i]._cardId))) { - subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayPile[0]); + if ((_gameBoardSide[2]._delayCard._cardId == 0) && (subC32B1(2, _gameBoardSide[0]._handCard[i]._cardId))) { + subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayCard); found = true; } } @@ -6325,8 +6358,8 @@ void Scene1337::subCF979() { if (tmpVal != -1) { // The variable 'j' is not used in the inner code of the loop. It's suspect. for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[1]._delayPile[0]._cardId == 0) && (subC32B1(1, _gameBoardSide[0]._handCard[i]._cardId))) { - subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayPile[0]); + if ((_gameBoardSide[1]._delayCard._cardId == 0) && (subC32B1(1, _gameBoardSide[0]._handCard[i]._cardId))) { + subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayCard); found = true; } } @@ -6334,8 +6367,8 @@ void Scene1337::subCF979() { if (!found) { // The variable 'j' is not used in the inner code of the loop. It's suspect. for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[3]._delayPile[0]._cardId == 0) && (subC32B1(3, _gameBoardSide[0]._handCard[i]._cardId))) { - subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayPile[0]); + if ((_gameBoardSide[3]._delayCard._cardId == 0) && (subC32B1(3, _gameBoardSide[0]._handCard[i]._cardId))) { + subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayCard); found = true; } } @@ -6354,8 +6387,8 @@ void Scene1337::subCF979() { if (tmpVal != -1) { // The variable 'j' is not used in the inner code of the loop. It's suspect. for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[1]._delayPile[0]._cardId == 0) && (subC32B1(1, _gameBoardSide[0]._handCard[i]._cardId))) { - subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayPile[0]); + if ((_gameBoardSide[1]._delayCard._cardId == 0) && (subC32B1(1, _gameBoardSide[0]._handCard[i]._cardId))) { + subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayCard); found = true; } } @@ -6363,8 +6396,8 @@ void Scene1337::subCF979() { if (!found) { // The variable 'j' is not used in the inner code of the loop. It's suspect. for (int j = 0; j <= 7; j++) { - if ((_gameBoardSide[3]._delayPile[0]._cardId == 0) && (subC32B1(3, _gameBoardSide[0]._handCard[i]._cardId))) { - subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayPile[0]); + if ((_gameBoardSide[3]._delayCard._cardId == 0) && (subC32B1(3, _gameBoardSide[0]._handCard[i]._cardId))) { + subC3456(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayCard); found = true; } } @@ -6386,107 +6419,117 @@ void Scene1337::subD026D() { } void Scene1337::subD0281() { - if (subC27F9(this->_gameBoardSide[2]._delayPile[0]._cardId) == -1) + if (subC27F9(this->_gameBoardSide[2]._delayCard._cardId) == -1) _unkFctPtr412 = &Scene1337::subD026D; else - subC4A39(&_gameBoardSide[2]._delayPile[0]); + discardCard(&_gameBoardSide[2]._delayCard); } void Scene1337::subD02CA() { - _item6._stationPos = g_globals->_events._mousePos; + _selectedCard._stationPos = g_globals->_events._mousePos; if (R2_GLOBALS._v57810 == 200) { - int di; - for (di = 0; di < 4; di++) { - if ((subC2BF8(&_gameBoardSide[2]._handCard[di], _item6._stationPos) != 0) && (_gameBoardSide[2]._handCard[di]._cardId != 0)) { - _item6._cardId = _gameBoardSide[2]._handCard[di]._cardId; - _item6._stationPos = _gameBoardSide[2]._handCard[di]._stationPos; - // _item6._actorName = _arrunkObj1337[2]._arr1[di]._actorName; - _item6._fieldE = _gameBoardSide[2]._handCard[di]._fieldE; - _item6._field10 = _gameBoardSide[2]._handCard[di]._field10; - warning("_item6._field12 = _arrunkObj1337[2]._arr1[di]._field12;"); - warning("_item6._field14 = _arrunkObj1337[2]._arr1[di]._field14;"); - warning("_item6._field16 = _arrunkObj1337[2]._arr1[di]._field16;"); - _item6._sceneRegionId = _gameBoardSide[2]._handCard[di]._sceneRegionId; - _item6._position = _gameBoardSide[2]._handCard[di]._position; - _item6._yDiff = _gameBoardSide[2]._handCard[di]._yDiff; - _item6._bounds = _gameBoardSide[2]._handCard[di]._bounds; - _item6._resNum = _gameBoardSide[2]._handCard[di]._resNum; - _item6._lookLineNum = _gameBoardSide[2]._handCard[di]._lookLineNum; - _item6._talkLineNum = _gameBoardSide[2]._handCard[di]._talkLineNum; - _item6._useLineNum = _gameBoardSide[2]._handCard[di]._useLineNum; - _item6._action = _gameBoardSide[2]._handCard[di]._action; - warning("_item6._field0 = _arrunkObj1337[2]._arr1[di]._field0;"); - _item6._card._updateStartFrame = _gameBoardSide[2]._handCard[di]._card._updateStartFrame; - _item6._card._walkStartFrame = _gameBoardSide[2]._handCard[di]._card._walkStartFrame; + // Hand + int i; + for (i = 0; i < 4; i++) { + if ((_gameBoardSide[2]._handCard[i].isIn(_selectedCard._stationPos)) && (_gameBoardSide[2]._handCard[i]._cardId != 0)) { + Card *handcard = &_gameBoardSide[2]._handCard[i]; + _selectedCard._cardId = handcard->_cardId; + _selectedCard._stationPos = handcard->_stationPos; + // _selectedCard._actorName = handcard->_actorName; + _selectedCard._fieldE = handcard->_fieldE; + _selectedCard._field10 = handcard->_field10; + warning("_selectedCard._field12 = handcard->_field12;"); + warning("_selectedCard._field14 = handcard->_field14;"); + warning("_selectedCard._field16 = handcard->_field16;"); + _selectedCard._sceneRegionId = handcard->_sceneRegionId; + _selectedCard._position = handcard->_position; + _selectedCard._yDiff = handcard->_yDiff; + _selectedCard._bounds = handcard->_bounds; + _selectedCard._resNum = handcard->_resNum; + _selectedCard._lookLineNum = handcard->_lookLineNum; + _selectedCard._talkLineNum = handcard->_talkLineNum; + _selectedCard._useLineNum = handcard->_useLineNum; + _selectedCard._action = handcard->_action; + warning("_selectedCard._field0 = handcard->_field0;"); + _selectedCard._card._updateStartFrame = handcard->_card._updateStartFrame; + _selectedCard._card._walkStartFrame = handcard->_card._walkStartFrame; // _field2E is named _field3C in R2R - _item6._card._field2E = _gameBoardSide[2]._handCard[di]._card._field2E; - _item6._card._percent = _gameBoardSide[2]._handCard[di]._card._percent; - _item6._card._priority = _gameBoardSide[2]._handCard[di]._card._priority; - _item6._card._angle = _gameBoardSide[2]._handCard[di]._card._angle; - _item6._card._flags = _gameBoardSide[2]._handCard[di]._card._flags; - _item6._card._xe = _gameBoardSide[2]._handCard[di]._card._xe; - _item6._card._xs = _gameBoardSide[2]._handCard[di]._card._xs; - _item6._card._paneRects[0] = _gameBoardSide[2]._handCard[di]._card._paneRects[0]; - _item6._card._paneRects[1] = _gameBoardSide[2]._handCard[di]._card._paneRects[1]; - _item6._card._visage = _gameBoardSide[2]._handCard[di]._card._visage; - _item6._card._objectWrapper = _gameBoardSide[2]._handCard[di]._card._objectWrapper; - _item6._card._strip = _gameBoardSide[2]._handCard[di]._card._strip; - _item6._card._animateMode = _gameBoardSide[2]._handCard[di]._card._animateMode; - _item6._card._frame = _gameBoardSide[2]._handCard[di]._card._frame; - _item6._card._endFrame = _gameBoardSide[2]._handCard[di]._card._endFrame; + _selectedCard._card._field2E = handcard->_card._field2E; + _selectedCard._card._percent = handcard->_card._percent; + _selectedCard._card._priority = handcard->_card._priority; + _selectedCard._card._angle = handcard->_card._angle; + _selectedCard._card._flags = handcard->_card._flags; + _selectedCard._card._xe = handcard->_card._xe; + _selectedCard._card._xs = handcard->_card._xs; + _selectedCard._card._paneRects[0] = handcard->_card._paneRects[0]; + _selectedCard._card._paneRects[1] = handcard->_card._paneRects[1]; + _selectedCard._card._visage = handcard->_card._visage; + _selectedCard._card._objectWrapper = handcard->_card._objectWrapper; + _selectedCard._card._strip = handcard->_card._strip; + _selectedCard._card._animateMode = handcard->_card._animateMode; + _selectedCard._card._frame = handcard->_card._frame; + _selectedCard._card._endFrame = handcard->_card._endFrame; // _field68 is named _field76 in R2R - _item6._card._field68 = _gameBoardSide[2]._handCard[di]._card._field68; - _item6._card._frameChange = _gameBoardSide[2]._handCard[di]._card._frameChange; - _item6._card._numFrames = _gameBoardSide[2]._handCard[di]._card._numFrames; - _item6._card._regionIndex = _gameBoardSide[2]._handCard[di]._card._regionIndex; - _item6._card._mover = _gameBoardSide[2]._handCard[di]._card._mover; - _item6._card._moveDiff = _gameBoardSide[2]._handCard[di]._card._moveDiff; - _item6._card._moveRate = _gameBoardSide[2]._handCard[di]._card._moveRate; - _item6._card._actorDestPos = _gameBoardSide[2]._handCard[di]._card._actorDestPos; - _item6._card._endAction = _gameBoardSide[2]._handCard[di]._card._endAction; - _item6._card._regionBitList = _gameBoardSide[2]._handCard[di]._card._regionBitList; - // _item6._object1._actorName = _arrunkObj1337[2]._arr1[di]._object1._actorName; - _item6._card._fieldE = _gameBoardSide[2]._handCard[di]._card._fieldE; - _item6._card._field10 = _gameBoardSide[2]._handCard[di]._card._field10; - warning("_item6._object1._field12 = _arrunkObj1337[2]._arr1[di]._object1._field12;"); - warning("_item6._object1._field14 = _arrunkObj1337[2]._arr1[di]._object1._field14;"); - warning("_item6._object1._field16 = _arrunkObj1337[2]._arr1[di]._object1._field16;"); - _item6._card = _gameBoardSide[2]._handCard[di]._card; - } - } - - if (di == 4) { - subCDB90(1, _item6._stationPos); + _selectedCard._card._field68 = handcard->_card._field68; + _selectedCard._card._frameChange = handcard->_card._frameChange; + _selectedCard._card._numFrames = handcard->_card._numFrames; + _selectedCard._card._regionIndex = handcard->_card._regionIndex; + _selectedCard._card._mover = handcard->_card._mover; + _selectedCard._card._moveDiff = handcard->_card._moveDiff; + _selectedCard._card._moveRate = handcard->_card._moveRate; + _selectedCard._card._actorDestPos = handcard->_card._actorDestPos; + _selectedCard._card._endAction = handcard->_card._endAction; + _selectedCard._card._regionBitList = handcard->_card._regionBitList; + // _selectedCard._object1._actorName = handcard->_object1._actorName; + _selectedCard._card._fieldE = handcard->_card._fieldE; + _selectedCard._card._field10 = handcard->_card._field10; + warning("_selectedCard._card._field12 = handcard->_card._field12;"); + warning("_selectedCard._card._field14 = handcard->_card._field14;"); + warning("_selectedCard._card._field16 = handcard->_card._field16;"); + // _selectedCard._card = _gameBoardSide[2]._handCard[i]._card; + + _gameBoardSide[2]._handCard[i]._cardId = 0; + _gameBoardSide[2]._handCard[i]._card.remove(); + break; + } + } + + if (i == 4) { + handleClick(1, _selectedCard._stationPos); subD0281(); return; + } else { + setCursorData(1332, _selectedCard._card._strip, _selectedCard._card._frame); + R2_GLOBALS._sceneObjects->draw(); } } else if (R2_GLOBALS._v57810 == 300) { - subCDB90(3, _item6._stationPos); + // Eye + handleClick(3, _selectedCard._stationPos); subD0281(); return; } else { - subD1A48(R2_GLOBALS._v57810); + // The original code is calling a function full of dead code. + // Only this message remains after a cleanup. + MessageDialog::show(WRONG_ANSWER_MSG, OK_BTN_STRING); + // subD0281(); return; } - // That continues the block when R2_GLOBALS._v57810 == 200 and di != 4 - setCursorData(1332, _item6._card._strip, _item6._card._frame); - R2_GLOBALS._sceneObjects->draw(); Event event; bool found = false; bool found_di; for (;;) { if ( ((g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN)) && (event.btnState == BTNSHIFT_RIGHT)) || (g_globals->_events.getEvent(event, EVENT_KEYPRESS)) ){ - _item6._stationPos = g_globals->_events._mousePos; + _selectedCard._stationPos = g_globals->_events._mousePos; found_di = false; for (int i = 0; i <= 3; i ++) { - if (subC2BF8(&_gameBoardSide[2]._handCard[i], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if (_gameBoardSide[2]._handCard[i].isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { if (_gameBoardSide[2]._handCard[i]._cardId == 0) { - _gameBoardSide[2]._handCard[i]._cardId = _item6._cardId; + _gameBoardSide[2]._handCard[i]._cardId = _selectedCard._cardId; _gameBoardSide[2]._handCard[i]._card.postInit(); _gameBoardSide[2]._handCard[i]._card.hide(); _gameBoardSide[2]._handCard[i]._card.setVisage(1332); @@ -6496,7 +6539,7 @@ void Scene1337::subD02CA() { setCursorData(5, 1, 4); found = true; _currentPlayerNumb--; - _field4244 = false; + _showPlayerTurn = false; subC20F9(); } else { actionDisplay(1330, 127, 159, 10, 1, 200, 0, 7, 0, 154, 154); @@ -6507,34 +6550,34 @@ void Scene1337::subD02CA() { } if ((!found) && (!found_di)) { - if (subC2BF8(&_discardPile, Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { - subC4A39(&_item6); + if (_discardPile.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { + discardCard(&_selectedCard); } else if (!found) { bool foundVar4; int i; - if (_item6._cardId == 1) { + if (_selectedCard._cardId == 1) { foundVar4 = false; for (i = 0; i <= 7; i++) { - if (subC2BF8(&_gameBoardSide[2]._outpostStation[i], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if (_gameBoardSide[2]._outpostStation[i].isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { foundVar4 = true; break; } } if ((foundVar4) && (_gameBoardSide[2]._outpostStation[i]._cardId == 0)) { - if (subC27B5(_gameBoardSide[2]._delayPile[0]._cardId) != -1) { + if (subC27B5(_gameBoardSide[2]._delayCard._cardId) != -1) { actionDisplay(1330, 55, 159, 10, 1, 200, 0, 7, 0, 154, 154); } else { - subC340B(&_item6, &_gameBoardSide[2]._outpostStation[i]); + subC340B(&_selectedCard, &_gameBoardSide[2]._outpostStation[i]); return; } } else { actionDisplay(1330, 56, 159, 10, 1, 200, 0, 7, 0, 154, 154); } - } else if (_item6._cardId <= 9) { + } else if (_selectedCard._cardId <= 9) { foundVar4 = false; for (i = 0; i <= 7; i++) { - if (subC2BF8(&_gameBoardSide[2]._outpostStation[i], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if (_gameBoardSide[2]._outpostStation[i].isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { foundVar4 = true; break; } @@ -6543,32 +6586,32 @@ void Scene1337::subD02CA() { foundVar4 = false; int j; for (j = 0; j <= 7; j++) { - if (_item6._cardId == _gameBoardSide[2]._outpostStation[j]._cardId) { + if (_selectedCard._cardId == _gameBoardSide[2]._outpostStation[j]._cardId) { foundVar4 = true; break; } } if (foundVar4) { actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (subC27B5(_gameBoardSide[2]._delayPile[0]._cardId) != -1) { + } else if (subC27B5(_gameBoardSide[2]._delayCard._cardId) != -1) { actionDisplay(1330, 35, 159, 10, 1, 200, 0, 7, 0, 154, 154); } else { if (j == 7) _field424A = 2; - subC33C0(&_item6, &_gameBoardSide[2]._outpostStation[i]); + subC33C0(&_selectedCard, &_gameBoardSide[2]._outpostStation[i]); return; } } else { actionDisplay(1330, 37, 159, 10, 1, 200, 0, 7, 0, 154, 154); } } else { - if ((_item6._cardId == 26) || (_item6._cardId == 30) ||(_item6._cardId == 32) || (_item6._cardId == 28)) { - if (subC2BF8(&_gameBoardSide[2]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if ((_selectedCard._cardId == 26) || (_selectedCard._cardId == 30) ||(_selectedCard._cardId == 32) || (_selectedCard._cardId == 28)) { + if (_gameBoardSide[2]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { actionDisplay(1330, 42, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (!subC3386(_gameBoardSide[2]._delayPile[0]._cardId, _item6._cardId)) { - if (_gameBoardSide[2]._delayPile[0]._cardId != 0) { - switch (_gameBoardSide[2]._delayPile[0]._cardId) { + } else if (!subC3386(_gameBoardSide[2]._delayCard._cardId, _selectedCard._cardId)) { + if (_gameBoardSide[2]._delayCard._cardId != 0) { + switch (_gameBoardSide[2]._delayCard._cardId) { case 11: actionDisplay(1330, 68, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; @@ -6588,36 +6631,36 @@ void Scene1337::subD02CA() { actionDisplay(1330, 41, 159, 10, 1, 200, 0, 7, 0, 154, 154); } } else { - subC34A1(&_item6, &_gameBoardSide[2]._delayPile[0]); + subC34A1(&_selectedCard, &_gameBoardSide[2]._delayCard); return; } } else { - if ((subC27F9(_item6._cardId) == -1) && (subC27B5(_item6._cardId) == -1)) { - if (_item6._cardId == 13) { - if (subC2BF8(&_gameBoardSide[0]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if ((subC27F9(_selectedCard._cardId) == -1) && (subC27B5(_selectedCard._cardId) == -1)) { + if (_selectedCard._cardId == 13) { + if (_gameBoardSide[0]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { for (int k = 0; k <= 7; k++) { if (_gameBoardSide[0]._outpostStation[k]._cardId != 0) { found = true; - subC358E(&_item6, 0); + subC358E(&_selectedCard, 0); } } if (!found) actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (subC2BF8(&_gameBoardSide[3]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + } else if (_gameBoardSide[3]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { for (int k = 0; k <= 7; k++) { if (_gameBoardSide[3]._outpostStation[k]._cardId != 0) { found = true; - subC358E(&_item6, 3); + subC358E(&_selectedCard, 3); } } if (!found) actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (subC2BF8(&_gameBoardSide[1]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + } else if (_gameBoardSide[1]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { for (int k = 0; k <= 7; k++) { if (_gameBoardSide[1]._outpostStation[k]._cardId == 0) { found = true; - subC358E(&_item6, 1); + subC358E(&_selectedCard, 1); } } if (!found) @@ -6625,9 +6668,9 @@ void Scene1337::subD02CA() { } else { actionDisplay(1330, 128, 159, 10, 1, 200, 0, 7, 0, 154, 154); } - } else if (_item6._cardId == 25) { + } else if (_selectedCard._cardId == 25) { int k; - if (subC2BF8(&_gameBoardSide[0]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if (_gameBoardSide[0]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { if ( (_gameBoardSide[0]._handCard[0]._cardId != 0) || (_gameBoardSide[0]._handCard[1]._cardId != 0) || (_gameBoardSide[0]._handCard[2]._cardId != 0) @@ -6641,7 +6684,7 @@ void Scene1337::subD02CA() { } else { actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154); } - } else if (subC2BF8(&_gameBoardSide[1]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + } else if (_gameBoardSide[1]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { if ( (_gameBoardSide[1]._handCard[0]._cardId != 0) || (_gameBoardSide[1]._handCard[1]._cardId != 0) || (_gameBoardSide[1]._handCard[2]._cardId != 0) @@ -6657,7 +6700,7 @@ void Scene1337::subD02CA() { } } - if (subC2BF8(&_gameBoardSide[3]._arr4[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { + if (_gameBoardSide[3]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { if ( (_gameBoardSide[3]._handCard[0]._cardId != 0) || (_gameBoardSide[3]._handCard[1]._cardId != 0) || (_gameBoardSide[3]._handCard[2]._cardId != 0) @@ -6674,17 +6717,17 @@ void Scene1337::subD02CA() { } else { actionDisplay(1330, 129, 159, 10, 1, 200, 0, 7, 0, 154, 154); } - } else if (_item6._cardId == 29) { + } else if (_selectedCard._cardId == 29) { actionDisplay(1330, 136, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (_item6._cardId == 27) { + } else if (_selectedCard._cardId == 27) { actionDisplay(1330, 137, 159, 10, 1, 200, 0, 7, 0, 154, 154); } } else { - if (subC2BF8(&_gameBoardSide[0]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { - if (_gameBoardSide[0]._delayPile[0]._cardId != 0) { + if (_gameBoardSide[0]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { + if (_gameBoardSide[0]._delayCard._cardId != 0) { actionDisplay(1330, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (!subC32B1(0, _item6._cardId)) { - switch (_item6._cardId) { + } else if (!subC32B1(0, _selectedCard._cardId)) { + switch (_selectedCard._cardId) { case 10: actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; @@ -6713,14 +6756,14 @@ void Scene1337::subD02CA() { break; } } else { - subC3456(&_item6, &_gameBoardSide[0]._delayPile[0]); + subC3456(&_selectedCard, &_gameBoardSide[0]._delayCard); found = true; } - } else if (subC2BF8(&_gameBoardSide[3]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { - if (_gameBoardSide[3]._delayPile[0]._cardId != 0) { + } else if (_gameBoardSide[3]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { + if (_gameBoardSide[3]._delayCard._cardId != 0) { actionDisplay(1330, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (!subC32B1(3, _item6._cardId)) { - switch (_item6._cardId) { + } else if (!subC32B1(3, _selectedCard._cardId)) { + switch (_selectedCard._cardId) { case 10: actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; @@ -6749,14 +6792,14 @@ void Scene1337::subD02CA() { break; } } else { - subC3456(&_item6, &_gameBoardSide[3]._delayPile[0]); + subC3456(&_selectedCard, &_gameBoardSide[3]._delayCard); found = true; } - } else if (subC2BF8(&_gameBoardSide[1]._delayPile[0], Common::Point(_item6._stationPos.x + 12, _item6._stationPos.y + 12)) != 0) { - if (_gameBoardSide[1]._delayPile[0]._cardId != 0) { + } else if (_gameBoardSide[1]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) { + if (_gameBoardSide[1]._delayCard._cardId != 0) { actionDisplay(1330, 19, 159, 10, 1, 200, 0, 7, 0, 154, 154); - } else if (!subC32B1(1, _item6._cardId)) { - switch (_item6._cardId) { + } else if (!subC32B1(1, _selectedCard._cardId)) { + switch (_selectedCard._cardId) { case 10: actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154); break; @@ -6785,7 +6828,7 @@ void Scene1337::subD02CA() { break; } } else { - subC3456(&_item6, &_gameBoardSide[1]._delayPile[0]); + subC3456(&_selectedCard, &_gameBoardSide[1]._delayCard); found = true; } } else { @@ -6807,26 +6850,28 @@ void Scene1337::subD02CA() { } } -void Scene1337::subD183F(int arg1, int arg2) { +void Scene1337::updateCursorId(int cursorId, bool updateFl) { if ((R2_GLOBALS._v57709 != 0) || (R2_GLOBALS._v5780C != 0)) return; - R2_GLOBALS._v5780E = arg1 + arg2; + R2_GLOBALS._mouseCursorId = cursorId; + + if (updateFl) { + R2_GLOBALS._mouseCursorId++; - if (arg2 != 0) { - if (R2_GLOBALS._v5780E < 1) - R2_GLOBALS._v5780E = 2; + if (R2_GLOBALS._mouseCursorId < 1) + R2_GLOBALS._mouseCursorId = 2; - if (R2_GLOBALS._v5780E > 2) - R2_GLOBALS._v5780E = 1; + if (R2_GLOBALS._mouseCursorId > 2) + R2_GLOBALS._mouseCursorId = 1; } // The original was using an intermediate function to call setCursorData. // It has been removed to improve readability - if (R2_GLOBALS._v5780E == 1) { + if (R2_GLOBALS._mouseCursorId == 1) { R2_GLOBALS._v57810 = 200; setCursorData(5, 1, 4); - } else if (R2_GLOBALS._v5780E == 2) { + } else if (R2_GLOBALS._mouseCursorId == 2) { R2_GLOBALS._v57810 = 300; setCursorData(5, 1, 5); } else { @@ -6845,6 +6890,9 @@ void Scene1337::setCursorData(int resNum, int rlbNum, int frameNum) { // FIXME: Use another cursor when possible R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); } else { + // TODO: The original was using some ressource caching, which was useless and complex + // and which has been removed. This cursor behavior clearly made intensive use of this caching... + // We now have to find a way to cache these cursor pointers and avoid loading them multiple times per seconds uint size; byte *cursor = g_resourceManager->getSubResource(resNum, rlbNum, frameNum, &size); // Decode the cursor @@ -6854,10 +6902,13 @@ void Scene1337::setCursorData(int resNum, int rlbNum, int frameNum) { const byte *cursorData = (const byte *)surface.getPixels(); CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor); s.unlockSurface(); + + DEALLOCATE(cursor); } } void Scene1337::subD18F5() { + warning("subD18F5 - %d", R2_GLOBALS._v57709); if (R2_GLOBALS._v57709 == 0) R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS); @@ -6865,6 +6916,7 @@ void Scene1337::subD18F5() { } void Scene1337::subD1917() { + warning("subD1917 - %d", R2_GLOBALS._v57709); if (R2_GLOBALS._v57709 != 0) { R2_GLOBALS._v57709--; if (R2_GLOBALS._v57709 != 0) { @@ -6886,27 +6938,6 @@ void Scene1337::subD1975(int arg1, int arg2) { warning("STUBBED lvl2 Scene1337::subD1975()"); } -void Scene1337::subD1A48(int arg1) { - int tmpVal = -1; - - switch (arg1) { - case 200: - tmpVal = 141; - break; - case 300: - tmpVal = 142; - break; - default: - MessageDialog::show(WRONG_ANSWER_MSG, OK_BTN_STRING); - break; - } - - if (tmpVal == -1) - return; - - actionDisplay(1330, tmpVal, -1, -1, 1, 220, 1, 5, 0, 105, 0); -} - /*-------------------------------------------------------------------------- * Scene 1500 - Cutscene: Ship landing * @@ -6971,6 +7002,7 @@ void Scene1500::postInit(SceneObjectList *OwnerList) { _sceneMode = 0; R2_GLOBALS._sound1.play(102); } + signal(); } diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h index 45ed746bac..c62dd941cf 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes1.h +++ b/engines/tsage/ringworld2/ringworld2_scenes1.h @@ -183,31 +183,32 @@ public: }; class Scene1337 : public SceneExt { - class unkObj1337sub1: public SceneHotspot { + class Card: public SceneHotspot { public: SceneObject _card; int _cardId; Common::Point _stationPos; - unkObj1337sub1(); + Card(); void synchronize(Serializer &s); + bool isIn(Common::Point pt); }; - class unkObj1337_1: public SceneHotspot { + class GameBoardSide: public SceneHotspot { public: - unkObj1337sub1 _handCard[4]; - unkObj1337sub1 _outpostStation[8]; - unkObj1337sub1 _delayPile[1]; - unkObj1337sub1 _arr4[1]; + Card _handCard[4]; + Card _outpostStation[8]; + Card _delayCard; + Card _emptyStationPos; - Common::Point _fieldB94; - Common::Point _fieldB98; - Common::Point _fieldB9C; - Common::Point _fieldBA0; - int _fieldBA4; + Common::Point _card1Pos; + Common::Point _card2Pos; + Common::Point _card3Pos; + Common::Point _card4Pos; + int _frameNum; - unkObj1337_1(); + GameBoardSide(); void synchronize(Serializer &s); }; @@ -274,9 +275,9 @@ public: ASound _aSound1; ASound _aSound2; - BackgroundSceneObject _background1; + SceneActor _helpIcon; bool _autoplay; - unkObj1337_1 _gameBoardSide[4]; + GameBoardSide _gameBoardSide[4]; SceneItem _item1; SceneObject _currentPlayerArrow; Action1 _action1; @@ -292,28 +293,30 @@ public: Action11 _action11; Action12 _action12; Action13 _action13; - unkObj1337sub1 _animatedCard; - unkObj1337sub1 _shuffleAnimation; - unkObj1337sub1 _item4; - BackgroundSceneObject _background2; + Card _animatedCard; + Card _shuffleAnimation; + Card _item4; + SceneActor _stockPile; int _cardsAvailableNumb; - int _field3E26; + + // Discarded cards are put in the available cards pile, with an higher index so there no conflict + int _currentDiscardIndex; int _availableCardsPile[100]; - unkObj1337sub1 *_field3EF0; - unkObj1337sub1 *_field3EF4; - unkObj1337sub1 *_field3EF8; - unkObj1337sub1 _item5; - unkObj1337sub1 _item6; - unkObj1337sub1 _discardPile; - unkObj1337sub1 _item8; + Card *_discardCard; + Card *_field3EF4; + Card *_field3EF8; + Card _item5; + Card _selectedCard; + Card _discardPile; + Card _stockCard; bool _shuffleEndedFl; int _currentPlayerNumb; int _field4240; int _field4242; - bool _field4244; + bool _showPlayerTurn; bool _field4246; int _field424A; - int _instructionsDisplayedFl; + bool _instructionsDisplayedFl; int _instructionsWaitCount; int _cursorCurRes; int _cursorCurStrip; @@ -325,8 +328,8 @@ public: Scene1337(); virtual void synchronize(Serializer &s); - void actionDisplay(int resNum, int lineNum, int x, int y, int arg5, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt); - void setAnimationInfo(unkObj1337sub1 *subObj); + void actionDisplay(int resNum, int lineNum, int x, int y, int keepOnScreen, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt); + void setAnimationInfo(Card *subObj); void subC20E5(); void subC20F9(); void subC2586(); @@ -339,44 +342,42 @@ public: int subC27B5(int arg1); int subC27F9(int arg1); void subC2835(int arg1); - bool subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt); void subC2C2F(); - void subC318B(int arg1, unkObj1337sub1 *subObj2, int arg3); + void subC318B(int arg1, Card *subObj2, int arg3); int subC3257(int arg1); bool subC32B1(int arg1, int arg2); int subC331B(int arg1); bool subC3386(int arg1, int arg2); - void subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2); - void subC3456(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2); - void subC340B(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2); - void subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2); - unkObj1337sub1 *subC34EC(int arg1); - void subC358E(unkObj1337sub1 *subObj1, int arg2); + void subC33C0(Card *subObj1, Card *subObj2); + void subC3456(Card *subObj1, Card *subObj2); + void subC340B(Card *subObj1, Card *subObj2); + void subC34A1(Card *subObj1, Card *subObj2); + Card *subC34EC(int arg1); + void subC358E(Card *subObj1, int arg2); int subC3E92(int arg1); - void subC4A39(unkObj1337sub1 *subObj); + void discardCard(Card *card); void subC4CD2(); void subC4CEC(); - void subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2); + void subC51A0(Card *subObj1, Card *subObj2); void displayDialog(int dialogNumb); void subPostInit(); void displayInstructions(); void suggestInstructions(); void shuffleCards(); - void firstShuffle(); + void dealCards(); void subCD193(); - void subCDB90(int arg1, Common::Point pt); + void handleClick(int arg1, Common::Point pt); void subCF31D(); void subCF979(); void subD026D(); void subD0281(); void subD02CA(); - void subD183F(int arg1, int arg2); + void updateCursorId(int arg1, bool arg2); void setCursorData(int resNum, int rlbNum, int frameNum); void subD18F5(); void subD1917(); void subD1940(bool flag); void subD1975(int arg1, int arg2); - void subD1A48(int arg1); virtual void postInit(SceneObjectList *OwnerList = NULL); virtual void remove(); diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h index 41179c4915..0896580b04 100644 --- a/engines/tsage/tsage.h +++ b/engines/tsage/tsage.h @@ -27,6 +27,7 @@ #include "common/rect.h" #include "audio/mixer.h" #include "common/file.h" +#include "gui/debugger.h" #include "tsage/core.h" #include "tsage/resources.h" @@ -76,6 +77,7 @@ public: MemoryManager _memoryManager; Debugger *_debugger; + GUI::Debugger *getDebugger() { return _debugger; } const char *getGameId() const; uint32 getGameID() const; diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp index 286f83defe..e39a15f469 100644 --- a/engines/wintermute/base/base_file_manager.cpp +++ b/engines/wintermute/base/base_file_manager.cpp @@ -246,8 +246,13 @@ bool BaseFileManager::registerPackages() { // Italian } else if (_language == Common::IT_ITA && (fileName != "italian.dcp" && fileName != "xlanguage_it.dcp")) { continue; + // Latvian + } else if (_language == Common::LV_LAT && (fileName != "latvian.dcp" && fileName != "xlanguage_lv.dcp")) { + // TODO: 'latvian.dcp' is just guesswork. Is there any + // game using Latvian and using this filename? + continue; // Polish - } else if (_language == Common::PL_POL && (fileName != "polish.dcp" && fileName != "xlanguage_po.dcp")) { + } else if (_language == Common::PL_POL && (fileName != "polish.dcp" && fileName != "xlanguage_pl.dcp")) { continue; // Portuguese } else if (_language == Common::PT_BRA && (fileName != "portuguese.dcp" && fileName != "xlanguage_pt.dcp")) { diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h index 46e05f2768..bec52c4957 100644 --- a/engines/wintermute/detection_tables.h +++ b/engines/wintermute/detection_tables.h @@ -689,6 +689,118 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO0() }, + // Reversion: The Escape Version 1.3.2369 (Chinese) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_nz.dcp", 0, "7146dfa43ffdf0886e034fffe2c8a0c0", 13722261}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::ZH_CNA, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (English) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_en.dcp", 0, "64b6fa7eedc09c231f6ce046e77fee05", 11339619}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (French) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_fr.dcp", 0, "d561d562224afea809153a1fd9fdb0c0", 11963210}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::FR_FRA, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (German) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_de.dcp", 0, "4e3f614c36bd6bae74b8cc83e663a8f0", 14040310}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::DE_DEU, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (Italian) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_it.dcp", 0, "10d09b7fe61946f09dd91d5e8d090f94", 11913752}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::IT_ITA, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (Latvian) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_lv.dcp", 0, "704359ab5040b0dab6545064d7aa6eb9", 11414925}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::LV_LAT, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (Polish) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_pl.dcp", 0, "c4ad33f57e1e998169552d521c1d6638", 11532215}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::PL_POL, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, + // Reversion: The Escape Version 1.3.2369 (Portuguese) + { + "reversion1", + "Version 1.3.2369", + { + {"xlanguage_pt.dcp", 0, "886886b6b14aadac844078de856799a6", 10620797}, + {"data.dcp", 0, "aecb5deeea7b0baa871fbd0cef35a648", 254219204}, + AD_LISTEND + }, + Common::PT_BRA, + Common::kPlatformWindows, + ADGF_UNSTABLE, + GUIO0() + }, // Reversion: The Meeting (Chinese) { "reversion2", diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h index 1c525c1fc1..7c130fc87f 100644 --- a/engines/zvision/zvision.h +++ b/engines/zvision/zvision.h @@ -24,6 +24,7 @@ #ifndef ZVISION_ZVISION_H #define ZVISION_ZVISION_H +#include "zvision/core/console.h" #include "zvision/detection.h" #include "zvision/utility/clock.h" @@ -44,7 +45,6 @@ class VideoDecoder; namespace ZVision { struct ZVisionGameDescription; -class Console; class ScriptManager; class RenderManager; class CursorManager; @@ -117,6 +117,7 @@ public: StringManager *getStringManager() const { return _stringManager; } Common::RandomSource *getRandomSource() const { return _rnd; } ZVisionGameId getGameId() const { return _gameDescription->gameId; } + GUI::Debugger *getDebugger() { return _console; } /** * Play a video until it is finished. This is a blocking call. It will call |