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)
This commit is contained in:
parent
2a1b80fe18
commit
ce595cb92d
4 changed files with 141 additions and 46 deletions
|
@ -37,7 +37,6 @@
|
||||||
#include "sci/engine/state.h"
|
#include "sci/engine/state.h"
|
||||||
#include "sci/engine/kernel.h"
|
#include "sci/engine/kernel.h"
|
||||||
#include "sci/engine/savegame.h"
|
#include "sci/engine/savegame.h"
|
||||||
#include "sci/graphics/menu.h"
|
|
||||||
#include "sci/sound/audio.h"
|
#include "sci/sound/audio.h"
|
||||||
#include "sci/console.h"
|
#include "sci/console.h"
|
||||||
|
|
||||||
|
@ -907,50 +906,8 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
|
||||||
gamestate_restore(s, in);
|
gamestate_restore(s, in);
|
||||||
delete in;
|
delete in;
|
||||||
|
|
||||||
switch (g_sci->getGameId()) {
|
gamestate_afterRestoreFixUp(s, savegameId);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
s->r_acc = TRUE_REG;
|
s->r_acc = TRUE_REG;
|
||||||
warning("Savegame #%d not found", savegameId);
|
warning("Savegame #%d not found", savegameId);
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "sci/engine/vm_types.h"
|
#include "sci/engine/vm_types.h"
|
||||||
#include "sci/engine/script.h" // for SCI_OBJ_EXPORTS and SCI_OBJ_SYNONYMS
|
#include "sci/engine/script.h" // for SCI_OBJ_EXPORTS and SCI_OBJ_SYNONYMS
|
||||||
#include "sci/graphics/helpers.h"
|
#include "sci/graphics/helpers.h"
|
||||||
|
#include "sci/graphics/menu.h"
|
||||||
#include "sci/graphics/palette.h"
|
#include "sci/graphics/palette.h"
|
||||||
#include "sci/graphics/ports.h"
|
#include "sci/graphics/ports.h"
|
||||||
#include "sci/graphics/screen.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);
|
extern void showScummVMDialog(const Common::String &message);
|
||||||
|
|
||||||
void gamestate_delayedrestore(EngineState *s) {
|
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);
|
Common::SeekableReadStream *in = g_sci->getSaveFileManager()->openForLoading(fileName);
|
||||||
|
|
||||||
if (in) {
|
if (in) {
|
||||||
|
@ -965,6 +967,7 @@ void gamestate_delayedrestore(EngineState *s) {
|
||||||
gamestate_restore(s, in);
|
gamestate_restore(s, in);
|
||||||
delete in;
|
delete in;
|
||||||
if (s->r_acc != make_reg(0, 1)) {
|
if (s->r_acc != make_reg(0, 1)) {
|
||||||
|
gamestate_afterRestoreFixUp(s, savegameId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -972,6 +975,53 @@ void gamestate_delayedrestore(EngineState *s) {
|
||||||
error("Restoring gamestate '%s' failed", fileName.c_str());
|
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) {
|
void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
|
||||||
SavegameMetadata meta;
|
SavegameMetadata meta;
|
||||||
|
|
||||||
|
|
|
@ -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()
|
// does a delayed saved game restore, used by ScummVM game menu - see detection.cpp / SciEngine::loadGameState()
|
||||||
void gamestate_delayedrestore(EngineState *s);
|
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.
|
* Restores a game state from a directory.
|
||||||
* @param s An older state from the same game
|
* @param s An older state from the same game
|
||||||
|
|
|
@ -1842,15 +1842,100 @@ static const SciScriptPatcherEntry laurabow2Signatures[] = {
|
||||||
// MG::replay somewhat calculates the savedgame-id used when saving again
|
// MG::replay somewhat calculates the savedgame-id used when saving again
|
||||||
// this doesn't work right and we remove the code completely.
|
// this doesn't work right and we remove the code completely.
|
||||||
// We set the savedgame-id directly right after restoring in kRestoreGame.
|
// 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[] = {
|
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
|
0x36, // push
|
||||||
0x35, SIG_MAGICDWORD, 0x20, // ldi 20
|
0x35, SIG_MAGICDWORD, 0x20, // ldi 20
|
||||||
0x04, // sub
|
0x04, // sub
|
||||||
0xa1, 0xb3, // sag global[b3]
|
0xa1, 0xb3, // sag global[b3]
|
||||||
|
// 6 bytes
|
||||||
SIG_END
|
SIG_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16 mothergoose256PatchReplay[] = {
|
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)
|
||||||
0x34, PATCH_UINT16(0x0000), // ldi 0000 (dummy)
|
0x34, PATCH_UINT16(0x0000), // ldi 0000 (dummy)
|
||||||
PATCH_END
|
PATCH_END
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue