Maelstrom: The GameInfo structure is the canonical place for the game parameters.

https://github.com/libsdl-org/Maelstrom/commit/458181e3fb1aff75c43d8af3d164e5a5667b0c9d

From 458181e3fb1aff75c43d8af3d164e5a5667b0c9d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 17 Nov 2011 01:50:02 -0500
Subject: [PATCH] The GameInfo structure is the canonical place for the game
 parameters. This will allow us to serialize this information for replays and
 maybe let us show more interesting information in the lobby.

---
 game/Maelstrom.h         |  4 +++
 game/Maelstrom_Globals.h |  7 ++---
 game/about.cpp           |  2 --
 game/game.cpp            | 30 ++++++++++---------
 game/gameinfo.cpp        | 38 +++++++++++++++++++++++-
 game/gameinfo.h          | 10 +++++--
 game/lobby.cpp           | 19 ++++++++----
 game/lobby.h             |  2 +-
 game/main.cpp            | 29 ++++++++++--------
 game/netplay.cpp         | 64 +++++++++++++++-------------------------
 game/netplay.h           |  5 ++--
 game/player.cpp          | 12 ++++----
 game/player.h            |  2 +-
 game/protocol.h          |  2 +-
 14 files changed, 131 insertions(+), 95 deletions(-)

diff --git a/game/Maelstrom.h b/game/Maelstrom.h
index 36f6af0d..aea32e54 100644
--- a/game/Maelstrom.h
+++ b/game/Maelstrom.h
@@ -37,6 +37,10 @@
 #define FRAME_DELAY		2
 #define FRAME_DELAY_MS		((FRAME_DELAY*1000)/60)
 
+#define DEFAULT_START_WAVE	1
+#define DEFAULT_START_LIVES	3
+#define DEFAULT_START_TURBO	0
+
 #define MAX_SPRITES		100
 #define MAX_SPRITE_FRAMES	60
 #define	MAX_STARS		30
diff --git a/game/Maelstrom_Globals.h b/game/Maelstrom_Globals.h
index fa8fd07f..6a4e46e1 100644
--- a/game/Maelstrom_Globals.h
+++ b/game/Maelstrom_Globals.h
@@ -40,6 +40,7 @@
 #include "fastrand.h"
 #include "scores.h"
 #include "controls.h"
+#include "gameinfo.h"
 
 // Preferences keys
 #define PREFERENCES_HANDLE "Handle"
@@ -93,7 +94,6 @@ extern void  SetStar(int which);
 // in main.cpp : 
 extern Bool	gUpdateBuffer;
 extern Bool	gRunning;
-extern int	gNoDelay;
 
 // in init.cpp : 
 extern Sint32	gLastHigh;
@@ -143,9 +143,8 @@ extern PrefsVariable<int> gGammaCorrect;
 extern Scores	hScores[];
 
 // -- Variables specific to each game 
-// in main.cpp : 
-extern int	gStartLives;
-extern int	gStartLevel;
+// in game.cpp : 
+extern GameInfo gGameInfo;
 // in init.cpp : 
 extern Uint32	gLastDrawn;
 extern int	gNumSprites;
