diff --git a/src/command.cpp b/src/command.cpp index a9ae18e0ea..a6a10e5a1b 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -217,7 +217,7 @@ std::tuple CommandHelperBase::InternalPostBefore(Commands cmd, * fancy things for 'success'. */ bool only_sending = _networking && !network_command; - if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) { + if (_pause_mode.Any() && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) { ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE); return { true, estimate_only, only_sending }; } else { @@ -384,7 +384,7 @@ CommandCost CommandHelperBase::InternalExecuteProcessResult(Commands cmd, Comman SubtractMoneyFromCompany(res_exec); /* Record if there was a command issues during pause; ignore pause/other setting related changes. */ - if (_pause_mode != PM_UNPAUSED && _command_proc_table[cmd].type != CMDT_SERVER_SETTING) _pause_mode |= PM_COMMAND_DURING_PAUSE; + if (_pause_mode.Any() && _command_proc_table[cmd].type != CMDT_SERVER_SETTING) _pause_mode.Set(PauseMode::CommandDuringPause); /* update signals if needed */ UpdateSignalsInBuffer(); diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 97b7feabe8..3104a611ac 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -813,8 +813,8 @@ DEF_CONSOLE_CMD(ConPauseGame) return true; } - if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - Command::Post(PM_PAUSED_NORMAL, true); + if (!_pause_mode.Test(PauseMode::Normal)) { + Command::Post(PauseMode::Normal, true); if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused."); } else { IConsolePrint(CC_DEFAULT, "Game is already paused."); @@ -835,12 +835,12 @@ DEF_CONSOLE_CMD(ConUnpauseGame) return true; } - if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) { - Command::Post(PM_PAUSED_NORMAL, false); + if (_pause_mode.Test(PauseMode::Normal)) { + Command::Post(PauseMode::Normal, false); if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused."); - } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) { + } else if (_pause_mode.Test(PauseMode::Error)) { IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console."); - } else if (_pause_mode != PM_UNPAUSED) { + } else if (_pause_mode.Any()) { IConsolePrint(CC_DEFAULT, "Game cannot be unpaused manually; disable pause_on_join/min_active_clients."); } else { IConsolePrint(CC_DEFAULT, "Game is already unpaused."); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 899b000046..c116a9e3d0 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -420,7 +420,7 @@ public: /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) { - Command::Post(PM_PAUSED_SAVELOAD, true); + Command::Post(PauseMode::SaveLoad, true); } SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); @@ -463,7 +463,7 @@ public: { /* pause is only used in single-player, non-editor mode, non menu mode */ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) { - Command::Post(PM_PAUSED_SAVELOAD, false); + Command::Post(PauseMode::SaveLoad, false); } this->Window::Close(); } diff --git a/src/gfx.cpp b/src/gfx.cpp index 1fef5755df..e4e2f299e5 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -47,7 +47,7 @@ bool _screen_disable_anim = false; ///< Disable palette animation (important f std::atomic _exit_game; GameMode _game_mode; SwitchMode _switch_mode; ///< The next mainloop command. -PauseMode _pause_mode; +PauseModes _pause_mode; GameSessionStats _game_session_stats; ///< Statistics about the current session. static uint8_t _stringwidth_table[FS_END][224]; ///< Cache containing width of often used characters. @see GetCharacterWidth() diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index 417f2a849f..dc899244e4 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -99,7 +99,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { EndGameWindow(WindowDesc &desc) : EndGameHighScoreBaseWindow(desc) { /* Pause in single-player to have a look at the highscore at your own leisure */ - if (!_networking) Command::Post(PM_PAUSED_NORMAL, true); + if (!_networking) Command::Post(PauseMode::Normal, true); this->background_img = SPR_TYCOON_IMG1_BEGIN; @@ -127,7 +127,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { void Close([[maybe_unused]] int data = 0) override { - if (!_networking) Command::Post(PM_PAUSED_NORMAL, false); // unpause + if (!_networking) Command::Post(PauseMode::Normal, false); // unpause if (_game_mode != GM_MENU && !_exit_game) ShowHighscoreTable(this->window_number, this->rank); this->EndGameHighScoreBaseWindow::Close(); } @@ -161,8 +161,8 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { HighScoreWindow(WindowDesc &desc, int difficulty, int8_t ranking) : EndGameHighScoreBaseWindow(desc) { /* pause game to show the chart */ - this->game_paused_by_player = _pause_mode == PM_PAUSED_NORMAL; - if (!_networking && !this->game_paused_by_player) Command::Post(PM_PAUSED_NORMAL, true); + this->game_paused_by_player = _pause_mode == PauseMode::Normal; + if (!_networking && !this->game_paused_by_player) Command::Post(PauseMode::Normal, true); /* Close all always on-top windows to get a clean screen */ if (_game_mode != GM_MENU) HideVitalWindows(); @@ -177,7 +177,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { if (_game_mode != GM_MENU && !_exit_game) ShowVitalWindows(); - if (!_networking && !this->game_paused_by_player) Command::Post(PM_PAUSED_NORMAL, false); // unpause + if (!_networking && !this->game_paused_by_player) Command::Post(PauseMode::Normal, false); // unpause this->EndGameHighScoreBaseWindow::Close(); } diff --git a/src/landscape.cpp b/src/landscape.cpp index 82886b450f..48b3efe71d 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -734,7 +734,7 @@ std::tuple CmdClearArea(DoCommandFlags flags, TileIndex tile /* draw explosion animation... * Disable explosions when game is paused. Looks silly and blocks the view. */ - if ((t == tile || t == start_tile) && _pause_mode == PM_UNPAUSED) { + if ((t == tile || t == start_tile) && _pause_mode.None()) { /* big explosion in two corners, or small explosion for single tiles */ CreateEffectVehicleAbove(TileX(t) * TILE_SIZE + TILE_SIZE / 2, TileY(t) * TILE_SIZE + TILE_SIZE / 2, 2, TileX(tile) == TileX(start_tile) && TileY(tile) == TileY(start_tile) ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index d9bee368d3..8b85761d79 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -168,18 +168,18 @@ LinkGraphSchedule::~LinkGraphSchedule() */ void StateGameLoop_LinkGraphPauseControl() { - if (_pause_mode & PM_PAUSED_LINK_GRAPH) { + if (_pause_mode.Test(PauseMode::LinkGraph)) { /* We are paused waiting on a job, check the job every tick. */ if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { - Command::Post(PM_PAUSED_LINK_GRAPH, false); + Command::Post(PauseMode::LinkGraph, false); } - } else if (_pause_mode == PM_UNPAUSED && + } else if (_pause_mode.None() && TimerGameEconomy::date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 && TimerGameEconomy::date.base() % (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / EconomyTime::SECONDS_PER_DAY) / 2 && LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { /* Perform check two TimerGameEconomy::date_fract ticks before we would join, to make * sure it also works in multiplayer. */ - Command::Post(PM_PAUSED_LINK_GRAPH, true); + Command::Post(PauseMode::LinkGraph, true); } } @@ -191,7 +191,7 @@ void StateGameLoop_LinkGraphPauseControl() void AfterLoad_LinkGraphPauseControl() { if (LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { - _pause_mode |= PM_PAUSED_LINK_GRAPH; + _pause_mode.Set(PauseMode::LinkGraph); } } diff --git a/src/misc.cpp b/src/misc.cpp index 01349b8aa5..101f089704 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -97,7 +97,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin Map::Allocate(size_x, size_y); - _pause_mode = PM_UNPAUSED; + _pause_mode = {}; _game_speed = 100; TimerGameTick::counter = 0; _cur_tileloop_tile = TileIndex{1}; diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 3321ca8cbe..c80c75483a 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -152,7 +152,7 @@ CommandCost CmdSetCompanyMaxLoan(DoCommandFlags flags, CompanyID company, Money static void AskUnsafeUnpauseCallback(Window *, bool confirmed) { if (confirmed) { - Command::Post(PM_PAUSED_ERROR, false); + Command::Post(PauseMode::Error, false); } } @@ -169,22 +169,22 @@ static void AskUnsafeUnpauseCallback(Window *, bool confirmed) CommandCost CmdPause(DoCommandFlags flags, PauseMode mode, bool pause) { switch (mode) { - case PM_PAUSED_SAVELOAD: - case PM_PAUSED_ERROR: - case PM_PAUSED_NORMAL: - case PM_PAUSED_GAME_SCRIPT: - case PM_PAUSED_LINK_GRAPH: + case PauseMode::SaveLoad: + case PauseMode::Error: + case PauseMode::Normal: + case PauseMode::GameScript: + case PauseMode::LinkGraph: break; - case PM_PAUSED_JOIN: - case PM_PAUSED_ACTIVE_CLIENTS: + case PauseMode::Join: + case PauseMode::ActiveClients: if (!_networking) return CMD_ERROR; break; default: return CMD_ERROR; } if (flags.Test(DoCommandFlag::Execute)) { - if (mode == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) { + if (mode == PauseMode::Normal && _pause_mode.Test(PauseMode::Error)) { ShowQuery( GetEncodedString(STR_NEWGRF_UNPAUSE_WARNING_TITLE), GetEncodedString(STR_NEWGRF_UNPAUSE_WARNING), @@ -192,16 +192,16 @@ CommandCost CmdPause(DoCommandFlags flags, PauseMode mode, bool pause) AskUnsafeUnpauseCallback ); } else { - PauseMode prev_mode = _pause_mode; + PauseModes prev_mode = _pause_mode; if (pause) { - _pause_mode |= mode; + _pause_mode.Set(mode); } else { - _pause_mode &= ~mode; + _pause_mode.Reset(mode); /* If the only remaining reason to be paused is that we saw a command during pause, unpause. */ - if (_pause_mode == PM_COMMAND_DURING_PAUSE) { - _pause_mode = PM_UNPAUSED; + if (_pause_mode == PauseMode::CommandDuringPause) { + _pause_mode = {}; } } diff --git a/src/misc_cmd.h b/src/misc_cmd.h index f80b92b5d7..f9b9628753 100644 --- a/src/misc_cmd.h +++ b/src/misc_cmd.h @@ -12,8 +12,7 @@ #include "command_type.h" #include "economy_type.h" - -enum PauseMode : uint8_t; +#include "openttd.h" enum class LoanCommand : uint8_t { Interval, diff --git a/src/network/network.cpp b/src/network/network.cpp index d530fcac39..9050c316ed 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -351,37 +351,37 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err) * @param prev_mode The previous pause mode. * @param changed_mode The pause mode that got changed. */ -void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode) +void NetworkHandlePauseChange(PauseModes prev_mode, PauseMode changed_mode) { if (!_networking) return; switch (changed_mode) { - case PM_PAUSED_NORMAL: - case PM_PAUSED_JOIN: - case PM_PAUSED_GAME_SCRIPT: - case PM_PAUSED_ACTIVE_CLIENTS: - case PM_PAUSED_LINK_GRAPH: { - bool changed = ((_pause_mode == PM_UNPAUSED) != (prev_mode == PM_UNPAUSED)); - bool paused = (_pause_mode != PM_UNPAUSED); + case PauseMode::Normal: + case PauseMode::Join: + case PauseMode::GameScript: + case PauseMode::ActiveClients: + case PauseMode::LinkGraph: { + bool changed = _pause_mode.None() != prev_mode.None(); + bool paused = _pause_mode.Any(); if (!paused && !changed) return; StringID str; if (!changed) { int i = -1; - if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL); - if ((_pause_mode & PM_PAUSED_JOIN) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS); - if ((_pause_mode & PM_PAUSED_GAME_SCRIPT) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT); - if ((_pause_mode & PM_PAUSED_ACTIVE_CLIENTS) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS); - if ((_pause_mode & PM_PAUSED_LINK_GRAPH) != PM_UNPAUSED) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH); + if (_pause_mode.Test(PauseMode::Normal)) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL); + if (_pause_mode.Test(PauseMode::Join)) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS); + if (_pause_mode.Test(PauseMode::GameScript)) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT); + if (_pause_mode.Test(PauseMode::ActiveClients)) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS); + if (_pause_mode.Test(PauseMode::LinkGraph)) SetDParam(++i, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH); str = STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 + i; } else { switch (changed_mode) { - case PM_PAUSED_NORMAL: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL); break; - case PM_PAUSED_JOIN: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS); break; - case PM_PAUSED_GAME_SCRIPT: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT); break; - case PM_PAUSED_ACTIVE_CLIENTS: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS); break; - case PM_PAUSED_LINK_GRAPH: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH); break; + case PauseMode::Normal: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL); break; + case PauseMode::Join: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS); break; + case PauseMode::GameScript: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT); break; + case PauseMode::ActiveClients: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS); break; + case PauseMode::LinkGraph: SetDParam(0, STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH); break; default: NOT_REACHED(); } str = paused ? STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED : STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED; @@ -407,7 +407,7 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode) */ static void CheckPauseHelper(bool pause, PauseMode pm) { - if (pause == ((_pause_mode & pm) != PM_UNPAUSED)) return; + if (pause == _pause_mode.Test(pm)) return; Command::Post(pm, pause); } @@ -435,12 +435,12 @@ static uint NetworkCountActiveClients() */ static void CheckMinActiveClients() { - if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED || + if (_pause_mode.Test(PauseMode::Error) || !_network_dedicated || - (_settings_client.network.min_active_clients == 0 && (_pause_mode & PM_PAUSED_ACTIVE_CLIENTS) == PM_UNPAUSED)) { + (_settings_client.network.min_active_clients == 0 && !_pause_mode.Test(PauseMode::ActiveClients))) { return; } - CheckPauseHelper(NetworkCountActiveClients() < _settings_client.network.min_active_clients, PM_PAUSED_ACTIVE_CLIENTS); + CheckPauseHelper(NetworkCountActiveClients() < _settings_client.network.min_active_clients, PauseMode::ActiveClients); } /** @@ -461,11 +461,11 @@ static bool NetworkHasJoiningClient() */ static void CheckPauseOnJoin() { - if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED || - (!_settings_client.network.pause_on_join && (_pause_mode & PM_PAUSED_JOIN) == PM_UNPAUSED)) { + if (_pause_mode.Test(PauseMode::Error) || + (!_settings_client.network.pause_on_join && !_pause_mode.Test(PauseMode::Join))) { return; } - CheckPauseHelper(NetworkHasJoiningClient(), PM_PAUSED_JOIN); + CheckPauseHelper(NetworkHasJoiningClient(), PauseMode::Join); } /** @@ -1203,7 +1203,7 @@ void NetworkGameLoop() cp = new CommandPacket(); cp->company = COMPANY_SPECTATOR; cp->cmd = CMD_PAUSE; - cp->data = EndianBufferWriter<>::FromValue(CommandTraits::Args{ PM_PAUSED_NORMAL, true }); + cp->data = EndianBufferWriter<>::FromValue(CommandTraits::Args{ PauseMode::Normal, true }); _ddc_fastforward = false; } else if (strncmp(p, "sync: ", 6) == 0) { uint32_t next_date_raw; diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index e38974a9c1..6e4752406b 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -328,7 +328,7 @@ static void DistributeQueue(CommandQueue &queue, const NetworkClientSocket *owne /* Not technically the most performant way, but consider clients rarely click more than once per tick. */ for (auto cp = queue.begin(); cp != queue.end(); /* removing some items */) { /* Do not distribute commands when paused and the command is not allowed while paused. */ - if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cp->cmd)) { + if (_pause_mode.Any() && !IsCommandAllowedWhilePaused(cp->cmd)) { ++cp; continue; } diff --git a/src/network/network_func.h b/src/network/network_func.h index d1dcd05d6c..df87ff71bc 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -58,7 +58,7 @@ uint NetworkMaxCompaniesAllowed(); bool NetworkMaxCompaniesReached(); void NetworkPrintClients(); std::string_view NetworkGetPublicKeyOfClient(ClientID client_id); -void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode); +void NetworkHandlePauseChange(PauseModes prev_mode, PauseMode changed_mode); void NetworkOnGameStart(); diff --git a/src/openttd.cpp b/src/openttd.cpp index 82943ac624..ce3a9d2784 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -331,7 +331,7 @@ static void LoadIntroGame(bool load_newgrfs = true) } FixTitleGameZoom(); - _pause_mode = PM_UNPAUSED; + _pause_mode = {}; _cursor.fix_at = false; CheckForMissingGlyphs(); @@ -861,7 +861,7 @@ static void MakeNewGameDone() /* In a dedicated server, the server does not play */ if (!VideoDriver::GetInstance()->HasGUI()) { OnStartGame(true); - if (_settings_client.gui.pause_on_newgame) Command::Post(PM_PAUSED_NORMAL, true); + if (_settings_client.gui.pause_on_newgame) Command::Post(PauseMode::Normal, true); return; } @@ -889,7 +889,7 @@ static void MakeNewGameDone() InitializeRailGUI(); InitializeRoadGUI(); - if (_settings_client.gui.pause_on_newgame) Command::Post(PM_PAUSED_NORMAL, true); + if (_settings_client.gui.pause_on_newgame) Command::Post(PauseMode::Normal, true); CheckEngines(); CheckIndustries(); @@ -1107,7 +1107,7 @@ void SwitchToMode(SwitchMode new_mode) } OnStartGame(_network_dedicated); /* Decrease pause counter (was increased from opening load dialog) */ - Command::Post(PM_PAUSED_SAVELOAD, false); + Command::Post(PauseMode::SaveLoad, false); } UpdateSocialIntegration(GM_NORMAL); @@ -1140,7 +1140,7 @@ void SwitchToMode(SwitchMode new_mode) GenerateSavegameId(); _settings_newgame.game_creation.starting_year = TimerGameCalendar::year; /* Cancel the saveload pausing */ - Command::Post(PM_PAUSED_SAVELOAD, false); + Command::Post(PauseMode::SaveLoad, false); } else { ShowErrorMessage(GetSaveLoadErrorType(), GetSaveLoadErrorMessage(), WL_CRITICAL); } @@ -1213,7 +1213,7 @@ void StateGameLoop() } /* Don't execute the state loop during pause or when modal windows are open. */ - if (_pause_mode != PM_UNPAUSED || HasModalProgress()) { + if (_pause_mode.Any() || HasModalProgress()) { PerformanceMeasurer::Paused(PFE_GAMELOOP); PerformanceMeasurer::Paused(PFE_GL_ECONOMY); PerformanceMeasurer::Paused(PFE_GL_TRAINS); @@ -1291,7 +1291,7 @@ static IntervalTimer _autosave_interval({std::chrono::millise { /* We reset the command-during-pause mode here, so we don't continue * to make auto-saves when nothing more is changing. */ - _pause_mode &= ~PM_COMMAND_DURING_PAUSE; + _pause_mode.Reset(PauseMode::CommandDuringPause); _do_autosave = true; SetWindowDirty(WC_STATUS_BAR, 0); @@ -1389,7 +1389,7 @@ void GameLoop() StateGameLoop(); } - if (!_pause_mode && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations(); + if (_pause_mode.None() && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations(); SoundDriver::GetInstance()->MainLoop(); MusicLoop(); diff --git a/src/openttd.h b/src/openttd.h index c38225201c..6e2edb4b00 100644 --- a/src/openttd.h +++ b/src/openttd.h @@ -65,24 +65,20 @@ extern std::atomic _exit_game; extern bool _save_config; /** Modes of pausing we've got */ -enum PauseMode : uint8_t { - PM_UNPAUSED = 0, ///< A normal unpaused game - PM_PAUSED_NORMAL = 1 << 0, ///< A game normally paused - PM_PAUSED_SAVELOAD = 1 << 1, ///< A game paused for saving/loading - PM_PAUSED_JOIN = 1 << 2, ///< A game paused for 'pause_on_join' - PM_PAUSED_ERROR = 1 << 3, ///< A game paused because a (critical) error - PM_PAUSED_ACTIVE_CLIENTS = 1 << 4, ///< A game paused for 'min_active_clients' - PM_PAUSED_GAME_SCRIPT = 1 << 5, ///< A game paused by a game script - PM_PAUSED_LINK_GRAPH = 1 << 6, ///< A game paused due to the link graph schedule lagging - PM_COMMAND_DURING_PAUSE = 1 << 7, ///< A game paused, and a command executed during the pause; resets on autosave - - /** Pause mode bits when paused for network reasons. */ - PMB_PAUSED_NETWORK = PM_PAUSED_ACTIVE_CLIENTS | PM_PAUSED_JOIN, +enum class PauseMode : uint8_t { + Normal = 0, ///< A game normally paused + SaveLoad = 1, ///< A game paused for saving/loading + Join = 2, ///< A game paused for 'pause_on_join' + Error = 3, ///< A game paused because a (critical) error + ActiveClients = 4, ///< A game paused for 'min_active_clients' + GameScript = 5, ///< A game paused by a game script + LinkGraph = 6, ///< A game paused due to the link graph schedule lagging + CommandDuringPause = 7, ///< A game paused, and a command executed during the pause; resets on autosave }; -DECLARE_ENUM_AS_BIT_SET(PauseMode) +using PauseModes = EnumBitSet; /** The current pause mode */ -extern PauseMode _pause_mode; +extern PauseModes _pause_mode; void AskExitGame(); void AskExitToGameMenu(); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index d2ab7e9aa5..63cf1e4150 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -584,8 +584,8 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_98)) _gamelog.GRFAddList(_grfconfig); if (IsSavegameVersionBefore(SLV_119)) { - _pause_mode = (_pause_mode == 2) ? PM_PAUSED_NORMAL : PM_UNPAUSED; - } else if (_network_dedicated && (_pause_mode & PM_PAUSED_ERROR) != 0) { + _pause_mode = (_pause_mode.base() == 2) ? PauseMode::Normal : PauseModes{}; + } else if (_network_dedicated && _pause_mode.Test(PauseMode::Error)) { Debug(net, 0, "The loading savegame was paused due to an error state"); Debug(net, 0, " This savegame cannot be used for multiplayer"); /* Restore the signals */ @@ -599,7 +599,7 @@ bool AfterLoadGame() * active clients. Note that resetting these values for a network * client are very bad because then the client is going to execute * the game loop when the server is not, i.e. it desyncs. */ - _pause_mode &= ~PMB_PAUSED_NETWORK; + _pause_mode.Reset({PauseMode::ActiveClients, PauseMode::Join}); } /* In very old versions, size of train stations was stored differently. @@ -723,7 +723,7 @@ bool AfterLoadGame() switch (gcf_res) { case GLC_COMPATIBLE: ShowErrorMessage(STR_NEWGRF_COMPATIBLE_LOAD_WARNING, INVALID_STRING_ID, WL_CRITICAL); break; - case GLC_NOT_FOUND: ShowErrorMessage(STR_NEWGRF_DISABLED_WARNING, INVALID_STRING_ID, WL_CRITICAL); _pause_mode = PM_PAUSED_ERROR; break; + case GLC_NOT_FOUND: ShowErrorMessage(STR_NEWGRF_DISABLED_WARNING, INVALID_STRING_ID, WL_CRITICAL); _pause_mode = PauseMode::Error; break; default: break; } diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp index 1e9116c51d..6b77904aaa 100644 --- a/src/saveload/oldloader.cpp +++ b/src/saveload/oldloader.cpp @@ -300,7 +300,7 @@ bool LoadOldSaveGame(const std::string &file) return false; } - _pause_mode = PM_PAUSED_SAVELOAD; + _pause_mode = PauseMode::SaveLoad; return true; } diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index b42c338141..0f4160c8b4 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -57,8 +57,8 @@ * needs manual action to continue. */ ShowScriptDebugWindow(ScriptObject::GetRootCompany()); - if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - ScriptObject::Command::Do(PM_PAUSED_NORMAL, true); + if (!_pause_mode.Test(PauseMode::Normal)) { + ScriptObject::Command::Do(PauseMode::Normal, true); } } diff --git a/src/script/api/script_game.cpp b/src/script/api/script_game.cpp index d338837f14..2b9fb4381b 100644 --- a/src/script/api/script_game.cpp +++ b/src/script/api/script_game.cpp @@ -19,17 +19,17 @@ /* static */ bool ScriptGame::Pause() { - return ScriptObject::Command::Do(PM_PAUSED_GAME_SCRIPT, true); + return ScriptObject::Command::Do(PauseMode::GameScript, true); } /* static */ bool ScriptGame::Unpause() { - return ScriptObject::Command::Do(PM_PAUSED_GAME_SCRIPT, false); + return ScriptObject::Command::Do(PauseMode::GameScript, false); } /* static */ bool ScriptGame::IsPaused() { - return !!_pause_mode; + return _pause_mode.Any(); } /* static */ ScriptGame::LandscapeType ScriptGame::GetLandscape() diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index d6c8b6212b..e02403c0fc 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -1081,7 +1081,7 @@ struct ScriptDebugWindow : public Window { } /* If the last AI/Game Script is unpaused, unpause the game too. */ - if ((_pause_mode & PM_PAUSED_NORMAL) == PM_PAUSED_NORMAL) { + if (_pause_mode.Test(PauseMode::Normal)) { bool all_unpaused = !Game::IsPaused(); if (all_unpaused) { for (const Company *c : Company::Iterate()) { @@ -1092,7 +1092,7 @@ struct ScriptDebugWindow : public Window { } if (all_unpaused) { /* All scripts have been unpaused => unpause the game. */ - Command::Post(PM_PAUSED_NORMAL, false); + Command::Post(PauseMode::Normal, false); } } } @@ -1144,8 +1144,8 @@ struct ScriptDebugWindow : public Window { } /* Pause the game. */ - if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - Command::Post(PM_PAUSED_NORMAL, true); + if (!_pause_mode.Test(PauseMode::Normal)) { + Command::Post(PauseMode::Normal, true); } /* Highlight row that matched */ diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 0da5c27794..7ad81b216e 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -142,8 +142,8 @@ struct StatusBarWindow : Window { DrawString(tr, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER | SA_VERT_CENTER); } else if (_do_autosave) { DrawString(tr, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER); - } else if (_pause_mode != PM_UNPAUSED) { - StringID msg = (_pause_mode & PM_PAUSED_LINK_GRAPH) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED; + } else if (_pause_mode.Any()) { + StringID msg = _pause_mode.Test(PauseMode::LinkGraph) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED; DrawString(tr, msg, TC_FROMSTRING, SA_HOR_CENTER); } else if (this->ticker_scroll < TICKER_STOP && GetStatusbarNews() != nullptr && GetStatusbarNews()->string_id != 0) { /* Draw the scrolling news text */ @@ -203,7 +203,7 @@ struct StatusBarWindow : Window { /** Move information on the ticker slowly from one side to the other. */ IntervalTimer ticker_scroll_interval = {std::chrono::milliseconds(15), [this](uint count) { - if (_pause_mode != PM_UNPAUSED) return; + if (_pause_mode.Any()) return; if (this->ticker_scroll < TICKER_STOP) { this->ticker_scroll += count; diff --git a/src/texteff.cpp b/src/texteff.cpp index 012ee24b8f..152ab89181 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -90,7 +90,7 @@ void RemoveTextEffect(TextEffectID te_id) /** Slowly move text effects upwards. */ IntervalTimer move_all_text_effects_interval = {std::chrono::milliseconds(30), [](uint count) { - if (_pause_mode && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return; + if (_pause_mode.Any() && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return; for (TextEffect &te : _text_effects) { if (!te.IsValid()) continue; diff --git a/src/timer/timer_game_realtime.cpp b/src/timer/timer_game_realtime.cpp index 0a9b7a9aa0..6fa76ca46b 100644 --- a/src/timer/timer_game_realtime.cpp +++ b/src/timer/timer_game_realtime.cpp @@ -21,8 +21,8 @@ template <> void IntervalTimer::Elapsed(TimerGameRealtime::TElapsed delta) { if (this->period.period == std::chrono::milliseconds::zero()) return; - if (this->period.flag == TimerGameRealtime::PeriodFlags::AUTOSAVE && _pause_mode != PM_UNPAUSED && (_pause_mode & PM_COMMAND_DURING_PAUSE) == 0) return; - if (this->period.flag == TimerGameRealtime::PeriodFlags::UNPAUSED && _pause_mode != PM_UNPAUSED) return; + if (this->period.flag == TimerGameRealtime::PeriodFlags::AUTOSAVE && _pause_mode.Any() && !_pause_mode.Test(PauseMode::CommandDuringPause)) return; + if (this->period.flag == TimerGameRealtime::PeriodFlags::UNPAUSED && _pause_mode.Any()) return; this->storage.elapsed += delta; @@ -42,8 +42,8 @@ void TimeoutTimer::Elapsed(TimerGameRealtime::TElapsed delta) { if (this->fired) return; if (this->period.period == std::chrono::milliseconds::zero()) return; - if (this->period.flag == TimerGameRealtime::PeriodFlags::AUTOSAVE && _pause_mode != PM_UNPAUSED && (_pause_mode & PM_COMMAND_DURING_PAUSE) == 0) return; - if (this->period.flag == TimerGameRealtime::PeriodFlags::UNPAUSED && _pause_mode != PM_UNPAUSED) return; + if (this->period.flag == TimerGameRealtime::PeriodFlags::AUTOSAVE && _pause_mode.Any() && _pause_mode.Test(PauseMode::CommandDuringPause)) return; + if (this->period.flag == TimerGameRealtime::PeriodFlags::UNPAUSED && _pause_mode.Any()) return; this->storage.elapsed += delta; diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index ca8cf0084b..cc55a0c7ef 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -200,7 +200,7 @@ static CallBackFunction ToolbarPauseClick(Window *) { if (_networking && !_network_server) return CBF_NONE; // only server can pause the game - if (Command::Post(PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED)) { + if (Command::Post(PauseMode::Normal, _pause_mode.None())) { if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); } return CBF_NONE; @@ -2096,7 +2096,7 @@ struct MainToolbarWindow : Window { /** Refresh the state of pause / game-speed on a regular interval.*/ IntervalTimer refresh_interval = {std::chrono::milliseconds(30), [this](auto) { - if (this->IsWidgetLowered(WID_TN_PAUSE) != !!_pause_mode) { + if (this->IsWidgetLowered(WID_TN_PAUSE) != _pause_mode.Any()) { this->ToggleWidgetLoweredState(WID_TN_PAUSE); this->SetWidgetDirty(WID_TN_PAUSE); } @@ -2462,7 +2462,7 @@ struct ScenarioEditorToolbarWindow : Window { /** Refresh the state of pause / game-speed on a regular interval.*/ IntervalTimer refresh_interval = {std::chrono::milliseconds(30), [this](auto) { - if (this->IsWidgetLowered(WID_TE_PAUSE) != !!_pause_mode) { + if (this->IsWidgetLowered(WID_TE_PAUSE) != _pause_mode.Any()) { this->ToggleWidgetLoweredState(WID_TE_PAUSE); this->SetDirty(); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 784c44ba78..1bca2a99ac 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -90,7 +90,7 @@ void CheckTrainsLengths() if (!_networking && first) { first = false; - Command::Post(PM_PAUSED_ERROR, true); + Command::Post(PauseMode::Error, true); } /* Break so we warn only once for each train. */ break; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 4a27f73fc2..8af11d87f8 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -327,7 +327,7 @@ void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRF SetDParamStr(0, grfconfig->GetName()); SetDParam(1, engine); ShowErrorMessage(part1, part2, WL_CRITICAL); - if (!_networking) Command::Do(DoCommandFlag::Execute, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, true); + if (!_networking) Command::Do(DoCommandFlag::Execute, critical ? PauseMode::Error : PauseMode::Normal, true); } /* debug output */ diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index 72731f0113..7d13e0a80f 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -319,7 +319,7 @@ protected: #endif /* DEBUG_DUMP_COMMANDS */ /* If we are paused, run on normal speed. */ - if (_pause_mode) return std::chrono::milliseconds(MILLISECONDS_PER_TICK); + if (_pause_mode.Any()) return std::chrono::milliseconds(MILLISECONDS_PER_TICK); /* Infinite speed, as quickly as you can. */ if (_game_speed == 0) return std::chrono::microseconds(0);