Added widget for toggling quickplay properties
This commit is contained in:
parent
7de85a5a2d
commit
42d079ff49
|
@ -70,17 +70,17 @@ bool CEditorApplication::CloseAllEditors()
|
||||||
|
|
||||||
bool CEditorApplication::CloseProject()
|
bool CEditorApplication::CloseProject()
|
||||||
{
|
{
|
||||||
if (mpActiveProject && CloseAllEditors())
|
if (mpActiveProject && !CloseAllEditors())
|
||||||
{
|
return false;
|
||||||
// Close any active quickplay sessions
|
|
||||||
NDolphinIntegration::KillQuickplay();
|
|
||||||
|
|
||||||
// Emit before actually deleting the project to allow editor references to clean up
|
// Close any active quickplay sessions
|
||||||
CGameProject *pOldProj = mpActiveProject;
|
NDolphinIntegration::KillQuickplay();
|
||||||
mpActiveProject = nullptr;
|
|
||||||
emit ActiveProjectChanged(nullptr);
|
// Emit before actually deleting the project to allow editor references to clean up
|
||||||
delete pOldProj;
|
CGameProject *pOldProj = mpActiveProject;
|
||||||
}
|
mpActiveProject = nullptr;
|
||||||
|
emit ActiveProjectChanged(nullptr);
|
||||||
|
delete pOldProj;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -255,6 +255,22 @@ bool CEditorApplication::CookPackageList(QList<CPackage*> PackageList)
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CEditorApplication::HasAnyDirtyPackages()
|
||||||
|
{
|
||||||
|
if (!mpActiveProject)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (uint32 PkgIdx = 0; PkgIdx < mpActiveProject->NumPackages(); PkgIdx++)
|
||||||
|
{
|
||||||
|
CPackage *pPackage = mpActiveProject->PackageByIndex(PkgIdx);
|
||||||
|
|
||||||
|
if (pPackage->NeedsRecook())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CEditorApplication::RebuildResourceDatabase()
|
bool CEditorApplication::RebuildResourceDatabase()
|
||||||
{
|
{
|
||||||
// Make sure all editors are closed
|
// Make sure all editors are closed
|
||||||
|
|
|
@ -43,6 +43,7 @@ public:
|
||||||
bool CookPackage(CPackage *pPackage);
|
bool CookPackage(CPackage *pPackage);
|
||||||
bool CookAllDirtyPackages();
|
bool CookAllDirtyPackages();
|
||||||
bool CookPackageList(QList<CPackage*> PackageList);
|
bool CookPackageList(QList<CPackage*> PackageList);
|
||||||
|
bool HasAnyDirtyPackages();
|
||||||
|
|
||||||
bool RebuildResourceDatabase();
|
bool RebuildResourceDatabase();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include "CQuickplayPropertyEditor.h"
|
||||||
|
#include "ui_CQuickplayPropertyEditor.h"
|
||||||
|
#include "UICommon.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
/** Validator class for Dolphin line edit */
|
||||||
|
class CDolphinValidator : public QValidator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CDolphinValidator(QObject* pParent = 0) : QValidator(pParent) {}
|
||||||
|
|
||||||
|
virtual QValidator::State validate(QString& Input, int& Pos) const override
|
||||||
|
{
|
||||||
|
return PathValid(Input) ? QValidator::Acceptable : QValidator::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool PathValid(const QString& kPath)
|
||||||
|
{
|
||||||
|
QFileInfo FileInfo(kPath);
|
||||||
|
return FileInfo.exists() && FileInfo.suffix() == "exe";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** CQuickplayPropertyEditor functions */
|
||||||
|
CQuickplayPropertyEditor::CQuickplayPropertyEditor(SQuickplayParameters& Parameters, QWidget* pParent /*= 0*/)
|
||||||
|
: QMenu(pParent)
|
||||||
|
, mpUI(new Ui::CQuickplayPropertyEditor)
|
||||||
|
, mParameters(Parameters)
|
||||||
|
{
|
||||||
|
mpUI->setupUi(this);
|
||||||
|
setMinimumWidth(300);
|
||||||
|
|
||||||
|
NDolphinIntegration::LoadQuickplayParameters(Parameters);
|
||||||
|
mpUI->DolphinPathLineEdit->setText( NDolphinIntegration::GetDolphinPath() );
|
||||||
|
mpUI->DolphinPathLineEdit->setValidator( new CDolphinValidator(this) );
|
||||||
|
mpUI->BootToAreaCheckBox->setChecked( Parameters.Features.HasFlag(EQuickplayFeature::JumpToArea) );
|
||||||
|
mpUI->SpawnAtCameraLocationCheckBox->setChecked( Parameters.Features.HasFlag(EQuickplayFeature::SetSpawnPosition) );
|
||||||
|
|
||||||
|
connect(mpUI->DolphinPathLineEdit, SIGNAL(textChanged(QString)),
|
||||||
|
this, SLOT(OnDolphinPathChanged(QString)));
|
||||||
|
|
||||||
|
connect(mpUI->BootToAreaCheckBox, SIGNAL(toggled(bool)),
|
||||||
|
this, SLOT(OnBootToAreaToggled(bool)));
|
||||||
|
|
||||||
|
connect(mpUI->SpawnAtCameraLocationCheckBox, SIGNAL(toggled(bool)),
|
||||||
|
this, SLOT(OnSpawnAtCameraLocationToggled(bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CQuickplayPropertyEditor::~CQuickplayPropertyEditor()
|
||||||
|
{
|
||||||
|
delete mpUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CQuickplayPropertyEditor::BrowseForDolphin()
|
||||||
|
{
|
||||||
|
QString Path = UICommon::OpenFileDialog(this, "Open Dolphin", "Dolphin.exe");
|
||||||
|
|
||||||
|
if (!Path.isEmpty())
|
||||||
|
{
|
||||||
|
mpUI->DolphinPathLineEdit->setText(Path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CQuickplayPropertyEditor::OnDolphinPathChanged(const QString& kNewPath)
|
||||||
|
{
|
||||||
|
if (CDolphinValidator::PathValid(kNewPath))
|
||||||
|
{
|
||||||
|
NDolphinIntegration::SetDolphinPath(parentWidget(), kNewPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CQuickplayPropertyEditor::OnBootToAreaToggled(bool Enabled)
|
||||||
|
{
|
||||||
|
if (Enabled)
|
||||||
|
{
|
||||||
|
mParameters.Features.SetFlag(EQuickplayFeature::JumpToArea);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mParameters.Features.ClearFlag(EQuickplayFeature::JumpToArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
NDolphinIntegration::SaveQuickplayParameters(mParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CQuickplayPropertyEditor::OnSpawnAtCameraLocationToggled(bool Enabled)
|
||||||
|
{
|
||||||
|
if (Enabled)
|
||||||
|
{
|
||||||
|
mParameters.Features.SetFlag(EQuickplayFeature::SetSpawnPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mParameters.Features.ClearFlag(EQuickplayFeature::SetSpawnPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
NDolphinIntegration::SaveQuickplayParameters(mParameters);
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef CQUICKPLAYPROPERTYEDITOR_H
|
||||||
|
#define CQUICKPLAYPROPERTYEDITOR_H
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
#include "NDolphinIntegration.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CQuickplayPropertyEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Property editor widget for quickplay.
|
||||||
|
* @todo may want this to use a CPropertyView eventually.
|
||||||
|
*/
|
||||||
|
class CQuickplayPropertyEditor : public QMenu
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Ui::CQuickplayPropertyEditor* mpUI;
|
||||||
|
SQuickplayParameters& mParameters;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CQuickplayPropertyEditor(SQuickplayParameters& Parameters, QWidget* pParent = 0);
|
||||||
|
~CQuickplayPropertyEditor();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void BrowseForDolphin();
|
||||||
|
void OnDolphinPathChanged(const QString& kNewPath);
|
||||||
|
void OnBootToAreaToggled(bool Enabled);
|
||||||
|
void OnSpawnAtCameraLocationToggled(bool Enabled);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CQUICKPLAYPROPERTYEDITOR_H
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CQuickplayPropertyEditor</class>
|
||||||
|
<widget class="QMenu" name="CQuickplayPropertyEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>345</width>
|
||||||
|
<height>94</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="DolphinPathLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Dolphin Path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="CSoftValidatorLineEdit" name="DolphinPathLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="DolphinBrowseButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="BootToAreaCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Boot to Current Area</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="SpawnAtCameraLocationCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spawn at Camera Location</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>CSoftValidatorLineEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>Editor/Widgets/CSoftValidatorLineEdit.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -519,7 +519,7 @@ void CSceneViewport::OnPlayFromHere()
|
||||||
|
|
||||||
if (mpMenuNode)
|
if (mpMenuNode)
|
||||||
{
|
{
|
||||||
pOwnerWorldEd->LaunchQuickplayFromLocation(mMenuPoint);
|
pOwnerWorldEd->LaunchQuickplayFromLocation(mMenuPoint, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -207,7 +207,8 @@ HEADERS += \
|
||||||
Undo/CSaveStoreCommand.h \
|
Undo/CSaveStoreCommand.h \
|
||||||
CollisionEditor/CCollisionEditor.h \
|
CollisionEditor/CCollisionEditor.h \
|
||||||
CollisionEditor/CCollisionEditorViewport.h \
|
CollisionEditor/CCollisionEditorViewport.h \
|
||||||
NDolphinIntegration.h
|
NDolphinIntegration.h \
|
||||||
|
CQuickplayPropertyEditor.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -286,7 +287,8 @@ SOURCES += \
|
||||||
ScanEditor/CScanEditor.cpp \
|
ScanEditor/CScanEditor.cpp \
|
||||||
CollisionEditor/CCollisionEditor.cpp \
|
CollisionEditor/CCollisionEditor.cpp \
|
||||||
CollisionEditor/CCollisionEditorViewport.cpp \
|
CollisionEditor/CCollisionEditorViewport.cpp \
|
||||||
NDolphinIntegration.cpp
|
NDolphinIntegration.cpp \
|
||||||
|
CQuickplayPropertyEditor.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
@ -315,7 +317,8 @@ FORMS += \
|
||||||
StringEditor/CStringEditor.ui \
|
StringEditor/CStringEditor.ui \
|
||||||
CTweakEditor.ui \
|
CTweakEditor.ui \
|
||||||
ScanEditor/CScanEditor.ui \
|
ScanEditor/CScanEditor.ui \
|
||||||
CollisionEditor/CCollisionEditor.ui
|
CollisionEditor/CCollisionEditor.ui \
|
||||||
|
CQuickplayPropertyEditor.ui
|
||||||
|
|
||||||
# Codegen
|
# Codegen
|
||||||
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace NDolphinIntegration
|
||||||
|
|
||||||
/** Constants */
|
/** Constants */
|
||||||
const char* const gkDolphinPathSetting = "Quickplay/DolphinPath";
|
const char* const gkDolphinPathSetting = "Quickplay/DolphinPath";
|
||||||
|
const char* const gkFeaturesSetting = "Quickplay/Features";
|
||||||
|
|
||||||
const char* const gkRelFileName = "EditorQuickplay.rel";
|
const char* const gkRelFileName = "EditorQuickplay.rel";
|
||||||
const char* const gkParameterFile = "dbgconfig";
|
const char* const gkParameterFile = "dbgconfig";
|
||||||
const char* const gkDolPath = "sys/main.dol";
|
const char* const gkDolPath = "sys/main.dol";
|
||||||
|
@ -20,23 +22,27 @@ const char* const gkDolBackupPath = "sys/main.original.dol";
|
||||||
QString gDolphinPath;
|
QString gDolphinPath;
|
||||||
|
|
||||||
/** The current Dolphin quickplay process */
|
/** The current Dolphin quickplay process */
|
||||||
QProcess gDolphinProcess;
|
QProcess* gpDolphinProcess = nullptr;
|
||||||
|
|
||||||
/** The project that the current active quickplay session is running for */
|
/** The project that the current active quickplay session is running for */
|
||||||
CGameProject* gpQuickplayProject = nullptr;
|
CGameProject* gpQuickplayProject = nullptr;
|
||||||
|
|
||||||
/** Quickplay relay implementation to detect when the active quickplay session closes */
|
/** Quickplay relay implementation to detect when the active quickplay session closes */
|
||||||
void CQuickplayRelay::TrackProcess(QProcess* pProcess)
|
void CQuickplayRelay::QuickplayStarted()
|
||||||
{
|
{
|
||||||
disconnect(this);
|
debugf("Quickplay session started.");
|
||||||
connect(pProcess, SIGNAL(finished(int)), this, SLOT(OnQuickplayFinished(int)));
|
connect(gpDolphinProcess, SIGNAL(finished(int)), this, SLOT(QuickplayFinished(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CQuickplayRelay::OnQuickplayFinished(int ReturnCode)
|
void CQuickplayRelay::QuickplayFinished(int ReturnCode)
|
||||||
{
|
{
|
||||||
debugf("Quickplay session finished.");
|
debugf("Quickplay session finished.");
|
||||||
disconnect(this);
|
|
||||||
|
disconnect(gpDolphinProcess, 0, this, 0);
|
||||||
CleanupQuickplayFiles(gpQuickplayProject);
|
CleanupQuickplayFiles(gpQuickplayProject);
|
||||||
|
gpDolphinProcess->waitForFinished();
|
||||||
|
gpDolphinProcess->deleteLater();
|
||||||
|
gpDolphinProcess = nullptr;
|
||||||
gpQuickplayProject = nullptr;
|
gpQuickplayProject = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +68,7 @@ EQuickplayLaunchResult LaunchQuickplay(QWidget* pParentWidget,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if quickplay is already running
|
// Check if quickplay is already running
|
||||||
if (gDolphinProcess.state() != QProcess::NotRunning)
|
if (gpDolphinProcess && gpDolphinProcess->state() != QProcess::NotRunning)
|
||||||
{
|
{
|
||||||
if (UICommon::YesNoQuestion(pParentWidget, "Quickplay",
|
if (UICommon::YesNoQuestion(pParentWidget, "Quickplay",
|
||||||
"Quickplay is already running. Close the existing session and relaunch?"))
|
"Quickplay is already running. Close the existing session and relaunch?"))
|
||||||
|
@ -80,8 +86,7 @@ EQuickplayLaunchResult LaunchQuickplay(QWidget* pParentWidget,
|
||||||
if (gDolphinPath.isEmpty())
|
if (gDolphinPath.isEmpty())
|
||||||
{
|
{
|
||||||
// If the user configured Dolphin on a previous run, it should be stashed in settings
|
// If the user configured Dolphin on a previous run, it should be stashed in settings
|
||||||
QSettings Settings;
|
QString Path = GetDolphinPath();
|
||||||
QString Path = Settings.value(gkDolphinPathSetting).toString();
|
|
||||||
|
|
||||||
if (Path.isEmpty())
|
if (Path.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -99,6 +104,16 @@ EQuickplayLaunchResult LaunchQuickplay(QWidget* pParentWidget,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the user has any dirty packages
|
||||||
|
if (gpEdApp->HasAnyDirtyPackages())
|
||||||
|
{
|
||||||
|
if (UICommon::YesNoQuestion(pParentWidget, "Uncooked Changes",
|
||||||
|
"You have uncooked changes. Cook before starting quickplay?"))
|
||||||
|
{
|
||||||
|
gpEdApp->CookAllDirtyPackages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// All good. Perform initialization tasks. Start by creating the patched dol.
|
// All good. Perform initialization tasks. Start by creating the patched dol.
|
||||||
TString DiscSys = pProject->DiscDir(false) / "sys";
|
TString DiscSys = pProject->DiscDir(false) / "sys";
|
||||||
std::vector<uint8> DolData;
|
std::vector<uint8> DolData;
|
||||||
|
@ -139,7 +154,7 @@ EQuickplayLaunchResult LaunchQuickplay(QWidget* pParentWidget,
|
||||||
memcpy(&DolData[PatchOffset], &PatchData[0], PatchData.size());
|
memcpy(&DolData[PatchOffset], &PatchData[0], PatchData.size());
|
||||||
|
|
||||||
// These constants are hardcoded for the moment.
|
// These constants are hardcoded for the moment.
|
||||||
// We write the patch to text section 6, which should be at address 0x80002600.
|
// We write the patch to text section 6, which must be at address 0x80002600.
|
||||||
// We hook over the call to LCEnable, which is at offset 0x1D64.
|
// We hook over the call to LCEnable, which is at offset 0x1D64.
|
||||||
CMemoryOutStream Mem(DolData.data(), DolData.size(), EEndian::BigEndian);
|
CMemoryOutStream Mem(DolData.data(), DolData.size(), EEndian::BigEndian);
|
||||||
Mem.GoTo(0x18);
|
Mem.GoTo(0x18);
|
||||||
|
@ -167,18 +182,20 @@ EQuickplayLaunchResult LaunchQuickplay(QWidget* pParentWidget,
|
||||||
kParms.Write(FSTParmPath);
|
kParms.Write(FSTParmPath);
|
||||||
|
|
||||||
// We're good to go - launch the quickplay process
|
// We're good to go - launch the quickplay process
|
||||||
gDolphinProcess.start(gDolphinPath, QStringList() << TO_QSTRING(DolPath));
|
gpDolphinProcess = new QProcess(pParentWidget);
|
||||||
gDolphinProcess.waitForStarted();
|
gpDolphinProcess->start(gDolphinPath, QStringList() << TO_QSTRING(DolPath));
|
||||||
|
gpDolphinProcess->waitForStarted();
|
||||||
|
|
||||||
if (gDolphinProcess.state() != QProcess::Running)
|
if (gpDolphinProcess->state() != QProcess::Running)
|
||||||
{
|
{
|
||||||
warnf("Quickplay launch failed! Process did not start correctly.");
|
warnf("Quickplay launch failed! Process did not start correctly.");
|
||||||
|
delete gpDolphinProcess;
|
||||||
|
gpDolphinProcess = nullptr;
|
||||||
return EQuickplayLaunchResult::Failure;
|
return EQuickplayLaunchResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
gQuickplayRelay.TrackProcess(&gDolphinProcess);
|
|
||||||
gpQuickplayProject = pProject;
|
gpQuickplayProject = pProject;
|
||||||
debugf("Quickplay session started.");
|
gQuickplayRelay.QuickplayStarted();
|
||||||
return EQuickplayLaunchResult::Success;
|
return EQuickplayLaunchResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,10 +213,12 @@ bool IsQuickplaySupported(CGameProject* pProject)
|
||||||
/** Kill the current quickplay process, if it exists. */
|
/** Kill the current quickplay process, if it exists. */
|
||||||
void KillQuickplay()
|
void KillQuickplay()
|
||||||
{
|
{
|
||||||
debugf("Killing quickplay.");
|
if (gpDolphinProcess)
|
||||||
gDolphinProcess.close();
|
{
|
||||||
CleanupQuickplayFiles(gpQuickplayProject);
|
debugf("Stopping active quickplay session.");
|
||||||
gpQuickplayProject = nullptr;
|
gpDolphinProcess->close();
|
||||||
|
// CQuickplayRelay handles remaining destruction & cleanup
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clean up any quickplay related file data from the project disc files. */
|
/** Clean up any quickplay related file data from the project disc files. */
|
||||||
|
@ -250,4 +269,38 @@ bool SetDolphinPath(QWidget* pParentWidget, const QString& kDolphinPath, bool bS
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Retrieves the user path to Dolphin. */
|
||||||
|
QString GetDolphinPath()
|
||||||
|
{
|
||||||
|
// Check if we have a path to Dolphin
|
||||||
|
QString Path = gDolphinPath;
|
||||||
|
|
||||||
|
if (Path.isEmpty())
|
||||||
|
{
|
||||||
|
// If the user configured Dolphin on a previous run, it should be stashed in settings
|
||||||
|
QSettings Settings;
|
||||||
|
Path = Settings.value(gkDolphinPathSetting).toString();
|
||||||
|
|
||||||
|
if (!Path.isEmpty())
|
||||||
|
{
|
||||||
|
gDolphinPath = Path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Saves/retrieves the given quickplay settings to/from QSettings. */
|
||||||
|
void SaveQuickplayParameters(const SQuickplayParameters& kParms)
|
||||||
|
{
|
||||||
|
QSettings Settings;
|
||||||
|
Settings.setValue(gkFeaturesSetting, kParms.Features.ToInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadQuickplayParameters(SQuickplayParameters& Parms)
|
||||||
|
{
|
||||||
|
QSettings Settings;
|
||||||
|
Parms.Features = Settings.value(gkFeaturesSetting, (uint32) EQuickplayFeature::DefaultFeatures).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
// are mirrored in PWEQuickplayPatch and are used by the game.
|
// are mirrored in PWEQuickplayPatch and are used by the game.
|
||||||
// If you modify one, make sure you modify the other.
|
// If you modify one, make sure you modify the other.
|
||||||
|
|
||||||
namespace NDolphinIntegration
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Return value for LaunchQuickplay */
|
/** Return value for LaunchQuickplay */
|
||||||
enum class EQuickplayLaunchResult
|
enum class EQuickplayLaunchResult
|
||||||
{
|
{
|
||||||
|
@ -33,6 +30,9 @@ enum class EQuickplayFeature
|
||||||
JumpToArea = 0x00000001,
|
JumpToArea = 0x00000001,
|
||||||
/** Spawn the player in the location specified by SpawnTransform */
|
/** Spawn the player in the location specified by SpawnTransform */
|
||||||
SetSpawnPosition = 0x00000002,
|
SetSpawnPosition = 0x00000002,
|
||||||
|
|
||||||
|
/** Flags enabled by default */
|
||||||
|
DefaultFeatures = JumpToArea | SetSpawnPosition
|
||||||
};
|
};
|
||||||
DECLARE_FLAGS_ENUMCLASS(EQuickplayFeature, FQuickplayFeatures)
|
DECLARE_FLAGS_ENUMCLASS(EQuickplayFeature, FQuickplayFeatures)
|
||||||
|
|
||||||
|
@ -71,17 +71,19 @@ struct SQuickplayParameters
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Minimal relay class that detects when the active quickplay session is closed */
|
namespace NDolphinIntegration
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Minimal relay class for internal use that detects when the active quickplay session is closed */
|
||||||
class CQuickplayRelay : public QObject
|
class CQuickplayRelay : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CQuickplayRelay() {}
|
CQuickplayRelay() {}
|
||||||
void TrackProcess(QProcess* pProcess);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnQuickplayFinished(int ReturnCode);
|
void QuickplayStarted();
|
||||||
|
void QuickplayFinished(int ReturnCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Attempt to launch quickplay based on the current editor state. */
|
/** Attempt to launch quickplay based on the current editor state. */
|
||||||
|
@ -103,6 +105,13 @@ bool SetDolphinPath(QWidget* pParentWidget,
|
||||||
const QString& kDolphinPath,
|
const QString& kDolphinPath,
|
||||||
bool bSilent = false);
|
bool bSilent = false);
|
||||||
|
|
||||||
|
/** Retrieves the user path to Dolphin. */
|
||||||
|
QString GetDolphinPath();
|
||||||
|
|
||||||
|
/** Saves/retrieves the given quickplay settings to/from QSettings. */
|
||||||
|
void SaveQuickplayParameters(const SQuickplayParameters& kParms);
|
||||||
|
void LoadQuickplayParameters(SQuickplayParameters& Parms);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CQUICKPLAYCONTROLLER_H
|
#endif // CQUICKPLAYCONTROLLER_H
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "Editor/CExportGameDialog.h"
|
#include "Editor/CExportGameDialog.h"
|
||||||
#include "Editor/CNodeCopyMimeData.h"
|
#include "Editor/CNodeCopyMimeData.h"
|
||||||
#include "Editor/CProjectSettingsDialog.h"
|
#include "Editor/CProjectSettingsDialog.h"
|
||||||
|
#include "Editor/CQuickplayPropertyEditor.h"
|
||||||
#include "Editor/CSelectionIterator.h"
|
#include "Editor/CSelectionIterator.h"
|
||||||
#include "Editor/UICommon.h"
|
#include "Editor/UICommon.h"
|
||||||
#include "Editor/PropertyEdit/CPropertyView.h"
|
#include "Editor/PropertyEdit/CPropertyView.h"
|
||||||
|
@ -122,6 +123,11 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
// Quickplay buttons
|
// Quickplay buttons
|
||||||
QToolButton* pQuickplayButton = new QToolButton(this);
|
QToolButton* pQuickplayButton = new QToolButton(this);
|
||||||
pQuickplayButton->setIcon( QIcon(":/icons/Play_32px.png") );
|
pQuickplayButton->setIcon( QIcon(":/icons/Play_32px.png") );
|
||||||
|
pQuickplayButton->setPopupMode( QToolButton::MenuButtonPopup );
|
||||||
|
pQuickplayButton->setMenu( new CQuickplayPropertyEditor(mQuickplayParms, this) );
|
||||||
|
pQuickplayButton->setToolTip( "Quickplay" );
|
||||||
|
|
||||||
|
ui->MainToolBar->addSeparator();
|
||||||
mpQuickplayAction = ui->MainToolBar->addWidget(pQuickplayButton);
|
mpQuickplayAction = ui->MainToolBar->addWidget(pQuickplayButton);
|
||||||
mpQuickplayAction->setVisible(false);
|
mpQuickplayAction->setVisible(false);
|
||||||
mpQuickplayAction->setEnabled(false);
|
mpQuickplayAction->setEnabled(false);
|
||||||
|
@ -950,23 +956,29 @@ void CWorldEditor::UpdateNewLinkLine()
|
||||||
void CWorldEditor::LaunchQuickplay()
|
void CWorldEditor::LaunchQuickplay()
|
||||||
{
|
{
|
||||||
CVector3f CameraPosition = Viewport()->Camera().Position();
|
CVector3f CameraPosition = Viewport()->Camera().Position();
|
||||||
LaunchQuickplayFromLocation(CameraPosition);
|
LaunchQuickplayFromLocation(CameraPosition, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::LaunchQuickplayFromLocation(CVector3f Location)
|
void CWorldEditor::LaunchQuickplayFromLocation(CVector3f Location, bool ForceAsSpawnPosition)
|
||||||
{
|
{
|
||||||
// This function should not be called if a level is not open in a project.
|
// This function should not be called if a level is not open in a project.
|
||||||
ASSERT( gpEdApp->ActiveProject() != nullptr );
|
ASSERT( gpEdApp->ActiveProject() != nullptr );
|
||||||
ASSERT( mpWorld && mpArea );
|
ASSERT( mpWorld && mpArea );
|
||||||
|
|
||||||
// Fill in parameters and start running
|
// Fill in parameters and start running
|
||||||
mQuickplayParms.BootWorldAssetID = mpWorld->ID().ToLong();
|
SQuickplayParameters Parameters = mQuickplayParms;
|
||||||
mQuickplayParms.BootAreaAssetID = mpArea->ID().ToLong();
|
Parameters.BootWorldAssetID = mpWorld->ID().ToLong();
|
||||||
mQuickplayParms.SpawnTransform = Viewport()->Camera().GetCameraTransform();
|
Parameters.BootAreaAssetID = mpArea->ID().ToLong();
|
||||||
mQuickplayParms.SpawnTransform.SetTranslation(Location);
|
Parameters.SpawnTransform = Viewport()->Camera().GetCameraTransform();
|
||||||
mQuickplayParms.Features.SetFlag(NDolphinIntegration::EQuickplayFeature::JumpToArea);
|
Parameters.SpawnTransform.SetTranslation(Location);
|
||||||
mQuickplayParms.Features.SetFlag(NDolphinIntegration::EQuickplayFeature::SetSpawnPosition);
|
|
||||||
NDolphinIntegration::LaunchQuickplay(this, gpEdApp->ActiveProject(), mQuickplayParms);
|
if (ForceAsSpawnPosition)
|
||||||
|
{
|
||||||
|
Parameters.Features.SetFlag(EQuickplayFeature::JumpToArea);
|
||||||
|
Parameters.Features.SetFlag(EQuickplayFeature::SetSpawnPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
NDolphinIntegration::LaunchQuickplay(this, gpEdApp->ActiveProject(), Parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ PROTECTED ************
|
// ************ PROTECTED ************
|
||||||
|
|
|
@ -67,7 +67,7 @@ class CWorldEditor : public INodeEditor
|
||||||
|
|
||||||
// Quickplay
|
// Quickplay
|
||||||
QAction* mpQuickplayAction;
|
QAction* mpQuickplayAction;
|
||||||
NDolphinIntegration::SQuickplayParameters mQuickplayParms;
|
SQuickplayParameters mQuickplayParms;
|
||||||
|
|
||||||
// Sidebars
|
// Sidebars
|
||||||
QVBoxLayout* mpRightSidebarLayout;
|
QVBoxLayout* mpRightSidebarLayout;
|
||||||
|
@ -136,7 +136,7 @@ public slots:
|
||||||
void UpdateNewLinkLine();
|
void UpdateNewLinkLine();
|
||||||
|
|
||||||
void LaunchQuickplay();
|
void LaunchQuickplay();
|
||||||
void LaunchQuickplayFromLocation(CVector3f Location);
|
void LaunchQuickplayFromLocation(CVector3f Location, bool ForceAsSpawnPosition);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QAction* AddEditModeButton(QIcon Icon, QString ToolTip, EWorldEditorMode Mode);
|
QAction* AddEditModeButton(QIcon Icon, QString ToolTip, EWorldEditorMode Mode);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CEditorApplication.h"
|
#include "CEditorApplication.h"
|
||||||
#include "CUIRelay.h"
|
#include "CUIRelay.h"
|
||||||
|
#include "NDolphinIntegration.h"
|
||||||
#include "UICommon.h"
|
#include "UICommon.h"
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ public:
|
||||||
/** Clean up any resources at the end of application execution */
|
/** Clean up any resources at the end of application execution */
|
||||||
~CMain()
|
~CMain()
|
||||||
{
|
{
|
||||||
|
NDolphinIntegration::KillQuickplay();
|
||||||
NGameList::Shutdown();
|
NGameList::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue