Add: save openttd.cfg immediately on changing a setting (#8358)

Formally it was only done on exit. This means that if it crashes
changes in settings were not stored. This is often rather
frustrating. Additionally, targets (like emscripten) where people
are unlike to use "Exit Game", will never see their configuration
stored.

The drawback is that on every setting change there is some minor
I/O of writing the ini file to disk again.
This commit is contained in:
Patric Stout 2020-12-13 16:28:06 +01:00 committed by GitHub
parent 40edc2863c
commit c66bd18a10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 11 deletions

View File

@ -84,6 +84,7 @@ bool HandleBootstrap();
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY); extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
extern void ShowOSErrorBox(const char *buf, bool system); extern void ShowOSErrorBox(const char *buf, bool system);
extern char *_config_file; extern char *_config_file;
extern bool _save_config = false;
/** /**
* Error handling for fatal user errors. * Error handling for fatal user errors.
@ -178,7 +179,7 @@ static void ShowHelp()
" -S sounds_set = Force the sounds set (see below)\n" " -S sounds_set = Force the sounds set (see below)\n"
" -M music_set = Force the music set (see below)\n" " -M music_set = Force the music set (see below)\n"
" -c config_file = Use 'config_file' instead of 'openttd.cfg'\n" " -c config_file = Use 'config_file' instead of 'openttd.cfg'\n"
" -x = Do not automatically save to config file on exit\n" " -x = Never save configuration changes to disk\n"
" -q savegame = Write some information about the savegame and exit\n" " -q savegame = Write some information about the savegame and exit\n"
"\n", "\n",
lastof(buf) lastof(buf)
@ -395,19 +396,16 @@ struct AfterNewGRFScan : NewGRFScanCallback {
char *network_conn; ///< Information about the server to connect to, or nullptr. char *network_conn; ///< Information about the server to connect to, or nullptr.
const char *join_server_password; ///< The password to join the server with. const char *join_server_password; ///< The password to join the server with.
const char *join_company_password; ///< The password to join the company with. const char *join_company_password; ///< The password to join the company with.
bool *save_config_ptr; ///< The pointer to the save config setting.
bool save_config; ///< The save config setting. bool save_config; ///< The save config setting.
/** /**
* Create a new callback. * Create a new callback.
* @param save_config_ptr Pointer to the save_config local variable which
* decides whether to save of exit or not.
*/ */
AfterNewGRFScan(bool *save_config_ptr) : AfterNewGRFScan() :
startyear(INVALID_YEAR), generation_seed(GENERATE_NEW_SEED), startyear(INVALID_YEAR), generation_seed(GENERATE_NEW_SEED),
dedicated_host(nullptr), dedicated_port(0), network_conn(nullptr), dedicated_host(nullptr), dedicated_port(0), network_conn(nullptr),
join_server_password(nullptr), join_company_password(nullptr), join_server_password(nullptr), join_company_password(nullptr),
save_config_ptr(save_config_ptr), save_config(true) save_config(true)
{ {
/* Visual C++ 2015 fails compiling this line (AfterNewGRFScan::generation_seed undefined symbol) /* Visual C++ 2015 fails compiling this line (AfterNewGRFScan::generation_seed undefined symbol)
* if it's placed outside a member function, directly in the struct body. */ * if it's placed outside a member function, directly in the struct body. */
@ -438,7 +436,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
WindowDesc::LoadFromConfig(); WindowDesc::LoadFromConfig();
/* We have loaded the config, so we may possibly save it. */ /* We have loaded the config, so we may possibly save it. */
*save_config_ptr = save_config; _save_config = save_config;
/* restore saved music volume */ /* restore saved music volume */
MusicDriver::GetInstance()->SetVolume(_settings_client.music.music_vol); MusicDriver::GetInstance()->SetVolume(_settings_client.music.music_vol);
@ -541,9 +539,7 @@ int openttd_main(int argc, char *argv[])
std::string sounds_set; std::string sounds_set;
std::string music_set; std::string music_set;
Dimension resolution = {0, 0}; Dimension resolution = {0, 0};
/* AfterNewGRFScan sets save_config to true after scanning completed. */ std::unique_ptr<AfterNewGRFScan> scanner(new AfterNewGRFScan());
bool save_config = false;
std::unique_ptr<AfterNewGRFScan> scanner(new AfterNewGRFScan(&save_config));
bool dedicated = false; bool dedicated = false;
char *debuglog_conn = nullptr; char *debuglog_conn = nullptr;
@ -847,7 +843,7 @@ int openttd_main(int argc, char *argv[])
WaitTillGeneratedWorld(); // Make sure any generate world threads have been joined. WaitTillGeneratedWorld(); // Make sure any generate world threads have been joined.
/* only save config if we have to */ /* only save config if we have to */
if (save_config) { if (_save_config) {
SaveToConfig(); SaveToConfig();
SaveHotkeysToConfig(); SaveHotkeysToConfig();
WindowDesc::SaveToConfig(); WindowDesc::SaveToConfig();

View File

@ -51,6 +51,7 @@ enum DisplayOptions {
extern GameMode _game_mode; extern GameMode _game_mode;
extern SwitchMode _switch_mode; extern SwitchMode _switch_mode;
extern bool _exit_game; extern bool _exit_game;
extern bool _save_config;
/** Modes of pausing we've got */ /** Modes of pausing we've got */
enum PauseMode : byte { enum PauseMode : byte {

View File

@ -1913,6 +1913,8 @@ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
} }
SetWindowClassesDirty(WC_GAME_OPTIONS); SetWindowClassesDirty(WC_GAME_OPTIONS);
if (_save_config) SaveToConfig();
} }
return CommandCost(); return CommandCost();
@ -1981,12 +1983,15 @@ bool SetSettingValue(uint index, int32 value, bool force_newgame)
SetWindowClassesDirty(WC_GAME_OPTIONS); SetWindowClassesDirty(WC_GAME_OPTIONS);
if (_save_config) SaveToConfig();
return true; return true;
} }
if (force_newgame) { if (force_newgame) {
void *var2 = GetVariableAddress(&_settings_newgame, &sd->save); void *var2 = GetVariableAddress(&_settings_newgame, &sd->save);
Write_ValidateSetting(var2, sd, value); Write_ValidateSetting(var2, sd, value);
if (_save_config) SaveToConfig();
return true; return true;
} }
@ -2080,6 +2085,7 @@ bool SetSettingValue(uint index, const char *value, bool force_newgame)
} }
if (sd->desc.proc != nullptr) sd->desc.proc(0); if (sd->desc.proc != nullptr) sd->desc.proc(0);
if (_save_config) SaveToConfig();
return true; return true;
} }