diff -r f5b526a3423a -r 07578e081ae8 src/demo.cpp
--- 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 .
- */
-
-#include
-#include
-#include
-#include
-#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 versions = Config::get ("versions").toList();
-
- for (int i = 0; i < versions.size(); ++i)
- {
- if (not versions[i].canConvert())
- continue;
-
- ZandronumVersion version = versions[i].value();
-
- 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 += "
";
-
- 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;
-}