launch/mainwindow.cpp

316 lines
7 KiB
C++
Raw Normal View History

#include <Qt>
#include <QProcess>
#include <QTextStream>
#ifdef Q_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shlobj.h>
#endif
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "installwizard.h"
ioLaunch::ioLaunch(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ioLaunch)
{
ui->setupUi(this);
// Calculate ioquake3 home path.
#ifdef Q_OS_WIN32
wchar_t path[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path)))
{
homePath = QString::fromWCharArray(path) + "/Quake3";
}
#elif defined(Q_OS_MAC) || defined(Q_OS_UNIX)
const QByteArray homeEnvRaw = qgetenv("HOME");
const QString homeEnv(homeEnvRaw.constData());
#if defined Q_OS_MAC
homePath = homeEnv + "/Library/Application Support/Quake3";
#elif defined Q_OS_UNIX
homePath = homeEnv + "/.q3a";
#endif
#endif
QDir homeDir(homePath);
// Try to parse q3config.cfg to get default settings if this is the first time the program has run.
if (!homePath.isEmpty() && homeDir.exists() && !settings.getHaveRun())
{
parseQuake3Config();
}
#ifdef Q_OS_WIN32
// On first run, try to get the Q3A path on Windows by reading it from the registry.
if (!settings.getHaveRun())
{
QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Id\\Quake III Arena", QSettings::NativeFormat);
if (registry.contains("INSTALLPATH"))
{
settings.setQuakePath(registry.value("INSTALLPATH").toString());
}
}
#endif
settings.setHaveRun(true);
2014-05-09 06:17:35 +00:00
// Populate the GUI with values read from settings.
if (settings.getResolutionMode() >= 0)
{
// Predefined.
ui->cbResolution->setCurrentIndex(2 + settings.getResolutionMode());
}
else if (settings.getResolutionMode() == -1)
{
// Custom.
ui->cbResolution->setCurrentIndex(1);
2014-05-09 06:17:35 +00:00
}
else if (settings.getResolutionMode() == -2)
{
// Desktop.
ui->cbResolution->setCurrentIndex(0);
2014-05-09 06:17:35 +00:00
}
ui->sbWidth->setValue(settings.getResolutionWidth());
ui->sbHeight->setValue(settings.getResolutionHeight());
if (settings.getResolutionFullscreen())
{
ui->rbFull->setChecked(true);
}
else
{
ui->rbWin->setChecked(true);
}
}
ioLaunch::~ioLaunch()
{
delete ui;
}
void ioLaunch::on_btnLaunch_clicked()
{
QString ioq3;
#ifdef Q_OS_WIN32
if(!isQuake3PathValid())
{
InstallWizard wizard(this, &settings);
wizard.exec();
if(!isQuake3PathValid())
return;
}
ioq3 = QString("\"") + settings.getQuakePath() + "/ioquake3.x86.exe\"";
2013-12-02 01:50:15 +00:00
#elif defined Q_OS_MAC
ioq3 = "open -a ioquake3 --args";
#elif defined Q_OS_UNIX
ioq3 = "ioquake3";
#else
#error "Unsupported platform"
#endif
int r_mode = settings.getResolutionMode();
int r_width = settings.getResolutionWidth();
int r_height = settings.getResolutionHeight();
// Handle modes outside what ioquake3 recognize.
if (r_mode == 12)
{
r_mode = -1;
r_width = 1280;
r_height = 720;
}
else if (r_mode == 13)
{
r_mode = -1;
r_width = 1920;
r_height = 1080;
}
else if (r_mode == 14)
{
r_mode = -1;
r_width = 1280;
r_height = 800;
}
ioq3 += QString(" +set r_mode \"%1\"").arg(r_mode);
if (r_mode == -1)
{
ioq3 += QString(" +set r_customwidth %1").arg(r_width) + QString(" +set r_customheight %1").arg(r_height);
}
ioq3 += QString(" +set r_fullscreen %1").arg(settings.getResolutionFullscreen() ? "1" : "0");
if(!QProcess::startDetached(ioq3))
{
QMessageBox ioq3Failed;
ioq3Failed.setText("ioquake3 failed to start!\nIs it installed?\n");
ioq3Failed.exec();
}
}
void ioLaunch::on_cbResolution_currentIndexChanged(int index)
{
2014-05-09 06:17:35 +00:00
if (index == 0)
{
// Desktop.
settings.setResolutionMode(-2);
2014-05-09 06:17:35 +00:00
}
else if (index == 1)
{
// Custom.
settings.setResolutionMode(-1);
2014-05-09 06:17:35 +00:00
}
else if (index >= 2)
2014-05-09 06:17:35 +00:00
{
// Predefined.
settings.setResolutionMode(index - 2);
}
if (index == 1)
{
ui->sbWidth->setEnabled(true);
ui->sbHeight->setEnabled(true);
}
else
{
ui->sbWidth->setEnabled(false);
ui->sbHeight->setEnabled(false);
}
}
void ioLaunch::on_rbFull_toggled(bool checked)
{
if(checked)
{
2014-05-09 06:17:35 +00:00
settings.setResolutionFullscreen(true);
}
}
void ioLaunch::on_rbWin_toggled(bool checked)
{
if(checked)
{
2014-05-09 06:17:35 +00:00
settings.setResolutionFullscreen(false);
}
}
void ioLaunch::on_sbWidth_valueChanged(int arg1)
{
2014-05-09 06:17:35 +00:00
settings.setResolutionWidth(arg1);
}
void ioLaunch::on_sbHeight_valueChanged(int arg1)
{
2014-05-09 06:17:35 +00:00
settings.setResolutionHeight(arg1);
}
void ioLaunch::on_btnRunInstallWizard_clicked()
{
InstallWizard wizard(this, &settings);
wizard.exec();
}
// Since q3config.cfg is generated it's nice and clean and shouldn't need a full parser.
static QString ParseToken(const QString &s, int &offset)
{
// Skip whitespace.
while (offset < s.length() && s[offset] == ' ')
{
offset++;
}
if (offset >= s.length())
return QString();
// Check for quoted token.
bool quoted = s[offset] == '\"';
if (quoted)
offset++;
// Parse token.
int start = offset;
while (offset < s.length() && ((quoted && s[offset] != '\"') || (!quoted && s[offset] != ' ')))
{
offset++;
}
// Get token substring.
int end = offset;
if (quoted && s[offset] == '\"')
{
offset++;
}
if (end - start <= 0)
return QString();
return s.mid(start, end - start);
}
#ifdef Q_OS_WIN32
bool ioLaunch::isQuake3PathValid() const
{
if (!settings.containsQuakePath())
return false;
return !settings.getQuakePath().isEmpty() && QDir(settings.getQuakePath()).exists();
}
#endif
void ioLaunch::parseQuake3Config()
{
QFile file(homePath + "/baseq3/q3config.cfg");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream stream(&file);
while (!stream.atEnd())
{
const QString line(stream.readLine());
// Skip comments.
if (line.startsWith("//"))
continue;
int offset = 0;
if (ParseToken(line, offset) == "seta")
{
const QString cvar(ParseToken(line, offset));
if (cvar == "r_mode")
{
2014-05-09 06:17:35 +00:00
settings.setResolutionMode(ParseToken(line, offset).toInt());
}
else if (cvar == "r_customwidth")
{
2014-05-09 06:17:35 +00:00
settings.setResolutionWidth(ParseToken(line, offset).toInt());
}
else if (cvar == "r_customheight")
{
2014-05-09 06:17:35 +00:00
settings.setResolutionHeight(ParseToken(line, offset).toInt());
}
else if (cvar == "r_fullscreen")
{
2014-05-09 06:17:35 +00:00
settings.setResolutionFullscreen(ParseToken(line, offset).toInt() != 0);
}
}
}
}