From 952468713f8b01fea1f0ead21ef66f4ab93a32f0 Mon Sep 17 00:00:00 2001
From: jsalmon3 <>
Date: Fri, 14 Feb 2003 02:04:07 +0000
Subject: [PATCH] Implemented feature request #631875: No MP menu pause

---
 doc/ChangeLog.html         |   2 +
 src/include/video.h        |   4 +
 src/stratagus/mainloop.cpp |  33 +++---
 src/ui/interface.cpp       | 123 +++++++++-------------
 src/ui/menu_proc.cpp       | 109 +++++++++++++++-----
 src/ui/menus.cpp           | 202 ++++++++++++++++++++++---------------
 src/ui/mouse.cpp           |   9 +-
 7 files changed, 286 insertions(+), 196 deletions(-)

diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html
index 03508be99..50ed9318a 100644
--- a/doc/ChangeLog.html
+++ b/doc/ChangeLog.html
@@ -1069,6 +1069,8 @@
 	Russell Smith).
     <LI>Fixed bug #685087: middle mouse button doesn't work in editor (from
 	Jimmy Salmon).
+    <LI>Implemented feature request #631875: No MP menu pause (from
+	Jimmy Salmon).
     <LI>+++
     </UL>
 </UL>
diff --git a/src/include/video.h b/src/include/video.h
index def4810ad..4ac797751 100644
--- a/src/include/video.h
+++ b/src/include/video.h
@@ -380,6 +380,10 @@ typedef struct _event_callback_ {
 --	Variables
 ----------------------------------------------------------------------------*/
 
+EventCallback* Callbacks;		/// Current callbacks
+EventCallback GameCallbacks;		/// Game callbacks
+EventCallback MenuCallbacks;		/// Menu callbacks
+
 extern PaletteLink* PaletteList;	/// List of all used palettes loaded
 extern int ColorCycleAll;		/// Flag color cycle palettes
 #ifdef DEBUG
diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp
index b89e5631e..afa67b569 100644
--- a/src/stratagus/mainloop.cpp
+++ b/src/stratagus/mainloop.cpp
@@ -83,6 +83,10 @@ global enum _scroll_state_ MouseScrollState=ScrollNone;
 global jmp_buf MainLoopJmpBuf;		/// Hierarchic pathfinder error exit.
 #endif
 
+EventCallback* Callbacks;		/// Current callbacks
+EventCallback GameCallbacks;		/// Game callbacks
+EventCallback MenuCallbacks;		/// Menu callbacks
+
 //----------------------------------------------------------------------------
 //	Functions
 //----------------------------------------------------------------------------
@@ -605,24 +609,23 @@ local void EnableDrawRefresh(void)
 */
 global void GameMainLoop(void)
 {
-    EventCallback callbacks;
 #ifdef DEBUG	// removes the setjmp warnings
     static int showtip;
 #else
     int showtip;
 #endif
 
-    callbacks.ButtonPressed=(void*)HandleButtonDown;
-    callbacks.ButtonReleased=(void*)HandleButtonUp;
-    callbacks.MouseMoved=(void*)HandleMouseMove;
-    callbacks.MouseExit=(void*)HandleMouseExit;
+    GameCallbacks.ButtonPressed=(void*)HandleButtonDown;
+    GameCallbacks.ButtonReleased=(void*)HandleButtonUp;
+    GameCallbacks.MouseMoved=(void*)HandleMouseMove;
+    GameCallbacks.MouseExit=(void*)HandleMouseExit;
+    GameCallbacks.KeyPressed=HandleKeyDown;
+    GameCallbacks.KeyReleased=HandleKeyUp;
+    GameCallbacks.KeyRepeated=HandleKeyRepeat;
+    GameCallbacks.NetworkEvent=NetworkEvent;
+    GameCallbacks.SoundReady=WriteSound;
 
-    callbacks.KeyPressed=HandleKeyDown;
-    callbacks.KeyReleased=HandleKeyUp;
-    callbacks.KeyRepeated=HandleKeyRepeat;
-
-    callbacks.NetworkEvent=NetworkEvent;
-    callbacks.SoundReady=WriteSound;
+    Callbacks=&GameCallbacks;
 
     SetVideoSync();
     EnableDrawRefresh();
@@ -751,6 +754,10 @@ global void GameMainLoop(void)
 #endif
 
 	if( MustRedraw /* && !VideoInterrupts */ ) {
+	    if( Callbacks==&MenuCallbacks ) {
+		MustRedraw|=RedrawMenu;
+	    }
+
 	    //For debuggin only: replace UpdateDisplay by DebugTestDisplay when
 	    //			 debugging linedraw routines..
 	    //FIXME: this might be better placed somewhere at front of the
@@ -772,13 +779,13 @@ global void GameMainLoop(void)
 
 	CheckVideoInterrupts();		// look if already an interrupt
 
-	WaitEventsOneFrame(&callbacks);
+	WaitEventsOneFrame(Callbacks);
 	if( !NetworkInSync ) {
 	    NetworkRecover();		// recover network
 	}
 
 	if( showtip ) {
-	    ProcessMenu("menu-tips", 1);
+	    ProcessMenu("menu-tips",1);
 	    InterfaceState = IfaceStateNormal;
 	    showtip=0;
 	}
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 40e4e4ee9..a7fc041b7 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -316,7 +316,7 @@ local void UiToggleMusic(void)
 global void UiTogglePause(void)
 {
     GamePaused^=1;
-    if(GamePaused) {
+    if( GamePaused ) {
 	SetStatusLine("Game Paused");
     } else {
 	SetStatusLine("Game Resumed");
@@ -328,9 +328,11 @@ global void UiTogglePause(void)
 */
 local void UiEnterMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
-    ProcessMenu("menu-game", 1);
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
+    ProcessMenu("menu-game", 0);
 }
 
 /**
@@ -338,13 +340,11 @@ local void UiEnterMenu(void)
 */
 local void UiEnterHelpMenu(void)
 {
-    GamePaused=1;
-    ProcessMenu("menu-help", 1);
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
+    ProcessMenu("menu-help", 0);
 }
 
 /**
@@ -352,14 +352,11 @@ local void UiEnterHelpMenu(void)
 */
 local void UiEnterOptionsMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
-    ProcessMenu("menu-game-options", 1);
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
+    ProcessMenu("menu-game-options", 0);
 }
 
 /**
@@ -367,14 +364,11 @@ local void UiEnterOptionsMenu(void)
 */
 local void UiEnterSoundOptionsMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     SoundOptionsMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -382,14 +376,11 @@ local void UiEnterSoundOptionsMenu(void)
 */
 local void UiEnterSpeedOptionsMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     SpeedOptionsMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -397,14 +388,11 @@ local void UiEnterSpeedOptionsMenu(void)
 */
 local void UiEnterPreferencesOptionsMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     PreferencesMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -417,14 +405,11 @@ local void UiEnterSaveGameMenu(void)
 	return;
     }
 
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     SaveGameMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -437,14 +422,11 @@ local void UiEnterLoadGameMenu(void)
 	return;
     }
 
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     LoadGameMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -452,14 +434,11 @@ local void UiEnterLoadGameMenu(void)
 */
 local void UiExitConfirmMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     ExitConfirmMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -467,14 +446,11 @@ local void UiExitConfirmMenu(void)
 */
 local void UiQuitToMenuConfirmMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     QuitToMenuConfirmMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
@@ -482,14 +458,11 @@ local void UiQuitToMenuConfirmMenu(void)
 */
 local void UiRestartConfirmMenu(void)
 {
-    GamePaused=1;
-    SetStatusLine("Game Paused");
+    if( NetworkFildes==-1 ) {
+	GamePaused=1;
+	SetStatusLine("Game Paused");
+    }
     RestartConfirmMenu();
-    InterfaceState=IfaceStateNormal;
-    ClearStatusLine();
-    MarkDrawEntireMap();
-    MustRedraw=RedrawEverything;
-    GamePaused=0;
 }
 
 /**
diff --git a/src/ui/menu_proc.cpp b/src/ui/menu_proc.cpp
index fa946ecb0..a065f0648 100644
--- a/src/ui/menu_proc.cpp
+++ b/src/ui/menu_proc.cpp
@@ -74,8 +74,6 @@
 --	Variables
 ----------------------------------------------------------------------------*/
 
-local EventCallback callbacks;
-
 /**
 **	Menu button graphics
 */
@@ -1962,16 +1960,72 @@ local void MenuHandleButtonUp(unsigned b)
     }
 }
 
+typedef struct _menu_stack_ {
+    Menu* Menu;
+    int CurSel;
+    struct _menu_stack_* Next;
+} MenuStack;
+
+MenuStack* Menus;
+
+/**
+**	Push the current menu onto the stack.
+*/
+local void PushMenu(void)
+{
+    MenuStack* menu;
+
+    menu = malloc(sizeof(MenuStack));
+    menu->Menu = CurrentMenu;
+    menu->CurSel = MenuButtonCurSel;
+    menu->Next = Menus;
+    Menus = menu;
+}
+
+/**
+**	Pop the stack and set the current menu
+*/
+local void PopMenu(void)
+{
+    MenuStack* menu;
+    Menuitem* mi;
+    int i;
+
+    for (i = 0; i < CurrentMenu->nitems; ++i) {
+	mi = CurrentMenu->items + i;
+	if (mi->exitfunc) {
+	    (*mi->exitfunc)(mi);		// action/destructor
+	}
+    }
+
+    MenuButtonUnderCursor = -1;
+    MenuButtonCurSel = -1;
+    CurrentMenu = NULL;
+
+    if (Menus) {
+	MenuButtonCurSel = Menus->CurSel;
+	menu = Menus;
+	Menus = Menus->Next;
+	free(menu);
+	if (Menus) {
+	    CurrentMenu = Menus->Menu;
+	}
+    }
+}
+
 /**
 **	End process menu
-**
 */
 global void EndMenu(void)
 {
     CursorOn = CursorOnUnknown;
-    CurrentMenu = NULL;
-
     MustRedraw = RedrawEverything;
+    PopMenu();
+
+    if (!CurrentMenu && Callbacks!=&GameCallbacks) {
+	InterfaceState=IfaceStateNormal;
+	Callbacks=&GameCallbacks;
+    }
 }
 
 /**
@@ -2003,9 +2057,9 @@ global void ProcessMenu(const char *menu_id, int loop)
 	CurrentMenuSave = CurrentMenu;
 	MenuButtonUnderCursorSave = MenuButtonUnderCursor;
 	MenuButtonCurSelSave = MenuButtonCurSel;
+	InterfaceState = IfaceStateMenu;
     }
 
-    InterfaceState = IfaceStateMenu;
     VideoLockScreen();
     HideAnyCursor();
     VideoUnlockScreen();
@@ -2018,6 +2072,12 @@ global void ProcessMenu(const char *menu_id, int loop)
 	return;
     }
     CurrentMenu = menu;
+
+    if (!loop) {
+	Callbacks = &MenuCallbacks;
+	PushMenu();
+    }
+
     MenuButtonCurSel = -1;
     for (i = 0; i < menu->nitems; ++i) {
 	mi = menu->items + i;
@@ -2072,8 +2132,8 @@ global void ProcessMenu(const char *menu_id, int loop)
 	MenuHandleMouseMove(CursorX,CursorY);	// This activates buttons as appropriate!
     }
 
+    MustRedraw = RedrawEverything;
     if (loop) {
-	MustRedraw = RedrawEverything;
 	while (CurrentMenu != NULL) {
 	    DebugLevel3("MustRedraw: 0x%08x\n" _C_ MustRedraw);
 	    if (MustRedraw) {
@@ -2091,7 +2151,7 @@ global void ProcessMenu(const char *menu_id, int loop)
 	    }
 	    RealizeVideoMemory();
 	    oldncr = NetConnectRunning;
-	    WaitEventsOneFrame(&callbacks);
+	    WaitEventsOneFrame(&MenuCallbacks);
 	    if (NetConnectRunning == 2) {
 		NetworkProcessClientRequest();
 		MustRedraw |= RedrawMenu;
@@ -2109,19 +2169,18 @@ global void ProcessMenu(const char *menu_id, int loop)
     } else {
 	VideoLockScreen();
 	DrawMenu(CurrentMenu);
-	MustRedraw&=~RedrawMenu;
+	MustRedraw &= ~RedrawMenu;
 	VideoUnlockScreen();
 	InvalidateAreaAndCheckCursor(MenuRedrawX,MenuRedrawY,MenuRedrawW,MenuRedrawH);
     }
 
-    for (i = 0; i < menu->nitems; ++i) {
-	mi = menu->items + i;
-	if (mi->exitfunc) {
-	    (*mi->exitfunc)(mi);		// action/destructor
-	}
-    }
-
     if (loop) {
+	for (i = 0; i < menu->nitems; ++i) {
+	    mi = menu->items + i;
+	    if (mi->exitfunc) {
+		(*mi->exitfunc)(mi);		// action/destructor
+	    }
+	}
 	CurrentMenu = CurrentMenuSave;
 	MenuButtonUnderCursor = MenuButtonUnderCursorSave;
 	MenuButtonCurSel = MenuButtonCurSelSave;
@@ -2155,15 +2214,15 @@ global void InitMenus(int race)
     }
 
     if (last_race == -1) {
-	callbacks.ButtonPressed = &MenuHandleButtonDown;
-	callbacks.ButtonReleased = &MenuHandleButtonUp;
-	callbacks.MouseMoved = &MenuHandleMouseMove;
-	callbacks.MouseExit = &HandleMouseExit;
-	callbacks.KeyPressed = &MenuHandleKeyDown;
-	callbacks.KeyReleased = &MenuHandleKeyUp;
-	callbacks.KeyRepeated = &MenuHandleKeyRepeat;
-	callbacks.NetworkEvent = NetworkEvent;
-	callbacks.SoundReady = WriteSound;
+	MenuCallbacks.ButtonPressed = &MenuHandleButtonDown;
+	MenuCallbacks.ButtonReleased = &MenuHandleButtonUp;
+	MenuCallbacks.MouseMoved = &MenuHandleMouseMove;
+	MenuCallbacks.MouseExit = &HandleMouseExit;
+	MenuCallbacks.KeyPressed = &MenuHandleKeyDown;
+	MenuCallbacks.KeyReleased = &MenuHandleKeyUp;
+	MenuCallbacks.KeyRepeated = &MenuHandleKeyRepeat;
+	MenuCallbacks.NetworkEvent = NetworkEvent;
+	MenuCallbacks.SoundReady = WriteSound;
     } else {
 	// free previous sprites for different race
 	VideoFree(MenuButtonGfx.Sprite);
diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp
index 1544154d0..e18ba6243 100644
--- a/src/ui/menus.cpp
+++ b/src/ui/menus.cpp
@@ -236,6 +236,8 @@ local void KeyboardScrollHSAction(Menuitem *mi, int i);
 // Game options
 
 // Diplomacy options
+local void DiplomacyInit(Menuitem *mi);
+local void DiplomacyExit(Menuitem *mi);
 local void DiplomacyWait(Menuitem *mi);
 local void DiplomacyOk(void);
 
@@ -249,6 +251,7 @@ local void KeystrokeHelpDrawFunc(Menuitem *mi);
 
 // Save
 local void SaveGameInit(Menuitem *mi);
+local void SaveGameExit(Menuitem *mi);
 local void SaveGameLBInit(Menuitem *mi);
 local void SaveGameLBExit(Menuitem *mi);
 local void SaveGameEnterAction(Menuitem *mi, int key);
@@ -262,6 +265,7 @@ local void CreateSaveDir(void);
 
 // Load
 local void LoadGameInit(Menuitem *mi);
+local void LoadGameExit(Menuitem *mi);
 local void LoadGameLBInit(Menuitem *mi);
 local void LoadGameLBExit(Menuitem *mi);
 local void LoadGameLBAction(Menuitem *mi, int i);
@@ -281,6 +285,10 @@ local void DeleteConfirmExit(Menuitem *mi);
 local void DeleteConfirmOk(void);
 local void DeleteConfirmCancel(void);
 
+// Save replay
+local void SaveReplayInit(Menuitem *mi);
+local void SaveReplayExit(Menuitem *mi);
+
 // Editor select
 local void EditorNewMap(void);
 local void EditorMainLoadMap(void);
@@ -390,8 +398,6 @@ local int GameLoaded;
 global int GuiGameStarted;
     /// Editor cancel button pressed
 local int EditorCancelled;
-    /// Confirmed, used for save and delete confirm menus
-local int Confirmed;
 
 /**
 **	Other client and server selection state for Multiplayer clients
@@ -608,6 +614,8 @@ global void InitMenuFuncHash(void) {
     HASHADD(DiplomacyMenu,"diplomacy-menu");
 
 // Diplomacy options
+    HASHADD(DiplomacyInit,"diplomacy-init");
+    HASHADD(DiplomacyExit,"diplomacy-exit");
     HASHADD(DiplomacyWait,"diplomacy-wait");
     HASHADD(DiplomacyOk,"diplomacy-ok");
 
@@ -621,6 +629,7 @@ global void InitMenuFuncHash(void) {
 
 // Save
     HASHADD(SaveGameInit,"save-game-init");
+    HASHADD(SaveGameExit,"save-game-exit");
     HASHADD(SaveGameLBInit,"save-game-lb-init");
     HASHADD(SaveGameLBExit,"save-game-lb-exit");
     HASHADD(SaveGameEnterAction,"save-game-enter-action");
@@ -632,6 +641,7 @@ global void InitMenuFuncHash(void) {
 
 // Load
     HASHADD(LoadGameInit,"load-game-init");
+    HASHADD(LoadGameExit,"load-game-exit");
     HASHADD(LoadGameLBInit,"load-game-lb-init");
     HASHADD(LoadGameLBExit,"load-game-lb-exit");
     HASHADD(LoadGameLBAction,"load-game-lb-action");
@@ -651,6 +661,10 @@ global void InitMenuFuncHash(void) {
     HASHADD(DeleteConfirmOk,"delete-confirm-ok");
     HASHADD(DeleteConfirmCancel,"delete-confirm-cancel");
 
+// Save replay
+    HASHADD(SaveReplayInit,"save-replay-init");
+    HASHADD(SaveReplayExit,"save-replay-exit");
+
 // Editor select
     HASHADD(EditorNewMap,"editor-new-map");
     HASHADD(EditorMainLoadMap,"editor-main-load-map");
@@ -788,7 +802,9 @@ local void PrgStartInit(Menuitem *mi)
 */
 local void GameMenuReturn(void)
 {
-    EndMenu();
+    while (CurrentMenu) {
+	EndMenu();
+    }
     MustRedraw &= ~RedrawMenu;
     InterfaceState = IfaceStateNormal;
     ClearStatusLine();
@@ -800,13 +816,33 @@ local void GameMenuReturn(void)
 /**
 **	Init callback for save game menu
 */
-local void SaveGameInit(Menuitem *mi)
+local void SaveGameInit(Menuitem *mi __attribute__ ((unused)))
 {
-    mi->menu->items[4].flags = MenuButtonDisabled;
-    mi->menu->items[5].flags = MenuButtonDisabled;
+    Menu *menu;
+    char *buf;
+
+    menu = CurrentMenu;
+
+    buf = malloc(32);
+    strcpy(buf, "~!_");
+    menu->items[1].d.input.buffer = buf;
+    menu->items[1].d.input.nch = 0;
+    menu->items[1].d.input.maxch = 24;
+
+    menu->items[4].flags = MenuButtonDisabled;
+    menu->items[5].flags = MenuButtonDisabled;
     CreateSaveDir();
 }
 
+/**
+**	Exit callback for save game menu
+*/
+local void SaveGameExit(Menuitem *mi)
+{
+    free(mi->menu->items[1].d.input.buffer);
+    mi->menu->items[1].d.input.buffer = NULL;
+}
+
 /**
 **	Save game input box callback
 */
@@ -850,10 +886,7 @@ local void SaveGameOk(void)
 	    SetMessage("Saved game to: %s", TempPathBuf);
 	    EndMenu();
 	} else {
-	    ProcessMenu("menu-save-confirm", 1);
-	    if (Confirmed) {
-		EndMenu();
-	    }
+	    ProcessMenu("menu-save-confirm", 0);
 	}
     }
 }
@@ -886,16 +919,7 @@ local void CreateSaveDir(void)
 */
 global void SaveGameMenu(void)
 {
-    char savegame_buffer[32];
-    Menu *menu;
-
-    menu = FindMenu("menu-save-game");
-    strcpy(savegame_buffer, "~!_");
-    menu->items[1].d.input.buffer = savegame_buffer;
-    menu->items[1].d.input.nch = strlen(savegame_buffer) - 3;
-    menu->items[1].d.input.maxch = 24;
-    menu->items[4].flags = MenuButtonDisabled;	/* Save button! */
-    ProcessMenu("menu-save-game", 1);
+    ProcessMenu("menu-save-game", 0);
 }
 
 /**
@@ -1130,9 +1154,20 @@ local int SaveGameRDFilter(char *pathbuf, FileList *fl)
 local void LoadGameInit(Menuitem *mi)
 {
     mi->menu->items[3].flags = MI_DISABLED;
+    GameLoaded=0;
     CreateSaveDir();
 }
 
+/**
+**	Load game exit callback
+*/
+local void LoadGameExit(Menuitem *mi)
+{
+    if( GameLoaded ) {
+	GameMenuReturn();
+    }
+}
+
 /**
 **	Exit callback for listbox in load game menu
 */
@@ -1342,7 +1377,6 @@ local void SaveConfirmInit(Menuitem *mi)
     int fileLength;
     Menu *menu;
 
