SCUMM: fix videomode var handling (LOOM CGA actor palette glitch)

(original bug)

In LOOM, the scripts actually read the videomode var and make actor palette adjustments based on that. Which means for games saved in EGA mode, with the wrong videomode var value,  there will be glitches.

This concerns not only Bobbin, but the script does things for various actors and costumes in various situations.

We just set the videomode var to the actual config after loading.

For Bobbin in normal costume, I also include a post-load fix for savegames that will not have the actor palettes fixed by the scripts (savegames that we allow in situations where the original would prevent them).
This commit is contained in:
athrxx
2022-07-16 14:51:11 +02:00
parent 3d27309624
commit 2fd8bf67db
5 changed files with 38 additions and 20 deletions
+5 -2
View File
@@ -21,8 +21,11 @@ For a more comprehensive changelog of the latest experimental code, see:
- Added support for the Hebrew version of Legend of Kyrandia 3.
SCUMM:
- Add support for CGA, CGA Composite, CGA black & white and Hercules modes
for SCUMM 1 versions of Zak McKracken and Maniac Mansion.
- Added support for CGA, CGA Composite, CGA black & white and Hercules modes
for SCUMM 1 versions of Zak McKracken and Maniac Mansion. Also improved
accuracy of CGA and Hercules modes for SCUMM 2 (enhanced) versions of
Zak McKracken and Maniac Mansion and fixed some minor glitches for the
CGA mode of Loom.
Toon:
- Made game menus behave like in the original.
+6
View File
@@ -3827,6 +3827,12 @@ void Actor::saveLoadWithSerializer(Common::Serializer &s) {
_cost.frame[i] = (_cost.frame[i] << 2) | newDirToOldDir(_facing);
}
}
// Post-load fix for games that were saved with a different video mode and which do not receive the normal
// post-load treatment in ScummEngine_v3::scummLoop_handleSaveLoad() where the script will take care of the
// actor palette. This fix is only for Bobbin in his normal costume.
if (_vm->_game.id == GID_LOOM && s.isLoading() && _vm->_renderMode == Common::kRenderCGA && _number == 1 && _palette[8] == 8)
_palette[8] = 0;
}
void Actor_v3::saveLoadWithSerializer(Common::Serializer &s) {
+4
View File
@@ -1443,6 +1443,10 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
s.syncBytes(_bitVars, _numBitVariables / 8);
// Set video mode var to the current actual mode, not the one that was enabled when the game was saved.
// At least for Loom this fixes glitches, since the game actually reads the var and makes actor palette
// adjustments based on that. This is a bug that happens in the original interpreter, too.
setVideoModeVarToCurrentConfig();
// WORKAROUND: FM-TOWNS Zak used the extra 40 pixels at the bottom to increase the inventory to 10 items
// if we trim to 200 pixels, we can show only 6 items
+1
View File
@@ -426,6 +426,7 @@ protected:
virtual void setupScummVars();
virtual void resetScummVars();
void setVideoModeVarToCurrentConfig();
void setupCharsetRenderer(const Common::String &macFontFile);
void setupCostumeRenderer();
+22 -18
View File
@@ -783,24 +783,7 @@ void ScummEngine::resetScummVars() {
break;
}
if (_game.platform == Common::kPlatformFMTowns)
VAR(VAR_VIDEOMODE) = 42;
// Value only used by the Macintosh version of Indiana Jones and the Last Crusade
else if (_game.platform == Common::kPlatformMacintosh && _game.version == 3)
VAR(VAR_VIDEOMODE) = 50;
// Value only used by the Amiga version of Monkey Island 2
else if (_game.platform == Common::kPlatformAmiga)
VAR(VAR_VIDEOMODE) = 82;
else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
VAR(VAR_VIDEOMODE) = 4;
else if (_renderMode == Common::kRenderCGA_BW)
VAR(VAR_VIDEOMODE) = 6;
else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
VAR(VAR_VIDEOMODE) = 30;
else if (_renderMode == Common::kRenderEGA)
VAR(VAR_VIDEOMODE) = 13;
else
VAR(VAR_VIDEOMODE) = 19;
setVideoModeVarToCurrentConfig();
if (_game.platform == Common::kPlatformMacintosh && (_game.features & GF_OLD_BUNDLE)) {
// Set screen size for the Macintosh version of Indy3/Loom
@@ -847,4 +830,25 @@ void ScummEngine::resetScummVars() {
setTalkingActor(0);
}
void ScummEngine::setVideoModeVarToCurrentConfig() {
if (_game.platform == Common::kPlatformFMTowns)
VAR(VAR_VIDEOMODE) = 42;
// Value only used by the Macintosh version of Indiana Jones and the Last Crusade
else if (_game.platform == Common::kPlatformMacintosh && _game.version == 3)
VAR(VAR_VIDEOMODE) = 50;
// Value only used by the Amiga version of Monkey Island 2
else if (_game.platform == Common::kPlatformAmiga)
VAR(VAR_VIDEOMODE) = 82;
else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
VAR(VAR_VIDEOMODE) = 4;
else if (_renderMode == Common::kRenderCGA_BW)
VAR(VAR_VIDEOMODE) = 6;
else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
VAR(VAR_VIDEOMODE) = 30;
else if (_renderMode == Common::kRenderEGA)
VAR(VAR_VIDEOMODE) = 13;
else
VAR(VAR_VIDEOMODE) = 19;
}
} // End of namespace Scumm