Maelstrom: Hooked up the game info to the UI.

https://github.com/libsdl-org/Maelstrom/commit/8485d0d16036cf737fe025081c20da2c837fd16c

From 8485d0d16036cf737fe025081c20da2c837fd16c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 6 Nov 2011 02:48:17 -0500
Subject: [PATCH] Hooked up the game info to the UI. The game info in the list
 magically binds to the list, and the game info for the hosting player
 magically binds to the game panel.  Woo!

---
 UI/lobby.xml          |  6 +--
 netlogic/gameinfo.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++-
 netlogic/gameinfo.h   | 39 +++++++++++++++++--
 netlogic/lobby.cpp    | 29 ++++++++++++++
 netlogic/lobby.h      |  2 +
 5 files changed, 157 insertions(+), 7 deletions(-)

diff --git a/UI/lobby.xml b/UI/lobby.xml
index 4e3dcd53..72d95e7f 100644
--- a/UI/lobby.xml
+++ b/UI/lobby.xml
@@ -138,7 +138,7 @@
 						<DialogCheckbox name="enabled" text="Player 1" checked="true">
 							<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT"/>
 						</DialogCheckbox>
-						<DialogRadioGroup>
+						<DialogRadioGroup name="control">
 							<Elements>
 								<DialogRadioButton name="keyboard" id="1" image="Images/keyboard.bmp" checked="true">
 									<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="enabled" x="8"/>
@@ -170,7 +170,7 @@
 						<DialogCheckbox name="enabled" text="Player 2" checked="true">
 							<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT"/>
 						</DialogCheckbox>
-						<DialogRadioGroup>
+						<DialogRadioGroup name="control">
 							<Elements>
 								<DialogRadioButton name="keyboard" id="1" image="Images/keyboard.bmp">
 									<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="enabled" x="8"/>
@@ -202,7 +202,7 @@
 						<DialogCheckbox name="enabled" text="Player 3" checked="true">
 							<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT"/>
 						</DialogCheckbox>
-						<DialogRadioGroup>
+						<DialogRadioGroup name="control">
 							<Elements>
 								<DialogRadioButton name="keyboard" id="1" image="Images/keyboard.bmp">
 									<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="enabled" x="8"/>
diff --git a/netlogic/gameinfo.cpp b/netlogic/gameinfo.cpp
index 90a7c62a..988147a3 100644
--- a/netlogic/gameinfo.cpp
+++ b/netlogic/gameinfo.cpp
@@ -20,6 +20,10 @@
     slouken@libsdl.org
 */
 
+#include "../screenlib/UIElement.h"
+#include "../screenlib/UIElementCheckbox.h"
+#include "../screenlib/UIElementRadio.h"
+
 #include "gameinfo.h"
 
 
@@ -49,6 +53,7 @@ GameInfo::CopyFrom(const GameInfo &rhs)
 		}
 		players[i] = rhs.players[i];
 	}
+	UpdateUI();
 }
 
 bool
@@ -61,7 +66,7 @@ GameInfo::ReadFromPacket(DynamicPacket &packet)
 		return false;
 	}
 
-	for (int i = 1; i < MAX_PLAYERS; ++i) {
+	for (int i = 0; i < MAX_PLAYERS; ++i) {
 		if (!packet.Read(players[i].playerID)) {
 			return false;
 		}
@@ -76,6 +81,9 @@ GameInfo::ReadFromPacket(DynamicPacket &packet)
 		}
 	}
 
+	// We want to get the public address of the server
+	players[0].address = packet.address;
+
 	return true;
 }
 
@@ -92,3 +100,81 @@ GameInfo::WriteToPacket(DynamicPacket &packet)
 		packet.Write(players[i].name);
 	}
 }
+
+void
+GameInfo::BindPlayerToUI(int index, UIElement *element)
+{
+	GameInfoPlayer *info = &players[index];
+
+	info->UI.enabled = element->GetElement<UIElementCheckbox>("enabled");
+	info->UI.name = element->GetElement<UIElement>("name");
+	info->UI.host = element->GetElement<UIElement>("host");
+	info->UI.ping = element->GetElement<UIElement>("ping");
+	info->UI.control = element->GetElement<UIElementRadioGroup>("control");
+	info->UI.keyboard = element->GetElement<UIElement>("keyboard");
+	info->UI.joystick = element->GetElement<UIElement>("joystick");
+	info->UI.network = element->GetElement<UIElement>("network");
+
+	UpdateUI(info);
+}
+
+void
+GameInfo::UpdateUI()
+{
+	for (int i = 0; i < MAX_PLAYERS; ++i) {
+		UpdateUI(&players[i]);
+	}
+}
+
+void
+GameInfo::UpdateUI(GameInfoPlayer *info)
+{
+	if (info->UI.name) {
+		if (info->name[0]) {
+			info->UI.name->Show();
+			info->UI.name->SetText(info->name);
+		} else {
+			info->UI.name->Hide();
+		}
+	}
+	if (info->UI.host) {
+		if (info->address.host) {
+			info->UI.host->Show();
+			info->UI.host->SetText(SDLNet_ResolveIP(&info->address));
+		} else {
+			info->UI.host->Hide();
+		}
+	}
+	if (info->UI.ping) {
+		// FIXME: not yet implemented
+		info->UI.ping->Hide();
+	}
+	if (info->UI.control) {
+		if (info->playerID == localID) {
+			info->UI.control->SetValue(CONTROL_KEYBOARD);
+		} else {
+			info->UI.control->SetValue(CONTROL_NETWORK);
+		}
+	}
+	if (info->UI.keyboard) {
+		if (info->playerID == localID) {
+			info->UI.keyboard->Show();
+		} else {
+			info->UI.keyboard->Hide();
+		}
+	}
+	if (info->UI.joystick) {
+		if (info->playerID == localID) {
+			info->UI.joystick->Show();
+		} else {
+			info->UI.joystick->Hide();
+		}
+	}
+	if (info->UI.network) {
+		if (info->playerID != localID) {
+			info->UI.network->Show();
+		} else {
+			info->UI.network->Hide();
+		}
+	}
+}
diff --git a/netlogic/gameinfo.h b/netlogic/gameinfo.h
index e9452096..25b2783d 100644
--- a/netlogic/gameinfo.h
+++ b/netlogic/gameinfo.h
@@ -26,6 +26,16 @@
 #include "protocol.h"
 #include "packet.h"
 