-    Confirmed = 0;
     menu = FindMenu("menu-save-game");
     fileLength = strlen(menu->items[1].d.input.buffer) - 3;
 
@@ -1370,7 +1404,6 @@ local void SaveConfirmOk(void)
     int fileLength;
     Menu *menu;
 
-    Confirmed = 1;
     menu = FindMenu("menu-save-game");
     fileLength = strlen(menu->items[1].d.input.buffer) - 3;
 
@@ -1382,7 +1415,7 @@ local void SaveConfirmOk(void)
     }
     SaveGame(TempPathBuf);
     SetMessage("Saved game to: %s", TempPathBuf);
-    EndMenu();
+    GameMenuReturn();
 }
 
 /**
@@ -1398,14 +1431,7 @@ local void SaveConfirmCancel(void)
 */
 local void DeleteConfirmMenu(void)
 {
-    ProcessMenu("menu-delete-confirm", 1);
-
-    if (Confirmed) {
-	// Update list of files and clear input
-	SaveGameLBInit(&CurrentMenu->items[2]);
-	strcpy(CurrentMenu->items[1].d.input.buffer,"~!_");
-	CurrentMenu->items[1].d.input.nch = 0;
-    }
+    ProcessMenu("menu-delete-confirm", 0);
 }
 
 /**
@@ -1416,7 +1442,6 @@ local void DeleteConfirmInit(Menuitem *mi)
     Menu *menu;
     static char name[PATH_MAX];		// FIXME: much memory wasted
 
-    Confirmed = 0;
     menu = FindMenu("menu-save-game");
     strcpy(name, "the file: ");
     strcat(name, menu->items[1].d.input.buffer);
@@ -1439,7 +1464,6 @@ local void DeleteConfirmOk(void)
 {
     Menu *menu;
 
-    Confirmed = 1;
     menu = FindMenu("menu-save-game");
     strcpy(TempPathBuf, SaveDir);
     strcat(TempPathBuf, "/");
@@ -1447,6 +1471,11 @@ local void DeleteConfirmOk(void)
     TempPathBuf[strlen(TempPathBuf) - 3] = '\0';
     unlink(TempPathBuf);
     EndMenu();
+
+    // Update list of files and clear input
+    SaveGameLBInit(&CurrentMenu->items[2]);
+    strcpy(CurrentMenu->items[1].d.input.buffer,"~!_");
+    CurrentMenu->items[1].d.input.nch = 0;
 }
 
 /**
@@ -1462,15 +1491,7 @@ local void DeleteConfirmCancel(void)
 */
 global void LoadGameMenu(void)
 {
-    Menu *menu;
-
-    menu = FindMenu("menu-load-game");
-    menu->items[3].flags = MI_DISABLED;		// Load button!
-    GameLoaded=0;
-    ProcessMenu("menu-load-game", 1);
-    if( GameLoaded ) {
-	GameMenuReturn();
-    }
+    ProcessMenu("menu-load-game", 0);
 }
 
 /**
@@ -1498,7 +1519,7 @@ local void GameMenuInit(Menuitem *mi __attribute__((unused)))
 */
 global void SoundOptionsMenu(void)
 {
-    ProcessMenu("menu-sound-options", 1);
+    ProcessMenu("menu-sound-options", 0);
 }
 
 /**
@@ -1600,7 +1621,7 @@ local void SoundOptionsExit(Menuitem *mi __attribute__((unused)))
 */
 local void GlobalOptionsMenu(void)
 {
-    ProcessMenu("menu-global-options", 1);
+    ProcessMenu("menu-global-options", 0);
 }
 
 /**
@@ -1889,7 +1910,7 @@ local void SetCdModeRandom(Menuitem *mi __attribute__((unused)))
 */
 global void SpeedOptionsMenu(void)
 {
-    ProcessMenu("menu-speed-options", 1);
+    ProcessMenu("menu-speed-options", 0);
 }
 
 /**
@@ -1934,12 +1955,20 @@ global void SpeedOptionsExit(Menuitem *mi __attribute__((unused)))
 **	Diplomacy options menu
 */
 global void DiplomacyMenu(void)
