changeset 11852:862dd1024fe7 draft

(svn r16242) -Codechange: rework pausing -Fix [FS#2864]: autopause and manual pausing conflict with eachother -Fix: new game + pause on new game + autopause make the game not unpause on the first join
author rubidium <rubidium@openttd.org>
date Wed, 06 May 2009 15:06:57 +0000
parents 78901cd3230f
children 90d709675eec
files src/console_cmds.cpp src/genworld.cpp src/gfx.cpp src/graph_gui.cpp src/group_gui.cpp src/highscore_gui.cpp src/industry_gui.cpp src/misc.cpp src/misc_cmd.cpp src/misc_gui.cpp src/network/network.cpp src/network/network_server.cpp src/openttd.cpp src/openttd.h src/saveload/afterload.cpp src/saveload/misc_sl.cpp src/saveload/oldloader.cpp src/saveload/saveload.cpp src/station_gui.cpp src/statusbar_gui.cpp src/toolbar_gui.cpp src/train_cmd.cpp src/vehicle.cpp src/vehicle_gui.cpp src/video/allegro_v.cpp src/video/cocoa/event.mm src/video/sdl_v.cpp src/video/win32_v.cpp src/window.cpp
diffstat 29 files changed, 110 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -472,8 +472,15 @@
 		return true;
 	}
 
