aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2016-02-09 01:28:08 +0100
committerMartin Kiewitz2016-02-09 01:28:34 +0100
commitce595cb92d5862c0bc5cdd703d1dd4e286ed3db9 (patch)
tree2f730745e2f5c2b11b7c19a4c88d92dd6d810308
parent2a1b80fe187dd3e67fe02373aa0f1173bb45f467 (diff)
downloadscummvm-rg350-ce595cb92d5862c0bc5cdd703d1dd4e286ed3db9.tar.gz
scummvm-rg350-ce595cb92d5862c0bc5cdd703d1dd4e286ed3db9.tar.bz2
scummvm-rg350-ce595cb92d5862c0bc5cdd703d1dd4e286ed3db9.zip
SCI: Script patch for Mixed Up Mother Goose SCI1
+ Mother Goose SCI1.1 Fixes graphic issues when restoring from GMM Also make the fix ups for Mixed Up Mother Goose, Jones + PQ2 get applied all the time (debugger command not included)
-rw-r--r--engines/sci/engine/kfile.cpp47
-rw-r--r--engines/sci/engine/savegame.cpp52
-rw-r--r--engines/sci/engine/savegame.h3
-rw-r--r--engines/sci/engine/script_patches.cpp85
4 files changed, 141 insertions, 46 deletions
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 979fa95a42..f155fe75cb 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -37,7 +37,6 @@
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
#include "sci/engine/savegame.h"
-#include "sci/graphics/menu.h"
#include "sci/sound/audio.h"
#include "sci/console.h"
@@ -907,50 +906,8 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
gamestate_restore(s, in);
delete in;
- switch (g_sci->getGameId()) {
- case GID_MOTHERGOOSE:
- // WORKAROUND: Mother Goose SCI0
- // Script 200 / rm200::newRoom will set global C5h directly right after creating a child to the
- // current number of children plus 1.
- // We can't trust that global, that's why we set the actual savedgame id right here directly after
- // restoring a saved game.
- // If we didn't, the game would always save to a new slot
- s->variables[VAR_GLOBAL][0xC5].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId);
- break;
- case GID_MOTHERGOOSE256:
- // WORKAROUND: Mother Goose SCI1/SCI1.1 does some weird things for
- // saving a previously restored game.
- // We set the current savedgame-id directly and remove the script
- // code concerning this via script patch.
- s->variables[VAR_GLOBAL][0xB3].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId);
- break;
- case GID_JONES:
- // HACK: The code that enables certain menu items isn't called when a game is restored from the
- // launcher, or the "Restore game" option in the game's main menu - bugs #6537 and #6723.
- // These menu entries are disabled when the game is launched, and are enabled when a new game is
- // started. The code for enabling these entries is is all in script 1, room1::init, but that code
- // path is never followed in these two cases (restoring game from the menu, or restoring a game
- // from the ScummVM launcher). Thus, we perform the calls to enable the menus ourselves here.
- // These two are needed when restoring from the launcher
- // FIXME: The original interpreter saves and restores the menu state, so these attributes
- // are automatically reset there. We may want to do the same.
- g_sci->_gfxMenu->kernelSetAttribute(257 >> 8, 257 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> About Jones
- g_sci->_gfxMenu->kernelSetAttribute(258 >> 8, 258 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> Help
- // The rest are normally enabled from room1::init
- g_sci->_gfxMenu->kernelSetAttribute(769 >> 8, 769 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Options -> Delete current player
- g_sci->_gfxMenu->kernelSetAttribute(513 >> 8, 513 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game
- g_sci->_gfxMenu->kernelSetAttribute(515 >> 8, 515 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Restore Game
- g_sci->_gfxMenu->kernelSetAttribute(1025 >> 8, 1025 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Statistics
- g_sci->_gfxMenu->kernelSetAttribute(1026 >> 8, 1026 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Goals
- break;
- case GID_PQ2:
- // HACK: Same as above - enable the save game menu option when loading in PQ2 (bug #6875).
- // It gets disabled in the game's death screen.
- g_sci->_gfxMenu->kernelSetAttribute(2, 1, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game
- break;
- default:
- break;
- }
+ gamestate_afterRestoreFixUp(s, savegameId);
+
} else {
s->r_acc = TRUE_REG;
warning("Savegame #%d not found", savegameId);
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 165c147c1c..fcf951e4f2 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -39,6 +39,7 @@
#include "sci/engine/vm_types.h"
#include "sci/engine/script.h" // for SCI_OBJ_EXPORTS and SCI_OBJ_SYNONYMS
#include "sci/graphics/helpers.h"
+#include "sci/graphics/menu.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/ports.h"
#include "sci/graphics/screen.h"
@@ -957,7 +958,8 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const Common::Strin
extern void showScummVMDialog(const Common::String &message);
void gamestate_delayedrestore(EngineState *s) {
- Common::String fileName = g_sci->getSavegameName(s->_delayedRestoreGameId);
+ int savegameId = s->_delayedRestoreGameId; // delayedRestoreGameId gets destroyed within gamestate_restore()!
+ Common::String fileName = g_sci->getSavegameName(savegameId);
Common::SeekableReadStream *in = g_sci->getSaveFileManager()->openForLoading(fileName);
if (in) {
@@ -965,6 +967,7 @@ void gamestate_delayedrestore(EngineState *s) {
gamestate_restore(s, in);
delete in;
if (s->r_acc != make_reg(0, 1)) {
+ gamestate_afterRestoreFixUp(s, savegameId);
return;
}
}
@@ -972,6 +975,53 @@ void gamestate_delayedrestore(EngineState *s) {
error("Restoring gamestate '%s' failed", fileName.c_str());
}
+void gamestate_afterRestoreFixUp(EngineState *s, int savegameId) {
+ switch (g_sci->getGameId()) {
+ case GID_MOTHERGOOSE:
+ // WORKAROUND: Mother Goose SCI0
+ // Script 200 / rm200::newRoom will set global C5h directly right after creating a child to the
+ // current number of children plus 1.
+ // We can't trust that global, that's why we set the actual savedgame id right here directly after
+ // restoring a saved game.
+ // If we didn't, the game would always save to a new slot
+ s->variables[VAR_GLOBAL][0xC5].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId);
+ break;
+ case GID_MOTHERGOOSE256:
+ // WORKAROUND: Mother Goose SCI1/SCI1.1 does some weird things for
+ // saving a previously restored game.
+ // We set the current savedgame-id directly and remove the script
+ // code concerning this via script patch.
+ s->variables[VAR_GLOBAL][0xB3].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId);
+ break;
+ case GID_JONES:
+ // HACK: The code that enables certain menu items isn't called when a game is restored from the
+ // launcher, or the "Restore game" option in the game's main menu - bugs #6537 and #6723.
+ // These menu entries are disabled when the game is launched, and are enabled when a new game is
+ // started. The code for enabling these entries is is all in script 1, room1::init, but that code
+ // path is never followed in these two cases (restoring game from the menu, or restoring a game
+ // from the ScummVM launcher). Thus, we perform the calls to enable the menus ourselves here.
+ // These two are needed when restoring from the launcher
+ // FIXME: The original interpreter saves and restores the menu state, so these attributes
+ // are automatically reset there. We may want to do the same.
+ g_sci->_gfxMenu->kernelSetAttribute(257 >> 8, 257 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> About Jones
+ g_sci->_gfxMenu->kernelSetAttribute(258 >> 8, 258 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Sierra -> Help
+ // The rest are normally enabled from room1::init
+ g_sci->_gfxMenu->kernelSetAttribute(769 >> 8, 769 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Options -> Delete current player
+ g_sci->_gfxMenu->kernelSetAttribute(513 >> 8, 513 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game
+ g_sci->_gfxMenu->kernelSetAttribute(515 >> 8, 515 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Restore Game
+ g_sci->_gfxMenu->kernelSetAttribute(1025 >> 8, 1025 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Statistics
+ g_sci->_gfxMenu->kernelSetAttribute(1026 >> 8, 1026 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Goals
+ break;
+ case GID_PQ2:
+ // HACK: Same as above - enable the save game menu option when loading in PQ2 (bug #6875).
+ // It gets disabled in the game's death screen.
+ g_sci->_gfxMenu->kernelSetAttribute(2, 1, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Game -> Save Game
+ break;
+ default:
+ break;
+ }
+}
+
void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
SavegameMetadata meta;
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index bb555434c9..459e992e24 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -87,6 +87,9 @@ bool gamestate_save(EngineState *s, Common::WriteStream *save, const Common::Str
// does a delayed saved game restore, used by ScummVM game menu - see detection.cpp / SciEngine::loadGameState()
void gamestate_delayedrestore(EngineState *s);
+// does a few fixups right after restoring a saved game
+void gamestate_afterRestoreFixUp(EngineState *s, int savegameId);
+
/**
* Restores a game state from a directory.
* @param s An older state from the same game
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index f732950c18..dac5c17a23 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -1842,15 +1842,100 @@ static const 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.
+// We also draw the background picture in here instead.
+// This Mixed Up Mother Goose draws the background picture before restoring,
+// instead of doing it properly in MG::replay. This fixes graphic issues,
+// when restoring from GMM.
static const uint16 mothergoose256SignatureReplay[] = {
+ 0x7a, // push2
+ 0x78, // push1
+ 0x5b, 0x00, 0xbe, // lea global[BEh]
+ 0x36, // push
+ 0x43, 0x70, 0x04, // callk MemorySegment
+ 0x7a, // push2
+ 0x5b, 0x00, 0xbe, // lea global[BEh]
+ 0x36, // push
+ 0x76, // push0
+ 0x43, 0x62, 0x04, // callk StrAt
+ 0xa1, 0xaa, // sag global[AAh]
+ 0x7a, // push2
+ 0x5b, 0x00, 0xbe, // lea global[BEh]
+ 0x36, // push
+ 0x78, // push1
+ 0x43, 0x62, 0x04, // callk StrAt
+ 0x36, // push
+ 0x35, 0x20, // ldi 20
+ 0x04, // sub
+ 0xa1, SIG_ADDTOOFFSET(+1), // sag global[57h] -> FM-Towns [9Dh]
+ // 35 bytes
+ 0x39, 0x03, // pushi 03
+ 0x89, SIG_ADDTOOFFSET(+1), // lsg global[1Dh] -> FM-Towns [1Eh]
+ 0x76, // push0
+ 0x7a, // push2
+ 0x5b, 0x00, 0xbe, // lea global[BEh]
+ 0x36, // push
+ 0x7a, // push2
+ 0x43, 0x62, 0x04, // callk StrAt
+ 0x36, // push
+ 0x35, 0x01, // ldi 01
+ 0x04, // sub
+ 0x36, // push
+ 0x43, 0x62, 0x06, // callk StrAt
+ // 22 bytes
+ 0x7a, // push2
+ 0x5b, 0x00, 0xbe, // lea global[BE]
+ 0x36, // push
+ 0x39, 0x03, // pushi 03
+ 0x43, 0x62, 0x04, // callk StrAt
+ // 10 bytes
0x36, // push
0x35, SIG_MAGICDWORD, 0x20, // ldi 20
0x04, // sub
0xa1, 0xb3, // sag global[b3]
+ // 6 bytes
SIG_END
};
static const uint16 mothergoose256PatchReplay[] = {
+ 0x39, 0x06, // pushi 06
+ 0x76, // push0
+ 0x76, // push0
+ 0x38, PATCH_UINT16(200), // pushi 200d
+ 0x38, PATCH_UINT16(320), // pushi 320d
+ 0x76, // push0
+ 0x76, // push0
+ 0x43, 0x15, 0x0c, // callk SetPort -> set picture port to full screen
+ // 15 bytes
+ 0x39, 0x04, // pushi 04
+ 0x3c, // dup
+ 0x76, // push0
+ 0x38, PATCH_UINT16(255), // pushi 255d
+ 0x76, // push0
+ 0x43, 0x6f, 0x08, // callk Palette -> set intensity to 0 for all colors
+ // 11 bytes
+ 0x7a, // push2
+ 0x38, PATCH_UINT16(800), // pushi 800
+ 0x76, // push0
+ 0x43, 0x08, 0x04, // callk DrawPic -> draw picture 800
+ // 8 bytes
+ 0x39, 0x06, // pushi 06
+ 0x39, 0x0c, // pushi 0Ch
+ 0x76, // push0
+ 0x76, // push0
+ 0x38, PATCH_UINT16(200), // push 200
+ 0x38, PATCH_UINT16(320), // push 320
+ 0x78, // push1
+ 0x43, 0x6c, 0x0c, // callk Graph -> send everything to screen
+ // 16 bytes
+ 0x39, 0x06, // pushi 06
+ 0x76, // push0
+ 0x76, // push0
+ 0x38, PATCH_UINT16(156), // pushi 156d
+ 0x38, PATCH_UINT16(258), // pushi 258d
+ 0x39, 0x03, // pushi 03
+ 0x39, 0x04, // pushi 04
+ 0x43, 0x15, 0x0c, // callk SetPort -> set picture port back
+ // 17 bytes
0x34, PATCH_UINT16(0x0000), // ldi 0000 (dummy)
0x34, PATCH_UINT16(0x0000), // ldi 0000 (dummy)
PATCH_END