mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Create headless application [WIP]
This commit is contained in:
parent
4df1c16099
commit
08c581947d
@ -1,4 +1,4 @@
|
|||||||
// Qt5.2+ frontend implementation for rpcs3. Known to work on Windows, Linux, Mac
|
// Qt5.10+ frontend implementation for rpcs3. Known to work on Windows, Linux, Mac
|
||||||
// by Sacha Refshauge, Megamouse and flash-fire
|
// by Sacha Refshauge, Megamouse and flash-fire
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@ -6,11 +6,18 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QTextDocument>
|
||||||
|
|
||||||
|
#include "rpcs3qt/gui_application.h"
|
||||||
|
|
||||||
#include "rpcs3_app.h"
|
#include "rpcs3_app.h"
|
||||||
#include "Utilities/sema.h"
|
#include "Utilities/sema.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include "Utilities/dynamic_library.h"
|
||||||
|
DYNAMIC_IMPORT("ntdll.dll", NtQueryTimerResolution, NTSTATUS(PULONG MinimumResolution, PULONG MaximumResolution, PULONG CurrentResolution));
|
||||||
|
DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -90,16 +97,20 @@ static semaphore<> s_qt_mutex{};
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* ARG_NO_GUI = "no-gui";
|
||||||
|
|
||||||
|
QCoreApplication* createApplication(int& argc, char* argv[])
|
||||||
|
{
|
||||||
|
for (int i = 1; i < argc; ++i)
|
||||||
|
if (!qstrcmp(argv[i], ARG_NO_GUI))
|
||||||
|
return new rpcs3_app(argc, argv);
|
||||||
|
return new gui_application(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
logs::set_init();
|
logs::set_init();
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__APPLE__)
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
|
||||||
#else
|
|
||||||
setenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1", 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
struct ::rlimit rlim;
|
struct ::rlimit rlim;
|
||||||
rlim.rlim_cur = 4096;
|
rlim.rlim_cur = 4096;
|
||||||
@ -108,16 +119,10 @@ int main(int argc, char** argv)
|
|||||||
std::fprintf(stderr, "Failed to set max open file limit (4096).");
|
std::fprintf(stderr, "Failed to set max open file limit (4096).");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
|
||||||
|
|
||||||
s_init.unlock();
|
s_init.unlock();
|
||||||
s_qt_mutex.lock();
|
s_qt_mutex.lock();
|
||||||
rpcs3_app app(argc, argv);
|
|
||||||
|
|
||||||
QCoreApplication::setApplicationVersion(qstr(rpcs3::version.to_string()));
|
QScopedPointer<QCoreApplication> app(createApplication(argc, argv));
|
||||||
QCoreApplication::setApplicationName("RPCS3");
|
|
||||||
|
|
||||||
// Command line args
|
// Command line args
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
@ -125,16 +130,46 @@ int main(int argc, char** argv)
|
|||||||
parser.addPositionalArgument("(S)ELF", "Path for directly executing a (S)ELF");
|
parser.addPositionalArgument("(S)ELF", "Path for directly executing a (S)ELF");
|
||||||
parser.addPositionalArgument("[Args...]", "Optional args for the executable");
|
parser.addPositionalArgument("[Args...]", "Optional args for the executable");
|
||||||
|
|
||||||
const QCommandLineOption helpOption = parser.addHelpOption();
|
const QCommandLineOption helpOption = parser.addHelpOption();
|
||||||
const QCommandLineOption versionOption = parser.addVersionOption();
|
const QCommandLineOption versionOption = parser.addVersionOption();
|
||||||
parser.parse(QCoreApplication::arguments());
|
parser.addOption(QCommandLineOption("no-gui"));
|
||||||
parser.process(app);
|
parser.process(app->arguments());
|
||||||
|
|
||||||
// Don't start up the full rpcs3 gui if we just want the version or help.
|
// Don't start up the full rpcs3 gui if we just want the version or help.
|
||||||
if (parser.isSet(versionOption) || parser.isSet(helpOption))
|
if (parser.isSet(versionOption) || parser.isSet(helpOption))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
app.Init();
|
app->setApplicationVersion(qstr(rpcs3::version.to_string()));
|
||||||
|
app->setApplicationName("RPCS3");
|
||||||
|
|
||||||
|
if (auto gui_app = qobject_cast<gui_application*>(app.get()))
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(__APPLE__)
|
||||||
|
app->setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
#else
|
||||||
|
setenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1", 0);
|
||||||
|
#endif
|
||||||
|
app->setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
app->setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
||||||
|
app->setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
||||||
|
|
||||||
|
gui_app->Init();
|
||||||
|
}
|
||||||
|
else if (auto non_gui_app = qobject_cast<rpcs3_app*>(app.get()))
|
||||||
|
{
|
||||||
|
non_gui_app->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Set 0.5 msec timer resolution for best performance
|
||||||
|
// - As QT5 timers (QTimer) sets the timer resolution to 1 msec, override it here.
|
||||||
|
// - Don't bother "unsetting" the timer resolution after the emulator stops as QT5 will still require the timer resolution to be set to 1 msec.
|
||||||
|
ULONG min_res, max_res, orig_res, new_res;
|
||||||
|
if (NtQueryTimerResolution(&min_res, &max_res, &orig_res) == 0)
|
||||||
|
{
|
||||||
|
NtSetTimerResolution(max_res, TRUE, &new_res);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QStringList args = parser.positionalArguments();
|
QStringList args = parser.positionalArguments();
|
||||||
|
|
||||||
@ -145,9 +180,11 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (args.length() > 1)
|
if (args.length() > 1)
|
||||||
{
|
{
|
||||||
|
args.removeAll(ARG_NO_GUI);
|
||||||
|
|
||||||
argv.emplace_back();
|
argv.emplace_back();
|
||||||
|
|
||||||
for (int i = 1; i < args.length(); i++)
|
for (u32 i = 1; i < args.length(); i++)
|
||||||
{
|
{
|
||||||
argv.emplace_back(args[i].toStdString());
|
argv.emplace_back(args[i].toStdString());
|
||||||
}
|
}
|
||||||
@ -164,5 +201,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
s_qt_init.unlock();
|
s_qt_init.unlock();
|
||||||
s_qt_mutex.unlock();
|
s_qt_mutex.unlock();
|
||||||
return QCoreApplication::exec();
|
|
||||||
|
// run event loop (maybe only needed for the gui application)
|
||||||
|
return app->exec();
|
||||||
}
|
}
|
||||||
|
137
rpcs3/main_application.cpp
Normal file
137
rpcs3/main_application.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#include "main_application.h"
|
||||||
|
|
||||||
|
#include "Emu/Io/Null/NullPadHandler.h"
|
||||||
|
#include "Emu/Io/Null/NullKeyboardHandler.h"
|
||||||
|
#include "Emu/Io/Null/NullMouseHandler.h"
|
||||||
|
#include "Emu/Io/KeyboardHandler.h"
|
||||||
|
#include "Emu/Io/PadHandler.h"
|
||||||
|
#include "Emu/Io/MouseHandler.h"
|
||||||
|
#include "basic_keyboard_handler.h"
|
||||||
|
#include "basic_mouse_handler.h"
|
||||||
|
#include "keyboard_pad_handler.h"
|
||||||
|
#include "ds4_pad_handler.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "xinput_pad_handler.h"
|
||||||
|
#include "mm_joystick_handler.h"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LIBEVDEV
|
||||||
|
#include "evdev_joystick_handler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Emu/Audio/AudioBackend.h"
|
||||||
|
#include "Emu/Audio/Null/NullAudioBackend.h"
|
||||||
|
#include "Emu/Audio/AL/OpenALBackend.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "Emu/Audio/XAudio2/XAudio2Backend.h"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
#include "Emu/Audio/ALSA/ALSABackend.h"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PULSE
|
||||||
|
#include "Emu/Audio/Pulse/PulseBackend.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Emu.Init() wrapper for user manager */
|
||||||
|
bool main_application::InitializeEmulator(const std::string& user, bool force_init)
|
||||||
|
{
|
||||||
|
// try to set a new user
|
||||||
|
const bool user_was_set = Emu.SetUsr(user);
|
||||||
|
|
||||||
|
// only init the emulation if forced or a user was set
|
||||||
|
if (user_was_set || force_init)
|
||||||
|
{
|
||||||
|
Emu.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
return user_was_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here. */
|
||||||
|
EmuCallbacks main_application::CreateCallbacks()
|
||||||
|
{
|
||||||
|
EmuCallbacks callbacks;
|
||||||
|
|
||||||
|
callbacks.reset_pads = [this](const std::string& title_id = "")
|
||||||
|
{
|
||||||
|
pad::get_current_handler()->Reset(title_id);
|
||||||
|
};
|
||||||
|
callbacks.enable_pads = [this](bool enable)
|
||||||
|
{
|
||||||
|
pad::get_current_handler()->SetEnabled(enable);
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks.get_kb_handler = [=]() -> std::shared_ptr<KeyboardHandlerBase>
|
||||||
|
{
|
||||||
|
switch (keyboard_handler type = g_cfg.io.keyboard)
|
||||||
|
{
|
||||||
|
case keyboard_handler::null: return std::make_shared<NullKeyboardHandler>();
|
||||||
|
case keyboard_handler::basic:
|
||||||
|
{
|
||||||
|
basic_keyboard_handler* ret = new basic_keyboard_handler();
|
||||||
|
ret->moveToThread(get_thread());
|
||||||
|
ret->SetTargetWindow(m_game_window);
|
||||||
|
return std::shared_ptr<KeyboardHandlerBase>(ret);
|
||||||
|
}
|
||||||
|
default: fmt::throw_exception("Invalid keyboard handler: %s", type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks.get_mouse_handler = [=]() -> std::shared_ptr<MouseHandlerBase>
|
||||||
|
{
|
||||||
|
switch (mouse_handler type = g_cfg.io.mouse)
|
||||||
|
{
|
||||||
|
case mouse_handler::null: return std::make_shared<NullMouseHandler>();
|
||||||
|
case mouse_handler::basic:
|
||||||
|
{
|
||||||
|
basic_mouse_handler* ret = new basic_mouse_handler();
|
||||||
|
ret->moveToThread(get_thread());
|
||||||
|
ret->SetTargetWindow(m_game_window);
|
||||||
|
return std::shared_ptr<MouseHandlerBase>(ret);
|
||||||
|
}
|
||||||
|
default: fmt::throw_exception("Invalid mouse handler: %s", type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks.get_pad_handler = [this](const std::string& title_id) -> std::shared_ptr<pad_thread>
|
||||||
|
{
|
||||||
|
return std::make_shared<pad_thread>(get_thread(), m_game_window, title_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks.get_gs_render = []() -> std::shared_ptr<GSRender>
|
||||||
|
{
|
||||||
|
switch (video_renderer type = g_cfg.video.renderer)
|
||||||
|
{
|
||||||
|
case video_renderer::null: return std::make_shared<named_thread<NullGSRender>>("rsx::thread");
|
||||||
|
case video_renderer::opengl: return std::make_shared<named_thread<GLGSRender>>("rsx::thread");
|
||||||
|
#if defined(_WIN32) || defined(HAVE_VULKAN)
|
||||||
|
case video_renderer::vulkan: return std::make_shared<named_thread<VKGSRender>>("rsx::thread");
|
||||||
|
#endif
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
case video_renderer::dx12: return std::make_shared<named_thread<D3D12GSRender>>("rsx::thread");
|
||||||
|
#endif
|
||||||
|
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks.get_audio = []() -> std::shared_ptr<AudioBackend>
|
||||||
|
{
|
||||||
|
switch (audio_renderer type = g_cfg.audio.renderer)
|
||||||
|
{
|
||||||
|
case audio_renderer::null: return std::make_shared<NullAudioBackend>();
|
||||||
|
#ifdef _WIN32
|
||||||
|
case audio_renderer::xaudio: return std::make_shared<XAudio2Backend>();
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
case audio_renderer::alsa: return std::make_shared<ALSABackend>();
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PULSE
|
||||||
|
case audio_renderer::pulse: return std::make_shared<PulseBackend>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case audio_renderer::openal: return std::make_shared<OpenALBackend>();
|
||||||
|
default: fmt::throw_exception("Invalid audio renderer: %s" HERE, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return callbacks;
|
||||||
|
}
|
32
rpcs3/main_application.h
Normal file
32
rpcs3/main_application.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "Emu/System.h"
|
||||||
|
|
||||||
|
#include "Emu/RSX/GSRender.h"
|
||||||
|
#include "Emu/RSX/Null/NullGSRender.h"
|
||||||
|
#include "Emu/RSX/GL/GLGSRender.h"
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include "Emu/RSX/D3D12/D3D12GSRender.h"
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32) || defined(HAVE_VULKAN)
|
||||||
|
#include "Emu/RSX/VK/VKGSRender.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
|
class main_application
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Init() = 0;
|
||||||
|
|
||||||
|
static bool InitializeEmulator(const std::string& user, bool force_init);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QThread* get_thread() = 0;
|
||||||
|
|
||||||
|
EmuCallbacks CreateCallbacks();
|
||||||
|
|
||||||
|
QWindow* m_game_window = nullptr; // (Currently) only needed so that pad handlers have a valid target for event filtering.
|
||||||
|
};
|
@ -340,6 +340,7 @@
|
|||||||
<ClCompile Include="evdev_joystick_handler.cpp" />
|
<ClCompile Include="evdev_joystick_handler.cpp" />
|
||||||
<ClCompile Include="keyboard_pad_handler.cpp" />
|
<ClCompile Include="keyboard_pad_handler.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="main_application.cpp" />
|
||||||
<ClCompile Include="mm_joystick_handler.cpp" />
|
<ClCompile Include="mm_joystick_handler.cpp" />
|
||||||
<ClCompile Include="pad_thread.cpp" />
|
<ClCompile Include="pad_thread.cpp" />
|
||||||
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_about_dialog.cpp">
|
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_about_dialog.cpp">
|
||||||
@ -412,6 +413,11 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gui_application.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gui_settings.cpp">
|
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gui_settings.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
@ -592,6 +598,11 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_gui_application.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Debug\moc_gui_settings.cpp">
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_gui_settings.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
@ -792,6 +803,11 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gui_application.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gui_settings.cpp">
|
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gui_settings.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
@ -972,6 +988,11 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Release\moc_gui_application.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="QTGeneratedFiles\Release\moc_gui_settings.cpp">
|
<ClCompile Include="QTGeneratedFiles\Release\moc_gui_settings.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
@ -1087,6 +1108,7 @@
|
|||||||
<ClCompile Include="rpcs3qt\breakpoint_list.cpp" />
|
<ClCompile Include="rpcs3qt\breakpoint_list.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\custom_dialog.cpp" />
|
<ClCompile Include="rpcs3qt\custom_dialog.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\debugger_list.cpp" />
|
<ClCompile Include="rpcs3qt\debugger_list.cpp" />
|
||||||
|
<ClCompile Include="rpcs3qt\gui_application.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\input_dialog.cpp" />
|
<ClCompile Include="rpcs3qt\input_dialog.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\osk_dialog_frame.cpp" />
|
<ClCompile Include="rpcs3qt\osk_dialog_frame.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\_discord_utils.cpp" />
|
<ClCompile Include="rpcs3qt\_discord_utils.cpp" />
|
||||||
@ -1335,6 +1357,32 @@
|
|||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="main_application.h">
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
|
||||||
|
</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
|
||||||
|
</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
|
||||||
|
</Command>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
</Command>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
</Command>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
|
||||||
|
</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
|
||||||
|
</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
|
||||||
|
</Command>
|
||||||
|
</CustomBuild>
|
||||||
<ClInclude Include="mm_joystick_handler.h" />
|
<ClInclude Include="mm_joystick_handler.h" />
|
||||||
<CustomBuild Include="rpcs3qt\cg_disasm_window.h">
|
<CustomBuild Include="rpcs3qt\cg_disasm_window.h">
|
||||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing cg_disasm_window.h...</Message>
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing cg_disasm_window.h...</Message>
|
||||||
@ -1585,6 +1633,24 @@
|
|||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -D%(PreprocessorDefinitions) "-I$(VULKAN_SDK)\Include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -D%(PreprocessorDefinitions) "-I$(VULKAN_SDK)\Include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="rpcs3qt\gui_application.h">
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB "-DBRANCH=$(BRANCH)" -D%(PreprocessorDefinitions) "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -D%(PreprocessorDefinitions) "-I$(VULKAN_SDK)\Include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -D%(PreprocessorDefinitions) "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">Moc%27ing %(Identity)...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -D%(PreprocessorDefinitions) "-I$(VULKAN_SDK)\Include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||||
|
</CustomBuild>
|
||||||
<ClInclude Include="rpcs3qt\_discord_utils.h" />
|
<ClInclude Include="rpcs3qt\_discord_utils.h" />
|
||||||
<ClInclude Include="rpcs3qt\find_dialog.h" />
|
<ClInclude Include="rpcs3qt\find_dialog.h" />
|
||||||
<ClInclude Include="rpcs3qt\custom_table_widget_item.h" />
|
<ClInclude Include="rpcs3qt\custom_table_widget_item.h" />
|
||||||
|
@ -725,6 +725,24 @@
|
|||||||
<ClCompile Include="ds3_pad_handler.cpp">
|
<ClCompile Include="ds3_pad_handler.cpp">
|
||||||
<Filter>Io\DS3</Filter>
|
<Filter>Io\DS3</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="rpcs3qt\gui_application.cpp">
|
||||||
|
<Filter>Gui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_gui_application.cpp">
|
||||||
|
<Filter>Generated Files\Release - LLVM</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Debug\moc_gui_application.cpp">
|
||||||
|
<Filter>Generated Files\Debug</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Release\moc_gui_application.cpp">
|
||||||
|
<Filter>Generated Files\Release</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_gui_application.cpp">
|
||||||
|
<Filter>Generated Files\Debug - LLVM</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main_application.cpp">
|
||||||
|
<Filter>rpcs3</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="\rpcs3qt\*.h">
|
<ClInclude Include="\rpcs3qt\*.h">
|
||||||
@ -957,6 +975,12 @@
|
|||||||
<CustomBuild Include="rpcs3qt\osk_dialog_frame.h">
|
<CustomBuild Include="rpcs3qt\osk_dialog_frame.h">
|
||||||
<Filter>Gui\message dialog</Filter>
|
<Filter>Gui\message dialog</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="rpcs3qt\gui_application.h">
|
||||||
|
<Filter>Gui</Filter>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="main_application.h">
|
||||||
|
<Filter>rpcs3</Filter>
|
||||||
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="rpcs3.ico" />
|
<Image Include="rpcs3.ico" />
|
||||||
|
@ -1,137 +1,34 @@
|
|||||||
#include "rpcs3_app.h"
|
#include "rpcs3_app.h"
|
||||||
|
|
||||||
#include "rpcs3qt/qt_utils.h"
|
|
||||||
|
|
||||||
#include "rpcs3qt/welcome_dialog.h"
|
|
||||||
|
|
||||||
#ifdef WITH_DISCORD_RPC
|
|
||||||
#include "rpcs3qt/_discord_utils.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "rpcs3qt/gs_frame.h"
|
|
||||||
#include "rpcs3qt/gl_gs_frame.h"
|
|
||||||
|
|
||||||
#include "rpcs3qt/trophy_notification_helper.h"
|
|
||||||
#include "rpcs3qt/save_data_dialog.h"
|
|
||||||
|
|
||||||
#include "Emu/Io/Null/NullKeyboardHandler.h"
|
|
||||||
#include "basic_keyboard_handler.h"
|
|
||||||
|
|
||||||
#include "Emu/Io/Null/NullMouseHandler.h"
|
|
||||||
#include "basic_mouse_handler.h"
|
|
||||||
|
|
||||||
#include "Emu/Io/Null/NullPadHandler.h"
|
|
||||||
#include "keyboard_pad_handler.h"
|
|
||||||
#include "ds4_pad_handler.h"
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "xinput_pad_handler.h"
|
|
||||||
#include "mm_joystick_handler.h"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBEVDEV
|
|
||||||
#include "evdev_joystick_handler.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pad_thread.h"
|
|
||||||
|
|
||||||
#include "Emu/RSX/Null/NullGSRender.h"
|
|
||||||
#include "Emu/RSX/GL/GLGSRender.h"
|
|
||||||
#include "Emu/Audio/Null/NullAudioBackend.h"
|
|
||||||
#include "Emu/Audio/AL/OpenALBackend.h"
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include "Emu/RSX/D3D12/D3D12GSRender.h"
|
|
||||||
#endif
|
|
||||||
#if defined(_WIN32) || defined(HAVE_VULKAN)
|
|
||||||
#include "Emu/RSX/VK/VKGSRender.h"
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "Emu/Audio/XAudio2/XAudio2Backend.h"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ALSA
|
|
||||||
#include "Emu/Audio/ALSA/ALSABackend.h"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_PULSE
|
|
||||||
#include "Emu/Audio/Pulse/PulseBackend.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "Utilities/dynamic_library.h"
|
|
||||||
DYNAMIC_IMPORT("ntdll.dll", NtQueryTimerResolution, NTSTATUS(PULONG MinimumResolution, PULONG MaximumResolution, PULONG CurrentResolution));
|
|
||||||
DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For now, a trivial constructor/destructor. May add command line usage later.
|
// For now, a trivial constructor/destructor. May add command line usage later.
|
||||||
rpcs3_app::rpcs3_app(int& argc, char** argv) : QApplication(argc, argv)
|
rpcs3_app::rpcs3_app(int& argc, char** argv) : QCoreApplication(argc, argv)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpcs3_app::Init()
|
void rpcs3_app::Init()
|
||||||
{
|
{
|
||||||
setApplicationName("RPCS3");
|
|
||||||
setWindowIcon(QIcon(":/rpcs3.ico"));
|
|
||||||
|
|
||||||
guiSettings.reset(new gui_settings());
|
|
||||||
emuSettings.reset(new emu_settings());
|
|
||||||
|
|
||||||
// Force init the emulator
|
// Force init the emulator
|
||||||
InitializeEmulator(guiSettings->GetCurrentUser().toStdString(), true);
|
InitializeEmulator("1", true); // TODO: get user from cli args if possible
|
||||||
|
|
||||||
// Create the main window
|
|
||||||
RPCS3MainWin = new main_window(guiSettings, emuSettings, nullptr);
|
|
||||||
|
|
||||||
// Create callbacks from the emulator, which reference the handlers.
|
// Create callbacks from the emulator, which reference the handlers.
|
||||||
InitializeCallbacks();
|
InitializeCallbacks();
|
||||||
|
|
||||||
// Create connects to propagate events throughout Gui.
|
// Create connects to propagate events throughout Gui.
|
||||||
InitializeConnects();
|
InitializeConnects();
|
||||||
|
|
||||||
RPCS3MainWin->Init();
|
|
||||||
|
|
||||||
if (guiSettings->GetValue(gui::ib_show_welcome).toBool())
|
|
||||||
{
|
|
||||||
welcome_dialog* welcome = new welcome_dialog();
|
|
||||||
welcome->exec();
|
|
||||||
}
|
|
||||||
#ifdef WITH_DISCORD_RPC
|
|
||||||
// Discord Rich Presence Integration
|
|
||||||
if (guiSettings->GetValue(gui::m_richPresence).toBool())
|
|
||||||
{
|
|
||||||
discord::initialize();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Set 0.5 msec timer resolution for best performance
|
|
||||||
// - As QT5 timers (QTimer) sets the timer resolution to 1 msec, override it here.
|
|
||||||
// - Don't bother "unsetting" the timer resolution after the emulator stops as QT5 will still require the timer resolution to be set to 1 msec.
|
|
||||||
ULONG min_res, max_res, orig_res, new_res;
|
|
||||||
if (NtQueryTimerResolution(&min_res, &max_res, &orig_res) == 0)
|
|
||||||
{
|
|
||||||
NtSetTimerResolution(max_res, TRUE, &new_res);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Emu.Init() wrapper for user manager */
|
void rpcs3_app::InitializeConnects()
|
||||||
bool rpcs3_app::InitializeEmulator(const std::string& user, bool force_init)
|
|
||||||
{
|
{
|
||||||
// try to set a new user
|
qRegisterMetaType<std::function<void()>>("std::function<void()>");
|
||||||
const bool user_was_set = Emu.SetUsr(user);
|
connect(this, &rpcs3_app::RequestCallAfter, this, &rpcs3_app::HandleCallAfter);
|
||||||
|
|
||||||
// only init the emulation if forced or a user was set
|
|
||||||
if (user_was_set || force_init)
|
|
||||||
{
|
|
||||||
Emu.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return user_was_set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here.
|
/** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here. */
|
||||||
*/
|
|
||||||
void rpcs3_app::InitializeCallbacks()
|
void rpcs3_app::InitializeCallbacks()
|
||||||
{
|
{
|
||||||
EmuCallbacks callbacks;
|
EmuCallbacks callbacks = CreateCallbacks();
|
||||||
|
|
||||||
callbacks.exit = [this]()
|
callbacks.exit = [this]()
|
||||||
{
|
{
|
||||||
@ -142,358 +39,24 @@ void rpcs3_app::InitializeCallbacks()
|
|||||||
RequestCallAfter(std::move(func));
|
RequestCallAfter(std::move(func));
|
||||||
};
|
};
|
||||||
|
|
||||||
callbacks.reset_pads = [this](const std::string& title_id = "")
|
callbacks.get_gs_frame = []() -> std::unique_ptr<GSFrameBase> { return std::unique_ptr<GSFrameBase>(); };
|
||||||
{
|
callbacks.get_msg_dialog = []() -> std::shared_ptr<MsgDialogBase> { return std::shared_ptr<MsgDialogBase>(); };
|
||||||
pad::get_current_handler()->Reset(title_id);
|
callbacks.get_osk_dialog = []() -> std::shared_ptr<OskDialogBase> { return std::shared_ptr<OskDialogBase>(); };
|
||||||
};
|
callbacks.get_save_dialog = []() -> std::unique_ptr<SaveDialogBase> { return std::unique_ptr<SaveDialogBase>(); };
|
||||||
callbacks.enable_pads = [this](bool enable)
|
callbacks.get_trophy_notification_dialog = []() -> std::unique_ptr<TrophyNotificationBase> { return std::unique_ptr<TrophyNotificationBase>(); };
|
||||||
{
|
|
||||||
pad::get_current_handler()->SetEnabled(enable);
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_kb_handler = [=]() -> std::shared_ptr<KeyboardHandlerBase>
|
callbacks.on_run = []() {};
|
||||||
{
|
callbacks.on_pause = []() {};
|
||||||
switch (keyboard_handler type = g_cfg.io.keyboard)
|
callbacks.on_resume = []() {};
|
||||||
{
|
callbacks.on_stop = []() {};
|
||||||
case keyboard_handler::null: return std::make_shared<NullKeyboardHandler>();
|
callbacks.on_ready = []() {};
|
||||||
case keyboard_handler::basic:
|
|
||||||
{
|
|
||||||
basic_keyboard_handler* ret = new basic_keyboard_handler();
|
|
||||||
ret->moveToThread(thread());
|
|
||||||
ret->SetTargetWindow(gameWindow);
|
|
||||||
return std::shared_ptr<KeyboardHandlerBase>(ret);
|
|
||||||
}
|
|
||||||
default: fmt::throw_exception("Invalid keyboard handler: %s", type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_mouse_handler = [=]() -> std::shared_ptr<MouseHandlerBase>
|
|
||||||
{
|
|
||||||
switch (mouse_handler type = g_cfg.io.mouse)
|
|
||||||
{
|
|
||||||
case mouse_handler::null: return std::make_shared<NullMouseHandler>();
|
|
||||||
case mouse_handler::basic:
|
|
||||||
{
|
|
||||||
basic_mouse_handler* ret = new basic_mouse_handler();
|
|
||||||
ret->moveToThread(thread());
|
|
||||||
ret->SetTargetWindow(gameWindow);
|
|
||||||
return std::shared_ptr<MouseHandlerBase>(ret);
|
|
||||||
}
|
|
||||||
default: fmt::throw_exception("Invalid mouse handler: %s", type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_pad_handler = [this](const std::string& title_id) -> std::shared_ptr<pad_thread>
|
|
||||||
{
|
|
||||||
return std::make_shared<pad_thread>(thread(), gameWindow, title_id);
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_gs_frame = [this]() -> std::unique_ptr<GSFrameBase>
|
|
||||||
{
|
|
||||||
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
|
|
||||||
|
|
||||||
const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution);
|
|
||||||
int w = size.first;
|
|
||||||
int h = size.second;
|
|
||||||
|
|
||||||
if (guiSettings->GetValue(gui::gs_resize).toBool())
|
|
||||||
{
|
|
||||||
w = guiSettings->GetValue(gui::gs_width).toInt();
|
|
||||||
h = guiSettings->GetValue(gui::gs_height).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto frame_geometry = gui::utils::create_centered_window_geometry(RPCS3MainWin->geometry(), w, h);
|
|
||||||
|
|
||||||
gs_frame* frame;
|
|
||||||
|
|
||||||
switch (video_renderer type = g_cfg.video.renderer)
|
|
||||||
{
|
|
||||||
case video_renderer::null:
|
|
||||||
{
|
|
||||||
frame = new gs_frame("Null", frame_geometry, RPCS3MainWin->GetAppIcon(), guiSettings);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case video_renderer::opengl:
|
|
||||||
{
|
|
||||||
frame = new gl_gs_frame(frame_geometry, RPCS3MainWin->GetAppIcon(), guiSettings);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case video_renderer::vulkan:
|
|
||||||
{
|
|
||||||
frame = new gs_frame("Vulkan", frame_geometry, RPCS3MainWin->GetAppIcon(), guiSettings);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
case video_renderer::dx12:
|
|
||||||
{
|
|
||||||
frame = new gs_frame("DirectX 12", frame_geometry, RPCS3MainWin->GetAppIcon(), guiSettings);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
gameWindow = frame;
|
|
||||||
return std::unique_ptr<gs_frame>(frame);
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_gs_render = []() -> std::shared_ptr<GSRender>
|
|
||||||
{
|
|
||||||
switch (video_renderer type = g_cfg.video.renderer)
|
|
||||||
{
|
|
||||||
case video_renderer::null: return std::make_shared<named_thread<NullGSRender>>("rsx::thread");
|
|
||||||
case video_renderer::opengl: return std::make_shared<named_thread<GLGSRender>>("rsx::thread");
|
|
||||||
#if defined(_WIN32) || defined(HAVE_VULKAN)
|
|
||||||
case video_renderer::vulkan: return std::make_shared<named_thread<VKGSRender>>("rsx::thread");
|
|
||||||
#endif
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
case video_renderer::dx12: return std::make_shared<named_thread<D3D12GSRender>>("rsx::thread");
|
|
||||||
#endif
|
|
||||||
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_audio = []() -> std::shared_ptr<AudioBackend>
|
|
||||||
{
|
|
||||||
switch (audio_renderer type = g_cfg.audio.renderer)
|
|
||||||
{
|
|
||||||
case audio_renderer::null: return std::make_shared<NullAudioBackend>();
|
|
||||||
#ifdef _WIN32
|
|
||||||
case audio_renderer::xaudio: return std::make_shared<XAudio2Backend>();
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ALSA
|
|
||||||
case audio_renderer::alsa: return std::make_shared<ALSABackend>();
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_PULSE
|
|
||||||
case audio_renderer::pulse: return std::make_shared<PulseBackend>();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case audio_renderer::openal: return std::make_shared<OpenALBackend>();
|
|
||||||
default: fmt::throw_exception("Invalid audio renderer: %s" HERE, type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_msg_dialog = [=]() -> std::shared_ptr<MsgDialogBase>
|
|
||||||
{
|
|
||||||
return std::make_shared<msg_dialog_frame>(RPCS3MainWin->windowHandle());
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_osk_dialog = [=]() -> std::shared_ptr<OskDialogBase>
|
|
||||||
{
|
|
||||||
return std::make_shared<osk_dialog_frame>();
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_save_dialog = [=]() -> std::unique_ptr<SaveDialogBase>
|
|
||||||
{
|
|
||||||
return std::make_unique<save_data_dialog>();
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.get_trophy_notification_dialog = [=]() -> std::unique_ptr<TrophyNotificationBase>
|
|
||||||
{
|
|
||||||
return std::make_unique<trophy_notification_helper>(gameWindow);
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.on_run = [=]() { OnEmulatorRun(); };
|
|
||||||
callbacks.on_pause = [=]() { OnEmulatorPause(); };
|
|
||||||
callbacks.on_resume = [=]() { OnEmulatorResume(); };
|
|
||||||
callbacks.on_stop = [=]() { OnEmulatorStop(); };
|
|
||||||
callbacks.on_ready = [=]() { OnEmulatorReady(); };
|
|
||||||
|
|
||||||
callbacks.handle_taskbar_progress = [=](s32 type, s32 value)
|
|
||||||
{
|
|
||||||
if (gameWindow)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
((gs_frame*)gameWindow)->progress_reset(value);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
((gs_frame*)gameWindow)->progress_increment(value);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
((gs_frame*)gameWindow)->progress_set_limit(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_FATAL(GENERAL, "Unknown type in handle_taskbar_progress(type=%d, value=%d)", type, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Emu.SetCallbacks(std::move(callbacks));
|
Emu.SetCallbacks(std::move(callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize connects here. These are used to connect things between UI elements that require the intervention of rpcs3_app.
|
|
||||||
*/
|
|
||||||
void rpcs3_app::InitializeConnects()
|
|
||||||
{
|
|
||||||
connect(RPCS3MainWin, &main_window::RequestGlobalStylesheetChange, this, &rpcs3_app::OnChangeStyleSheetRequest);
|
|
||||||
|
|
||||||
qRegisterMetaType <std::function<void()>>("std::function<void()>");
|
|
||||||
connect(this, &rpcs3_app::RequestCallAfter, this, &rpcs3_app::HandleCallAfter);
|
|
||||||
|
|
||||||
connect(this, &rpcs3_app::OnEmulatorRun, RPCS3MainWin, &main_window::OnEmuRun);
|
|
||||||
connect(this, &rpcs3_app::OnEmulatorStop, RPCS3MainWin, &main_window::OnEmuStop);
|
|
||||||
connect(this, &rpcs3_app::OnEmulatorPause, RPCS3MainWin, &main_window::OnEmuPause);
|
|
||||||
connect(this, &rpcs3_app::OnEmulatorResume, RPCS3MainWin, &main_window::OnEmuResume);
|
|
||||||
connect(this, &rpcs3_app::OnEmulatorReady, RPCS3MainWin, &main_window::OnEmuReady);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle a request to change the stylesheet. May consider adding reporting of errors in future.
|
|
||||||
* Empty string means default.
|
|
||||||
*/
|
|
||||||
void rpcs3_app::OnChangeStyleSheetRequest(const QString& path)
|
|
||||||
{
|
|
||||||
QString style_sheet
|
|
||||||
(
|
|
||||||
// main window toolbar search
|
|
||||||
"QLineEdit#mw_searchbar { padding: 0 1em; background: #fdfdfd; selection-background-color: #148aff; margin: .8em; color:#000000; }"
|
|
||||||
|
|
||||||
// main window toolbar slider
|
|
||||||
"QSlider#sizeSlider { color: #505050; background: #F0F0F0; }"
|
|
||||||
"QSlider#sizeSlider::handle:horizontal { border: 0em smooth rgba(227, 227, 227, 255); border-radius: .58em; background: #404040; width: 1.2em; margin: -.5em 0; }"
|
|
||||||
"QSlider#sizeSlider::groove:horizontal { border-radius: .15em; background: #5b5b5b; height: .3em; }"
|
|
||||||
|
|
||||||
// main window toolbar
|
|
||||||
"QToolBar#mw_toolbar { background-color: #F0F0F0; border: none; }"
|
|
||||||
"QToolBar#mw_toolbar::separator { background-color: rgba(207, 207, 207, 235); width: 0.125em; margin-top: 0.250em; margin-bottom: 0.250em; }"
|
|
||||||
|
|
||||||
// main window toolbar icon color
|
|
||||||
"QLabel#toolbar_icon_color { color: #5b5b5b; }"
|
|
||||||
|
|
||||||
// thumbnail icon color
|
|
||||||
"QLabel#thumbnail_icon_color { color: rgba(0, 100, 231, 255); }"
|
|
||||||
|
|
||||||
// game list icon color
|
|
||||||
"QLabel#gamelist_icon_background_color { color: rgba(240, 240, 240, 255); }"
|
|
||||||
|
|
||||||
// save manager icon color
|
|
||||||
"QLabel#save_manager_icon_background_color { color: rgba(240, 240, 240, 255); }"
|
|
||||||
|
|
||||||
// trophy manager icon color
|
|
||||||
"QLabel#trophy_manager_icon_background_color { color: rgba(240, 240, 240, 255); }"
|
|
||||||
|
|
||||||
// tables
|
|
||||||
"QTableWidget { alternate-background-color: #f2f2f2; background-color: #fff; border: none; }"
|
|
||||||
"QTableWidget#game_grid { alternate-background-color: #f2f2f2; background-color: #fff; font-weight: 600; font-size: 8pt; font-family: Lucida Grande; color: rgba(51, 51, 51, 255); border: 0em solid white; }"
|
|
||||||
"QTableView::item { border-left: 0.063em solid white; border-right: 0.063em solid white; padding-left:0.313em; }"
|
|
||||||
"QTableView::item:selected { background-color: #148aff; color: #fff; }"
|
|
||||||
"QTableView#game_grid::item:hover:!selected { background-color: #94c9ff; color: #fff; }"
|
|
||||||
"QTableView#game_grid::item:hover:selected { background-color: #007fff; color: #fff; }"
|
|
||||||
|
|
||||||
// table headers
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(5,11,0))
|
|
||||||
"QHeaderView::section { padding: .5em; border: 0.063em solid #ffffff; }"
|
|
||||||
"QHeaderView::section:hover { background: #e3e3e3; padding: .5em; border: 0.063em solid #ffffff; }"
|
|
||||||
#else
|
|
||||||
"QHeaderView::section { padding-left: .5em; padding-right: .5em; padding-top: .4em; padding-bottom: -.1em; border: 0.063em solid #ffffff; }"
|
|
||||||
"QHeaderView::section:hover { background: #e3e3e3; padding-left: .5em; padding-right: .5em; padding-top: .4em; padding-bottom: -.1em; border: 0.063em solid #ffffff; }"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// dock widget
|
|
||||||
"QDockWidget{ background: transparent; color: black; }"
|
|
||||||
"[floating=\"true\"]{ background: white; }"
|
|
||||||
"QDockWidget::title{ background: #e3e3e3; border: none; padding-top: 0.2em; padding-left: 0.2em; }"
|
|
||||||
"QDockWidget::close-button, QDockWidget::float-button{ background-color: #e3e3e3; }"
|
|
||||||
|
|
||||||
// log frame tty
|
|
||||||
"QTextEdit#tty_frame { background-color: #ffffff; }"
|
|
||||||
"QLabel#tty_text { color: #000000; }"
|
|
||||||
|
|
||||||
// log frame log
|
|
||||||
"QTextEdit#log_frame { background-color: #ffffff; }"
|
|
||||||
"QLabel#log_level_always { color: #107896; }"
|
|
||||||
"QLabel#log_level_fatal { color: #ff00ff; }"
|
|
||||||
"QLabel#log_level_error { color: #C02F1D; }"
|
|
||||||
"QLabel#log_level_todo { color: #ff6000; }"
|
|
||||||
"QLabel#log_level_success { color: #008000; }"
|
|
||||||
"QLabel#log_level_warning { color: #BA8745; }"
|
|
||||||
"QLabel#log_level_notice { color: #000000; }"
|
|
||||||
"QLabel#log_level_trace { color: #808080; }"
|
|
||||||
"QLabel#log_stack { color: #000000; }"
|
|
||||||
|
|
||||||
// about dialog
|
|
||||||
"QWidget#header_section { background-color: #ffffff; }"
|
|
||||||
|
|
||||||
// kernel explorer
|
|
||||||
"QDialog#kernel_explorer { background-color: rgba(240, 240, 240, 255); }"
|
|
||||||
|
|
||||||
// memory viewer
|
|
||||||
"QDialog#memory_viewer { background-color: rgba(240, 240, 240, 255); }"
|
|
||||||
"QLabel#memory_viewer_address_panel { color: rgba(75, 135, 150, 255); background-color: rgba(240, 240, 240, 255); }"
|
|
||||||
"QLabel#memory_viewer_hex_panel { color: #000000; background-color: rgba(240, 240, 240, 255); }"
|
|
||||||
"QLabel#memory_viewer_ascii_panel { color: #000000; background-color: rgba(240, 240, 240, 255); }"
|
|
||||||
|
|
||||||
// debugger frame
|
|
||||||
"QLabel#debugger_frame_breakpoint { color: #000000; background-color: #ffff00; }"
|
|
||||||
"QLabel#debugger_frame_pc { color: #000000; background-color: #00ff00; }"
|
|
||||||
|
|
||||||
// rsx debugger
|
|
||||||
"QLabel#rsx_debugger_display_buffer { background-color: rgba(240, 240, 240, 255); }"
|
|
||||||
|
|
||||||
// pad settings
|
|
||||||
"QLabel#l_controller { color: #434343; }"
|
|
||||||
);
|
|
||||||
|
|
||||||
QFile file(path);
|
|
||||||
|
|
||||||
// If we can't open the file, try the /share or /Resources folder
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
#ifdef __APPLE__
|
|
||||||
QString share_dir = QCoreApplication::applicationDirPath() + "/../Resources/";
|
|
||||||
#else
|
|
||||||
QString share_dir = QCoreApplication::applicationDirPath() + "/../share/rpcs3/";
|
|
||||||
#endif
|
|
||||||
QFile share_file(share_dir + "GuiConfigs/" + QFileInfo(file.fileName()).fileName());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (path == "")
|
|
||||||
{
|
|
||||||
setStyleSheet(style_sheet);
|
|
||||||
}
|
|
||||||
else if (file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
||||||
{
|
|
||||||
QString config_dir = qstr(fs::get_config_dir());
|
|
||||||
|
|
||||||
// Add PS3 fonts
|
|
||||||
QDirIterator ps3_font_it(qstr(g_cfg.vfs.get_dev_flash() + "data/font/"), QStringList() << "*.ttf", QDir::Files, QDirIterator::Subdirectories);
|
|
||||||
while (ps3_font_it.hasNext())
|
|
||||||
QFontDatabase::addApplicationFont(ps3_font_it.next());
|
|
||||||
|
|
||||||
// Add custom fonts
|
|
||||||
QDirIterator custom_font_it(config_dir + "fonts/", QStringList() << "*.ttf", QDir::Files, QDirIterator::Subdirectories);
|
|
||||||
while (custom_font_it.hasNext())
|
|
||||||
QFontDatabase::addApplicationFont(custom_font_it.next());
|
|
||||||
|
|
||||||
// Set root for stylesheets
|
|
||||||
QDir::setCurrent(config_dir);
|
|
||||||
setStyleSheet(file.readAll());
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
else if (share_file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
||||||
{
|
|
||||||
QDir::setCurrent(share_dir);
|
|
||||||
setStyleSheet(share_file.readAll());
|
|
||||||
share_file.close();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setStyleSheet(style_sheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
gui::stylesheet = styleSheet();
|
|
||||||
RPCS3MainWin->RepaintGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Using connects avoids timers being unable to be used in a non-qt thread. So, even if this looks stupid to just call func, it's succinct.
|
* Using connects avoids timers being unable to be used in a non-qt thread. So, even if this looks stupid to just call func, it's succinct.
|
||||||
*/
|
*/
|
||||||
void rpcs3_app::HandleCallAfter(const std::function<void()>& func)
|
void rpcs3_app::HandleCallAfter(const std::function<void()>& func)
|
||||||
{
|
{
|
||||||
func();
|
func();
|
||||||
|
@ -2,59 +2,35 @@
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include "keyboard_pad_handler.h"
|
#include "main_application.h"
|
||||||
#include "basic_keyboard_handler.h"
|
|
||||||
#include "basic_mouse_handler.h"
|
|
||||||
|
|
||||||
#include "Utilities/Config.h"
|
#include <QCoreApplication>
|
||||||
#include "Emu/VFS.h"
|
|
||||||
#include "Emu/RSX/GSRender.h"
|
|
||||||
#include "Emu/Io/KeyboardHandler.h"
|
|
||||||
#include "Emu/Io/PadHandler.h"
|
|
||||||
#include "Emu/Io/MouseHandler.h"
|
|
||||||
#include "Emu/Audio/AudioBackend.h"
|
|
||||||
|
|
||||||
#include "rpcs3qt/msg_dialog_frame.h"
|
|
||||||
#include "rpcs3qt/osk_dialog_frame.h"
|
|
||||||
#include "rpcs3qt/main_window.h"
|
|
||||||
#include "rpcs3qt/gui_settings.h"
|
|
||||||
#include "rpcs3qt/emu_settings.h"
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QFontDatabase>
|
|
||||||
|
|
||||||
/** RPCS3 Application Class
|
/** RPCS3 Application Class
|
||||||
* The point of this class is to do application initialization and to hold onto the main window. The main thing I intend this class to do, for now, is to initialize callbacks and the main_window.
|
* The point of this class is to do application initialization and to hold onto the main window. The main thing I intend this class to do, for now, is to initialize callbacks and the main_window.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class rpcs3_app : public QApplication
|
class rpcs3_app : public QCoreApplication, public main_application
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
rpcs3_app(int& argc, char** argv);
|
rpcs3_app(int& argc, char** argv);
|
||||||
/** Call this method before calling app.exec
|
|
||||||
*/
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
/** Emu.Init() wrapper for user manager */
|
/** Call this method before calling app.exec */
|
||||||
static bool InitializeEmulator(const std::string& user, bool force_init);
|
void Init() override;
|
||||||
Q_SIGNALS:
|
|
||||||
void OnEmulatorRun();
|
|
||||||
void OnEmulatorPause();
|
|
||||||
void OnEmulatorResume();
|
|
||||||
void OnEmulatorStop();
|
|
||||||
void OnEmulatorReady();
|
|
||||||
void RequestCallAfter(const std::function<void()>& func);
|
|
||||||
private Q_SLOTS:
|
|
||||||
void OnChangeStyleSheetRequest(const QString& path);
|
|
||||||
void HandleCallAfter(const std::function<void()>& func);
|
|
||||||
private:
|
private:
|
||||||
void InitializeCallbacks();
|
void InitializeCallbacks();
|
||||||
void InitializeConnects();
|
void InitializeConnects();
|
||||||
|
|
||||||
main_window* RPCS3MainWin = nullptr;
|
QThread* get_thread() override
|
||||||
|
{
|
||||||
|
return thread();
|
||||||
|
};
|
||||||
|
|
||||||
std::shared_ptr<gui_settings> guiSettings;
|
Q_SIGNALS:
|
||||||
std::shared_ptr<emu_settings> emuSettings;
|
void RequestCallAfter(const std::function<void()>& func);
|
||||||
QWindow* gameWindow = nullptr; //! (Currently) only needed so that pad handlers have a valid target for event filtering.
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void HandleCallAfter(const std::function<void()>& func);
|
||||||
};
|
};
|
||||||
|
315
rpcs3/rpcs3qt/gui_application.cpp
Normal file
315
rpcs3/rpcs3qt/gui_application.cpp
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
#include "gui_application.h"
|
||||||
|
|
||||||
|
#include "qt_utils.h"
|
||||||
|
#include "welcome_dialog.h"
|
||||||
|
|
||||||
|
#ifdef WITH_DISCORD_RPC
|
||||||
|
#include "_discord_utils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "trophy_notification_helper.h"
|
||||||
|
#include "save_data_dialog.h"
|
||||||
|
#include "msg_dialog_frame.h"
|
||||||
|
#include "osk_dialog_frame.h"
|
||||||
|
|
||||||
|
gui_application::gui_application(int& argc, char** argv) : QApplication(argc, argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_application::Init()
|
||||||
|
{
|
||||||
|
setWindowIcon(QIcon(":/rpcs3.ico"));
|
||||||
|
|
||||||
|
m_emu_settings.reset(new emu_settings());
|
||||||
|
m_gui_settings.reset(new gui_settings());
|
||||||
|
|
||||||
|
// Force init the emulator
|
||||||
|
InitializeEmulator(m_gui_settings->GetCurrentUser().toStdString(), true);
|
||||||
|
|
||||||
|
// Create the main window
|
||||||
|
m_main_window = new main_window(m_gui_settings, m_emu_settings, nullptr);
|
||||||
|
|
||||||
|
// Create callbacks from the emulator, which reference the handlers.
|
||||||
|
InitializeCallbacks();
|
||||||
|
|
||||||
|
// Create connects to propagate events throughout Gui.
|
||||||
|
InitializeConnects();
|
||||||
|
|
||||||
|
m_main_window->Init();
|
||||||
|
|
||||||
|
if (m_gui_settings->GetValue(gui::ib_show_welcome).toBool())
|
||||||
|
{
|
||||||
|
welcome_dialog* welcome = new welcome_dialog();
|
||||||
|
welcome->exec();
|
||||||
|
}
|
||||||
|
#ifdef WITH_DISCORD_RPC
|
||||||
|
// Discord Rich Presence Integration
|
||||||
|
if (m_gui_settings->GetValue(gui::m_richPresence).toBool())
|
||||||
|
{
|
||||||
|
discord::initialize();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_application::InitializeConnects()
|
||||||
|
{
|
||||||
|
connect(m_main_window, &main_window::RequestGlobalStylesheetChange, this, &gui_application::OnChangeStyleSheetRequest);
|
||||||
|
|
||||||
|
connect(this, &gui_application::OnEmulatorRun, m_main_window, &main_window::OnEmuRun);
|
||||||
|
connect(this, &gui_application::OnEmulatorStop, m_main_window, &main_window::OnEmuStop);
|
||||||
|
connect(this, &gui_application::OnEmulatorPause, m_main_window, &main_window::OnEmuPause);
|
||||||
|
connect(this, &gui_application::OnEmulatorResume, m_main_window, &main_window::OnEmuResume);
|
||||||
|
connect(this, &gui_application::OnEmulatorReady, m_main_window, &main_window::OnEmuReady);
|
||||||
|
|
||||||
|
qRegisterMetaType<std::function<void()>>("std::function<void()>");
|
||||||
|
connect(this, &gui_application::RequestCallAfter, this, &gui_application::HandleCallAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<gs_frame> gui_application::get_gs_frame()
|
||||||
|
{
|
||||||
|
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
|
||||||
|
|
||||||
|
const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution);
|
||||||
|
int w = size.first;
|
||||||
|
int h = size.second;
|
||||||
|
|
||||||
|
if (m_gui_settings->GetValue(gui::gs_resize).toBool())
|
||||||
|
{
|
||||||
|
w = m_gui_settings->GetValue(gui::gs_width).toInt();
|
||||||
|
h = m_gui_settings->GetValue(gui::gs_height).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto frame_geometry = gui::utils::create_centered_window_geometry(m_main_window->geometry(), w, h);
|
||||||
|
|
||||||
|
gs_frame* frame;
|
||||||
|
|
||||||
|
switch (video_renderer type = g_cfg.video.renderer)
|
||||||
|
{
|
||||||
|
case video_renderer::null:
|
||||||
|
{
|
||||||
|
frame = new gs_frame("Null", frame_geometry, m_main_window->GetAppIcon(), m_gui_settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case video_renderer::opengl:
|
||||||
|
{
|
||||||
|
frame = new gl_gs_frame(frame_geometry, m_main_window->GetAppIcon(), m_gui_settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case video_renderer::vulkan:
|
||||||
|
{
|
||||||
|
frame = new gs_frame("Vulkan", frame_geometry, m_main_window->GetAppIcon(), m_gui_settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
case video_renderer::dx12:
|
||||||
|
{
|
||||||
|
frame = new gs_frame("DirectX 12", frame_geometry, m_main_window->GetAppIcon(), m_gui_settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_game_window = frame;
|
||||||
|
return std::unique_ptr<gs_frame>(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here. */
|
||||||
|
void gui_application::InitializeCallbacks()
|
||||||
|
{
|
||||||
|
EmuCallbacks callbacks = CreateCallbacks();
|
||||||
|
|
||||||
|
callbacks.exit = [this]()
|
||||||
|
{
|
||||||
|
quit();
|
||||||
|
};
|
||||||
|
callbacks.call_after = [=](std::function<void()> func)
|
||||||
|
{
|
||||||
|
RequestCallAfter(std::move(func));
|
||||||
|
};
|
||||||
|
|
||||||
|
callbacks.get_gs_frame = [this]() -> std::unique_ptr<GSFrameBase> { return get_gs_frame(); };
|
||||||
|
callbacks.get_msg_dialog = [this]() -> std::shared_ptr<MsgDialogBase> { return std::make_shared<msg_dialog_frame>(m_main_window->windowHandle()); };
|
||||||
|
callbacks.get_osk_dialog = []() -> std::shared_ptr<OskDialogBase> { return std::make_shared<osk_dialog_frame>(); };
|
||||||
|
callbacks.get_save_dialog = []() -> std::unique_ptr<SaveDialogBase> { return std::make_unique<save_data_dialog>(); };
|
||||||
|
callbacks.get_trophy_notification_dialog = [this]() -> std::unique_ptr<TrophyNotificationBase> { return std::make_unique<trophy_notification_helper>(m_game_window); };
|
||||||
|
|
||||||
|
callbacks.on_run = [=]() { OnEmulatorRun(); };
|
||||||
|
callbacks.on_pause = [=]() { OnEmulatorPause(); };
|
||||||
|
callbacks.on_resume = [=]() { OnEmulatorResume(); };
|
||||||
|
callbacks.on_stop = [=]() { OnEmulatorStop(); };
|
||||||
|
callbacks.on_ready = [=]() { OnEmulatorReady(); };
|
||||||
|
|
||||||
|
callbacks.handle_taskbar_progress = [=](s32 type, s32 value)
|
||||||
|
{
|
||||||
|
if (m_game_window)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0: ((gs_frame*)m_game_window)->progress_reset(value); break;
|
||||||
|
case 1: ((gs_frame*)m_game_window)->progress_increment(value); break;
|
||||||
|
case 2: ((gs_frame*)m_game_window)->progress_set_limit(value); break;
|
||||||
|
default: LOG_FATAL(GENERAL, "Unknown type in handle_taskbar_progress(type=%d, value=%d)", type, value); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Emu.SetCallbacks(std::move(callbacks));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle a request to change the stylesheet. May consider adding reporting of errors in future.
|
||||||
|
* Empty string means default.
|
||||||
|
*/
|
||||||
|
void gui_application::OnChangeStyleSheetRequest(const QString& path)
|
||||||
|
{
|
||||||
|
QString style_sheet
|
||||||
|
(
|
||||||
|
// main window toolbar search
|
||||||
|
"QLineEdit#mw_searchbar { padding: 0 1em; background: #fdfdfd; selection-background-color: #148aff; margin: .8em; color:#000000; }"
|
||||||
|
|
||||||
|
// main window toolbar slider
|
||||||
|
"QSlider#sizeSlider { color: #505050; background: #F0F0F0; }"
|
||||||
|
"QSlider#sizeSlider::handle:horizontal { border: 0em smooth rgba(227, 227, 227, 255); border-radius: .58em; background: #404040; width: 1.2em; margin: -.5em 0; }"
|
||||||
|
"QSlider#sizeSlider::groove:horizontal { border-radius: .15em; background: #5b5b5b; height: .3em; }"
|
||||||
|
|
||||||
|
// main window toolbar
|
||||||
|
"QToolBar#mw_toolbar { background-color: #F0F0F0; border: none; }"
|
||||||
|
"QToolBar#mw_toolbar::separator { background-color: rgba(207, 207, 207, 235); width: 0.125em; margin-top: 0.250em; margin-bottom: 0.250em; }"
|
||||||
|
|
||||||
|
// main window toolbar icon color
|
||||||
|
"QLabel#toolbar_icon_color { color: #5b5b5b; }"
|
||||||
|
|
||||||
|
// thumbnail icon color
|
||||||
|
"QLabel#thumbnail_icon_color { color: rgba(0, 100, 231, 255); }"
|
||||||
|
|
||||||
|
// game list icon color
|
||||||
|
"QLabel#gamelist_icon_background_color { color: rgba(240, 240, 240, 255); }"
|
||||||
|
|
||||||
|
// save manager icon color
|
||||||
|
"QLabel#save_manager_icon_background_color { color: rgba(240, 240, 240, 255); }"
|
||||||
|
|
||||||
|
// trophy manager icon color
|
||||||
|
"QLabel#trophy_manager_icon_background_color { color: rgba(240, 240, 240, 255); }"
|
||||||
|
|
||||||
|
// tables
|
||||||
|
"QTableWidget { alternate-background-color: #f2f2f2; background-color: #fff; border: none; }"
|
||||||
|
"QTableWidget#game_grid { alternate-background-color: #f2f2f2; background-color: #fff; font-weight: 600; font-size: 8pt; font-family: Lucida Grande; color: rgba(51, 51, 51, 255); border: 0em solid white; }"
|
||||||
|
"QTableView::item { border-left: 0.063em solid white; border-right: 0.063em solid white; padding-left:0.313em; }"
|
||||||
|
"QTableView::item:selected { background-color: #148aff; color: #fff; }"
|
||||||
|
"QTableView#game_grid::item:hover:!selected { background-color: #94c9ff; color: #fff; }"
|
||||||
|
"QTableView#game_grid::item:hover:selected { background-color: #007fff; color: #fff; }"
|
||||||
|
|
||||||
|
// table headers
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(5,11,0))
|
||||||
|
"QHeaderView::section { padding: .5em; border: 0.063em solid #ffffff; }"
|
||||||
|
"QHeaderView::section:hover { background: #e3e3e3; padding: .5em; border: 0.063em solid #ffffff; }"
|
||||||
|
#else
|
||||||
|
"QHeaderView::section { padding-left: .5em; padding-right: .5em; padding-top: .4em; padding-bottom: -.1em; border: 0.063em solid #ffffff; }"
|
||||||
|
"QHeaderView::section:hover { background: #e3e3e3; padding-left: .5em; padding-right: .5em; padding-top: .4em; padding-bottom: -.1em; border: 0.063em solid #ffffff; }"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// dock widget
|
||||||
|
"QDockWidget{ background: transparent; color: black; }"
|
||||||
|
"[floating=\"true\"]{ background: white; }"
|
||||||
|
"QDockWidget::title{ background: #e3e3e3; border: none; padding-top: 0.2em; padding-left: 0.2em; }"
|
||||||
|
"QDockWidget::close-button, QDockWidget::float-button{ background-color: #e3e3e3; }"
|
||||||
|
|
||||||
|
// log frame tty
|
||||||
|
"QTextEdit#tty_frame { background-color: #ffffff; }"
|
||||||
|
"QLabel#tty_text { color: #000000; }"
|
||||||
|
|
||||||
|
// log frame log
|
||||||
|
"QTextEdit#log_frame { background-color: #ffffff; }"
|
||||||
|
"QLabel#log_level_always { color: #107896; }"
|
||||||
|
"QLabel#log_level_fatal { color: #ff00ff; }"
|
||||||
|
"QLabel#log_level_error { color: #C02F1D; }"
|
||||||
|
"QLabel#log_level_todo { color: #ff6000; }"
|
||||||
|
"QLabel#log_level_success { color: #008000; }"
|
||||||
|
"QLabel#log_level_warning { color: #BA8745; }"
|
||||||
|
"QLabel#log_level_notice { color: #000000; }"
|
||||||
|
"QLabel#log_level_trace { color: #808080; }"
|
||||||
|
"QLabel#log_stack { color: #000000; }"
|
||||||
|
|
||||||
|
// about dialog
|
||||||
|
"QWidget#header_section { background-color: #ffffff; }"
|
||||||
|
|
||||||
|
// kernel explorer
|
||||||
|
"QDialog#kernel_explorer { background-color: rgba(240, 240, 240, 255); }"
|
||||||
|
|
||||||
|
// memory viewer
|
||||||
|
"QDialog#memory_viewer { background-color: rgba(240, 240, 240, 255); }"
|
||||||
|
"QLabel#memory_viewer_address_panel { color: rgba(75, 135, 150, 255); background-color: rgba(240, 240, 240, 255); }"
|
||||||
|
"QLabel#memory_viewer_hex_panel { color: #000000; background-color: rgba(240, 240, 240, 255); }"
|
||||||
|
"QLabel#memory_viewer_ascii_panel { color: #000000; background-color: rgba(240, 240, 240, 255); }"
|
||||||
|
|
||||||
|
// debugger frame
|
||||||
|
"QLabel#debugger_frame_breakpoint { color: #000000; background-color: #ffff00; }"
|
||||||
|
"QLabel#debugger_frame_pc { color: #000000; background-color: #00ff00; }"
|
||||||
|
|
||||||
|
// rsx debugger
|
||||||
|
"QLabel#rsx_debugger_display_buffer { background-color: rgba(240, 240, 240, 255); }"
|
||||||
|
|
||||||
|
// pad settings
|
||||||
|
"QLabel#l_controller { color: #434343; }"
|
||||||
|
);
|
||||||
|
|
||||||
|
QFile file(path);
|
||||||
|
|
||||||
|
// If we can't open the file, try the /share or /Resources folder
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
#ifdef __APPLE__
|
||||||
|
QString share_dir = QCoreApplication::applicationDirPath() + "/../Resources/";
|
||||||
|
#else
|
||||||
|
QString share_dir = QCoreApplication::applicationDirPath() + "/../share/rpcs3/";
|
||||||
|
#endif
|
||||||
|
QFile share_file(share_dir + "GuiConfigs/" + QFileInfo(file.fileName()).fileName());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (path == "")
|
||||||
|
{
|
||||||
|
setStyleSheet(style_sheet);
|
||||||
|
}
|
||||||
|
else if (file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
QString config_dir = qstr(fs::get_config_dir());
|
||||||
|
|
||||||
|
// Add PS3 fonts
|
||||||
|
QDirIterator ps3_font_it(qstr(g_cfg.vfs.get_dev_flash() + "data/font/"), QStringList() << "*.ttf", QDir::Files, QDirIterator::Subdirectories);
|
||||||
|
while (ps3_font_it.hasNext())
|
||||||
|
QFontDatabase::addApplicationFont(ps3_font_it.next());
|
||||||
|
|
||||||
|
// Add custom fonts
|
||||||
|
QDirIterator custom_font_it(config_dir + "fonts/", QStringList() << "*.ttf", QDir::Files, QDirIterator::Subdirectories);
|
||||||
|
while (custom_font_it.hasNext())
|
||||||
|
QFontDatabase::addApplicationFont(custom_font_it.next());
|
||||||
|
|
||||||
|
// Set root for stylesheets
|
||||||
|
QDir::setCurrent(config_dir);
|
||||||
|
setStyleSheet(file.readAll());
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
else if (share_file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
QDir::setCurrent(share_dir);
|
||||||
|
setStyleSheet(share_file.readAll());
|
||||||
|
share_file.close();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStyleSheet(style_sheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
gui::stylesheet = styleSheet();
|
||||||
|
m_main_window->RepaintGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using connects avoids timers being unable to be used in a non-qt thread. So, even if this looks stupid to just call func, it's succinct.
|
||||||
|
*/
|
||||||
|
void gui_application::HandleCallAfter(const std::function<void()>& func)
|
||||||
|
{
|
||||||
|
func();
|
||||||
|
}
|
55
rpcs3/rpcs3qt/gui_application.h
Normal file
55
rpcs3/rpcs3qt/gui_application.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "main_application.h"
|
||||||
|
#include "main_window.h"
|
||||||
|
#include "emu_settings.h"
|
||||||
|
#include "gui_settings.h"
|
||||||
|
#include "gs_frame.h"
|
||||||
|
#include "gl_gs_frame.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFontDatabase>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
class gui_application : public QApplication, public main_application
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
gui_application(int& argc, char** argv);
|
||||||
|
|
||||||
|
/** Call this method before calling app.exec */
|
||||||
|
void Init() override;
|
||||||
|
|
||||||
|
std::unique_ptr<gs_frame> get_gs_frame();
|
||||||
|
|
||||||
|
main_window* m_main_window = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QThread* get_thread() override
|
||||||
|
{
|
||||||
|
return thread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeCallbacks();
|
||||||
|
void InitializeConnects();
|
||||||
|
|
||||||
|
std::shared_ptr<emu_settings> m_emu_settings;
|
||||||
|
std::shared_ptr<gui_settings> m_gui_settings;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void OnChangeStyleSheetRequest(const QString& path);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void OnEmulatorRun();
|
||||||
|
void OnEmulatorPause();
|
||||||
|
void OnEmulatorResume();
|
||||||
|
void OnEmulatorStop();
|
||||||
|
void OnEmulatorReady();
|
||||||
|
|
||||||
|
void RequestCallAfter(const std::function<void()>& func);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void HandleCallAfter(const std::function<void()>& func);
|
||||||
|
};
|
@ -1,12 +1,13 @@
|
|||||||
#include "user_manager_dialog.h"
|
#include "user_manager_dialog.h"
|
||||||
#include "table_item_delegate.h"
|
#include "table_item_delegate.h"
|
||||||
#include "rpcs3_app.h"
|
#include "main_application.h"
|
||||||
|
|
||||||
#include "Utilities/StrUtil.h"
|
#include "Utilities/StrUtil.h"
|
||||||
|
|
||||||
#include <QRegExpValidator>
|
#include <QRegExpValidator>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -362,7 +363,7 @@ void user_manager_dialog::OnUserLogin()
|
|||||||
const u32 key = GetUserKey();
|
const u32 key = GetUserKey();
|
||||||
const std::string new_user = m_user_list[key].GetUserId();
|
const std::string new_user = m_user_list[key].GetUserId();
|
||||||
|
|
||||||
if (!rpcs3_app::InitializeEmulator(new_user, false))
|
if (!main_application::InitializeEmulator(new_user, false))
|
||||||
{
|
{
|
||||||
LOG_FATAL(GENERAL, "Failed to login user! username=%s key=%d", new_user, key);
|
LOG_FATAL(GENERAL, "Failed to login user! username=%s key=%d", new_user, key);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user