Maelstrom: Allow the host to specify the control scheme for the players in the game.

https://github.com/libsdl-org/Maelstrom/commit/81e4aab13adc7fce6bf6ee67890394116f6b020a

From 81e4aab13adc7fce6bf6ee67890394116f6b020a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 23 Nov 2011 21:07:42 -0500
Subject: [PATCH] Allow the host to specify the control scheme for the players
 in the game.

---
 Maelstrom_Data.zip | Bin 754184 -> 764302 bytes
 game/gameinfo.cpp  |  50 +++++++-------------
 game/gameinfo.h    |  17 ++++---
 game/lobby.cpp     | 114 ++++++++++++++++++++++++++++++++++++++++++++-
 game/lobby.h       |   3 +-
 5 files changed, 141 insertions(+), 43 deletions(-)

diff --git a/Maelstrom_Data.zip b/Maelstrom_Data.zip
index 6fda0f4e4b23a158a833ad7cff739a3e2446b1cd..792093588a20c91b46f3b8142ecc70651658d40f 100644
GIT binary patch
delta 14738
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
W5gAY<z$C!daKXTGl0XM6!Tvu;QCUp@

delta 4565
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
SzAkdOFC!fUGGYVZ(0>4|^;MSu

diff --git a/game/gameinfo.cpp b/game/gameinfo.cpp
index 4075111a..ce0f7b18 100644
--- a/game/gameinfo.cpp
+++ b/game/gameinfo.cpp
@@ -93,6 +93,14 @@ GameInfo::SetPlayerName(int slot, const char *name)
 	UpdateUI(player);
 }
 
+void
+GameInfo::SetPlayerControls(int slot, Uint8 controlMask)
+{
+	GameInfoPlayer *player = &players[slot];
+	player->controlMask = controlMask;
+	UpdateUI(player);
+}
+
 bool
 GameInfo::AddNetworkPlayer(Uint32 nodeID, const IPaddress &address, const char *name)
 {
@@ -110,7 +118,8 @@ GameInfo::AddNetworkPlayer(Uint32 nodeID, const IPaddress &address, const char *
 	++numNodes;
 
 	for (slot = 0; slot < MAX_PLAYERS; ++slot) {
-		if (!players[slot].nodeID) {
+		if (!players[slot].nodeID &&
+		    players[slot].controlMask == CONTROL_NETWORK) {
 			break;
 		}
 	}
@@ -119,7 +128,6 @@ GameInfo::AddNetworkPlayer(Uint32 nodeID, const IPaddress &address, const char *
 	GameInfoPlayer *player = &players[slot];
 	player->nodeID = nodeID;
 	SDL_strlcpy(player->name, name, sizeof(player->name));
-	player->controlMask = CONTROL_NETWORK;
 
 	UpdateUI(player);
 
@@ -410,7 +418,8 @@ bool
 GameInfo::IsFull() const
 {
 	for (int i = 0; i < MAX_PLAYERS; ++i) {
-		if (!players[i].nodeID) {
+		if (!players[i].nodeID &&
+		    players[i].controlMask == CONTROL_NETWORK) {
 			return false;
 		}
 	}
@@ -460,13 +469,9 @@ GameInfo::BindPlayerToUI(int index, UIElement *element)
 	}
 
 	player->UI.element = element;
-	player->UI.enabled = element->GetElement<UIElementCheckbox>("enabled");
 	player->UI.name = element->GetElement<UIElement>("name");
 	player->UI.host = element->GetElement<UIElement>("host");
-	player->UI.control = element->GetElement<UIElementRadioGroup>("control");
-	player->UI.keyboard = element->GetElement<UIElement>("keyboard");
-	player->UI.joystick = element->GetElement<UIElement>("joystick");
-	player->UI.network = element->GetElement<UIElement>("network");
+	player->UI.control = element->GetElement<UIElement>("control");
 
 	for (int i = 0; i < NUM_PING_STATES; ++i) {
 		SDL_snprintf(name, sizeof(name), "ping%d", i);
@@ -513,32 +518,9 @@ GameInfo::UpdateUI(GameInfoPlayer *player)
 		}
 	}
 	if (player->UI.control) {
-		if (player->nodeID == localID) {
-			player->UI.control->SetValue(CONTROL_KEYBOARD);
-		} else {
-			player->UI.control->SetValue(CONTROL_NETWORK);
-		}
-	}
-	if (player->UI.keyboard) {
-		if (player->nodeID == localID) {
-			player->UI.keyboard->Show();
-		} else {
-			player->UI.keyboard->Hide();
-		}
-	}
-	if (player->UI.joystick) {
-		if (player->nodeID == localID) {
-			player->UI.joystick->Show();
-		} else {
-			player->UI.joystick->Hide();
-		}
-	}
-	if (player->UI.network) {
-		if (player->nodeID != localID) {
-			player->UI.network->Show();
-		} else {
-			player->UI.network->Hide();
-		}
+		char name[128];
+		SDL_snprintf(name, sizeof(name), "Images/control%d.bmp", player->controlMask);
+		player->UI.control->SetImage(name);
 	}
 	for (int i = 0; i < NUM_PING_STATES; ++i) {
 		UIElement *element = player->UI.ping_states[i];
diff --git a/game/gameinfo.h b/game/gameinfo.h
index f99e5118..e0b622cd 100644
--- a/game/gameinfo.h
+++ b/game/gameinfo.h
@@ -25,6 +25,7 @@
 
 #include "protocol.h"
 #include "packet.h"
+#include "controls.h"
 
 class UIElement;
 class UIElementCheckbox;
@@ -36,9 +37,14 @@ enum PLAYER_CONTROL {
 	CONTROL_JOYSTICK1 = 0x02,
 	CONTROL_JOYSTICK2 = 0x04,
 	CONTROL_JOYSTICK3 = 0x08,
-	CONTROL_NETWORK   = 0x10,
-	CONTROL_REPLAY    = 0x20,
+	CONTROL_TOUCH     = 0x10,
+	CONTROL_NETWORK   = 0x20,
+	CONTROL_REPLAY    = 0x40,
+#ifdef USE_TOUCHCONTROL
+	CONTROL_LOCAL     = CONTROL_TOUCH
+#else
 	CONTROL_LOCAL     = (CONTROL_KEYBOARD|CONTROL_JOYSTICK1)
+#endif
 };
 
 enum NODE_STATE_FLAG {
@@ -87,13 +93,9 @@ struct GameInfoPlayer
 
 	struct {
 		UIElement *element;
-		UIElementCheckbox *enabled;
 		UIElement *name;
 		UIElement *host;
-		UIElementRadioGroup *control;
-		UIElement *keyboard;
-		UIElement *joystick;
-		UIElement *network;
+		UIElement *control;
 		UIElement *ping_states[NUM_PING_STATES];
 	} UI;
 };
@@ -118,6 +120,7 @@ class GameInfo
 
 	void SetPlayerSlot(int slot, const char *name, Uint8 controlMask);
 	void SetPlayerName(int slot, const char *name);
+	void SetPlayerControls(int slot, Uint8 controlMask);
 	bool AddNetworkPlayer(Uint32 nodeID, const IPaddress &address, const char *name);
 
 	void CopyFrom(const GameInfo &rhs);
diff --git a/game/lobby.cpp b/game/lobby.cpp
index ed5e2ed0..e2a42d9b 100644
--- a/game/lobby.cpp
+++ b/game/lobby.cpp
@@ -41,6 +41,94 @@
 #define LOBBY_BROADCAST
 
 
+class SelectControlCallback : public UIClickCallback
+{
+public:
+	SelectControlCallback(LobbyDialogDelegate *lobby, UIElement *dialog, GameInfo &game, int index, Uint8 controlType) :
+		m_lobby(lobby), m_dialog(dialog), m_game(game), m_index(index), m_controlType(controlType) { }
+
+	virtual void operator()() {
+		// Select the control and hide the dialog
+		if (m_controlType == CONTROL_NONE) {
+			const GameInfoPlayer *player = m_game.GetPlayer(m_index);
+			int nodeIndex = m_game.GetNodeIndex(player->nodeID);
+			if (nodeIndex >= 0) {
+				m_lobby->SendKick(nodeIndex);
+			}
+		}
+		m_game.SetPlayerControls(m_index, m_controlType);
+		m_dialog->Hide();
+	}
+
+private:
+	LobbyDialogDelegate *m_lobby;
+	UIElement *m_dialog;
+	GameInfo &m_game;
+	int m_index;
+	Uint8 m_controlType;
+};
+
+class ControlClickCallback : public UIClickCallback
+{
+public:
+	ControlClickCallback(LobbyDialogDelegate *lobby, UIElement *button, UIElement *dialog, GameInfo &game, int index) :
+		m_lobby(lobby), m_button(button), m_dialog(dialog), m_game(game), m_index(index) { }
+
+	virtual void operator()() {
+		if (!m_game.IsLocalPlayer(m_index) && !m_game.IsHosting()) {
+			return;
+		}
+
+		// Show the control dialog
+		SetControl(CONTROL_NONE, (m_index > 0) && m_game.IsHosting());
+#ifdef USE_TOUCHCONTROL
+		SetControl(CONTROL_TOUCH, true);
+		SetControl(CONTROL_KEYBOARD, false);
+		SetControl(CONTROL_KEYBOARD|CONTROL_JOYSTICK1, false);
+		SetControl(CONTROL_JOYSTICK1, false);
+		SetControl(CONTROL_JOYSTICK2, false);
+		SetControl(CONTROL_JOYSTICK3, false);
+#else
+		SetControl(CONTROL_TOUCH, false);
+		SetControl(CONTROL_KEYBOARD, true);
+		SetControl(CONTROL_KEYBOARD|CONTROL_JOYSTICK1, true);
+		SetControl(CONTROL_JOYSTICK1, SDL_NumJoysticks() > 0);
+		SetControl(CONTROL_JOYSTICK2, SDL_NumJoysticks() > 1);
+		SetControl(CONTROL_JOYSTICK3, SDL_NumJoysticks() > 2);
+#endif
+		SetControl(CONTROL_NETWORK, (m_index > 0) && m_game.IsHosting());
+
+		m_dialog->SetAnchor(LEFT, RIGHT, m_button, -4, 0);
+		m_dialog->Show();
+	}
+
+private:
+	void SetControl(Uint8 control, bool enabled) {
+		char name[128];
+		UIElement *element;
+
+		SDL_snprintf(name, sizeof(name), "control%d", control);
+		element = m_dialog->GetElement<UIElement>(name);
+		if (!element) {
+			return;
+		}
+		if (enabled) {
+			element->SetClickCallback(new SelectControlCallback(m_lobby, m_dialog, m_game, m_index, control));
+			element->Show();
+		} else {
+			element->Hide();
+		}
+	}
+
+private:
+	LobbyDialogDelegate *m_lobby;
+	UIElement *m_button;
+	UIElement *m_dialog;
+	GameInfo &m_game;
+	int m_index;
+};
+
+
 LobbyDialogDelegate::LobbyDialogDelegate(UIPanel *panel) :
 	UIDialogDelegate(panel),
 	m_game(gGameInfo)
@@ -117,12 +205,19 @@ LobbyDialogDelegate::OnLoad()
 		}
 	}
 
+	UIElement *controlDropdown = m_dialog->GetElement<UIElement>("control_dropdown");
+
 	count = SDL_arraysize(m_gameInfoPlayers);
 	for (i = 0; i < count; ++i) {
 		SDL_snprintf(name, sizeof(na

(Patch may be truncated, please check the link at the top of this post.)