Codechange: Use EnumBitSet for PauseMode. (#13553)

This commit is contained in:
Peter Nelson 2025-02-14 08:30:04 +00:00 committed by GitHub
parent 3518d7e0f1
commit 6cf7a899e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 113 additions and 118 deletions

View File

@ -217,7 +217,7 @@ std::tuple<bool, bool, bool> 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();

View File

@ -813,8 +813,8 @@ DEF_CONSOLE_CMD(ConPauseGame)
return true;
}
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
if (!_pause_mode.Test(PauseMode::Normal)) {
Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, false);
if (_pause_mode.Test(PauseMode::Normal)) {
Command<CMD_PAUSE>::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.");

View File

@ -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<CMD_PAUSE>::Post(PM_PAUSED_SAVELOAD, true);
Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_SAVELOAD, false);
Command<CMD_PAUSE>::Post(PauseMode::SaveLoad, false);
}
this->Window::Close();
}

View File

@ -47,7 +47,7 @@ bool _screen_disable_anim = false; ///< Disable palette animation (important f
std::atomic<bool> _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()

View File

@ -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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
if (!_networking) Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, false); // unpause
if (!_networking) Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
this->game_paused_by_player = _pause_mode == PauseMode::Normal;
if (!_networking && !this->game_paused_by_player) Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, false); // unpause
if (!_networking && !this->game_paused_by_player) Command<CMD_PAUSE>::Post(PauseMode::Normal, false); // unpause
this->EndGameHighScoreBaseWindow::Close();
}

View File

@ -734,7 +734,7 @@ std::tuple<CommandCost, Money> 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

View File

@ -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<CMD_PAUSE>::Post(PM_PAUSED_LINK_GRAPH, false);
Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_LINK_GRAPH, true);
Command<CMD_PAUSE>::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);
}
}

View File

@ -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};

View File

@ -152,7 +152,7 @@ CommandCost CmdSetCompanyMaxLoan(DoCommandFlags flags, CompanyID company, Money
static void AskUnsafeUnpauseCallback(Window *, bool confirmed)
{
if (confirmed) {
Command<CMD_PAUSE>::Post(PM_PAUSED_ERROR, false);
Command<CMD_PAUSE>::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 = {};
}
}

View File

@ -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,

View File

@ -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<CMD_PAUSE>::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<CMD_PAUSE>::Args{ PM_PAUSED_NORMAL, true });
cp->data = EndianBufferWriter<>::FromValue(CommandTraits<CMD_PAUSE>::Args{ PauseMode::Normal, true });
_ddc_fastforward = false;
} else if (strncmp(p, "sync: ", 6) == 0) {
uint32_t next_date_raw;

View File

@ -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;
}

View File

@ -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();

View File

@ -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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(PauseMode::Normal, true);
return;
}
@ -889,7 +889,7 @@ static void MakeNewGameDone()
InitializeRailGUI();
InitializeRoadGUI();
if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_SAVELOAD, false);
Command<CMD_PAUSE>::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<CMD_PAUSE>::Post(PM_PAUSED_SAVELOAD, false);
Command<CMD_PAUSE>::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<TimerGameRealtime> _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();

View File

@ -65,24 +65,20 @@ extern std::atomic<bool> _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<PauseMode, uint8_t>;
/** The current pause mode */
extern PauseMode _pause_mode;
extern PauseModes _pause_mode;
void AskExitGame();
void AskExitToGameMenu();

View File

@ -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;
}

View File

@ -300,7 +300,7 @@ bool LoadOldSaveGame(const std::string &file)
return false;
}
_pause_mode = PM_PAUSED_SAVELOAD;
_pause_mode = PauseMode::SaveLoad;
return true;
}

View File

@ -57,8 +57,8 @@
* needs manual action to continue. */
ShowScriptDebugWindow(ScriptObject::GetRootCompany());
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_NORMAL, true);
if (!_pause_mode.Test(PauseMode::Normal)) {
ScriptObject::Command<CMD_PAUSE>::Do(PauseMode::Normal, true);
}
}

View File

@ -19,17 +19,17 @@
/* static */ bool ScriptGame::Pause()
{
return ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_GAME_SCRIPT, true);
return ScriptObject::Command<CMD_PAUSE>::Do(PauseMode::GameScript, true);
}
/* static */ bool ScriptGame::Unpause()
{
return ScriptObject::Command<CMD_PAUSE>::Do(PM_PAUSED_GAME_SCRIPT, false);
return ScriptObject::Command<CMD_PAUSE>::Do(PauseMode::GameScript, false);
}
/* static */ bool ScriptGame::IsPaused()
{
return !!_pause_mode;
return _pause_mode.Any();
}
/* static */ ScriptGame::LandscapeType ScriptGame::GetLandscape()

View File

@ -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<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, false);
Command<CMD_PAUSE>::Post(PauseMode::Normal, false);
}
}
}
@ -1144,8 +1144,8 @@ struct ScriptDebugWindow : public Window {
}
/* Pause the game. */
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
if (!_pause_mode.Test(PauseMode::Normal)) {
Command<CMD_PAUSE>::Post(PauseMode::Normal, true);
}
/* Highlight row that matched */

View File

@ -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<TimerWindow> 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;

View File

@ -90,7 +90,7 @@ void RemoveTextEffect(TextEffectID te_id)
/** Slowly move text effects upwards. */
IntervalTimer<TimerWindow> 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;

View File

@ -21,8 +21,8 @@ template <>
void IntervalTimer<TimerGameRealtime>::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<TimerGameRealtime>::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;

View File

@ -200,7 +200,7 @@ static CallBackFunction ToolbarPauseClick(Window *)
{
if (_networking && !_network_server) return CBF_NONE; // only server can pause the game
if (Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED)) {
if (Command<CMD_PAUSE>::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<TimerWindow> 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<TimerWindow> 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();
}

View File

@ -90,7 +90,7 @@ void CheckTrainsLengths()
if (!_networking && first) {
first = false;
Command<CMD_PAUSE>::Post(PM_PAUSED_ERROR, true);
Command<CMD_PAUSE>::Post(PauseMode::Error, true);
}
/* Break so we warn only once for each train. */
break;

View File

@ -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<CMD_PAUSE>::Do(DoCommandFlag::Execute, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, true);
if (!_networking) Command<CMD_PAUSE>::Do(DoCommandFlag::Execute, critical ? PauseMode::Error : PauseMode::Normal, true);
}
/* debug output */

View File

@ -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);