-	if (_pause_game == 0) {
-		DoCommandP(0, 1, 0, CMD_PAUSE);
+#ifdef ENABLE_NETWORK
+	if (_network_dedicated && _settings_client.network.min_active_clients != 0) {
+		IConsolePrint(CC_WARNING, "Manual pausing is disabled. Set network.min_active_clients to 0 (disable autopausing) to enable manual pausing.");
+		return true;
+	}
+#endif /* ENABLE_NETWORK */
+
+	if (_pause_mode == PM_UNPAUSED) {
+		DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 		IConsolePrint(CC_DEFAULT, "Game paused.");
 	} else {
 		IConsolePrint(CC_DEFAULT, "Game is already paused.");
@@ -489,8 +496,15 @@
 		return true;
 	}
 
-	if (_pause_game != 0) {
-		DoCommandP(0, 0, 0, CMD_PAUSE);
+#ifdef ENABLE_NETWORK
+	if (_network_dedicated && _settings_client.network.min_active_clients != 0) {
+		IConsolePrint(CC_WARNING, "Manual unpausing is disabled. Set network.min_active_clients to 0 (disable autopausing) to enable manual unpausing.");
+		return true;
+	}
+#endif /* ENABLE_NETWORK */
+
+	if (_pause_mode != PM_UNPAUSED) {
+		DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE);
 		IConsolePrint(CC_DEFAULT, "Game unpaused.");
 	} else {
 		IConsolePrint(CC_DEFAULT, "Game is already unpaused.");
--- a/src/genworld.cpp
+++ b/src/genworld.cpp
@@ -166,7 +166,7 @@
 		if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
 		DEBUG(desync, 1, "new_map: %i\n", _settings_game.game_creation.generation_seed);
 
-		if (_settings_client.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, CMD_PAUSE);
+		if (_settings_client.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 		if (_debug_desync_level > 0) {
 			char name[MAX_PATH];
 			snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -40,7 +40,7 @@
 bool _exit_game;
 GameMode _game_mode;
 SwitchMode _switch_mode;  ///< The next mainloop command.
-int8 _pause_game;
+PauseModeByte _pause_mode;
 int _pal_first_dirty;
 int _pal_count_dirty;
 
--- a/src/graph_gui.cpp
+++ b/src/graph_gui.cpp
@@ -1182,7 +1182,7 @@
 
 	virtual void OnTick()
 	{
-		if (_pause_game != 0) return;
+		if (_pause_mode != PM_UNPAUSED) return;
 
 		/* Update the company score every 5 days */
 		if (--this->timeout == 0) {
--- a/src/group_gui.cpp
+++ b/src/group_gui.cpp
@@ -724,7 +724,7 @@
 
 	virtual void OnTick()
 	{
-		if (_pause_game != 0) return;
+		if (_pause_mode != PM_UNPAUSED) return;
 		if (this->groups.NeedResort() || this->vehicles.NeedResort()) {
 			this->SetDirty();
 		}
--- a/src/highscore_gui.cpp
+++ b/src/highscore_gui.cpp
@@ -54,7 +54,7 @@
 	EndGameWindow(const WindowDesc *desc) : EndGameHighScoreBaseWindow(desc)
 	{
 		/* Pause in single-player to have a look at the highscore at your own leisure */
-		if (!_networking) DoCommandP(0, 1, 0, CMD_PAUSE);
+		if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 
 		this->background_img = SPR_TYCOON_IMG1_BEGIN;
 
@@ -82,7 +82,7 @@
 
 	~EndGameWindow()
 	{
-		if (!_networking) DoCommandP(0, 0, 0, CMD_PAUSE); // unpause
+		if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause
 		ShowHighscoreTable(this->window_number, this->rank);
 	}
 
@@ -115,7 +115,7 @@
 	HighScoreWindow(const WindowDesc *desc, int difficulty, int8 ranking) : EndGameHighScoreBaseWindow(desc)
 	{
 		/* pause game to show the chart */
-		if (!_networking) DoCommandP(0, 1, 0, CMD_PAUSE);
+		if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 
 		/* Close all always on-top windows to get a clean screen */
 		if (_game_mode != GM_MENU) HideVitalWindows();
@@ -130,7 +130,7 @@
 	{
 		if (_game_mode != GM_MENU) ShowVitalWindows();
 
-		if (!_networking) DoCommandP(0, 0, 0, CMD_PAUSE); // unpause
+		if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause
 	}
 
 	virtual void OnPaint()
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -395,7 +395,7 @@
 
 	virtual void OnTick()
 	{
-		if (_pause_game != 0) return;
+		if (_pause_mode != PM_UNPAUSED) return;
 		if (!this->timer_enabled) return;
 		if (--this->callback_timer == 0) {
 			/* We have just passed another day.
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -61,7 +61,7 @@
 
 	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
 
-	_pause_game = 0;
+	_pause_mode = PM_UNPAUSED;
 	_fast_forward = 0;
 	_tick_counter = 0;
 	_realtime_tick = 0;
--- a/src/misc_cmd.cpp
+++ b/src/misc_cmd.cpp
@@ -308,7 +308,7 @@
  */
 static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
 {
-	DoCommandP(0, confirmed ? 0 : 1, 0, CMD_PAUSE);
+	DoCommandP(0, PM_PAUSED_ERROR, confirmed ? 0 : 1, CMD_PAUSE);
 }
 
 /** Pause/Unpause the game (server-only).
@@ -317,29 +317,34 @@
  * to have more control over the game when saving/loading, etc.
  * @param tile unused
  * @param flags operation to perform
- * @param p1 0 = decrease pause counter; 1 = increase pause counter
- * @param p2 unused
+ * @param p1 the pause mode to change
+ * @param p2 1 pauses, 0 unpauses this mode
  */
 CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 {
-	if (flags & DC_EXEC) {
-		_pause_game += (p1 == 0) ? -1 : 1;
+	switch (p1) {
+		case PM_PAUSED_SAVELOAD:
+		case PM_PAUSED_ERROR:
+		case PM_PAUSED_JOIN:
+		case PM_PAUSED_NORMAL:
+			break;
 
-		switch (_pause_game) {
-			case -4:
-			case -1:
-				_pause_game = 0;
-				break;
-			case -3:
-				ShowQuery(
-					STR_NEWGRF_UNPAUSE_WARNING_TITLE,
-					STR_NEWGRF_UNPAUSE_WARNING,
-					NULL,
-					AskUnsafeUnpauseCallback
-				);
-				break;
-
-			default: break;
+		default: return CMD_ERROR;
+	}
+	if (flags & DC_EXEC) {
+		if (p1 == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) {
+			ShowQuery(
+				STR_NEWGRF_UNPAUSE_WARNING_TITLE,
+				STR_NEWGRF_UNPAUSE_WARNING,
+				NULL,
+				AskUnsafeUnpauseCallback
+			);
+		} else {
+			if (p2 == 0) {
+				_pause_mode = _pause_mode & ~p1;
+			} else {
+				_pause_mode = _pause_mode | p1;
+			}
 		}
 
 		InvalidateWindow(WC_STATUS_BAR, 0);
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -1644,7 +1644,7 @@
 		/* 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) {
-			if (_pause_game >= 0) DoCommandP(0, 1, 0, CMD_PAUSE);
+			DoCommandP(0, PM_PAUSED_SAVELOAD, 1, CMD_PAUSE);
 		}
 
 		BuildFileList();
@@ -1683,7 +1683,7 @@
 	{
 		/* pause is only used in single-player, non-editor mode, non menu mode */
 		if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
-			if (_pause_game >= 0) DoCommandP(0, 0, 0, CMD_PAUSE);
+			DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
 		}
 		FiosFreeSavegameList();
 	}
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -345,24 +345,20 @@
 	return count;
 }
 
-static bool _min_active_clients_paused = false;
-
 /* Check if the minimum number of active clients has been reached and pause or unpause the game as appropriate */
 static void CheckMinActiveClients()
 {
-	if (!_network_dedicated) return;
+	if (!_network_dedicated || _settings_client.network.min_active_clients == 0) return;
 
 	if (NetworkCountActiveClients() < _settings_client.network.min_active_clients) {
-		if (_min_active_clients_paused) return;
+		if ((_pause_mode & PM_PAUSED_NORMAL) != 0) return;
 
-		_min_active_clients_paused = true;
-		DoCommandP(0, 1, 0, CMD_PAUSE);
+		DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 		NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "", CLIENT_ID_SERVER, NETWORK_SERVER_MESSAGE_GAME_PAUSED_PLAYERS);
 	} else {
-		if (!_min_active_clients_paused) return;
+		if (_pause_mode == PM_UNPAUSED) return;
 
-		_min_active_clients_paused = false;
-		DoCommandP(0, 0, 0, CMD_PAUSE);
+		DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE);
 		NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "", CLIENT_ID_SERVER, NETWORK_SERVER_MESSAGE_GAME_UNPAUSED_PLAYERS);
 	}
 }
@@ -464,8 +460,8 @@
 	}
 
 	/* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
-	if (cs->status == STATUS_PRE_ACTIVE && _settings_client.network.pause_on_join) {
-		DoCommandP(0, 0, 0, CMD_PAUSE);
+	if (cs->status == STATUS_PRE_ACTIVE && _pause_mode & PM_PAUSED_JOIN) {
+		DoCommandP(0, PM_PAUSED_JOIN, 0, CMD_PAUSE);
 		NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "", CLIENT_ID_SERVER, NETWORK_SERVER_MESSAGE_GAME_UNPAUSED_CONNECT_FAIL);
 	}
 
@@ -794,8 +790,6 @@
 	/* if the server is dedicated ... add some other script */
 	if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
 
-	_min_active_clients_paused = false;
-
 	/* Try to register us to the master server */
 	_network_last_advertise_frame = 0;
 	_network_need_advertise = true;
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -23,6 +23,7 @@
 #include "../company_gui.h"
 #include "../settings_type.h"
 #include "../window_func.h"
+#include "../openttd.h"
 
 #include "table/strings.h"
 
@@ -820,7 +821,7 @@
 
 		if (_settings_client.network.pause_on_join) {
 			/* Now pause the game till the client is in sync */
-			DoCommandP(0, 1, 0, CMD_PAUSE);
+			DoCommandP(0, PM_PAUSED_JOIN, 1, CMD_PAUSE);
 
 			NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "", CLIENT_ID_SERVER, NETWORK_SERVER_MESSAGE_GAME_PAUSED_CONNECT);
 		}
@@ -1013,8 +1014,8 @@
 		/* Now he is! Unpause the game */
 		cs->status = STATUS_ACTIVE;
 
-		if (_settings_client.network.pause_on_join) {
-			DoCommandP(0, 0, 0, CMD_PAUSE);
+		if (_pause_mode & PM_PAUSED_JOIN) {
+			DoCommandP(0, PM_PAUSED_JOIN, 0, CMD_PAUSE);
 			NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "", CLIENT_ID_SERVER, NETWORK_SERVER_MESSAGE_GAME_UNPAUSED_CONNECT);
 		}
 
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -352,7 +352,7 @@
 		SetLocalCompany(COMPANY_FIRST);
 	}
 
-	_pause_game = 0;
+	_pause_mode = PM_UNPAUSED;
 	_cursor.fix_at = false;
 
 	CheckForMissingGlyphsInLoadedLanguagePack();
@@ -961,7 +961,7 @@
 				/* Execute the game-start script */
 				IConsoleCmdExec("exec scripts/game_start.scr 0");
 				/* Decrease pause counter (was increased from opening load dialog) */
-				DoCommandP(0, 0, 0, CMD_PAUSE);
+				DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
 #ifdef ENABLE_NETWORK
 				if (_network_server) {
 					snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
@@ -1004,14 +1004,12 @@
 
 		case SM_SAVE: // Save game
 			/* Make network saved games on pause compatible to singleplayer */
-			if (_networking && _pause_game == 1) _pause_game = 2;
 			if (SaveOrLoad(_file_to_saveload.name, SL_SAVE, NO_DIRECTORY) != SL_OK) {
 				SetDParamStr(0, GetSaveLoadErrorString());
 				ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0);
 			} else {
 				DeleteWindowById(WC_SAVELOAD, 0);
 			}
-			if (_networking && _pause_game == 2) _pause_game = 1;
 			break;
 
 		case SM_GENRANDLAND: // Generate random land within scenario editor
@@ -1038,7 +1036,7 @@
 void StateGameLoop()
 {
 	/* dont execute the state loop during pause */
-	if (_pause_game) {
+	if (_pause_mode != PM_UNPAUSED) {
 		CallWindowTickEvent();
 		return;
 	}
@@ -1201,9 +1199,9 @@
 	StateGameLoop();
 #endif /* ENABLE_NETWORK */
 
-	if (!_pause_game && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations();
+	if (!_pause_mode && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations();
 
-	if (!_pause_game || _cheats.build_in_pause.value) MoveAllTextEffects();
+	if (!_pause_mode || _cheats.build_in_pause.value) MoveAllTextEffects();
 
 	InputLoop();
 
--- a/src/openttd.h
+++ b/src/openttd.h
@@ -5,6 +5,8 @@
 #ifndef OPENTTD_H
 #define OPENTTD_H
 
+#include "core/enum_type.hpp"
+
 enum GameMode {
 	GM_MENU,
 	GM_NORMAL,
@@ -38,6 +40,19 @@
 extern GameMode _game_mode;
 extern SwitchMode _switch_mode;
 extern bool _exit_game;
-extern int8 _pause_game;
+
+/** Modes of pausing we've got */
+enum PauseMode {
+	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
+};
+DECLARE_ENUM_AS_BIT_SET(PauseMode);
+typedef SimpleTinyEnumT<PauseMode, byte> PauseModeByte;
+
+/** The current pause mode */
+extern PauseModeByte _pause_mode;
 
 #endif /* OPENTTD_H */
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -336,6 +336,10 @@
 
 	if (CheckSavegameVersion(98)) GamelogGRFAddList(_grfconfig);
 
+	if (CheckSavegameVersion(119)) {
+		_pause_mode = (_pause_mode == 2) ? PM_PAUSED_NORMAL : PM_UNPAUSED;
+	}
+
 	/* in very old versions, size of train stations was stored differently */
 	if (CheckSavegameVersion(2)) {
 		Station *st;
@@ -440,7 +444,7 @@
 
 	switch (gcf_res) {
 		case GLC_COMPATIBLE: _switch_mode_errorstr = STR_NEWGRF_COMPATIBLE_LOAD_WARNING; break;
-		case GLC_NOT_FOUND: _switch_mode_errorstr = STR_NEWGRF_DISABLED_WARNING; _pause_game = -1; break;
+		case GLC_NOT_FOUND:  _switch_mode_errorstr = STR_NEWGRF_DISABLED_WARNING; _pause_mode = PM_PAUSED_ERROR; break;
 		default: break;
 	}
 
--- a/src/saveload/misc_sl.cpp
+++ b/src/saveload/misc_sl.cpp
@@ -74,7 +74,7 @@
 	SLEG_CONDVAR(_next_competitor_start,  SLE_FILE_U16 | SLE_VAR_U32,  0, 108),
 	SLEG_CONDVAR(_next_competitor_start,  SLE_UINT32,                109, SL_MAX_VERSION),
 	    SLEG_VAR(_trees_tick_ctr,         SLE_UINT8),
-	SLEG_CONDVAR(_pause_game,             SLE_UINT8,                   4, SL_MAX_VERSION),
+	SLEG_CONDVAR(_pause_mode,             SLE_UINT8,                   4, SL_MAX_VERSION),
 	SLEG_CONDVAR(_cur_town_iter,          SLE_UINT32,                 11, SL_MAX_VERSION),
 	    SLEG_END()
 };
--- a/src/saveload/oldloader.cpp
+++ b/src/saveload/oldloader.cpp
@@ -302,7 +302,7 @@
 		return false;
 	}
 
-	_pause_game = 2;
+	_pause_mode = 2;
 
 	return true;
 }
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -40,7 +40,7 @@
 
 #include "saveload_internal.h"
 
-extern const uint16 SAVEGAME_VERSION = 118;
+extern const uint16 SAVEGAME_VERSION = 119;
 
 SavegameType _savegame_type; ///< type of savegame we are loading
 
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -549,7 +549,7 @@
 
 	virtual void OnTick()
 	{
-		if (_pause_game != 0) return;
+		if (_pause_mode != PM_UNPAUSED) return;
 		if (this->stations.NeedResort()) {
 			DEBUG(misc, 3, "Periodic rebuild station list company %d", this->window_number);
 			this->SetDirty();
--- a/src/statusbar_gui.cpp
+++ b/src/statusbar_gui.cpp
@@ -97,7 +97,7 @@
 
 		this->DrawWidgets();
 		SetDParam(0, _date);
-		DrawString(this->widget[SBW_LEFT].left + 1, this->widget[SBW_LEFT].right - 1, 1, (_pause_game || _settings_client.gui.status_long_date) ? STR_DATE_LONG_WHITE : STR_DATE_SHORT_WHITE, TC_FROMSTRING, SA_CENTER);
+		DrawString(this->widget[SBW_LEFT].left + 1, this->widget[SBW_LEFT].right - 1, 1, (_pause_mode || _settings_client.gui.status_long_date) ? STR_DATE_LONG_WHITE : STR_DATE_SHORT_WHITE, TC_FROMSTRING, SA_CENTER);
 
 		if (c != NULL) {
 			/* Draw company money */
@@ -110,7 +110,7 @@
 			DrawString(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_CENTER);
 		} else if (_do_autosave) {
 			DrawString(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_CENTER);
-		} else if (_pause_game) {
+		} else if (_pause_mode != PM_UNPAUSED) {
 			DrawString(this->widget[SBW_MIDDLE].left + 1, this->widget[SBW_MIDDLE].right - 1, 1, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_CENTER);
 		} else if (this->ticker_scroll > TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item.string_id != 0) {
 			/* Draw the scrolling news text */
@@ -159,7 +159,7 @@
 
 	virtual void OnTick()
 	{
-		if (_pause_game) return;
+		if (_pause_mode != PM_UNPAUSED) return;
 
 		if (this->ticker_scroll > TICKER_STOP) { // Scrolling text
 			this->ticker_scroll -= COUNTER_STEP;
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -249,7 +249,7 @@
 {
 	if (_networking && !_network_server) return; // only server can pause the game
 
-	if (DoCommandP(0, _pause_game ? 0 : 1, 0, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
+	if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) SndPlayFx(SND_15_BEEP);
 }
 
 /* --- Fast forwarding --- */
@@ -1106,7 +1106,7 @@
 
 	virtual void OnTick()
 	{
-		if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_game) {
+		if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_mode) {
 			this->ToggleWidgetLoweredState(TBN_PAUSE);
 			this->InvalidateWidget(TBN_PAUSE);
 		}
@@ -1379,7 +1379,7 @@
 
 	virtual void OnTick()
 	{
-		if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_game) {
+		if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_mode) {
 			this->ToggleWidgetLoweredState(TBSE_PAUSE);
 			this->SetDirty();
 		}
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -198,7 +198,7 @@
 						SetDParam(1, v->owner);
 						ShowErrorMessage(INVALID_STRING_ID, STR_BROKEN_VEHICLE_LENGTH, 0, 0);
 
-						if (!_networking) _pause_game = -1;
+						if (!_networking) DoCommandP(0, PM_PAUSED_ERROR, 1, CMD_PAUSE);
 					}
 				}
 			}
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -121,7 +121,7 @@
 		SetDParamStr(0, grfconfig->name);
 		SetDParam(1, engine);
 		ShowErrorMessage(part2, part1, 0, 0);
-		if (!_networking) _pause_game = (critical ? -1 : 1);
+		if (!_networking) DoCommandP(0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1, CMD_PAUSE);
 	}
 
 	/* debug output */
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -1171,7 +1171,7 @@
 
 	virtual void OnTick()
 	{
-		if (_pause_game != 0) return;
+		if (_pause_mode != PM_UNPAUSED) return;
 		if (this->vehicles.NeedResort()) {
 			StationID station = ((this->window_number & VLW_MASK) == VLW_STATION_LIST) ? GB(this->window_number, 16, 16) : INVALID_STATION;
 
--- a/src/video/allegro_v.cpp
+++ b/src/video/allegro_v.cpp
@@ -483,7 +483,7 @@
 		}
 
 		cur_ticks = GetTime();
-		if (cur_ticks >= next_tick || (_fast_forward && !_pause_game) || cur_ticks < prev_cur_ticks) {
+		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 			_realtime_tick += cur_ticks - last_cur_ticks;
 			last_cur_ticks = cur_ticks;
 			next_tick = cur_ticks + 30;
--- a/src/video/cocoa/event.mm
+++ b/src/video/cocoa/event.mm
@@ -664,7 +664,7 @@
 		}
 
 		cur_ticks = GetTick();
-		if (cur_ticks >= next_tick || (_fast_forward && !_pause_game) || cur_ticks < prev_cur_ticks) {
+		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 			_realtime_tick += cur_ticks - last_cur_ticks;
 			last_cur_ticks = cur_ticks;
 			next_tick = cur_ticks + 30;
--- a/src/video/sdl_v.cpp
+++ b/src/video/sdl_v.cpp
@@ -476,7 +476,7 @@
 		}
 
 		cur_ticks = SDL_CALL SDL_GetTicks();
-		if (cur_ticks >= next_tick || (_fast_forward && !_pause_game) || cur_ticks < prev_cur_ticks) {
+		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 			_realtime_tick += cur_ticks - last_cur_ticks;
 			last_cur_ticks = cur_ticks;
 			next_tick = cur_ticks + 30;
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -848,7 +848,7 @@
 		}
 
 		cur_ticks = GetTickCount();
-		if (cur_ticks >= next_tick || (_fast_forward && !_pause_game) || cur_ticks < prev_cur_ticks) {
+		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
 			_realtime_tick += cur_ticks - last_cur_ticks;
 			last_cur_ticks = cur_ticks;
 			next_tick = cur_ticks + 30;
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1979,7 +1979,7 @@
 						/* query button and place sign button work in pause mode */
 						_cursor.sprite != SPR_CURSOR_QUERY &&
 						_cursor.sprite != SPR_CURSOR_SIGN &&
-						_pause_game != 0 &&
+						_pause_mode != PM_UNPAUSED &&
 						!_cheats.build_in_pause.value) {
 					return;
 				}