+{
+    ProcessMenu("menu-diplomacy", 0);
+}
+
+/**
+**	Diplomacy init callback
+*/
+local void DiplomacyInit(Menuitem *mi)
 {
     Menu *menu;
     int i;
     int j;
 
-    menu = FindMenu("menu-diplomacy");
+    menu = CurrentMenu;
     j = 0;
 
     for (i=0; i<=PlayerMax-2; ++i) {
@@ -1980,8 +2009,17 @@ global void DiplomacyMenu(void)
 	menu->items[4*j+6].d.gem.state = MI_GSTATE_INVISIBLE;
 	menu->items[4*j+7].d.gem.state = MI_GSTATE_INVISIBLE;
     }
+}
 
-    ProcessMenu("menu-diplomacy", 1);
+/**
+**	Diplomacy exit callback
+*/
+local void DiplomacyExit(Menuitem *mi)
+{
+    Menu* menu;
+    int i;
+
+    menu = CurrentMenu;
 
     for (i=0; i<=PlayerMax-3; ++i) {
 	menu->items[4*i+4].d.text.text = NULL;
@@ -2091,7 +2129,7 @@ local void DiplomacyOk(void)
 */
 global void PreferencesMenu(void)
 {
-    ProcessMenu("menu-preferences", 1);
+    ProcessMenu("menu-preferences", 0);
 }
 
 /**
@@ -2136,7 +2174,7 @@ local void PreferencesExit(Menuitem *mi __attribute__((unused)))
 */
 local void GameOptionsMenu(void)
 {
-    ProcessMenu("menu-game-options", 1);
+    ProcessMenu("menu-game-options", 0);
 }
 
 /**
@@ -2152,10 +2190,7 @@ local void GameShowCredits(void)
 */
 global void RestartConfirmMenu(void)
 {
-    ProcessMenu("menu-restart-confirm", 1);
-    if (!GameRunning && CurrentMenu) {
-	EndMenu();
-    }
+    ProcessMenu("menu-restart-confirm", 0);
 }
 
 /**
@@ -2163,10 +2198,7 @@ global void RestartConfirmMenu(void)
 */
 local void SurrenderConfirmMenu(void)
 {
-    ProcessMenu("menu-surrender-confirm", 1);
-    if (!GameRunning && CurrentMenu) {
-	EndMenu();
-    }
+    ProcessMenu("menu-surrender-confirm", 0);
 }
 
 /**
@@ -2174,10 +2206,7 @@ local void SurrenderConfirmMenu(void)
 */
 global void QuitToMenuConfirmMenu(void)
 {
-    ProcessMenu("menu-quit-to-menu-confirm", 1);
-    if (!GameRunning && CurrentMenu) {
-	EndMenu();
-    }
+    ProcessMenu("menu-quit-to-menu-confirm", 0);
 }
 
 /**
@@ -2185,7 +2214,7 @@ global void QuitToMenuConfirmMenu(void)
 */
 global void ExitConfirmMenu(void)
 {
-    ProcessMenu("menu-exit-confirm", 1);
+    ProcessMenu("menu-exit-confirm", 0);
 }
 
 /**
@@ -2193,11 +2222,7 @@ global void ExitConfirmMenu(void)
 */
 local void EndScenarioMenu(void)
 {
-    ProcessMenu("menu-end-scenario", 1);
-    if (!GameRunning) {
-	EndMenu();
-	InterfaceState = IfaceStateNormal;
-    }
+    ProcessMenu("menu-end-scenario", 0);
 }
 
 /**
@@ -2207,7 +2232,7 @@ local void EndScenarioRestart(void)
 {
     RestartScenario = 1;
     GameRunning = 0;
-    EndMenu();
+    GameMenuReturn();
 }
 
 /**
@@ -2217,7 +2242,7 @@ local void EndScenarioSurrender(void)
 {
     GameResult = GameDefeat;
     GameRunning = 0;
-    EndMenu();
+    GameMenuReturn();
 }
 
 /**
@@ -2227,7 +2252,7 @@ local void EndScenarioQuitMenu(void)
 {
     QuitToMenu = 1;
     GameRunning = 0;
-    EndMenu();
+    GameMenuReturn();
 }
 
 /**
@@ -2246,16 +2271,33 @@ local void GameMenuEnd(void)
 */
 local void SaveReplay(void)
 {
-    char filename[32];
-    Menu *menu;
+    ProcessMenu("menu-save-replay", 0);
+}
 
-    menu = FindMenu("menu-save-replay");
-    menu->items[1].d.input.buffer = filename;
-    strcpy(filename, "~!_");
+/**
+**	Save replay menu init callback
+*/
+local void SaveReplayInit(Menuitem *mi __attribute__((unused)))
+{
+    Menu *menu;
+    char *buf;
+
+    menu = CurrentMenu;
+
+    buf = malloc(32);
+    strcpy(buf, "~!_");
+    menu->items[1].d.input.buffer = buf;
     menu->items[1].d.input.nch = 0;
     menu->items[1].d.input.maxch = 28;
+}
 
-    ProcessMenu("menu-save-replay", 1);
+/**
+**	Save replay menu exit callback
+*/
+local void SaveReplayExit(Menuitem *mi)
+{
+    free(mi->menu->items[1].d.input.buffer);
+    mi->menu->items[1].d.input.buffer = NULL;
 }
 
 /**
@@ -2320,7 +2362,7 @@ local void SaveReplayOk(void)
 */
 local void KeystrokeHelpMenu(void)
 {
-    ProcessMenu("menu-keystroke-help", 1);
+    ProcessMenu("menu-keystroke-help", 0);
 }
 
 /**
@@ -2328,7 +2370,7 @@ local void KeystrokeHelpMenu(void)
 */
 local void HelpMenu(void)
 {
-    ProcessMenu("menu-help", 1);
+    ProcessMenu("menu-help", 0);
 }
 
 /**
@@ -2336,7 +2378,7 @@ local void HelpMenu(void)
 */
 local void TipsMenu(void)
 {
-    ProcessMenu("menu-tips", 1);
+    ProcessMenu("menu-tips", 0);
 }
 
 /**
@@ -2581,7 +2623,7 @@ local void ObjectivesExit(Menuitem *mi)
 */
 local void ObjectivesMenu(void)
 {
-    ProcessMenu("menu-objectives", 1);
+    ProcessMenu("menu-objectives", 0);
 }
 
 /**
diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp
index 71b474778..ede3af1a0 100644
--- a/src/ui/mouse.cpp
+++ b/src/ui/mouse.cpp
@@ -50,6 +50,7 @@
 #include "menus.h"
 #include "sound.h"
 #include "ui.h"
+#include "network.h"
 
 /*----------------------------------------------------------------------------
 --	Variables
@@ -1542,9 +1543,11 @@ global void UIHandleButtonUp(unsigned button)
 	MustRedraw|=RedrawMenuButton;
 	if( ButtonUnderCursor == 0 ) {
 	    // FIXME: Not if, in input mode.
-	    GamePaused=1;
-	    SetStatusLine("Game Paused");
-	    ProcessMenu("menu-game", 1);
+	    if( NetworkFildes==-1 ) {
+		GamePaused=1;
+		SetStatusLine("Game Paused");
+	    }
+	    ProcessMenu("menu-game",0);
 	    return;
 	}
     }