diff --git a/game/about.cpp b/game/about.cpp
index e207dc56..23232b5e 100644
--- a/game/about.cpp
+++ b/game/about.cpp
@@ -30,8 +30,6 @@ AboutPanelDelegate::OnShow()
 {
 	int x, y, off;
 
-	gNoDelay = 0;
-
 	x = (80) * SCALE_FACTOR;
 	y = (136) * SCALE_FACTOR;
 	off = 39 * SCALE_FACTOR;
diff --git a/game/game.cpp b/game/game.cpp
index 9e92a896..339ac43f 100644
--- a/game/game.cpp
+++ b/game/game.cpp
@@ -30,6 +30,7 @@
 #include "../screenlib/UIElement.h"
 
 // Global variables set in this file...
+GameInfo gGameInfo;
 int	gScore;
 int	gGameOn;
 int	gPaused;
@@ -66,15 +67,16 @@ void NewGame(void)
 	if ( CheckPlayers() < 0 )
 		return;
 
+	/* Start up the random number generator */
+	SeedRandom(gGameInfo.seed);
+
 	/* Send a "NEW_GAME" packet onto the network */
 	if ( gNumPlayers > 1 ) {
 		if ( gOurPlayer == 0 ) {
-			if ( Send_NewGame(&gStartLevel,&gStartLives,&gNoDelay)
-									< 0)
+			if ( Send_NewGame() < 0)
 				return;
 		} else {
-			if ( Await_NewGame(&gStartLevel,&gStartLives,&gNoDelay)
-									< 0 )
+			if ( Await_NewGame() < 0 )
 				return;
 		}
 	}
@@ -92,7 +94,7 @@ void NewGame(void)
 		screen->FadeIn();
 
 		/* Timing handling -- Delay the FRAME_DELAY */
-		if ( ! gNoDelay ) {
+		if ( ! gGameInfo.turbo ) {
 			DelayFrame();
 		}
 	}
@@ -151,9 +153,9 @@ GamePanelDelegate::OnShow()
 	/* Initialize some game variables */
 	gGameOn = 1;
 	gPaused = 0;
-	gWave = gStartLevel - 1;
+	gWave = gGameInfo.wave - 1;
 	for ( i=gNumPlayers; i--; )
-		gPlayers[i]->NewGame(gStartLives);
+		gPlayers[i]->NewGame(gGameInfo.lives, gGameInfo.deathMatch);
 	gLastStar = STAR_DELAY;
 	gLastDrawn = 0L;
 	gNumSprites = 0;
@@ -173,7 +175,7 @@ GamePanelDelegate::OnShow()
 			m_multiplayerColor->Hide();
 		}
 	}
-	if ( gDeathMatch ) {
+	if ( gGameInfo.deathMatch ) {
 		if (m_fragsLabel) {
 			m_fragsLabel->Show();
 		}
@@ -261,7 +263,7 @@ GamePanelDelegate::OnTick()
 				gSprites[i] = gSprites[gNumSprites];
 			}
 		}
