Maelstrom: Massively compress the replay data. It can be zlib compressed for even more savings.

https://github.com/libsdl-org/Maelstrom/commit/001a45101c44da993662fe4edc49515401f34e09

From 001a45101c44da993662fe4edc49515401f34e09 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 20 Nov 2011 03:39:59 -0500
Subject: [PATCH] Massively compress the replay data.  It can be zlib
 compressed for even more savings.

---
 game/replay.cpp | 39 ++++++++++++++++++++++++++++++---------
 game/replay.h   |  1 +
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/game/replay.cpp b/game/replay.cpp
index 5e31a45a..05feeb42 100644
--- a/game/replay.cpp
+++ b/game/replay.cpp
@@ -25,6 +25,10 @@
 #include "replay.h"
 
 
+#define DELTA_SIZEMASK	0x7F
+#define DELTA_SEED	0x80
+
+
 Replay::Replay()
 {
 	m_mode = REPLAY_IDLE;
@@ -60,6 +64,7 @@ Replay::HandleNewGame()
 		gGameInfo.CopyFrom(m_game);
 		gGameInfo.PrepareForReplay();
 	}
+	m_seed = m_game.seed;
 	m_data.Seek(0);
 }
 
@@ -70,21 +75,28 @@ Replay::HandlePlayback()
 		return true;
 	}
 
-	// Check to make sure we haven't gotten a consistency error
-	Uint32 seed;
-	if (!m_data.Read(seed)) {
+	Uint8 delta;
+	if (!m_data.Read(delta)) {
 		// That's it, end of recording
 		return false;
 	}
-	if (seed != GetRandSeed()) {
+
+	// Check to make sure we haven't gotten a consistency error
+	if (delta & DELTA_SEED) {
+		if (!m_data.Read(m_seed)) {
+			error("Error in replay, missing data\r\n");
+			return false;
+		}
+	}
+	if (m_seed != GetRandSeed()) {
 		error("Error!! \a Frame consistency problem, aborting!!\r\n");
 		return false;
 	}
 
 	// Add the input for this frame
-	Uint16 size;
+	int size = (delta & DELTA_SIZEMASK);
 	Uint8 value;
-	if (!m_data.Read(size) || (m_data.Size() < (int)size)) {
+	if (m_data.Size() < size) {
 		error("Error in replay, missing data\r\n");
 		return false;
 	}
@@ -103,12 +115,21 @@ Replay::HandleRecording()
 	}
 
 	// Get the input for this frame
+	Uint8 delta;
 	Uint8 *data;
 	int len = GetSyncBuf(&data);
+	assert(len < DELTA_SIZEMASK);
+	delta = (Uint8)len;
 
 	// Add it to our data buffer
-	m_data.Write(GetRandSeed());
-	assert(len <= 0xFFFF);
-	m_data.Write((Uint16)len);
+	Uint32 seed = GetRandSeed();
+	if (seed != m_seed) {
+		delta |= DELTA_SEED;
+		m_data.Write(delta);
+		m_data.Write(seed);
+		m_seed = seed;
+	} else {
+		m_data.Write(delta);
+	}
 	m_data.Write(data, len);
 }
diff --git a/game/replay.h b/game/replay.h
index eb948e6d..23bdd74a 100644
--- a/game/replay.h
+++ b/game/replay.h
@@ -65,6 +65,7 @@ class Replay
 protected:
 	REPLAY_MODE m_mode;
 	GameInfo m_game;
+	Uint32 m_seed;
 	DynamicPacket m_data;
 };