Maelstrom: Made it easier to change multiplayer controls

From dab56abaf6616fdb76c63770d19f612800dfec6c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 31 Dec 2025 15:21:42 -0800
Subject: [PATCH] Made it easier to change multiplayer controls

---
 game/gameinfo.cpp | 17 -----------------
 game/gameinfo.h   |  1 -
 game/lobby.cpp    | 39 +++++++++++++++++++++++++++------------
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/game/gameinfo.cpp b/game/gameinfo.cpp
index f57ee45a..f5e6c3a2 100644
--- a/game/gameinfo.cpp
+++ b/game/gameinfo.cpp
@@ -407,23 +407,6 @@ GameInfo::IsNetworkPlayer(int index) const
 	return (players[index].nodeID != localID);
 }
 
-bool
-GameInfo::OtherPlayerHasControl(int index, Uint8 controlMask)
-{
-	for (int i = 0; i < MAX_PLAYERS; ++i) {
-		if (!IsValidPlayer(i)) {
-			continue;
-		}
-		if (i == index) {
-			continue;
-		}
-		if (players[i].controlMask == controlMask) {
-			return true;
-		}
-	}
-	return false;
-}
-
 int
 GameInfo::GetNumPlayers() const
 {
diff --git a/game/gameinfo.h b/game/gameinfo.h
index 63e51ef9..ff311e13 100644
--- a/game/gameinfo.h
+++ b/game/gameinfo.h
@@ -185,7 +185,6 @@ class GameInfo
 	bool IsValidPlayer(int index) const;
 	bool IsLocalPlayer(int index) const;
 	bool IsNetworkPlayer(int index) const;
-	bool OtherPlayerHasControl(int index, Uint8 controlMask);
 	int GetNumPlayers() const;
 
 	bool IsFull() const;
diff --git a/game/lobby.cpp b/game/lobby.cpp
index dcdb3517..561ea70f 100644
--- a/game/lobby.cpp
+++ b/game/lobby.cpp
@@ -47,12 +47,27 @@ class SelectControlCallback : public UIClickCallback
 		m_lobby(lobby), m_dialog(dialog), m_game(game), m_index(index), m_controlType(controlType) { }
 
 	virtual void operator()() {
-		// Kick any player that was connected
-		if (m_controlType != CONTROL_NETWORK) {
-			const GameInfoPlayer *player = m_game.GetPlayer(m_index);
-			int nodeIndex = m_game.GetNodeIndex(player->nodeID);
-			if (nodeIndex >= 0) {
-				m_lobby->SendKick(nodeIndex);
+		if (m_game.IsHosting()) {
+			// Kick any player that was connected
+			if (m_controlType != CONTROL_NETWORK) {
+				const GameInfoPlayer* player = m_game.GetPlayer(m_index);
+				int nodeIndex = m_game.GetNodeIndex(player->nodeID);
+				if (nodeIndex >= 0) {
+					m_lobby->SendKick(nodeIndex);
+				}
+			}
+
+			if (m_controlType != CONTROL_NONE && m_controlType != CONTROL_NETWORK) {
+				for (int i = 0; i < MAX_PLAYERS; ++i) {
+					if (i == m_index) {
+						continue;
+					}
+
+					const GameInfoPlayer* player = m_game.GetPlayer(i);
+					if (player->controlMask == m_controlType) {
+						m_game.SetPlayerSlot(i, NULL, CONTROL_NETWORK);
+					}
+				}
 			}
 		}
 
@@ -89,12 +104,12 @@ class ControlClickCallback : public UIClickCallback
 		// Show the control dialog
 		int num_gamepads = GetNumGamepads();
 		SetControl(CONTROL_NONE, (m_index > 0) && m_game.IsHosting());
-		SetControl(CONTROL_LOCAL, !m_game.OtherPlayerHasControl(m_index, CONTROL_LOCAL));
-		SetControl(CONTROL_JOYSTICK1, num_gamepads > 0 && !m_game.OtherPlayerHasControl(m_index, CONTROL_JOYSTICK1));
-		SetControl(CONTROL_JOYSTICK2, num_gamepads > 1 && !m_game.OtherPlayerHasControl(m_index, CONTROL_JOYSTICK2));
-		SetControl(CONTROL_JOYSTICK3, num_gamepads > 2 && !m_game.OtherPlayerHasControl(m_index, CONTROL_JOYSTICK3));
-		SetControl(CONTROL_REMOTE1, (m_index > 0) && m_game.IsHosting() && GetRemotePlayerName(CONTROL_REMOTE1) && !m_game.OtherPlayerHasControl(m_index, CONTROL_REMOTE1));
-		SetControl(CONTROL_REMOTE2, (m_index > 0) && m_game.IsHosting() && GetRemotePlayerName(CONTROL_REMOTE2) && !m_game.OtherPlayerHasControl(m_index, CONTROL_REMOTE2));
+		SetControl(CONTROL_LOCAL, true);
+		SetControl(CONTROL_JOYSTICK1, num_gamepads >= 1);
+		SetControl(CONTROL_JOYSTICK2, num_gamepads >= 2);
+		SetControl(CONTROL_JOYSTICK3, num_gamepads >= 3);
+		SetControl(CONTROL_REMOTE1, (m_index > 0) && m_game.IsHosting() && GetRemotePlayerName(CONTROL_REMOTE1));
+		SetControl(CONTROL_REMOTE2, (m_index > 0) && m_game.IsHosting() && GetRemotePlayerName(CONTROL_REMOTE2));
 		SetControl(CONTROL_NETWORK, (m_index > 0) && m_game.IsHosting());
 
 		m_dialog->SetAnchor(LEFT, RIGHT, m_button, -4, 0);