Skip to content

Commit

Permalink
Engine: ensure that restricted game options not loaded from save
Browse files Browse the repository at this point in the history
This fixes occasional problem with save overriding game options that must not be changed at runtime.
  • Loading branch information
ivan-mogilko committed Aug 6, 2023
1 parent efc3941 commit 985c82f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 26 deletions.
12 changes: 12 additions & 0 deletions Common/ac/gamesetupstructbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ struct GameSetupStructBase
return IsLegacyAudioSystem() ? "music.vox" : "audio.vox";
}

// Returns a list of game options that are forbidden to change at runtime
inline static std::array<int, 17> GetRestrictedOptions()
{
return std::array<int,17> {{
OPT_DEBUGMODE, OPT_LETTERBOX, OPT_HIRES_FONTS, OPT_SPLITRESOURCES,
OPT_STRICTSCRIPTING, OPT_LEFTTORIGHTEVAL, OPT_COMPRESSSPRITES, OPT_STRICTSTRINGS,
OPT_NATIVECOORDINATES, OPT_SAFEFILEPATHS, OPT_DIALOGOPTIONSAPI, OPT_BASESCRIPTAPI,
OPT_SCRIPTCOMPATLEV, OPT_RELATIVEASSETRES, OPT_GAMETEXTENCODING, OPT_KEYHANDLEAPI,
OPT_CUSTOMENGINETAG
}};
}

private:
void SetDefaultResolution(GameResolutionType type, Size game_res);
void SetNativeResolution(GameResolutionType type, Size game_res);
Expand Down
32 changes: 9 additions & 23 deletions Engine/ac/global_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,33 +433,19 @@ int SetGameOption (int opt, int newval) {
}

// Handle forbidden options
switch (opt)
const auto restricted_opts = GameSetupStructBase::GetRestrictedOptions();
for (auto r_opt : restricted_opts)
{
case OPT_DEBUGMODE: // we don't support switching OPT_DEBUGMODE from script
case OPT_LETTERBOX:
case OPT_HIRES_FONTS:
case OPT_SPLITRESOURCES:
case OPT_STRICTSCRIPTING:
case OPT_LEFTTORIGHTEVAL:
case OPT_COMPRESSSPRITES:
case OPT_STRICTSTRINGS:
case OPT_NATIVECOORDINATES:
case OPT_SAFEFILEPATHS:
case OPT_DIALOGOPTIONSAPI:
case OPT_BASESCRIPTAPI:
case OPT_SCRIPTCOMPATLEV:
case OPT_RELATIVEASSETRES:
case OPT_GAMETEXTENCODING:
case OPT_KEYHANDLEAPI:
case OPT_CUSTOMENGINETAG:
debug_script_warn("SetGameOption: option %d cannot be modified at runtime", opt);
return game.options[opt];
default:
break;
if (r_opt == opt)
{
debug_script_warn("SetGameOption: option %d cannot be modified at runtime", opt);
return game.options[opt];
}
}

// Test if option already has this value
if (game.options[opt] == newval)
return game.options[opt]; // no change necessary
return game.options[opt];

const int oldval = game.options[opt];
game.options[opt] = newval;
Expand Down
12 changes: 12 additions & 0 deletions Engine/game/savegame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ void DoBeforeRestore(PreservedParams &pp)
{
pp.SpeechVOX = play.voice_avail;
pp.MusicVOX = play.separate_music_lib;
memcpy(pp.GameOptions, game.options, GameSetupStruct::MAX_OPTIONS * sizeof(int));

unload_old_room();
raw_saved_screen = nullptr;
Expand Down Expand Up @@ -459,6 +460,14 @@ void RestoreViewportsAndCameras(const RestoredData &r_data)
play.InvalidateViewportZOrder();
}

// Resets a number of options that are not supposed to be changed at runtime
static void CopyPreservedGameOptions(GameSetupStructBase &gs, const PreservedParams &pp)
{
const auto restricted_opts = GameSetupStructBase::GetRestrictedOptions();
for (auto opt : restricted_opts)
gs.options[opt] = pp.GameOptions[opt];
}

// Final processing after successfully restoring from save
HSaveError DoAfterRestore(const PreservedParams &pp, RestoredData &r_data)
{
Expand All @@ -471,6 +480,9 @@ HSaveError DoAfterRestore(const PreservedParams &pp, RestoredData &r_data)
play.voice_avail = pp.SpeechVOX;
play.separate_music_lib = pp.MusicVOX;

// Restore particular game options that must not change at runtime
CopyPreservedGameOptions(game, pp);

// Restore debug flags
if (debug_flags & DBG_DEBUGMODE)
play.debug_mode = 1;
Expand Down
8 changes: 5 additions & 3 deletions Engine/game/savegame_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ typedef std::shared_ptr<Bitmap> PBitmap;
struct PreservedParams
{
// Whether speech and audio packages available
bool SpeechVOX;
bool MusicVOX;
bool SpeechVOX = false;
bool MusicVOX = false;
// Game options, to preserve ones that must not change at runtime
int GameOptions[GameSetupStructBase::MAX_OPTIONS]{};
// Script global data sizes
size_t GlScDataSize;
size_t GlScDataSize = 0u;
std::vector<size_t> ScMdDataSize;

PreservedParams();
Expand Down

0 comments on commit 985c82f

Please sign in to comment.