Fix demo launching

Fri, 05 Jun 2015 19:13:44 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Fri, 05 Jun 2015 19:13:44 +0300
changeset 38
db677d321cf4
parent 37
c82a86ea87be
child 39
2c368cf5cc19

Fix demo launching

src/demo.cpp file | annotate | diff | comparison | revisions
src/demo.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/types.h file | annotate | diff | comparison | revisions
--- a/src/demo.cpp	Fri Jun 05 18:33:51 2015 +0300
+++ b/src/demo.cpp	Fri Jun 05 19:13:44 2015 +0300
@@ -74,15 +74,21 @@
 // -------------------------------------------------------------------------------------------------
 //
 
-static bool isKnownVersion (QString ver)
+static ZandronumVersion findVersion (QString versionName)
 {
 	for (const QVariant& it : getVersions())
 	{
-		if (it.toString() == ver || it.toString() + 'M' == ver)
-			return true;
+		ZandronumVersion version = it.value<ZandronumVersion>();
+
+		if (version.name == versionName
+			or version.name + "M" == versionName
+			or version.name == versionName + "M")
+		{
+			return version;
+		}
 	}
 	
-	return false;
+	return ZandronumVersion();
 }
 
 //
@@ -149,6 +155,15 @@
 	uint8 connectionType;
 };
 
+struct DemoHeaders
+{
+	uint8 length;
+	uint8 version;
+	uint8 userInfo;
+	uint8 bodyStart;
+	uint8 wads;
+};
+
 int launchDemo (QString path)
 {
 	QFile f (path);
@@ -161,8 +176,8 @@
 	
 	QDataStream stream (&f);
 	stream.setByteOrder (QDataStream::LittleEndian);
-
-	uint8 offset;
+	
+	DemoHeaders headers;
 	uint32 length;
 	uint16 zanversionID, numWads;
 	uint32 longSink;
@@ -188,12 +203,15 @@
 			return 1;
 		}
 	}
-	
-	// Zandronum stores CLD_DEMOLENGTH after the signature. This is also the
-	// first demo enumerator, so we can determine the offset (which is variable!)
-	// from this byte
-	stream >> offset
+
+	stream >> headers.length
 	       >> length;
+
+	// The remaining headers are variable and relative to the length header.
+	headers.version = headers.length + 1;
+	headers.userInfo = headers.length + 3,
+	headers.bodyStart = headers.length + 4;
+	headers.wads = headers.length + 10;
 	
 	// Read the demo header and get data
 	for (;;)
@@ -201,12 +219,12 @@
 		uint8 header;
 		stream >> header;
 		
-		if (header == DemoBodyStart + offset)
+		if (header == headers.bodyStart)
 		{
 			ready = true;
 			break;
 		}
-		else if (header == DemoVersion + offset)
+		else if (header == headers.version)
 		{
 			stream >> zanversionID;
 			zanversion = readString (stream);
@@ -218,9 +236,13 @@
 				buildID = (BuildType) a;
 			}
 
+			// The demo wads header accidentally changed in 1.3. :(
+			if (zanversion.left(1).toInt() >= 2 or zanversion.startsWith ("1.3"))
+				headers.wads = headers.length + 8;
+
 			stream >> longSink; // rng seed - we don't need it
 		}
-		else if (header == DemoUserInfo + offset)
+		else if (header == headers.userInfo)
 		{
 			userinfo.netname = readString (stream);
 			stream >> userinfo.gender;
@@ -235,20 +257,19 @@
 			stream >> userinfo.connectionType;
 			userinfo.className = readString (stream);
 		}
-		else if (header == DemoWads + offset)
+		else if (header == headers.wads)
 		{
 			QString sink;
 			stream >> numWads;
 			
-			for (uint8 i = 0; i < numWads; ++i) {
+			for (uint8 i = 0; i < numWads; ++i)
+			{
 				QString wad = readString (stream);
 				wads << wad;
 			}
 			
-			// The demo has two checksum strings. We're not interested
-			// in them though. Down the sink they go...
-			for (int i = 0; i < 2; ++i)
-				sink = readString (stream);
+			// The demo has two checksum strings. We're not interested in them, though.
+			(sink = readString (stream)) = readString (stream);
 		}
 		else
 		{
@@ -262,22 +283,16 @@
 		error (tr ("Incomplete demo header in '%s'!").arg (path));
 		return 1;
 	}
-	
-	if (not isKnownVersion (zanversion))
+
+	ZandronumVersion version = findVersion (zanversion);
+
+	if (version.name.isNull())
 	{
 		QDialog* prompt = new UnknownVersionPrompt (path, zanversion, (buildID == ReleaseBuild));
 
 		if (not prompt->exec())
 			return 1;
 	}
-
-	QString binarypath = Config::get ("binarypaths").toMap()[zanversion].toString();
-
-	if (binarypath.isEmpty())
-	{
-		error (tr ("No binary path specified for Zandronum version %1!").arg (zanversion));
-		return 1;
-	}
 	
 	QString iwadpath;
 	QStringList pwadpaths;
@@ -341,7 +356,7 @@
 
 	// print ("Executing: %1 %2\n", binarypath, cmdlineList.join (" "));
 	QProcess* proc = new QProcess;
-	proc->start (binarypath, cmdlineList);
+	proc->start (version.binaryPath, cmdlineList);
 	proc->waitForFinished (-1);
 	return 0;
 }
--- a/src/demo.h	Fri Jun 05 18:33:51 2015 +0300
+++ b/src/demo.h	Fri Jun 05 19:13:44 2015 +0300
@@ -19,21 +19,6 @@
 #pragma once
 #include "types.h"
 
-enum
-{
-	DemoLength,
-	DemoVersion,
-	DemoCVars,
-	DemoUserInfo,
-	DemoBodyStart,
-	DemoTiccmd,
-	DemoInvUse,
-	DemoCenterView,
-	DemoTaunt,
-	DemoEnd,
-	DemoWads
-};
-
 enum BuildType
 {
 	OtherBuild    = 0,
--- a/src/main.cpp	Fri Jun 05 18:33:51 2015 +0300
+++ b/src/main.cpp	Fri Jun 05 19:13:44 2015 +0300
@@ -32,6 +32,8 @@
 	app.setApplicationName (UNIXNAME);
 	app.setOrganizationName (UNIXNAME);
 	app.setApplicationVersion (versionString());
+	qRegisterMetaType<ZandronumVersion> ("ZandronumVersion");
+	qRegisterMetaTypeStreamOperators<ZandronumVersion> ("ZandronumVersion");
 
 	for (int i = 1; i < argc; ++i)
 	{
--- a/src/types.h	Fri Jun 05 18:33:51 2015 +0300
+++ b/src/types.h	Fri Jun 05 19:13:44 2015 +0300
@@ -54,6 +54,14 @@
 	bool isRelease;
 };
 
-Q_DECLARE_METATYPE (ZandronumVersion)
-typedef QList<ZandronumVersion> VersionList;
+inline QDataStream& operator<< (QDataStream& out, const ZandronumVersion& version)
+{
+	return (out << version.name << version.binaryPath << version.isRelease);
+}
 
+inline QDataStream& operator>> (QDataStream& in, ZandronumVersion& version)
+{
+	return (in >> version.name >> version.binaryPath >> version.isRelease);
+}
+
+Q_DECLARE_METATYPE (ZandronumVersion)
\ No newline at end of file

mercurial