Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCUMM: (LOOM) - fix bugs #6011 and #13369 #3792

Merged
merged 2 commits into from
May 12, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions engines/scumm/scumm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2584,24 +2584,52 @@ void ScummEngine::scummLoop(int delta) {
clearCharsetMask();
_charset->_hasMask = false;

// HACK as in game save stuff isn't supported currently
if (_game.id == GID_LOOM) {
// HACK as in game save stuff isn't supported exactly as in the original interpreter when using the
// ScummVM save/load dialog. The original save/load screen uses a special script (which we cannot
// call without displaying that screen) which will also makes some necessary follow-up operations. We
// simply try to achieve that manually. It fixes bugs #6011 and #13369.
// We just have to kind of pretend that we've gone through the save/load "room" (with all the right
// variables in place), so that all the operations get triggered properly.
// The glitch with the flask (#6011) seems to be present only in the DOS EGA, Amiga, Atari ST and
// FM-Towns versions. Mac, DOS Talkie and PC-Engine don't have that bug. We can rely on our old hack
// there, since it wouldn't work otherwise, anyway.
int args[NUM_SCRIPT_LOCAL];
uint var;
memset(args, 0, sizeof(args));
args[0] = 2;

uint saveLoadVar = 100;
if (_game.platform == Common::kPlatformMacintosh)
var = 105;
// 256 color CD version and PC engine version
saveLoadVar = 105;
else if (_game.platform == Common::kPlatformPCEngine || _game.version == 4)
var = 150;
else
var = 100;
byte restoreScript = (_game.platform == Common::kPlatformFMTowns) ? 17 : 18;
// if verbs should be shown restore them
if (VAR(var) == 2)
saveLoadVar = 150;

// Run this hack only under conditions where the original save script could actually be executed.
// Otherwise this would cause all sorts of glitches. Also exclude Mac, PC-Engine and DOS Talkie...
if (saveLoadVar == 100 && _userPut > 0 && !isScriptRunning(VAR(VAR_VERB_SCRIPT))) {
uint16 prevFlag = VAR(214) & 0x6000;
beginCutscene(args);
uint16 blockVerbsFlag = VAR(214) & (0x6000 ^ prevFlag);
if (Actor *a = derefActor(VAR(VAR_EGO))) {
// This is used to restore the correct camera position.
VAR(171) = a->_walkbox;
VAR(172) = a->getRealPos().x;
VAR(173) = a->getRealPos().y;
}
startScene(70, nullptr, 0);
VAR(saveLoadVar) = 0;
VAR(214) &= ~blockVerbsFlag;
endCutscene();
} else if (VAR(saveLoadVar) == 2) {
// This is our old hack. If verbs should be shown restore them.
byte restoreScript = (_game.platform == Common::kPlatformFMTowns) ? 17 : 18;
args[0] = 2;
runScript(restoreScript, 0, 0, args);
// Reset two variables, similar to what the save script would do, to avoid minor glitches
// of the verb image on the right of the distaff (image remaining blank when moving the
// mouse cursor over an object, bug #13369).
VAR(saveLoadVar + 2) = VAR(saveLoadVar + 3) = 0;
}

} else if (_game.version > 3) {
for (int i = 0; i < _numVerbs; i++)
drawVerb(i, 0);
Expand Down