https://github.com/libsdl-org/Maelstrom/commit/d5c2b7aaeb76e53bfdab9da0a4dcd3df0a81bfc8
From d5c2b7aaeb76e53bfdab9da0a4dcd3df0a81bfc8 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 6 Nov 2011 10:57:27 -0500
Subject: [PATCH] Actually wire up the networked players and start a game
together! At this point we have functional multiplayer from the lobby screen.
Now we just have to handle the many edge cases and improve user flow.
---
netlogic/gameinfo.h | 45 ++++++++++++++++---------------
netlogic/lobby.cpp | 30 ++++++++++++++++++---
netlogic/lobby.h | 1 +
netlogic/netplay.cpp | 64 ++++++++------------------------------------
netlogic/netplay.h | 5 ++--
5 files changed, 66 insertions(+), 79 deletions(-)
diff --git a/netlogic/gameinfo.h b/netlogic/gameinfo.h
index 24facc3f..bde72ab7 100644
--- a/netlogic/gameinfo.h
+++ b/netlogic/gameinfo.h
@@ -36,6 +36,24 @@ enum {
CONTROL_NETWORK,
};
+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;
+};
+
class GameInfo
{
public:
@@ -59,6 +77,10 @@ class GameInfo
bool ReadFromPacket(DynamicPacket &packet);
void WriteToPacket(DynamicPacket &packet);
+ GameInfoPlayer *GetPlayer(int index) {
+ return &players[index];
+ }
+
bool HasPlayer(Uint32 playerID) {
for (int i = 0; i < MAX_PLAYERS; ++i) {
if (players[i].playerID == playerID) {
@@ -86,34 +108,15 @@ class GameInfo
}
void BindPlayerToUI(int index, UIElement *element);
+ void UpdateUI();
+ void UpdateUI(GameInfoPlayer *player);
public:
Uint32 gameID;
Uint8 deathMatch;
-
- 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;
- };
GameInfoPlayer players[MAX_PLAYERS];
Uint32 localID;
-
-protected:
- void UpdateUI();
- void UpdateUI(GameInfoPlayer *player);
};
#endif // _gameinfo_h
diff --git a/netlogic/lobby.cpp b/netlogic/lobby.cpp
index fea0cd91..00875bf1 100644
--- a/netlogic/lobby.cpp
+++ b/netlogic/lobby.cpp
@@ -25,6 +25,7 @@
#include "SDL_net.h"
#include "../Maelstrom_Globals.h"
+#include "../screenlib/UIElement.h"
#include "../screenlib/UIElementCheckbox.h"
#include "../screenlib/UIElementRadio.h"
#include "lobby.h"
@@ -143,6 +144,16 @@ LobbyDialogDelegate::OnHide()
{
// Start the game!
if (m_dialog->GetDialogStatus() > 0) {
+ for (int i = 0; i < MAX_PLAYERS; ++i) {
+ GameInfoPlayer *player = m_game.GetPlayer(i);
+ if (player->playerID) {
+ if (player->playerID == m_game.localID) {
+ AddLocalPlayer(i);
+ } else {
+ AddNetworkPlayer(i, player->address);
+ }
+ }
+ }
NewGame();
}
@@ -369,6 +380,9 @@ LobbyDialogDelegate::ProcessPacket(DynamicPacket &packet)
return;
}
if (cmd != LOBBY_MSG) {
+ if (cmd == NEW_GAME) {
+ ProcessNewGame(packet);
+ }
return;
}
if (!m_packet.Read(cmd)) {
@@ -419,6 +433,15 @@ LobbyDialogDelegate::ProcessPacket(DynamicPacket &packet)
}
}
+void
+LobbyDialogDelegate::ProcessNewGame(DynamicPacket &packet)
+{
+ // Ooh, ooh, they're starting!
+ if (m_game.HasPlayer(packet.address)) {
+ m_playButton->OnClick();
+ }
+}
+
void
LobbyDialogDelegate::ProcessAnnouncePlayer(DynamicPacket &packet)
{
@@ -487,7 +510,7 @@ LobbyDialogDelegate::ProcessRequestJoin(DynamicPacket &packet)
assert(slot < MAX_PLAYERS);
// Fill in the data
- GameInfo::GameInfoPlayer *player = &m_game.players[slot];
+ GameInfoPlayer *player = m_game.GetPlayer(slot);
player->playerID = playerID;
player->address = packet.address;
SDL_strlcpy(player->name, name, sizeof(player->name));
@@ -496,9 +519,10 @@ LobbyDialogDelegate::ProcessRequestJoin(DynamicPacket &packet)
m_reply.StartLobbyMessage(LOBBY_GAME_INFO);
m_game.WriteToPacket(m_reply);
for (slot = 0; slot < MAX_PLAYERS; ++slot) {
- Uint32 playerID = m_game.players[slot].playerID;
+ GameInfoPlayer *player = m_game.GetPlayer(slot);
+ Uint32 playerID = player->playerID;
if (playerID && playerID != m_uniqueID) {
- m_reply.address = m_game.players[slot].address;
+ m_reply.address = player->address;
SDLNet_UDP_Send(gNetFD, -1, &m_reply);
}
}
diff --git a/netlogic/lobby.h b/netlogic/lobby.h
index 01ec2a29..9ee95bd9 100644
--- a/netlogic/lobby.h
+++ b/netlogic/lobby.h
@@ -68,6 +68,7 @@ class LobbyDialogDelegate : public UIDialogDelegate
void PackAddresses(DynamicPacket &packet);
void ProcessPacket(DynamicPacket &packet);
+ void ProcessNewGame(DynamicPacket &packet);
void ProcessAnnouncePlayer(DynamicPacket &packet);
void ProcessRequestGameInfo(DynamicPacket &packet);
void ProcessRequestJoin(DynamicPacket &packet);
diff --git a/netlogic/netplay.cpp b/netlogic/netplay.cpp
index 6d2460be..6af5016e 100644
--- a/netlogic/netplay.cpp
+++ b/netlogic/netplay.cpp
@@ -79,7 +79,7 @@ int InitNetData(bool hosting)
/* Initialize the networking subsystem */
if ( SDLNet_Init() < 0 ) {
- error("Couldn't initialize networking: %s\n", SDL_GetError());
+ error("Couldn't initialize networking: %s\n", SDLNet_GetError());
return(-1);
}
@@ -91,7 +91,7 @@ int InitNetData(bool hosting)
}
gNetFD = SDLNet_UDP_Open(port);
if ( gNetFD == NULL ) {
- error("Couldn't create bound network socket\n");
+ error("Couldn't create socket bound to port %d: %s\n", port, SDLNet_GetError());
return(-1);
}
SocketSet = SDLNet_AllocSocketSet(1);
@@ -147,59 +147,17 @@ void HaltNetData(void)
SDLNet_Quit();
}
-int AddPlayer(const char *playerstr)
+void AddLocalPlayer(int playernum)
{
- int playernum;
- int portnum;
- char *host=NULL, *port=NULL;
-
- /* Extract host and port information */
- if ( (port=strchr(playerstr, ':')) != NULL )
- *(port++) = '\0';
- if ( (host=strchr(playerstr, '@')) != NULL )
- *(host++) = '\0';
-
- /* Find out which player we are referring to */
- if (((playernum = atoi(playerstr)) <= 0) || (playernum > MAX_PLAYERS)) {
- error(
-"Argument to '-player' must be in integer between 1 and %d inclusive.\r\n",
- MAX_PLAYERS);
- PrintUsage();
- }
-
- /* Do some error checking */
- if ( GotPlayer[--playernum] ) {
- error("Player %d specified multiple times!\r\n", playernum+1);
- return(-1);
- }
- if ( port ) {
- portnum = atoi(port);
- } else {
- portnum = NETPLAY_PORT+playernum;
- }
- if ( host ) {
- /* Resolve the remote address */
- SDLNet_ResolveHost(&PlayAddr[playernum], host, portnum);
- if ( PlayAddr[playernum].host == INADDR_NONE ) {
- error("Couldn't resolve host name for %s\r\n", host);
- return(-1);
- }
- } else { /* No host specified, local player */
- if ( FoundUs ) {
- error(
-"More than one local player! (players %d and %d specified as local players)\r\n",
- gOurPlayer+1, playernum+1);
- return(-1);
- } else {
- gOurPlayer = playernum;
- FoundUs = 1;
- SDLNet_ResolveHost(&PlayAddr[playernum], NULL, portnum);
- }
- }
+ gOurPlayer = playernum;
+ FoundUs = 1;
+ GotPlayer[playernum] = 1;
+}
- /* We're done! */
+void AddNetworkPlayer(int playernum, const IPaddress &address)
+{
+ PlayAddr[playernum] = address;
GotPlayer[playernum] = 1;
- return(0);
}
/* This MUST be called after command line options have been processed. */
@@ -214,7 +172,7 @@ int CheckPlayers(void)
}
/* Add ourselves if needed */
if ( gNumPlayers == 0 ) {
- AddPlayer("1");
+ AddLocalPlayer(0);
gNumPlayers = 1;
FoundUs = 1;
}
diff --git a/netlogic/netplay.h b/netlogic/netplay.h
index 56e64d7d..65211462 100644
--- a/netlogic/netplay.h
+++ b/netlogic/netplay.h
@@ -20,13 +20,14 @@
slouken@libsdl.org
*/
-// Forward declaration from SDL_net.h
-typedef struct _UDPsocket *UDPsocket;
+#include "SDL_net.h"
/* Functions in netplay.cpp */
extern int InitNetData(bool hosting);
extern void HaltNetData(void);
extern int AddPlayer(const char *playerstr);
+extern void AddLocalPlayer(int playernum);
+extern void AddNetworkPlayer(int playernum, const IPaddress &address);
extern int CheckPlayers(void);
extern void QueueKey(unsigned char Op, unsigned char Type);
extern int SyncNetwork(void);