+class UIElement;
+class UIElementCheckbox;
+class UIElementRadioGroup;
+
+enum {
+	CONTROL_KEYBOARD = 1,
+	CONTROL_JOYSTICK,
+	CONTROL_NETWORK,
+};
+
 class GameInfo
 {
 public:
@@ -38,6 +48,10 @@ class GameInfo
 
 	void Reset();
 
+	void SetLocalID(Uint32 playerID) {
+		localID = playerID;
+	}
+
 	void SetHostInfo(Uint32 gameID, const char *name);
 
 	void CopyFrom(const GameInfo &rhs);
@@ -70,17 +84,36 @@ class GameInfo
 		}
 		return true;
 	}
-		
+
+	void BindPlayerToUI(int index, UIElement *element);
+
 public:
 	Uint32 gameID;
 	Uint8 deathMatch;
 
-	struct PlayerInfo {
+	struct GameInfoPlayer {
 		Uint32 playerID;
 		IPaddress address;
 		char name[MAX_NAMELEN+1];
+
+		struct {
+			UIElementCheckbox *enabled;
+			UIElement *name;
+			UIElement *host;
+			UIElement *ping;
+			UIElementRadioGroup *control;
+			UIElement *keyboard;
+			UIElement *joystick;
+			UIElement *network;
+		} UI;
 	};
-	PlayerInfo players[MAX_PLAYERS];
+	GameInfoPlayer players[MAX_PLAYERS];
+
+	Uint32 localID;
+
+protected:
+	void UpdateUI();
+	void UpdateUI(GameInfoPlayer *info);
 };
 
 #endif // _gameinfo_h
diff --git a/netlogic/lobby.cpp b/netlogic/lobby.cpp
index 53584b20..f83653ee 100644
--- a/netlogic/lobby.cpp
+++ b/netlogic/lobby.cpp
@@ -51,6 +51,7 @@ LobbyDialogDelegate::OnLoad()
 {
 	int i, count;
 	IPaddress addresses[32];
+	char name[32];
 
 	// Get the address of the global server
 	if (SDLNet_ResolveHost(&m_globalServer, GLOBAL_SERVER_HOST, LOBBY_PORT) < 0) {
@@ -92,6 +93,22 @@ LobbyDialogDelegate::OnLoad()
 		return false;
 	}
 
+	count = SDL_arraysize(m_gameListElements);
+	for (i = 0; i < count; ++i) {
+		SDL_snprintf(name, sizeof(name), "game%d", i+1);
+		if (!GetElement(name, m_gameListElements[i])) {
+			return false;
+		}
+	}
+
+	count = SDL_arraysize(m_gameInfoPlayers);
+	for (i = 0; i < count; ++i) {
+		SDL_snprintf(name, sizeof(name), "player%d", i+1);
+		if (!GetElement(name, m_gameInfoPlayers[i])) {
+			return false;
+		}
+	}
+
 	return true;
 }
 
@@ -180,6 +197,7 @@ LobbyDialogDelegate::SetHostOrJoin(void*, int value)
 		if (m_state == STATE_HOSTING) {
 			m_game.SetHostInfo(m_uniqueID, prefs->GetString(PREFERENCES_HANDLE));
 		}
+		m_game.SetLocalID(m_uniqueID);
 	} else {
 		m_state = STATE_NONE;
 	}
@@ -210,9 +228,20 @@ LobbyDialogDelegate::UpdateUI()
 	} else if (m_state == STATE_LISTING) {
 		m_gameListArea->Show();
 		m_gameInfoArea->Hide();
+		for (int i = 0; (unsigned)i < SDL_arraysize(m_gameListElements); ++i) {
+			if (i < m_gameList.length()) {
+				m_gameListElements[i]->Show();
+				m_gameList[i].BindPlayerToUI(0, m_gameListElements[i]);
+			} else {
+				m_gameListElements[i]->Hide();
+			}
+		}
 	} else {
 		m_gameInfoArea->Show();
 		m_gameListArea->Hide();
+		for (int i = 0; i < MAX_PLAYERS; ++i) {
+			m_game.BindPlayerToUI(i, m_gameInfoPlayers[i]);
+		}
 	}
 	if (m_state == STATE_HOSTING) {
 		m_playButton->SetDisabled(false);
diff --git a/netlogic/lobby.h b/netlogic/lobby.h
index 91e6ac06..5c8a8cfb 100644
--- a/netlogic/lobby.h
+++ b/netlogic/lobby.h
@@ -94,7 +94,9 @@ class LobbyDialogDelegate : public UIDialogDelegate
 	UIElementRadioGroup *m_hostOrJoin;
 	UIElementCheckbox *m_globalGame;
 	UIElement *m_gameListArea;
+	UIElement *m_gameListElements[5];
 	UIElement *m_gameInfoArea;
+	UIElement *m_gameInfoPlayers[MAX_PLAYERS];
 	UIElement *m_playButton;
 };