Maelstrom: Added pause status UI

From ee0d1517b7baa042ab42598a54762b92f9ae5d14 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 31 Mar 2026 21:14:21 -0700
Subject: [PATCH] Added pause status UI

---
 Data/UI/game.xml |  5 +++++
 game/game.cpp    | 36 +++++++++++++++++++++++++++++++++++-
 game/game.h      |  2 ++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/Data/UI/game.xml b/Data/UI/game.xml
index e3718a36..7fed0403 100644
--- a/Data/UI/game.xml
+++ b/Data/UI/game.xml
@@ -93,6 +93,11 @@
 			<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="frags_label" x="4"/>
 		</Label>
 
+		<!-- Pause label -->
+		<Label name="paused" template="SmallYellow">
+			<Anchor anchorFrom="CENTER" anchorTo="TOP" y="16"/>
+		</Label>
+
 		<!-- Touch controls -->
 		<Area condition="!PHONE" name="touch_controls" show="false">
 			<Elements>
diff --git a/game/game.cpp b/game/game.cpp
index dc245bda..9d87eae3 100644
--- a/game/game.cpp
+++ b/game/game.cpp
@@ -184,6 +184,8 @@ GamePanelDelegate::OnLoad()
 	m_fragsLabel = m_panel->GetElement<UIElement>("frags_label");
 	m_frags = m_panel->GetElement<UIElement>("frags");
 
+	m_paused = m_panel->GetElement<UIElement>("paused");
+
 	m_zoom = false;
 
 	return true;
@@ -242,6 +244,9 @@ GamePanelDelegate::OnShow()
 			m_frags->Hide();
 		}
 	}
+	if (m_paused) {
+		m_paused->Hide();
+	}
 
 	NextWave();
 }
@@ -948,14 +953,43 @@ GamePanelDelegate::UpdateGameState()
 	}
 
 	// Check for pause status
+	bool locally_paused = false;
+	int index_paused = -1;
 	paused = 0;
 	for (i = 0; i < gGameInfo.GetNumNodes(); ++i) {
-		paused |= gGameInfo.GetNodeState(i);
+		Uint8 state = gGameInfo.GetNodeState(i);
+		paused |= state;
+		if (state & (STATE_PAUSE|STATE_MINIMIZE)) {
+			if (i == gGameInfo.GetLocalIndex()) {
+				locally_paused = true;
+			} else {
+				index_paused = i;
+			}
+		}
 	}
 	if ((paused & (STATE_PAUSE|STATE_MINIMIZE)) &&
 	    !(gPaused & (STATE_PAUSE|STATE_MINIMIZE))) {
 		sound->PlaySound(gPauseSound, 5);
 	}
+	if (m_paused) {
+		// Update the pause label
+		if (paused & (STATE_PAUSE|STATE_MINIMIZE)) {
+			char label[128] = { 0 };
+			if (!locally_paused) {
+				const GameInfoPlayer *player = gGameInfo.GetPlayer(index_paused);
+				if (*player->name) {
+					SDL_snprintf(label, sizeof(label), "Paused by %s", player->name);
+				}
+			}
+			if (!*label) {
+				SDL_strlcpy(label, "Paused", sizeof(label));
+			}
+			m_paused->SetText(label);
+			m_paused->Show();
+		} else if (gPaused & (STATE_PAUSE|STATE_MINIMIZE)) {
+			m_paused->Hide();
+		}
+	}
 	gPaused = paused;
 
 	return true;
diff --git a/game/game.h b/game/game.h
index 0c1a36e8..fd7e8029 100644
--- a/game/game.h
+++ b/game/game.h
@@ -87,6 +87,8 @@ class GamePanelDelegate : public UIPanelDelegate
 	UIElement *m_fragsLabel;
 	UIElement *m_frags;
 
+	UIElement *m_paused;
+
 	enum {
 		STATE_PLAYING,
 		STATE_SHOW_BONUS,