-		if ( gDeathMatch ) {
+		if ( gGameInfo.deathMatch ) {
 			OBJ_LOOP(i, gNumPlayers) {
 				if ( i == j )	// Don't shoot ourselves. :)
 					continue;
@@ -736,7 +738,7 @@ GamePanelDelegate::NextWave()
 	gShakeTime = 0;
 	gFreezeTime = 0;
 
-	if (gWave != (gStartLevel - 1))
+	if (gWave != (gGameInfo.wave - 1))
 		DoBonus();
 
 	gWave++;
@@ -866,7 +868,7 @@ static void DoGameOver(void)
 		final[i].Score = gPlayers[i]->GetScore();
 		final[i].Frags = gPlayers[i]->GetFrags();
 	}
-	if ( gDeathMatch )
+	if ( gGameInfo.deathMatch )
 		qsort(final,gNumPlayers,sizeof(struct FinalScore),cmp_byfrags);
 	else
 		qsort(final,gNumPlayers,sizeof(struct FinalScore),cmp_byscore);
@@ -893,7 +895,7 @@ static void DoGameOver(void)
 			if (!label) {
 				continue;
 			}
-			if (gDeathMatch) {
+			if (gGameInfo.deathMatch) {
 				sprintf(num1, "%7d", final[i].Score);
 				sprintf(num2, "%3d", final[i].Frags);
 				sprintf(buffer, "Player %d: %s Points, %s Frags", final[i].Player, num1, num2);
@@ -925,8 +927,8 @@ static void DoGameOver(void)
 	/* -- They got a high score! */
 	gLastHigh = which;
 
-	if ((which != -1) && (gStartLevel == 1) && (gStartLives == 3) &&
-					(gNumPlayers == 1) && !gDeathMatch ) {
+	if ((which != -1) && (gNumPlayers == 1) &&
+			(gGameInfo.wave == 1) && (gGameInfo.lives == 3)) {
 		sound->PlaySound(gBonusShot, 5);
 
 		/* -- Let them enter their name */
diff --git a/game/gameinfo.cpp b/game/gameinfo.cpp
index 5f4ebfb6..aff77464 100644
--- a/game/gameinfo.cpp
+++ b/game/gameinfo.cpp
@@ -35,9 +35,25 @@ GameInfo::Reset()
 }
 
 void
-GameInfo::SetHostInfo(Uint32 gameID, const char *name)
+GameInfo::SetSinglePlayer(Uint8 wave, Uint8 lives, Uint8 turbo)
+{
+	this->gameID = 1;
+	this->seed = GetRandSeed();
+	this->wave = wave;
+	this->lives = lives;
+	this->turbo = turbo;
+	this->deathMatch = 0;
+}
+
+void
+GameInfo::SetMultiplayerHost(Uint32 gameID, const char *name)
 {
 	this->gameID = gameID;
+	this->seed = GetRandSeed();
+	this->wave = DEFAULT_START_WAVE;
+	this->lives = DEFAULT_START_LIVES;
+	this->turbo = DEFAULT_START_TURBO;
+	this->deathMatch = 0;
 	players[HOST_PLAYER].playerID = gameID;
 	SDL_strlcpy(players[HOST_PLAYER].name, name ? name : "",
 			sizeof(players[HOST_PLAYER].name));
@@ -47,6 +63,10 @@ void
 GameInfo::CopyFrom(const GameInfo &rhs)
 {
 	gameID = rhs.gameID;
+	seed = rhs.seed;
+	wave = rhs.wave;
+	lives = rhs.lives;
+	turbo = rhs.turbo;
 	deathMatch = rhs.deathMatch;
 
 	for (int i = 0; i < MAX_PLAYERS; ++i) {
@@ -69,6 +89,18 @@ GameInfo::ReadFromPacket(DynamicPacket &packet)
 	if (!packet.Read(gameID)) {
 		return false;
 	}
+	if (!packet.Read(seed)) {
+		return false;
+	}
+	if (!packet.Read(wave)) {
+		return false;
+	}
+	if (!packet.Read(lives)) {
+		return false;
+	}
+	if (!packet.Read(turbo)) {
+		return false;
+	}
 	if (!packet.Read(deathMatch)) {
 		return false;
 	}
@@ -101,6 +133,10 @@ void
 GameInfo::WriteToPacket(DynamicPacket &packet)
 {
 	packet.Write(gameID);
+	packet.Write(seed);
+	packet.Write(wave);
+	packet.Write(lives);
+	packet.Write(turbo);
 	packet.Write(deathMatch);
 
 	for (int i = 0; i < MAX_PLAYERS; ++i) {
diff --git a/game/gameinfo.h b/game/gameinfo.h
index 639a4422..864cc1f7 100644
--- a/game/gameinfo.h
+++ b/game/gameinfo.h
@@ -82,12 +82,14 @@ class GameInfo
 
 	void Reset();
 
+	void SetSinglePlayer(Uint8 wave, Uint8 lives, Uint8 turbo);
+
+	void SetMultiplayerHost(Uint32 gameID, const char *name);
+
 	void SetLocalID(Uint32 playerID) {
 		localID = playerID;
 	}
 
-	void SetHostInfo(Uint32 gameID, const char *name);
-
 	void CopyFrom(const GameInfo &rhs);
 
 	bool ReadFromPacket(DynamicPacket &packet);
@@ -164,6 +166,10 @@ class GameInfo
 
 public:
 	Uint32 gameID;
+	Uint32 seed;
+	Uint8 wave;
+	Uint8 lives;
+	Uint8 turbo;
 	Uint8 deathMatch;
 	GameInfoPlayer players[MAX_PLAYERS];
 
diff --git a/game/lobby.cpp b/game/lobby.cpp
index 33a742f7..3b244ed4 100644
--- a/game/lobby.cpp
+++ b/game/lobby.cpp
@@ -42,7 +42,8 @@
 
 
 LobbyDialogDelegate::LobbyDialogDelegate(UIPanel *panel) :
-	UIDialogDelegate(panel)
+	UIDialogDelegate(panel),
+	m_game(gGameInfo)
 {
 	m_state = STATE_NONE;
 	m_uniqueID = 0;
@@ -155,10 +156,6 @@ LobbyDialogDelegate::OnHide()
 	// Start the game!
 	if (m_dialog->GetDialogStatus() > 0) {
 		SetState(STATE_PLAYING);
-		gStartLevel = 1;
-		gStartLives = 3;
-		gNoDelay = 0;
-		gDeathMatch = m_game.deathMatch;
 
 		for (int i = 0; i < MAX_PLAYERS; ++i) {
 			GameInfoPlayer *player = m_game.GetPlayer(i);
@@ -327,7 +324,7 @@ LobbyDialogDelegate::SetState(LOBBY_STATE state)
 			SendLeaveRequest();
 		}
 	} else if (state == STATE_HOSTING) {
-		m_game.SetHostInfo(m_uniqueID, prefs->GetString(PREFERENCES_HANDLE));
+		m_game.SetMultiplayerHost(m_uniqueID, prefs->GetString(PREFERENCES_HANDLE));
 	} else if (state == STATE_LISTING) {
 		ClearGameList();
 	}
@@ -659,6 +656,16 @@ LobbyDialogDelegate::ProcessPong(DynamicPacket &packet)
 void
 LobbyDialogDelegate::ProcessNewGame(DynamicPacket &packet)
 {
+	Uint8 playerIndex;
+	Uint32 gameID;
+
+	if (!packet.Read(playerIndex)) {
+		return;
+	}
+	if (!packet.Read(gameID) || gameID != m_game.gameID) {
+		return;
+	}
+
 	// Ooh, ooh, they're starting!
 	if (m_game.HasPlayer(packet.address)) {
 		m_playButton->OnClick();
diff --git a/game/lobby.h b/game/lobby.h
index 760c064e..562dac25 100644
--- a/game/lobby.h
+++ b/game/lobby.h
@@ -102,7 +102,7 @@ class LobbyDialogDelegate : public UIDialogDelegate
 	Uint32 m_lastRefresh;
 	Uint32 m_requestSequence;
 
-	GameInfo m_game;
+	GameInfo &m_game;
 	array<GameInfo> m_gameList;
 
 	DynamicPacket m_packet, m_reply;
diff --git a/game/main.cpp b/game/main.cpp
index 9d2e7daf..b4f3b9c6 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -53,11 +53,8 @@ static const char *Version =
 "Maelstrom v1.4.3 (GPL version 4.0.0) -- 10/08/2011 by Sam Lantinga\n";
 
 // Global variables set in this file...
-int	gStartLives;
-int	gStartLevel;
 Bool	gUpdateBuffer;
 Bool	gRunning;
-int	gNoDelay;
 
 
 // Main Menu actions:
@@ -75,9 +72,9 @@ static void RunSinglePlayerGame()
 }
 static void RunPlayGame(void*)
 {
-	gStartLevel = 1;
-	gStartLives = 3;
-	gNoDelay = 0;
+	gGameInfo.SetSinglePlayer(DEFAULT_START_WAVE,
+	                          DEFAULT_START_LIVES,
+	                          DEFAULT_START_TURBO);
 	RunSinglePlayerGame();
 }
 static void RunQuitGame(void*)
@@ -135,30 +132,36 @@ static void CheatDialogDone(UIDialog *dialog, int status)
 {
 	UIElementEditbox *editbox;
 	UIElementCheckbox *checkbox;
+	Uint8 wave = DEFAULT_START_WAVE;
+	Uint8 lives = DEFAULT_START_LIVES;
+	Uint8 turbo = DEFAULT_START_TURBO;
 
 	if (status > 0) {
 		editbox = dialog->GetElement<UIElementEditbox>("level");
 		if (editbox) {
-			gStartLevel = editbox->GetNumber();
-			if (gStartLevel < 1 || gStartLevel > 40) {
-				return;
+			wave = editbox->GetNumber();
+			if (wave < 1 || wave > 40) {
+				wave = DEFAULT_START_WAVE;
 			}
 		}
 
 		editbox = dialog->GetElement<UIElementEditbox>("lives");
 		if (editbox) {
-			gStartLives = editbox->GetNumber();
-			if (gStartLives < 1 || gStartLives > 40) {
-				gStartLives = 3;
+			lives = editbox->GetNumber();
+			if (lives < 1 || lives > 40) {
+				lives = DEFAULT_START_LIVES;
 			}
 		}
 
 		checkbox = dialog->GetElement<UIElementCheckbox>("turbofunk");
-		gNoDelay = checkbox->IsChecked();
+		if (checkbox) {
+			turbo = checkbox->IsChecked();
+		}
 
 		Delay(SOUND_DELAY);
 		sound->PlaySound(gNewLife, 5);
 		Delay(SOUND_DELAY);
+		gGameInfo.SetSinglePlayer(wave, lives, turbo);
 		RunSinglePlayerGame();
 	}
 }
diff --git a/game/netplay.cpp b/game/netplay.cpp
index 6e2840dd..cdca7eb3 100644
--- a/game/netplay.cpp
+++ b/game/netplay.cpp
@@ -34,7 +34,6 @@
 
 int   gNumPlayers;
 int   gOurPlayer;
-int   gDeathMatch;
 UDPsocket gNetFD;
 
 static int            GotPlayer[MAX_PLAYERS];
@@ -113,7 +112,6 @@ int InitNetData(bool hosting)
 	/* Initialize network game variables */
 	FoundUs   = 0;
 	gOurPlayer  = -1;
-	gDeathMatch = 0;
 	for ( i=0; i<MAX_PLAYERS; ++i ) {
 		GotPlayer[i] = 0;
 		SyncPtrs[0][i] = NULL;
@@ -192,9 +190,9 @@ int CheckPlayers(void)
 						gOurPlayer+1, gNumPlayers);
 		return(-1);
 	}
-	if ( (gNumPlayers == 1) && gDeathMatch ) {
+	if ( (gNumPlayers == 1) && gGameInfo.deathMatch ) {
 		error("Warning: No deathmatch in a single player game!\r\n");
-		gDeathMatch = 0;
+		gGameInfo.deathMatch = 0;
 	}
 
 	/* Now, so we can send to ourselves... */
@@ -365,13 +363,10 @@ error("Warning! Received packet for really old frame! (%lu, current = %lu)\r\n",
 		/* Do a consistency check!! */
 		Uint32 newseed = SDLNet_Read32(&buf[1+sizeof(frame)]);
 		if ( newseed != seed ) {
-//error("New seed (from player %d) is: 0x%x\r\n", index+1, newseed);
-			if ( gOurPlayer == 0 ) {
-				error(
-"Warning!! \a Frame consistency error with player %d!! (corrected)\r\n", index+1);
-SDL_Delay(3000);
-			} else	/* Player 1 sent us good seed */
-				SeedRandom(newseed);
+			/* We're hosed, to correct this we would have to sync the complete game state */
+			error(
+"Error!! \a Frame consistency error with player %d!!\r\n", index+1);
+			return(-1);
 		}
 
 		/* Okay, we finally have a valid timely packet */
@@ -423,20 +418,11 @@ inline void SuckPackets(void)
 	}
 }
 
-static inline void MakeNewPacket(int Wave, int Lives, int Turbo,
-					unsigned char *packet)
+static inline void MakeNewPacket(Uint32 gameID, unsigned char *packet)
 {
 	*packet++ = NEW_GAME;
 	*packet++ = gOurPlayer;
-	*packet++ = (unsigned char)Turbo;
-	SDLNet_Write32(Wave, packet);
-	packet += 4;
-	if ( gDeathMatch ) {
-		Lives = (gDeathMatch|0x8000);
-	}
-	SDLNet_Write32(Lives, packet);
-	packet += 4;
-	SDLNet_Write32(GetRandSeed(), packet);
+	SDLNet_Write32(gameID, packet);
 }
 
 /* Flash an error up on the screen and pause for 3 seconds */
@@ -449,13 +435,13 @@ static void ErrorMessage(const char *message)
 	SDL_Delay(3000);
 }
 
-/* This function sends a NEWGAME packet, and waits for all other players
+/* This function sends a NEW_GAME packet, and waits for all other players
    to respond in kind.
    This function is not very robust in handling errors such as multiple
    machines thinking they are the same player.  The address server is
    supposed to handle such things gracefully.
 */
-int Send_NewGame(int *Wave, int *Lives, int *Turbo)
+int Send_NewGame()
 {
 	Uint8 netbuf[BUFSIZ], sendbuf[NEW_PACKETLEN];
 	char message[BUFSIZ];
@@ -465,7 +451,7 @@ int Send_NewGame(int *Wave, int *Lives, int *Turbo)
 	UDPpacket newgame, sent;
 
 	/* Send all the packets */
-	MakeNewPacket(*Wave, *Lives, *Turbo, sendbuf);
+	MakeNewPacket(gGameInfo.gameID, sendbuf);
 	newgame.data = sendbuf;
 	newgame.len = sizeof(sendbuf);
 	SDLNet_UDP_Send(gNetFD, 0, &newgame);
@@ -526,6 +512,12 @@ int Send_NewGame(int *Wave, int *Lives, int *Turbo)
 			continue;
 		}
 
+		Uint32 gameID = SDLNet_Read32(&netbuf[2]);
+		if (gameID != gGameInfo.gameID) {
+			/* This must be for a different game */
+			continue;
+		}
+
 		/* Loop, check the address */
 		for ( i=gNumPlayers; i--; ) {
 			if ( acked[i] )
@@ -557,7 +549,7 @@ int Send_NewGame(int *Wave, int *Lives, int *Turbo)
 	return(0);
 }
 
-int Await_NewGame(int *Wave, int *Lives, int *Turbo)
+int Await_NewGame()
 {
 	unsigned char netbuf[BUFSIZ];
 	int len, gameon;
@@ -602,21 +594,11 @@ int Await_NewGame(int *Wave, int *Lives, int *Turbo)
 			continue;
 		}
 
-		/* Extract the RandomSeed and return the packet */
-		*Turbo = (int)netbuf[2];
-		len = 3;
-		*Wave = SDLNet_Read32(&netbuf[len]);
-		len += 4;
-		lives = SDLNet_Read32(&netbuf[len]);
-		len += 4;
-		if ( lives & 0x8000 )
-			gDeathMatch = (lives&(~0x8000));
-		else
-			*Lives = lives;
-		seed = SDLNet_Read32(&netbuf[len]);
-		len += 4;
-		SeedRandom(seed);
-//error("Seed is 0x%x\r\n", seed);
+		Uint32 gameID = SDLNet_Read32(&netbuf[2]);
+		if (gameID != gGameInfo.gameID) {
+			/* This must be for a different game */
+			continue;
+		}
 
 		netbuf[1] = gOurPlayer;
 		SDLNet_UDP_Send(gNetFD, 1, &sent);
diff --git a/game/netplay.h b/game/netplay.h
index 65211462..ded9463e 100644
--- a/game/netplay.h
+++ b/game/netplay.h
@@ -32,11 +32,10 @@ extern int   CheckPlayers(void);
 extern void  QueueKey(unsigned char Op, unsigned char Type);
 extern int   SyncNetwork(void);
 extern int   GetSyncBuf(int index, unsigned char **bufptr);
-extern int   Send_NewGame(int *Wave, int *Lives, int *Turbo);
-extern int   Await_NewGame(int *Wave, int *Lives, int *Turbo);
+extern int   Send_NewGame();
+extern int   Await_NewGame();
 
 /* Variables from netplay.cpp */
 extern int	gOurPlayer;
 extern int	gNumPlayers;
-extern int	gDeathMatch;
 extern UDPsocket gNetFD;
diff --git a/game/player.cpp b/game/player.cpp
index 5a59fbb8..4b2ad845 100644
--- a/game/player.cpp
+++ b/game/player.cpp
@@ -73,10 +73,10 @@ Player::~Player()
 
 /* Note that the lives argument is ignored during deathmatches */
 void
-Player::NewGame(int lives)
+Player::NewGame(int lives, int deathMatch)
 {
 	Playing = 1;
-	if ( gDeathMatch )
+	if ( deathMatch )
 		Lives = 1;
 	else
 		Lives = lives;
@@ -146,7 +146,7 @@ Player::NewShip(void)
 	Dead = 0;
 	Exploding = 0;
 	Set_TTL(-1);
-	if ( ! gDeathMatch )
+	if ( ! gGameInfo.deathMatch )
 		--Lives;
 	return(Lives);
 }
@@ -156,7 +156,7 @@ void
 Player::IncrFrags(void)
 {
 	++Frags;
-	if ( gDeathMatch && (Frags >= gDeathMatch) ) {
+	if ( gGameInfo.deathMatch && (Frags >= gGameInfo.deathMatch) ) {
 		/* Game over, we got a stud. :) */
 		int i;
 		OBJ_LOOP(i, gNumPlayers) {
@@ -172,7 +172,7 @@ error("Killing player %d\n", i+1);
 void
 Player::IncrLives(int lives)
 {
-	if ( gDeathMatch && (lives > 0) )
+	if ( gGameInfo.deathMatch && (lives > 0) )
 		return;
 	Lives += lives;
 }
@@ -245,7 +245,7 @@ Player::BeenTimedOut(void)
 							*SCALE_FACTOR),
 		((SCREEN_HEIGHT/2)*SCALE_FACTOR)
 	);
-	if ( gDeathMatch )
+	if ( gGameInfo.deathMatch )
 		Dead = (DEAD_DELAY/2);
 	else
 		Dead = DEAD_DELAY;
diff --git a/game/player.h b/game/player.h
index 42761203..f7fdffc5 100644
--- a/game/player.h
+++ b/game/player.h
@@ -46,7 +46,7 @@ class Player : public Object {
 	virtual int Kicking(void) {
 		return(Playing);
 	}
-	virtual void NewGame(int lives);
+	virtual void NewGame(int lives, int deathMatch);
 	virtual void NewWave(void);
 	/* NewShip() MUST be called before Move() */
 	virtual int NewShip(void);
diff --git a/game/protocol.h b/game/protocol.h
index 08654dab..23a64698 100644
--- a/game/protocol.h
+++ b/game/protocol.h
@@ -191,7 +191,7 @@ enum LobbyProtocol {
 #define NETPLAY_PORT	0xAF00			/* port 44800 */
 
 /* The minimum length of a new packet buffer */
-#define NEW_PACKETLEN	(3+3*4)
+#define NEW_PACKETLEN	(1+1+sizeof(Uint32))
 
 /* Note: if you change MAX_PLAYERS, you need to modify the gPlayerColors
    array in player.cpp