src/demo.cpp

changeset 46
07578e081ae8
parent 45
f5b526a3423a
child 47
4a0ad0a08ea1
--- a/src/demo.cpp	Sat Jun 06 23:06:14 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,369 +0,0 @@
-/*
- *  ZCinema: Zandronum demo launcher
- *  Copyright (C) 2013-2015 Teemu Piippo
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <QFile>
-#include <QDataStream>
-#include <QMessageBox>
-#include <QProcess>
-#include "demo.h"
-#include "misc.h"
-#include "ui_demoprompt.h"
-#include "prompts.h"
-#include "config.h"
-#include "version.h"
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-QString uncolorize (const QString& in)
-{
-	// TODO: Handle long-form colors like \c[Red]
-	QString out;
-	int skip = 0;
-
-	for (QChar c : in)
-	{
-		if (skip-- > 0)
-			continue;
-
-		if (c == QChar ('\034'))
-		{
-			skip = 1;
-			continue;
-		}
-
-		out += c;
-	}
-
-	return out;
-}
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-static QString tr (const char* msg)
-{
-	return QObject::tr (msg);
-}
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-static void error (QString msg)
-{
-	QMessageBox::critical (NULL, "Error", msg);
-}
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-static ZandronumVersion findVersion (QString versionName)
-{
-	QList<QVariant> versions = Config::get ("versions").toList();
-
-	for (int i = 0; i < versions.size(); ++i)
-	{
-		if (not versions[i].canConvert<ZandronumVersion>())
-			continue;
-
-		ZandronumVersion version = versions[i].value<ZandronumVersion>();
-
-		if (version.name == versionName
-			or version.name + "M" == versionName
-			or version.name == versionName + "M")
-		{
-			return version;
-		}
-	}
-
-	return ZandronumVersion();
-}
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-static QString findWAD (QString name)
-{
-	QStringList wadpaths = Config::get ("wadpaths").toStringList();
-
-	if (wadpaths.empty())
-	{
-		error (tr ("No WAD paths configured!"));
-
-		// Cannot just return an empty string here since that'd trigger another error prompt - skip
-		// ahead and exit.
-		exit (1);
-	}
-
-	for (int i = 0; i < wadpaths.size(); ++i)
-	{
-		QString fullpath = QString ("%1/%2").arg (wadpaths[i]).arg (name);
-		QFile f (fullpath);
-
-		if (f.exists())
-			return fullpath;
-	}
-
-	return "";
-}
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-QString readString (QDataStream& stream)
-{
-	QString out;
-	uint8 ch;
-
-	for (stream >> ch; ch != 0; stream >> ch)
-		out += QChar (ch);
-
-	return out;
-}
-
-//
-// -------------------------------------------------------------------------------------------------
-//
-
-struct UserInfo
-{
-	QString netname;
-	QString skin;
-	QString className;
-	uint32 color;
-	uint32 aimdist;
-	uint32 railcolor;
-	uint8 gender;
-	uint8 handicap;
-	uint8 unlagged;
-	uint8 respawnOnFire;
-	uint8 ticsPerUpdate;
-	uint8 connectionType;
-};
-
-struct DemoHeaders
-{
-	uint8 length;
-	uint8 version;
-	uint8 userInfo;
-	uint8 bodyStart;
-	uint8 wads;
-};
-
-int launchDemo (QString path)
-{
-	QFile f (path);
-
-	if (not f.open (QIODevice::ReadOnly))
-	{
-		error (tr ("Couldn't open '%1' for reading: %2").arg (path).arg (strerror (errno)));
-		return 1;
-	}
-
-	QDataStream stream (&f);
-	stream.setByteOrder (QDataStream::LittleEndian);
-
-	DemoHeaders headers;
-	uint32 length;
-	uint16 zanversionID, numWads;
-	uint32 longSink;
-	QString zanversion;
-	QStringList wads;
-	UserInfo userinfo;
-
-	// Assume a release build if the build ID not supplied. The demo only got the "ZCLD" signature
-	// in the 1.1 release build, 1.1.1 had no testing binaries and the build ID is included in 1.2
-	// onward.
-	BuildType buildID = ReleaseBuild;
-
-	bool ready = false;
-
-	// Check signature
-	{
-		uint32 demosignature;
-		stream >> demosignature;
-
-		if (demosignature != makeByteID ('Z', 'C', 'L', 'D'))
-		{
-			error (tr ("'%1' is not a valid Zandronum demo file!").arg (path));
-			return 1;
-		}
-	}
-
-	stream >> headers.length;
-	stream >> 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 (;;)
-	{
-		uint8 header;
-		stream >> header;
-
-		if (header == headers.bodyStart)
-		{
-			ready = true;
-			break;
-		}
-		else if (header == headers.version)
-		{
-			stream >> zanversionID;
-			zanversion = readString (stream);
-
-			if (not zanversion.startsWith ("1.1-") and not zanversion.startsWith ("1.1.1-"))
-			{
-				uint8 a;
-				stream >> a;
-				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 == headers.userInfo)
-		{
-			userinfo.netname = readString (stream);
-			stream >> userinfo.gender;
-			stream >> userinfo.color;
-			stream >> userinfo.aimdist;
-			userinfo.skin = readString (stream);
-			stream >> userinfo.railcolor;
-			stream >> userinfo.handicap;
-			stream >> userinfo.unlagged;
-			stream >> userinfo.respawnOnFire;
-			stream >> userinfo.ticsPerUpdate;
-			stream >> userinfo.connectionType;
-			userinfo.className = readString (stream);
-		}
-		else if (header == headers.wads)
-		{
-			QString sink;
-			stream >> numWads;
-
-			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.
-			(sink = readString (stream)) = readString (stream);
-		}
-		else
-		{
-			error (tr ("Unknown header %1!\n").arg (int (header)));
-			return 1;
-		}
-	}
-
-	if (not ready)
-	{
-		error (tr ("Incomplete demo header in '%s'!").arg (path));
-		return 1;
-	}
-
-	ZandronumVersion version = findVersion (zanversion);
-
-	if (version.name.isNull())
-	{
-		QDialog* prompt = new UnknownVersionPrompt (path, zanversion, (buildID == ReleaseBuild));
-
-		if (not prompt->exec())
-			return 1;
-	}
-
-	QString iwadpath;
-	QStringList pwadpaths;
-
-	// Find the WADs
-	for (const QString& wad : wads)
-	{
-		QString path = findWAD (wad);
-
-		// WAD names are case-sensitive under non-Windows and they can appear in uppercase
-		// so we need to test that too.
-		if (path.isEmpty())
-			path = findWAD (wad.toUpper());
-
-		if (path.isEmpty())
-		{
-			error (tr ("Couldn't find %1!").arg (wad));
-			return 1;
-		}
-
-		if (&wad == &wads.first())
-			iwadpath = path;
-		else
-			pwadpaths << path;
-	}
-
-	if (not Config::get ("noprompt").toBool())
-	{
-		QString pwadtext;
-
-		for (const QString& wad : wads)
-		{
-			if (&wad == &wads.first())
-				continue; // skip the IWAD
-
-			if (not pwadtext.isEmpty())
-				pwadtext += "<br />";
-
-			pwadtext += wad;
-		}
-
-		QDialog* dlg = new QDialog;
-		Ui_DemoPrompt ui;
-		ui.setupUi (dlg);
-		ui.demoNameLabel->setText (basename (path));
-		ui.demoRecorder->setText (uncolorize (userinfo.netname));
-		ui.versionLabel->setText (zanversion);
-		ui.iwadLabel->setText (wads[0]);
-		ui.pwadsLabel->setText (pwadtext);
-		dlg->setWindowTitle (versionSignature());
-
-		if (not dlg->exec())
-			return 0;
-	}
-
-	QStringList cmdlineList;
-	cmdlineList << "-playdemo" << path << "-iwad" << iwadpath;
-
-	if (pwadpaths.size() > 0)
-		cmdlineList << "-file" << pwadpaths;
-
-	// print ("Executing: %1 %2\n", binarypath, cmdlineList.join (" "));
-	QProcess* proc = new QProcess;
-	proc->start (version.binaryPath, cmdlineList);
-	proc->waitForFinished (-1);
-	return 0;
-}

mercurial