summaryrefslogtreecommitdiffstats
path: root/src/citra
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/citra/CMakeLists.txt11
-rw-r--r--src/citra/citra.cpp40
-rw-r--r--src/citra/citra.rc2
-rw-r--r--src/citra/emu_window/emu_window_sdl2.cpp2
-rw-r--r--src/citra/emu_window/emu_window_sdl2.h2
-rw-r--r--src/citra_qt/CMakeLists.txt59
-rw-r--r--src/citra_qt/bootmanager.cpp15
-rw-r--r--src/citra_qt/bootmanager.h6
-rw-r--r--src/citra_qt/citra-qt.rc2
-rw-r--r--src/citra_qt/configure_general.cpp4
-rw-r--r--src/citra_qt/configure_graphics.cpp4
-rw-r--r--src/citra_qt/configure_input.cpp169
-rw-r--r--src/citra_qt/configure_input.h47
-rw-r--r--src/citra_qt/configure_system.cpp3
-rw-r--r--src/citra_qt/debugger/callstack.cpp2
-rw-r--r--src/citra_qt/debugger/callstack.h4
-rw-r--r--src/citra_qt/debugger/disassembler.cpp10
-rw-r--r--src/citra_qt/debugger/disassembler.h6
-rw-r--r--src/citra_qt/debugger/graphics/graphics.cpp (renamed from src/citra_qt/debugger/graphics.cpp)18
-rw-r--r--src/citra_qt/debugger/graphics/graphics.h (renamed from src/citra_qt/debugger/graphics.h)2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_breakpoint_observer.cpp (renamed from src/citra_qt/debugger/graphics_breakpoint_observer.cpp)2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_breakpoint_observer.h (renamed from src/citra_qt/debugger/graphics_breakpoint_observer.h)0
-rw-r--r--src/citra_qt/debugger/graphics/graphics_breakpoints.cpp (renamed from src/citra_qt/debugger/graphics_breakpoints.cpp)4
-rw-r--r--src/citra_qt/debugger/graphics/graphics_breakpoints.h (renamed from src/citra_qt/debugger/graphics_breakpoints.h)4
-rw-r--r--src/citra_qt/debugger/graphics/graphics_breakpoints_p.h (renamed from src/citra_qt/debugger/graphics_breakpoints_p.h)0
-rw-r--r--src/citra_qt/debugger/graphics/graphics_cmdlists.cpp (renamed from src/citra_qt/debugger/graphics_cmdlists.cpp)44
-rw-r--r--src/citra_qt/debugger/graphics/graphics_cmdlists.h (renamed from src/citra_qt/debugger/graphics_cmdlists.h)4
-rw-r--r--src/citra_qt/debugger/graphics/graphics_surface.cpp (renamed from src/citra_qt/debugger/graphics_surface.cpp)2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_surface.h (renamed from src/citra_qt/debugger/graphics_surface.h)9
-rw-r--r--src/citra_qt/debugger/graphics/graphics_tracing.cpp (renamed from src/citra_qt/debugger/graphics_tracing.cpp)2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_tracing.h (renamed from src/citra_qt/debugger/graphics_tracing.h)6
-rw-r--r--src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp (renamed from src/citra_qt/debugger/graphics_vertex_shader.cpp)2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_vertex_shader.h (renamed from src/citra_qt/debugger/graphics_vertex_shader.h)4
-rw-r--r--src/citra_qt/debugger/profiler.h6
-rw-r--r--src/citra_qt/debugger/ramview.h4
-rw-r--r--src/citra_qt/debugger/registers.cpp16
-rw-r--r--src/citra_qt/debugger/registers.h4
-rw-r--r--src/citra_qt/debugger/wait_tree.cpp6
-rw-r--r--src/citra_qt/debugger/wait_tree.h26
-rw-r--r--src/citra_qt/game_list.cpp46
-rw-r--r--src/citra_qt/game_list.h16
-rw-r--r--src/citra_qt/game_list_p.h5
-rw-r--r--src/citra_qt/hotkeys.h2
-rw-r--r--src/citra_qt/main.cpp236
-rw-r--r--src/citra_qt/main.h29
-rw-r--r--src/citra_qt/util/spinbox.h2
46 files changed, 452 insertions, 437 deletions
diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt
index f9c488a1a..ecb5d2dfe 100644
--- a/src/citra/CMakeLists.txt
+++ b/src/citra/CMakeLists.txt
@@ -1,3 +1,5 @@
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
+
set(SRCS
emu_window/emu_window_sdl2.cpp
citra.cpp
@@ -28,11 +30,6 @@ if(UNIX AND NOT APPLE)
endif()
if (MSVC)
- include(WindowsCopyFiles)
-
- set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
-
- windows_copy_files(citra ${SDL2_DLL_DIR} ${DLL_DEST} SDL2.dll)
-
- unset(DLL_DEST)
+ include(CopyCitraSDLDeps)
+ copy_citra_SDL_deps(citra)
endif()
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index f9387e61c..99c096ac7 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -18,7 +18,7 @@
#endif
#ifdef _WIN32
-#include <Windows.h>
+#include <windows.h>
#endif
#include "citra/config.h"
@@ -33,7 +33,6 @@
#include "core/gdbstub/gdbstub.h"
#include "core/loader/loader.h"
#include "core/settings.h"
-#include "core/system.h"
#include "video_core/video_core.h"
static void PrintHelp(const char* argv0) {
@@ -64,7 +63,7 @@ int main(int argc, char** argv) {
return -1;
}
#endif
- std::string boot_filename;
+ std::string filepath;
static struct option long_options[] = {
{"gdbport", required_argument, 0, 'g'},
@@ -97,9 +96,9 @@ int main(int argc, char** argv) {
}
} else {
#ifdef _WIN32
- boot_filename = Common::UTF16ToUTF8(argv_w[optind]);
+ filepath = Common::UTF16ToUTF8(argv_w[optind]);
#else
- boot_filename = argv[optind];
+ filepath = argv[optind];
#endif
optind++;
}
@@ -115,7 +114,7 @@ int main(int argc, char** argv) {
MicroProfileOnThreadCreate("EmuThread");
SCOPE_EXIT({ MicroProfileShutdown(); });
- if (boot_filename.empty()) {
+ if (filepath.empty()) {
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
return -1;
}
@@ -127,32 +126,25 @@ int main(int argc, char** argv) {
Settings::values.use_gdbstub = use_gdbstub;
Settings::Apply();
- std::unique_ptr<EmuWindow_SDL2> emu_window = std::make_unique<EmuWindow_SDL2>();
+ std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>()};
- std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(boot_filename);
- if (!loader) {
- LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", boot_filename.c_str());
- return -1;
- }
-
- boost::optional<u32> system_mode = loader->LoadKernelSystemMode();
+ Core::System& system{Core::System::GetInstance()};
- if (!system_mode) {
- LOG_CRITICAL(Frontend, "Failed to load ROM (Could not determine system mode)!");
- return -1;
- }
+ SCOPE_EXIT({ system.Shutdown(); });
- System::Init(emu_window.get(), system_mode.get());
- SCOPE_EXIT({ System::Shutdown(); });
+ const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)};
- Loader::ResultStatus load_result = loader->Load();
- if (Loader::ResultStatus::Success != load_result) {
- LOG_CRITICAL(Frontend, "Failed to load ROM (Error %i)!", load_result);
+ switch (load_result) {
+ case Core::System::ResultStatus::ErrorGetLoader:
+ LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str());
+ return -1;
+ case Core::System::ResultStatus::ErrorLoader:
+ LOG_CRITICAL(Frontend, "Failed to load ROM!");
return -1;
}
while (emu_window->IsOpen()) {
- Core::RunLoop();
+ system.RunLoop();
}
return 0;
diff --git a/src/citra/citra.rc b/src/citra/citra.rc
index b0edb2e6b..fea603004 100644
--- a/src/citra/citra.rc
+++ b/src/citra/citra.rc
@@ -5,5 +5,5 @@
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
-GLFW_ICON ICON "..\\..\\dist\\citra.ico"
+CITRA_ICON ICON "../../dist/citra.ico"
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp
index 8abe48984..b0d82b670 100644
--- a/src/citra/emu_window/emu_window_sdl2.cpp
+++ b/src/citra/emu_window/emu_window_sdl2.cpp
@@ -9,10 +9,10 @@
#include <SDL.h>
#include <glad/glad.h>
#include "citra/emu_window/emu_window_sdl2.h"
-#include "common/key_map.h"
#include "common/logging/log.h"
#include "common/scm_rev.h"
#include "common/string_util.h"
+#include "core/frontend/key_map.h"
#include "core/hle/service/hid/hid.h"
#include "core/settings.h"
#include "video_core/video_core.h"
diff --git a/src/citra/emu_window/emu_window_sdl2.h b/src/citra/emu_window/emu_window_sdl2.h
index e4d14ef12..c8cd919c6 100644
--- a/src/citra/emu_window/emu_window_sdl2.h
+++ b/src/citra/emu_window/emu_window_sdl2.h
@@ -5,7 +5,7 @@
#pragma once
#include <utility>
-#include "common/emu_window.h"
+#include "core/frontend/emu_window.h"
struct SDL_Window;
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index a9dacd5f1..93f1c339d 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -1,17 +1,18 @@
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
set(SRCS
config.cpp
debugger/callstack.cpp
debugger/disassembler.cpp
- debugger/graphics.cpp
- debugger/graphics_breakpoint_observer.cpp
- debugger/graphics_breakpoints.cpp
- debugger/graphics_cmdlists.cpp
- debugger/graphics_surface.cpp
- debugger/graphics_tracing.cpp
- debugger/graphics_vertex_shader.cpp
+ debugger/graphics/graphics.cpp
+ debugger/graphics/graphics_breakpoint_observer.cpp
+ debugger/graphics/graphics_breakpoints.cpp
+ debugger/graphics/graphics_cmdlists.cpp
+ debugger/graphics/graphics_surface.cpp
+ debugger/graphics/graphics_tracing.cpp
+ debugger/graphics/graphics_vertex_shader.cpp
debugger/profiler.cpp
debugger/ramview.cpp
debugger/registers.cpp
@@ -38,14 +39,14 @@ set(HEADERS
config.h
debugger/callstack.h
debugger/disassembler.h
- debugger/graphics.h
- debugger/graphics_breakpoint_observer.h
- debugger/graphics_breakpoints.h
- debugger/graphics_breakpoints_p.h
- debugger/graphics_cmdlists.h
- debugger/graphics_surface.h
- debugger/graphics_tracing.h
- debugger/graphics_vertex_shader.h
+ debugger/graphics/graphics.h
+ debugger/graphics/graphics_breakpoint_observer.h
+ debugger/graphics/graphics_breakpoints.h
+ debugger/graphics/graphics_breakpoints_p.h
+ debugger/graphics/graphics_cmdlists.h
+ debugger/graphics/graphics_surface.h
+ debugger/graphics/graphics_tracing.h
+ debugger/graphics/graphics_vertex_shader.h
debugger/profiler.h
debugger/ramview.h
debugger/registers.h
@@ -107,27 +108,9 @@ if(UNIX AND NOT APPLE)
install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endif()
-if (Qt5_FOUND AND MSVC)
- include(WindowsCopyFiles)
-
- set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
- set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
- set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
- set(PLATFORMS ${DLL_DEST}platforms/)
-
- windows_copy_files(citra-qt ${Qt5_DLL_DIR} ${DLL_DEST}
- icudt*.dll
- icuin*.dll
- icuuc*.dll
- Qt5Core$<$<CONFIG:Debug>:d>.*
- Qt5Gui$<$<CONFIG:Debug>:d>.*
- Qt5OpenGL$<$<CONFIG:Debug>:d>.*
- Qt5Widgets$<$<CONFIG:Debug>:d>.*
- )
- windows_copy_files(citra-qt ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
-
- unset(Qt5_DLL_DIR)
- unset(Qt5_PLATFORMS_DIR)
- unset(DLL_DEST)
- unset(PLATFORMS)
+if (MSVC)
+ include(CopyCitraQt5Deps)
+ include(CopyCitraSDLDeps)
+ copy_citra_Qt5_deps(citra-qt)
+ copy_citra_SDL_deps(citra-qt)
endif()
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 7699ca8d0..57fde6caa 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -9,21 +9,14 @@
#endif
#include "citra_qt/bootmanager.h"
-#include "common/key_map.h"
#include "common/microprofile.h"
#include "common/scm_rev.h"
#include "common/string_util.h"
#include "core/core.h"
-#include "core/settings.h"
-#include "core/system.h"
+#include "core/frontend/key_map.h"
#include "video_core/debug_utils/debug_utils.h"
#include "video_core/video_core.h"
-#define APP_NAME "citra"
-#define APP_VERSION "0.1-" VERSION
-#define APP_TITLE APP_NAME " " APP_VERSION
-#define COPYRIGHT "Copyright (C) 2013-2014 Citra Team"
-
EmuThread::EmuThread(GRenderWindow* render_window)
: exec_step(false), running(false), stop_run(false), render_window(render_window) {}
@@ -43,7 +36,7 @@ void EmuThread::run() {
if (!was_active)
emit DebugModeLeft();
- Core::RunLoop();
+ Core::System::GetInstance().RunLoop();
was_active = running || exec_step;
if (!was_active && !stop_run)
@@ -53,7 +46,7 @@ void EmuThread::run() {
emit DebugModeLeft();
exec_step = false;
- Core::SingleStep();
+ Core::System::GetInstance().SingleStep();
emit DebugModeEntered();
yieldCurrentThread();
@@ -65,7 +58,7 @@ void EmuThread::run() {
}
// Shutdown the core emulation
- System::Shutdown();
+ Core::System::GetInstance().Shutdown();
#if MICROPROFILE_ENABLED
MicroProfileOnThreadExit();
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index 67228b94f..43015390b 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -2,13 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#pragma once
+
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <QGLWidget>
#include <QThread>
-#include "common/emu_window.h"
#include "common/thread.h"
+#include "core/frontend/emu_window.h"
class QKeyEvent;
class QScreen;
@@ -21,7 +23,7 @@ class EmuThread : public QThread {
Q_OBJECT
public:
- EmuThread(GRenderWindow* render_window);
+ explicit EmuThread(GRenderWindow* render_window);
/**
* Start emulation (on new thread)
diff --git a/src/citra_qt/citra-qt.rc b/src/citra_qt/citra-qt.rc
index 3c7239853..fea603004 100644
--- a/src/citra_qt/citra-qt.rc
+++ b/src/citra_qt/citra-qt.rc
@@ -5,5 +5,5 @@
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
-IDI_ICON1 ICON "..\\..\\dist\\citra.ico"
+CITRA_ICON ICON "../../dist/citra.ico"
diff --git a/src/citra_qt/configure_general.cpp b/src/citra_qt/configure_general.cpp
index 0b802d081..ac90a6df4 100644
--- a/src/citra_qt/configure_general.cpp
+++ b/src/citra_qt/configure_general.cpp
@@ -4,8 +4,8 @@
#include "citra_qt/configure_general.h"
#include "citra_qt/ui_settings.h"
+#include "core/core.h"
#include "core/settings.h"
-#include "core/system.h"
#include "ui_configure_general.h"
ConfigureGeneral::ConfigureGeneral(QWidget* parent)
@@ -14,7 +14,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
ui->setupUi(this);
this->setConfiguration();
- ui->toggle_cpu_jit->setEnabled(!System::IsPoweredOn());
+ ui->toggle_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
ConfigureGeneral::~ConfigureGeneral() {}
diff --git a/src/citra_qt/configure_graphics.cpp b/src/citra_qt/configure_graphics.cpp
index 36f10c8d7..cea7db388 100644
--- a/src/citra_qt/configure_graphics.cpp
+++ b/src/citra_qt/configure_graphics.cpp
@@ -3,8 +3,8 @@
// Refer to the license.txt file included.
#include "citra_qt/configure_graphics.h"
+#include "core/core.h"
#include "core/settings.h"
-#include "core/system.h"
#include "ui_configure_graphics.h"
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
@@ -13,7 +13,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
ui->setupUi(this);
this->setConfiguration();
- ui->toggle_vsync->setEnabled(!System::IsPoweredOn());
+ ui->toggle_vsync->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
ConfigureGraphics::~ConfigureGraphics() {}
diff --git a/src/citra_qt/configure_input.cpp b/src/citra_qt/configure_input.cpp
index d321db71f..3e6803b8a 100644
--- a/src/citra_qt/configure_input.cpp
+++ b/src/citra_qt/configure_input.cpp
@@ -5,15 +5,33 @@
#include <memory>
#include <utility>
#include <QTimer>
+#include "citra_qt/config.h"
#include "citra_qt/configure_input.h"
+static QString getKeyName(Qt::Key key_code) {
+ switch (key_code) {
+ case Qt::Key_Shift:
+ return QObject::tr("Shift");
+ case Qt::Key_Control:
+ return QObject::tr("Ctrl");
+ case Qt::Key_Alt:
+ return QObject::tr("Alt");
+ case Qt::Key_Meta:
+ case -1:
+ return "";
+ default:
+ return QKeySequence(key_code).toString();
+ }
+}
+
ConfigureInput::ConfigureInput(QWidget* parent)
- : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) {
+ : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()),
+ timer(std::make_unique<QTimer>()) {
ui->setupUi(this);
+ setFocusPolicy(Qt::ClickFocus);
- // Initialize mapping of input enum to UI button.
- input_mapping = {
+ button_map = {
{Settings::NativeInput::Values::A, ui->buttonA},
{Settings::NativeInput::Values::B, ui->buttonB},
{Settings::NativeInput::Values::X, ui->buttonX},
@@ -40,114 +58,89 @@ ConfigureInput::ConfigureInput(QWidget* parent)
{Settings::NativeInput::Values::CIRCLE_MODIFIER, ui->buttonCircleMod},
};
- // Attach handle click method to each button click.
- for (const auto& entry : input_mapping) {
- connect(entry.second, SIGNAL(released()), this, SLOT(handleClick()));
+ for (const auto& entry : button_map) {
+ const Settings::NativeInput::Values input_id = entry.first;
+ connect(entry.second, &QPushButton::released,
+ [this, input_id]() { handleClick(input_id); });
}
- connect(ui->buttonRestoreDefaults, SIGNAL(released()), this, SLOT(restoreDefaults()));
- setFocusPolicy(Qt::ClickFocus);
- timer = new QTimer(this);
+
+ connect(ui->buttonRestoreDefaults, &QPushButton::released, [this]() { restoreDefaults(); });
+
timer->setSingleShot(true);
- connect(timer, &QTimer::timeout, this, [&]() {
- key_pressed = Qt::Key_Escape;
- setKey();
+ connect(timer.get(), &QTimer::timeout, [this]() {
+ releaseKeyboard();
+ releaseMouse();
+ current_input_id = boost::none;
+ updateButtonLabels();
});
- this->setConfiguration();
-}
-void ConfigureInput::handleClick() {
- QPushButton* sender = qobject_cast<QPushButton*>(QObject::sender());
- previous_mapping = sender->text();
- sender->setText(tr("[waiting]"));
- sender->setFocus();
- grabKeyboard();
- grabMouse();
- changing_button = sender;
- timer->start(5000); // Cancel after 5 seconds
+ this->loadConfiguration();
}
void ConfigureInput::applyConfiguration() {
- for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
- int value = getKeyValue(input_mapping[Settings::NativeInput::Values(i)]->text());
- Settings::values.input_mappings[Settings::NativeInput::All[i]] = value;
+ for (const auto& input_id : Settings::NativeInput::All) {
+ const size_t index = static_cast<size_t>(input_id);
+ Settings::values.input_mappings[index] = static_cast<int>(key_map[input_id]);
}
Settings::Apply();
}
-void ConfigureInput::setConfiguration() {
- for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
- QString keyValue = getKeyName(Settings::values.input_mappings[i]);
- input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue);
+void ConfigureInput::loadConfiguration() {
+ for (const auto& input_id : Settings::NativeInput::All) {
+ const size_t index = static_cast<size_t>(input_id);
+ key_map[input_id] = static_cast<Qt::Key>(Settings::values.input_mappings[index]);
}
+ updateButtonLabels();
}
-void ConfigureInput::keyPressEvent(QKeyEvent* event) {
- if (!changing_button)
- return;
- if (!event || event->key() == Qt::Key_unknown)
- return;
- key_pressed = event->key();
- timer->stop();
- setKey();
+void ConfigureInput::restoreDefaults() {
+ for (const auto& input_id : Settings::NativeInput::All) {
+ const size_t index = static_cast<size_t>(input_id);
+ key_map[input_id] = static_cast<Qt::Key>(Config::defaults[index].toInt());
+ }
+ updateButtonLabels();
+ applyConfiguration();
}
-void ConfigureInput::setKey() {
- const QString key_value = getKeyName(key_pressed);
- if (key_pressed == Qt::Key_Escape)
- changing_button->setText(previous_mapping);
- else
- changing_button->setText(key_value);
- removeDuplicates(key_value);
- key_pressed = Qt::Key_unknown;
- releaseKeyboard();
- releaseMouse();
- changing_button = nullptr;
- previous_mapping = nullptr;
+void ConfigureInput::updateButtonLabels() {
+ for (const auto& input_id : Settings::NativeInput::All) {
+ button_map[input_id]->setText(getKeyName(key_map[input_id]));
+ }
}
-QString ConfigureInput::getKeyName(int key_code) const {
- if (key_code == Qt::Key_Shift)
- return tr("Shift");
- if (key_code == Qt::Key_Control)
- return tr("Ctrl");
- if (key_code == Qt::Key_Alt)
- return tr("Alt");
- if (key_code == Qt::Key_Meta)
- return "";
- if (key_code == -1)
- return "";
+void ConfigureInput::handleClick(Settings::NativeInput::Values input_id) {
+ QPushButton* button = button_map[input_id];
+ button->setText(tr("[press key]"));
+ button->setFocus();
- return QKeySequence(key_code).toString();
-}
+ current_input_id = input_id;
-Qt::Key ConfigureInput::getKeyValue(const QString& text) const {
- if (text == "Shift")
- return Qt::Key_Shift;
- if (text == "Ctrl")
- return Qt::Key_Control;
- if (text == "Alt")
- return Qt::Key_Alt;
- if (text == "Meta")
- return Qt::Key_unknown;
- if (text == "")
- return Qt::Key_unknown;
-
- return Qt::Key(QKeySequence(text)[0]);
+ grabKeyboard();
+ grabMouse();
+ timer->start(5000); // Cancel after 5 seconds
}
-void ConfigureInput::removeDuplicates(const QString& newValue) {
- for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
- if (changing_button != input_mapping[Settings::NativeInput::Values(i)]) {
- const QString oldValue = input_mapping[Settings::NativeInput::Values(i)]->text();
- if (newValue == oldValue)
- input_mapping[Settings::NativeInput::Values(i)]->setText("");
- }
- }
+void ConfigureInput::keyPressEvent(QKeyEvent* event) {
+ releaseKeyboard();
+ releaseMouse();
+
+ if (!current_input_id || !event)
+ return;
+
+ if (event->key() != Qt::Key_Escape)
+ setInput(*current_input_id, static_cast<Qt::Key>(event->key()));
+
+ updateButtonLabels();
+ current_input_id = boost::none;
+ timer->stop();
}
-void ConfigureInput::restoreDefaults() {
- for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
- const QString keyValue = getKeyName(Config::defaults[i].toInt());
- input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue);
+void ConfigureInput::setInput(Settings::NativeInput::Values input_id, Qt::Key key_pressed) {
+ // Remove duplicates
+ for (auto& pair : key_map) {
+ if (pair.second == key_pressed)
+ pair.second = Qt::Key_unknown;
}
+
+ key_map[input_id] = key_pressed;
}
diff --git a/src/citra_qt/configure_input.h b/src/citra_qt/configure_input.h
index 5183b904d..bc343db83 100644
--- a/src/citra_qt/configure_input.h
+++ b/src/citra_qt/configure_input.h
@@ -7,7 +7,7 @@
#include <memory>
#include <QKeyEvent>
#include <QWidget>
-#include "citra_qt/config.h"
+#include <boost/optional.hpp>
#include "core/settings.h"
#include "ui_configure_input.h"
@@ -30,35 +30,28 @@ public:
private:
std::unique_ptr<Ui::ConfigureInput> ui;
- std::map<Settings::NativeInput::Values, QPushButton*> input_mapping;
- int key_pressed;
- QPushButton* changing_button = nullptr; ///< button currently waiting for key press.
- QString previous_mapping;
- QTimer* timer;
- /// Load configuration settings into button text
- void setConfiguration();
+ /// This input is currently awaiting configuration.
+ /// (i.e.: its corresponding QPushButton has been pressed.)
+ boost::optional<Settings::NativeInput::Values> current_input_id;
+ std::unique_ptr<QTimer> timer;
- /// Check all inputs for duplicate keys. Clears out any other button with the same value as this
- /// button's new value.
- void removeDuplicates(const QString& newValue);
-
- /// Handle key press event for input tab when a button is 'waiting'.
- void keyPressEvent(QKeyEvent* event) override;
-
- /// Convert key ASCII value to its' letter/name
- QString getKeyName(int key_code) const;
-
- /// Convert letter/name of key to its ASCII value.
- Qt::Key getKeyValue(const QString& text) const;
-
- /// Set button text to name of key pressed.
- void setKey();
-
-private slots:
- /// Event handler for all button released() event.
- void handleClick();
+ /// Each input is represented by a QPushButton.
+ std::map<Settings::NativeInput::Values, QPushButton*> button_map;
+ /// Each input is configured to respond to the press of a Qt::Key.
+ std::map<Settings::NativeInput::Values, Qt::Key> key_map;
+ /// Load configuration settings.
+ void loadConfiguration();
/// Restore all buttons to their default values.
void restoreDefaults();
+ /// Update UI to reflect current configuration.
+ void updateButtonLabels();
+
+ /// Called when the button corresponding to input_id was pressed.
+ void handleClick(Settings::NativeInput::Values input_id);
+ /// Handle key press events.
+ void keyPressEvent(QKeyEvent* event) override;
+ /// Configure input input_id to respond to key key_pressed.
+ void setInput(Settings::NativeInput::Values input_id, Qt::Key key_pressed);
};
diff --git a/src/citra_qt/configure_system.cpp b/src/citra_qt/configure_system.cpp
index 873d314ec..eb1276ef3 100644
--- a/src/citra_qt/configure_system.cpp
+++ b/src/citra_qt/configure_system.cpp
@@ -6,7 +6,6 @@
#include "citra_qt/ui_settings.h"
#include "core/hle/service/cfg/cfg.h"
#include "core/hle/service/fs/archive.h"
-#include "core/system.h"
#include "ui_configure_system.h"
static const std::array<int, 12> days_in_month = {{
@@ -24,7 +23,7 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::
ConfigureSystem::~ConfigureSystem() {}
void ConfigureSystem::setConfiguration() {
- enabled = !System::IsPoweredOn();
+ enabled = !Core::System::GetInstance().IsPoweredOn();
if (!enabled) {
ReadSystemSettings();
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp
index c66f2b96a..c1db93583 100644
--- a/src/citra_qt/debugger/callstack.cpp
+++ b/src/citra_qt/debugger/callstack.cpp
@@ -25,7 +25,7 @@ CallstackWidget::CallstackWidget(QWidget* parent) : QDockWidget(parent) {
void CallstackWidget::OnDebugModeEntered() {
// Stack pointer
- const u32 sp = Core::g_app_core->GetReg(13);
+ const u32 sp = Core::CPU().GetReg(13);
Clear();
diff --git a/src/citra_qt/debugger/callstack.h b/src/citra_qt/debugger/callstack.h
index 765757986..f04ab9c7e 100644
--- a/src/citra_qt/debugger/callstack.h
+++ b/src/citra_qt/debugger/callstack.h
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#pragma once
+
#include <QDockWidget>
#include "ui_callstack.h"
@@ -11,7 +13,7 @@ class CallstackWidget : public QDockWidget {
Q_OBJECT
public:
- CallstackWidget(QWidget* parent = nullptr);
+ explicit CallstackWidget(QWidget* parent = nullptr);
public slots:
void OnDebugModeEntered();
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index 1ee6bbd6a..e9c8ad858 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -185,13 +185,13 @@ DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread)
}
void DisassemblerWidget::Init() {
- model->ParseFromAddress(Core::g_app_core->GetPC());
+ model->ParseFromAddress(Core::CPU().GetPC());
disasm_ui.treeView->resizeColumnToContents(0);
disasm_ui.treeView->resizeColumnToContents(1);
disasm_ui.treeView->resizeColumnToContents(2);
- QModelIndex model_index = model->IndexFromAbsoluteAddress(Core::g_app_core->GetPC());
+ QModelIndex model_index = model->IndexFromAbsoluteAddress(Core::CPU().GetPC());
disasm_ui.treeView->scrollTo(model_index);
disasm_ui.treeView->selectionModel()->setCurrentIndex(
model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
@@ -214,8 +214,8 @@ void DisassemblerWidget::OnPause() {
emu_thread->SetRunning(false);
// TODO: By now, the CPU might not have actually stopped...
- if (Core::g_app_core) {
- model->SetNextInstruction(Core::g_app_core->GetPC());
+ if (Core::System::GetInstance().IsPoweredOn()) {
+ model->SetNextInstruction(Core::CPU().GetPC());
}
}
@@ -224,7 +224,7 @@ void DisassemblerWidget::OnToggleStartStop() {
}
void DisassemblerWidget::OnDebugModeEntered() {
- u32 next_instr = Core::g_app_core->GetPC();
+ u32 next_instr = Core::CPU().GetPC();
if (model->GetBreakPoints().IsAddressBreakPoint(next_instr))
emu_thread->SetRunning(false);
diff --git a/src/citra_qt/debugger/disassembler.h b/src/citra_qt/debugger/disassembler.h
index 2ca6c2bd4..a6e59515c 100644
--- a/src/citra_qt/debugger/disassembler.h
+++ b/src/citra_qt/debugger/disassembler.h
@@ -17,7 +17,7 @@ class DisassemblerModel : public QAbstractListModel {
Q_OBJECT
public:
- DisassemblerModel(QObject* parent);
+ explicit DisassemblerModel(QObject* parent);
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
@@ -38,9 +38,7 @@ private:
unsigned int program_counter;
QModelIndex selection;
-
- // TODO: Make BreakPoints less crappy (i.e. const-correct) so that this needn't be mutable.
- mutable BreakPoints breakpoints;
+ BreakPoints breakpoints;
};
class DisassemblerWidget : public QDockWidget {
diff --git a/src/citra_qt/debugger/graphics.cpp b/src/citra_qt/debugger/graphics/graphics.cpp
index ef6712bfa..6a76adeae 100644
--- a/src/citra_qt/debugger/graphics.cpp
+++ b/src/citra_qt/debugger/graphics/graphics.cpp
@@ -3,7 +3,7 @@
// Refer to the license.txt file included.
#include <QListView>
-#include "citra_qt/debugger/graphics.h"
+#include "citra_qt/debugger/graphics/graphics.h"
#include "citra_qt/util/util.h"
extern GraphicsDebugger g_debugger;
@@ -22,15 +22,15 @@ QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) con
return QVariant();
int command_index = index.row();
- const GSP_GPU::Command& command = GetDebugger()->ReadGXCommandHistory(command_index);
+ const Service::GSP::Command& command = GetDebugger()->ReadGXCommandHistory(command_index);
if (role == Qt::DisplayRole) {
- std::map<GSP_GPU::CommandId, const char*> command_names = {
- {GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA"},
- {GSP_GPU::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST"},
- {GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL"},
- {GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER"},
- {GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY"},
- {GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH"},
+ std::map<Service::GSP::CommandId, const char*> command_names = {
+ {Service::GSP::CommandId::REQUEST_DMA, "REQUEST_DMA"},
+ {Service::GSP::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST"},
+ {Service::GSP::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL"},
+ {Service::GSP::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER"},
+ {Service::GSP::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY"},
+ {Service::GSP::CommandId::CACHE_FLUSH, "CACHE_FLUSH"},
};
const u32* command_data = reinterpret_cast<const u32*>(&command);
QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9")
diff --git a/src/citra_qt/debugger/graphics.h b/src/citra_qt/debugger/graphics/graphics.h
index bedf3e596..8837fb792 100644
--- a/src/citra_qt/debugger/graphics.h
+++ b/src/citra_qt/debugger/graphics/graphics.h
@@ -13,7 +13,7 @@ class GPUCommandStreamItemModel : public QAbstractListModel,
Q_OBJECT
public:
- GPUCommandStreamItemModel(QObject* parent);
+ explicit GPUCommandStreamItemModel(QObject* parent);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
diff --git a/src/citra_qt/debugger/graphics_breakpoint_observer.cpp b/src/citra_qt/debugger/graphics/graphics_breakpoint_observer.cpp
index e01d3440e..dc6070dea 100644
--- a/src/citra_qt/debugger/graphics_breakpoint_observer.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_breakpoint_observer.cpp
@@ -3,7 +3,7 @@
// Refer to the license.txt file included.
#include <QMetaType>
-#include "citra_qt/debugger/graphics_breakpoint_observer.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoint_observer.h"
BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Pica::DebugContext> debug_context,
const QString& title, QWidget* parent)
diff --git a/src/citra_qt/debugger/graphics_breakpoint_observer.h b/src/citra_qt/debugger/graphics/graphics_breakpoint_observer.h
index e77df4f5b..e77df4f5b 100644
--- a/src/citra_qt/debugger/graphics_breakpoint_observer.h
+++ b/src/citra_qt/debugger/graphics/graphics_breakpoint_observer.h
diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics/graphics_breakpoints.cpp
index d2a036dfa..030828ba8 100644
--- a/src/citra_qt/debugger/graphics_breakpoints.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_breakpoints.cpp
@@ -7,8 +7,8 @@
#include <QPushButton>
#include <QTreeView>
#include <QVBoxLayout>
-#include "citra_qt/debugger/graphics_breakpoints.h"
-#include "citra_qt/debugger/graphics_breakpoints_p.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoints_p.h"
#include "common/assert.h"
BreakPointModel::BreakPointModel(std::shared_ptr<Pica::DebugContext> debug_context, QObject* parent)
diff --git a/src/citra_qt/debugger/graphics_breakpoints.h b/src/citra_qt/debugger/graphics/graphics_breakpoints.h
index 5fc40c916..bec72a2db 100644
--- a/src/citra_qt/debugger/graphics_breakpoints.h
+++ b/src/citra_qt/debugger/graphics/graphics_breakpoints.h
@@ -20,8 +20,8 @@ class GraphicsBreakPointsWidget : public QDockWidget, Pica::DebugContext::BreakP
using Event = Pica::DebugContext::Event;
public:
- GraphicsBreakPointsWidget(std::shared_ptr<Pica::DebugContext> debug_context,
- QWidget* parent = nullptr);
+ explicit GraphicsBreakPointsWidget(std::shared_ptr<Pica::DebugContext> debug_context,
+ QWidget* parent = nullptr);
void OnPicaBreakPointHit(Pica::DebugContext::Event event, void* data) override;
void OnPicaResume() override;
diff --git a/src/citra_qt/debugger/graphics_breakpoints_p.h b/src/citra_qt/debugger/graphics/graphics_breakpoints_p.h
index dc64706bd..dc64706bd 100644
--- a/src/citra_qt/debugger/graphics_breakpoints_p.h
+++ b/src/citra_qt/debugger/graphics/graphics_breakpoints_p.h
diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp
index 8a784d108..dab529e3a 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp
@@ -13,7 +13,7 @@
#include <QSpinBox>
#include <QTreeView>
#include <QVBoxLayout>
-#include "citra_qt/debugger/graphics_cmdlists.h"
+#include "citra_qt/debugger/graphics/graphics_cmdlists.h"
#include "citra_qt/util/spinbox.h"
#include "citra_qt/util/util.h"
#include "common/vector_math.h"
@@ -21,7 +21,8 @@
#include "video_core/pica.h"
#include "video_core/pica_state.h"
-QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) {
+namespace {
+QImage LoadTexture(const u8* src, const Pica::DebugUtils::TextureInfo& info) {
QImage decoded_image(info.width, info.height, QImage::Format_ARGB32);
for (int y = 0; y < info.height; ++y) {
for (int x = 0; x < info.width; ++x) {
@@ -35,7 +36,8 @@ QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) {
class TextureInfoWidget : public QWidget {
public:
- TextureInfoWidget(u8* src, const Pica::DebugUtils::TextureInfo& info, QWidget* parent = nullptr)
+ TextureInfoWidget(const u8* src, const Pica::DebugUtils::TextureInfo& info,
+ QWidget* parent = nullptr)
: QWidget(parent) {
QLabel* image_widget = new QLabel;
QPixmap image_pixmap = QPixmap::fromImage(LoadTexture(src, info));
@@ -47,6 +49,7 @@ public:
setLayout(layout);
}
};
+} // Anonymous namespace
GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(parent) {}
@@ -65,7 +68,6 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const {
const auto& write = pica_trace.writes[index.row()];
if (role == Qt::DisplayRole) {
- QString content;
switch (index.column()) {
case 0:
return QString::fromLatin1(Pica::Regs::GetCommandName(write.cmd_id).c_str());
@@ -122,19 +124,21 @@ void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) {
if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) ||
COMMAND_IN_RANGE(command_id, texture2)) {
- unsigned index;
+ unsigned texture_index;
if (COMMAND_IN_RANGE(command_id, texture0)) {
- index = 0;
+ texture_index = 0;
} else if (COMMAND_IN_RANGE(command_id, texture1)) {
- index = 1;
+ texture_index = 1;
} else if (COMMAND_IN_RANGE(command_id, texture2)) {
- index = 2;
+ texture_index = 2;
} else {
UNREACHABLE_MSG("Unknown texture command");
}
- auto config = Pica::g_state.regs.GetTextures()[index].config;
- auto format = Pica::g_state.regs.GetTextures()[index].format;
- auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format);
+
+ const auto texture = Pica::g_state.regs.GetTextures()[texture_index];
+ const auto config = texture.config;
+ const auto format = texture.format;
+ const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format);
// TODO: Open a surface debugger
}
@@ -148,19 +152,21 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) ||
COMMAND_IN_RANGE(command_id, texture2)) {
- unsigned index;
+ unsigned texture_index;
if (COMMAND_IN_RANGE(command_id, texture0)) {
- index = 0;
+ texture_index = 0;
} else if (COMMAND_IN_RANGE(command_id, texture1)) {
- index = 1;
+ texture_index = 1;
} else {
- index = 2;
+ texture_index = 2;
}
- auto config = Pica::g_state.regs.GetTextures()[index].config;
- auto format = Pica::g_state.regs.GetTextures()[index].format;
- auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format);
- u8* src = Memory::GetPhysicalPointer(config.GetPhysicalAddress());
+ const auto texture = Pica::g_state.regs.GetTextures()[texture_index];
+ const auto config = texture.config;
+ const auto format = texture.format;
+
+ const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format);
+ const u8* src = Memory::GetPhysicalPointer(config.GetPhysicalAddress());
new_info_widget = new TextureInfoWidget(src, info);
}
if (command_info_widget) {
diff --git a/src/citra_qt/debugger/graphics_cmdlists.h b/src/citra_qt/debugger/graphics/graphics_cmdlists.h
index fa2b9122b..8f40b94c5 100644
--- a/src/citra_qt/debugger/graphics_cmdlists.h
+++ b/src/citra_qt/debugger/graphics/graphics_cmdlists.h
@@ -20,7 +20,7 @@ public:
CommandIdRole = Qt::UserRole,
};
- GPUCommandListModel(QObject* parent);
+ explicit GPUCommandListModel(QObject* parent);
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
@@ -39,7 +39,7 @@ class GPUCommandListWidget : public QDockWidget {
Q_OBJECT
public:
- GPUCommandListWidget(QWidget* parent = nullptr);
+ explicit GPUCommandListWidget(QWidget* parent = nullptr);
public slots:
void OnToggleTracing();
diff --git a/src/citra_qt/debugger/graphics_surface.cpp b/src/citra_qt/debugger/graphics/graphics_surface.cpp
index 906daaa50..4efd95d3c 100644
--- a/src/citra_qt/debugger/graphics_surface.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_surface.cpp
@@ -11,7 +11,7 @@
#include <QPushButton>
#include <QScrollArea>
#include <QSpinBox>
-#include "citra_qt/debugger/graphics_surface.h"
+#include "citra_qt/debugger/graphics/graphics_surface.h"
#include "citra_qt/util/spinbox.h"
#include "common/color.h"
#include "core/hw/gpu.h"
diff --git a/src/citra_qt/debugger/graphics_surface.h b/src/citra_qt/debugger/graphics/graphics_surface.h
index 21e6b5b8b..28f5650a7 100644
--- a/src/citra_qt/debugger/graphics_surface.h
+++ b/src/citra_qt/debugger/graphics/graphics_surface.h
@@ -6,7 +6,7 @@
#include <QLabel>
#include <QPushButton>
-#include "citra_qt/debugger/graphics_breakpoint_observer.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoint_observer.h"
class QComboBox;
class QSpinBox;
@@ -18,7 +18,8 @@ class SurfacePicture : public QLabel {
Q_OBJECT
public:
- SurfacePicture(QWidget* parent = 0, GraphicsSurfaceWidget* surface_widget = nullptr);
+ explicit SurfacePicture(QWidget* parent = nullptr,
+ GraphicsSurfaceWidget* surface_widget = nullptr);
~SurfacePicture();
protected slots:
@@ -71,8 +72,8 @@ class GraphicsSurfaceWidget : public BreakPointObserverDock {
static unsigned int NibblesPerPixel(Format format);
public:
- GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
- QWidget* parent = nullptr);
+ explicit GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
+ QWidget* parent = nullptr);
void Pick(int x, int y);
public slots:
diff --git a/src/citra_qt/debugger/graphics_tracing.cpp b/src/citra_qt/debugger/graphics/graphics_tracing.cpp
index 5c6b74034..716ed50b8 100644
--- a/src/citra_qt/debugger/graphics_tracing.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_tracing.cpp
@@ -12,7 +12,7 @@
#include <QMessageBox>
#include <QPushButton>
#include <boost/range/algorithm/copy.hpp>
-#include "citra_qt/debugger/graphics_tracing.h"
+#include "citra_qt/debugger/graphics/graphics_tracing.h"
#include "common/common_types.h"
#include "core/hw/gpu.h"
#include "core/hw/lcd.h"
diff --git a/src/citra_qt/debugger/graphics_tracing.h b/src/citra_qt/debugger/graphics/graphics_tracing.h
index e04a3dac3..3f73bcd2e 100644
--- a/src/citra_qt/debugger/graphics_tracing.h
+++ b/src/citra_qt/debugger/graphics/graphics_tracing.h
@@ -4,7 +4,7 @@
#pragma once
-#include "citra_qt/debugger/graphics_breakpoint_observer.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoint_observer.h"
class EmuThread;
@@ -12,8 +12,8 @@ class GraphicsTracingWidget : public BreakPointObserverDock {
Q_OBJECT
public:
- GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context,
- QWidget* parent = nullptr);
+ explicit GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context,
+ QWidget* parent = nullptr);
private slots:
void StartRecording();
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp
index 96b40db1e..b75b94ef8 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp
@@ -14,7 +14,7 @@
#include <QSignalMapper>
#include <QSpinBox>
#include <QTreeView>
-#include "citra_qt/debugger/graphics_vertex_shader.h"
+#include "citra_qt/debugger/graphics/graphics_vertex_shader.h"
#include "citra_qt/util/util.h"
#include "video_core/pica.h"
#include "video_core/pica_state.h"
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.h b/src/citra_qt/debugger/graphics/graphics_vertex_shader.h
index ec42f24bb..bedea0bed 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.h
+++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.h
@@ -6,7 +6,7 @@
#include <QAbstractTableModel>
#include <QTreeView>
-#include "citra_qt/debugger/graphics_breakpoint_observer.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoint_observer.h"
#include "nihstro/parser_shbin.h"
#include "video_core/shader/shader.h"
@@ -19,7 +19,7 @@ class GraphicsVertexShaderModel : public QAbstractTableModel {
Q_OBJECT
public:
- GraphicsVertexShaderModel(GraphicsVertexShaderWidget* parent);
+ explicit GraphicsVertexShaderModel(GraphicsVertexShaderWidget* parent);
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h
index d8c6487aa..c8912fd5a 100644
--- a/src/citra_qt/debugger/profiler.h
+++ b/src/citra_qt/debugger/profiler.h
@@ -15,7 +15,7 @@ class ProfilerModel : public QAbstractItemModel {
Q_OBJECT
public:
- ProfilerModel(QObject* parent);
+ explicit ProfilerModel(QObject* parent);
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
@@ -37,7 +37,7 @@ class ProfilerWidget : public QDockWidget {
Q_OBJECT
public:
- ProfilerWidget(QWidget* parent = nullptr);
+ explicit ProfilerWidget(QWidget* parent = nullptr);
private slots:
void setProfilingInfoUpdateEnabled(bool enable);
@@ -53,7 +53,7 @@ class MicroProfileDialog : public QWidget {
Q_OBJECT
public:
- MicroProfileDialog(QWidget* parent = nullptr);
+ explicit MicroProfileDialog(QWidget* parent = nullptr);
/// Returns a QAction that can be used to toggle visibility of this dialog.
QAction* toggleViewAction();
diff --git a/src/citra_qt/debugger/ramview.h b/src/citra_qt/debugger/ramview.h
index 8043c59e8..d01cea93b 100644
--- a/src/citra_qt/debugger/ramview.h
+++ b/src/citra_qt/debugger/ramview.h
@@ -2,13 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#pragma once
+
#include "qhexedit.h"
class GRamView : public QHexEdit {
Q_OBJECT
public:
- GRamView(QWidget* parent = nullptr);
+ explicit GRamView(QWidget* parent = nullptr);
public slots:
void OnCPUStepped();
diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp
index 4c529d3c3..b982bc58b 100644
--- a/src/citra_qt/debugger/registers.cpp
+++ b/src/citra_qt/debugger/registers.cpp
@@ -58,16 +58,16 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) {
}
void RegistersWidget::OnDebugModeEntered() {
- if (!Core::g_app_core)
+ if (!Core::System::GetInstance().IsPoweredOn())
return;
for (int i = 0; i < core_registers->childCount(); ++i)
core_registers->child(i)->setText(
- 1, QString("0x%1").arg(Core::g_app_core->GetReg(i), 8, 16, QLatin1Char('0')));
+ 1, QString("0x%1").arg(Core::CPU().GetReg(i), 8, 16, QLatin1Char('0')));
for (int i = 0; i < vfp_registers->childCount(); ++i)
vfp_registers->child(i)->setText(
- 1, QString("0x%1").arg(Core::g_app_core->GetVFPReg(i), 8, 16, QLatin1Char('0')));
+ 1, QString("0x%1").arg(Core::CPU().GetVFPReg(i), 8, 16, QLatin1Char('0')));
UpdateCPSRValues();
UpdateVFPSystemRegisterValues();
@@ -127,7 +127,7 @@ void RegistersWidget::CreateCPSRChildren() {
}
void RegistersWidget::UpdateCPSRValues() {
- const u32 cpsr_val = Core::g_app_core->GetCPSR();
+ const u32 cpsr_val = Core::CPU().GetCPSR();
cpsr->setText(1, QString("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0')));
cpsr->child(0)->setText(
@@ -191,10 +191,10 @@ void RegistersWidget::CreateVFPSystemRegisterChildren() {
}
void RegistersWidget::UpdateVFPSystemRegisterValues() {
- const u32 fpscr_val = Core::g_app_core->GetVFPSystemReg(VFP_FPSCR);
- const u32 fpexc_val = Core::g_app_core->GetVFPSystemReg(VFP_FPEXC);
- const u32 fpinst_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST);
- const u32 fpinst2_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST2);
+ const u32 fpscr_val = Core::CPU().GetVFPSystemReg(VFP_FPSCR);
+ const u32 fpexc_val = Core::CPU().GetVFPSystemReg(VFP_FPEXC);
+ const u32 fpinst_val = Core::CPU().GetVFPSystemReg(VFP_FPINST);
+ const u32 fpinst2_val = Core::CPU().GetVFPSystemReg(VFP_FPINST2);
QTreeWidgetItem* const fpscr = vfp_system_registers->child(0);
fpscr->setText(1, QString("0x%1").arg(fpscr_val, 8, 16, QLatin1Char('0')));
diff --git a/src/citra_qt/debugger/registers.h b/src/citra_qt/debugger/registers.h
index 54c9a8155..55bda5b59 100644
--- a/src/citra_qt/debugger/registers.h
+++ b/src/citra_qt/debugger/registers.h
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#pragma once
+
#include <QDockWidget>
#include "ui_registers.h"
@@ -13,7 +15,7 @@ class RegistersWidget : public QDockWidget {
Q_OBJECT
public:
- RegistersWidget(QWidget* parent = nullptr);
+ explicit RegistersWidget(QWidget* parent = nullptr);
public slots:
void OnDebugModeEntered();
diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp
index be5a51e52..1d2de5185 100644
--- a/src/citra_qt/debugger/wait_tree.cpp
+++ b/src/citra_qt/debugger/wait_tree.cpp
@@ -8,7 +8,6 @@
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/semaphore.h"
-#include "core/hle/kernel/session.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
@@ -230,7 +229,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
list.push_back(std::make_unique<WaitTreeMutexList>(thread.held_mutexes));
}
if (thread.status == THREADSTATUS_WAIT_SYNCH) {
- list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, thread.wait_all));
+ list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects,
+ thread.IsSleepingOnWaitAll()));
}
return list;
@@ -391,7 +391,7 @@ WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), p
}
void WaitTreeWidget::OnDebugModeEntered() {
- if (!Core::g_app_core)
+ if (!Core::System::GetInstance().IsPoweredOn())
return;
model->InitItems();
view->setModel(model);
diff --git a/src/citra_qt/debugger/wait_tree.h b/src/citra_qt/debugger/wait_tree.h
index 5d1d964d1..ee9708fc1 100644
--- a/src/citra_qt/debugger/wait_tree.h
+++ b/src/citra_qt/debugger/wait_tree.h
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#pragma once
+
#include <boost/container/flat_set.hpp>
#include <QAbstractItemModel>
@@ -49,7 +51,7 @@ private:
class WaitTreeText : public WaitTreeItem {
Q_OBJECT
public:
- WaitTreeText(const QString& text);
+ explicit WaitTreeText(const QString& text);
QString GetText() const override;
private:
@@ -65,7 +67,7 @@ public:
class WaitTreeWaitObject : public WaitTreeExpandableItem {
Q_OBJECT
public:
- WaitTreeWaitObject(const Kernel::WaitObject& object);
+ explicit WaitTreeWaitObject(const Kernel::WaitObject& object);
static std::unique_ptr<WaitTreeWaitObject> make(const Kernel::WaitObject& object);
QString GetText() const override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
@@ -92,7 +94,7 @@ private:
class WaitTreeThread : public WaitTreeWaitObject {
Q_OBJECT
public:
- WaitTreeThread(const Kernel::Thread& thread);
+ explicit WaitTreeThread(const Kernel::Thread& thread);
QString GetText() const override;
QColor GetColor() const override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
@@ -101,35 +103,37 @@ public:
class WaitTreeEvent : public WaitTreeWaitObject {
Q_OBJECT
public:
- WaitTreeEvent(const Kernel::Event& object);
+ explicit WaitTreeEvent(const Kernel::Event& object);
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
class WaitTreeMutex : public WaitTreeWaitObject {
Q_OBJECT
public:
- WaitTreeMutex(const Kernel::Mutex& object);
+ explicit WaitTreeMutex(const Kernel::Mutex& object);
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
class WaitTreeSemaphore : public WaitTreeWaitObject {
Q_OBJECT
public:
- WaitTreeSemaphore(const Kernel::Semaphore& object);
+ explicit WaitTreeSemaphore(const Kernel::Semaphore& object);
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
class WaitTreeTimer : public WaitTreeWaitObject {
Q_OBJECT
public:
- WaitTreeTimer(const Kernel::Timer& object);
+ explicit WaitTreeTimer(const Kernel::Timer& object);
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
class WaitTreeMutexList : public WaitTreeExpandableItem {
Q_OBJECT
public:
- WaitTreeMutexList(const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list);
+ explicit WaitTreeMutexList(
+ const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list);
+
QString GetText() const override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
@@ -140,7 +144,7 @@ private:
class WaitTreeThreadList : public WaitTreeExpandableItem {
Q_OBJECT
public:
- WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list);
+ explicit WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list);
QString GetText() const override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
@@ -152,7 +156,7 @@ class WaitTreeModel : public QAbstractItemModel {
Q_OBJECT
public:
- WaitTreeModel(QObject* parent = nullptr);
+ explicit WaitTreeModel(QObject* parent = nullptr);
QVariant data(const QModelIndex& index, int role) const override;
QModelIndex index(int row, int column, const QModelIndex& parent) const override;
@@ -171,7 +175,7 @@ class WaitTreeWidget : public QDockWidget {
Q_OBJECT
public:
- WaitTreeWidget(QWidget* parent = nullptr);
+ explicit WaitTreeWidget(QWidget* parent = nullptr);
public slots:
void OnDebugModeEntered();
diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index 07bc35308..09469f3c5 100644
--- a/src/citra_qt/game_list.cpp
+++ b/src/citra_qt/game_list.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <QHeaderView>
+#include <QMenu>
#include <QThreadPool>
#include <QVBoxLayout>
#include "common/common_paths.h"
@@ -13,7 +14,7 @@
#include "game_list_p.h"
#include "ui_settings.h"
-GameList::GameList(QWidget* parent) {
+GameList::GameList(QWidget* parent) : QWidget{parent} {
QVBoxLayout* layout = new QVBoxLayout;
tree_view = new QTreeView;
@@ -28,18 +29,18 @@ GameList::GameList(QWidget* parent) {
tree_view->setSortingEnabled(true);
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
tree_view->setUniformRowHeights(true);
+ tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
item_model->insertColumns(0, COLUMN_COUNT);
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, "Name");
item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type");
item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size");
- connect(tree_view, SIGNAL(activated(const QModelIndex&)), this,
- SLOT(ValidateEntry(const QModelIndex&)));
+ connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry);
+ connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
// We must register all custom types with the Qt Automoc system so that we are able to use it
- // with
- // signals/slots. In this case, QList falls under the umbrells of custom types.
+ // with signals/slots. In this case, QList falls under the umbrells of custom types.
qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
layout->addWidget(tree_view);
@@ -50,7 +51,7 @@ GameList::~GameList() {
emit ShouldCancelWorker();
}
-void GameList::AddEntry(QList<QStandardItem*> entry_items) {
+void GameList::AddEntry(const QList<QStandardItem*>& entry_items) {
item_model->invisibleRootItem()->appendRow(entry_items);
}
@@ -72,6 +73,23 @@ void GameList::DonePopulating() {
tree_view->setEnabled(true);
}
+void GameList::PopupContextMenu(const QPoint& menu_location) {
+ QModelIndex item = tree_view->indexAt(menu_location);
+ if (!item.isValid())
+ return;
+
+ int row = item_model->itemFromIndex(item)->row();
+ QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME);
+ u64 program_id = child_file->data(GameListItemPath::ProgramIdRole).toULongLong();
+
+ QMenu context_menu;
+ QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
+ open_save_location->setEnabled(program_id != 0);
+ connect(open_save_location, &QAction::triggered,
+ [&]() { emit OpenSaveFolderRequested(program_id); });
+ context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
+}
+
void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
if (!FileUtil::Exists(dir_path.toStdString()) ||
!FileUtil::IsDirectory(dir_path.toStdString())) {
@@ -86,12 +104,13 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
emit ShouldCancelWorker();
GameListWorker* worker = new GameListWorker(dir_path, deep_scan);
- connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this,
- SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection);
- connect(worker, SIGNAL(Finished()), this, SLOT(DonePopulating()), Qt::QueuedConnection);
+ connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
+ connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
+ Qt::QueuedConnection);
// Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel
// without delay.
- connect(this, SIGNAL(ShouldCancelWorker()), worker, SLOT(Cancel()), Qt::DirectConnection);
+ connect(this, &GameList::ShouldCancelWorker, worker, &GameListWorker::Cancel,
+ Qt::DirectConnection);
QThreadPool::globalInstance()->start(worker);
current_worker = std::move(worker);
@@ -128,8 +147,11 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
std::vector<u8> smdh;
loader->ReadIcon(smdh);
+ u64 program_id = 0;
+ loader->ReadProgramId(program_id);
+
emit EntryReady({
- new GameListItemPath(QString::fromStdString(physical_name), smdh),
+ new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id),
new GameListItem(
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
new GameListItemSize(FileUtil::GetSize(physical_name)),
@@ -151,6 +173,6 @@ void GameListWorker::run() {
}
void GameListWorker::Cancel() {
- disconnect(this, 0, 0, 0);
+ disconnect(this, nullptr, nullptr, nullptr);
stop_processing = true;
}
diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h
index a22e9bc60..1abf10051 100644
--- a/src/citra_qt/game_list.h
+++ b/src/citra_qt/game_list.h
@@ -25,7 +25,7 @@ public:
COLUMN_COUNT, // Number of columns
};
- GameList(QWidget* parent = nullptr);
+ explicit GameList(QWidget* parent = nullptr);
~GameList() override;
void PopulateAsync(const QString& dir_path, bool deep_scan);
@@ -33,18 +33,18 @@ public:
void SaveInterfaceLayout();
void LoadInterfaceLayout();
-public slots:
- void AddEntry(QList<QStandardItem*> entry_items);
-
-private slots:
- void ValidateEntry(const QModelIndex& item);
- void DonePopulating();
-
signals:
void GameChosen(QString game_path);
void ShouldCancelWorker();
+ void OpenSaveFolderRequested(u64 program_id);
private:
+ void AddEntry(const QList<QStandardItem*>& entry_items);
+ void ValidateEntry(const QModelIndex& item);
+ void DonePopulating();
+
+ void PopupContextMenu(const QPoint& menu_location);
+
QTreeView* tree_view = nullptr;
QStandardItemModel* item_model = nullptr;
GameListWorker* current_worker = nullptr;
diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h
index 5ca3fe991..a15f06c5f 100644
--- a/src/citra_qt/game_list_p.h
+++ b/src/citra_qt/game_list_p.h
@@ -71,10 +71,13 @@ class GameListItemPath : public GameListItem {
public:
static const int FullPathRole = Qt::UserRole + 1;
static const int TitleRole = Qt::UserRole + 2;
+ static const int ProgramIdRole = Qt::UserRole + 3;
GameListItemPath() : GameListItem() {}
- GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data) : GameListItem() {
+ GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id)
+ : GameListItem() {
setData(game_path, FullPathRole);
+ setData(qulonglong(program_id), ProgramIdRole);
if (!Loader::IsValidSMDH(smdh_data)) {
// SMDH is not valid, set a default icon
diff --git a/src/citra_qt/hotkeys.h b/src/citra_qt/hotkeys.h
index 350103c6f..46f48c2d8 100644
--- a/src/citra_qt/hotkeys.h
+++ b/src/citra_qt/hotkeys.h
@@ -55,7 +55,7 @@ class GHotkeysDialog : public QWidget {
Q_OBJECT
public:
- GHotkeysDialog(QWidget* parent = nullptr);
+ explicit GHotkeysDialog(QWidget* parent = nullptr);
private:
Ui::hotkeys ui;
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index a3887f9ab..6d59cf640 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cinttypes>
#include <clocale>
#include <memory>
#include <thread>
@@ -16,12 +17,12 @@
#include "citra_qt/configure_dialog.h"
#include "citra_qt/debugger/callstack.h"
#include "citra_qt/debugger/disassembler.h"
-#include "citra_qt/debugger/graphics.h"
-#include "citra_qt/debugger/graphics_breakpoints.h"
-#include "citra_qt/debugger/graphics_cmdlists.h"
-#include "citra_qt/debugger/graphics_surface.h"
-#include "citra_qt/debugger/graphics_tracing.h"
-#include "citra_qt/debugger/graphics_vertex_shader.h"
+#include "citra_qt/debugger/graphics/graphics.h"
+#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
+#include "citra_qt/debugger/graphics/graphics_cmdlists.h"
+#include "citra_qt/debugger/graphics/graphics_surface.h"
+#include "citra_qt/debugger/graphics/graphics_tracing.h"
+#include "citra_qt/debugger/graphics/graphics_vertex_shader.h"
#include "citra_qt/debugger/profiler.h"
#include "citra_qt/debugger/ramview.h"
#include "citra_qt/debugger/registers.h"
@@ -41,10 +42,10 @@
#include "common/string_util.h"
#include "core/arm/disassembler/load_symbol_map.h"
#include "core/core.h"
+#include "core/file_sys/archive_source_sd_savedata.h"
#include "core/gdbstub/gdbstub.h"
#include "core/loader/loader.h"
#include "core/settings.h"
-#include "core/system.h"
#include "qhexedit.h"
#include "video_core/video_core.h"
@@ -58,6 +59,36 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
ui.setupUi(this);
statusBar()->hide();
+ InitializeWidgets();
+ InitializeDebugMenuActions();
+ InitializeRecentFileMenuActions();
+ InitializeHotkeys();
+
+ SetDefaultUIGeometry();
+ RestoreUIState();
+
+ ConnectWidgetEvents();
+
+ setWindowTitle(QString("Citra | %1-%2").arg(Common::g_scm_branch, Common::g_scm_desc));
+ show();
+
+ game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
+
+ QStringList args = QApplication::arguments();
+ if (args.length() >= 2) {
+ BootGame(args[1].toStdString());
+ }
+}
+
+GMainWindow::~GMainWindow() {
+ // will get automatically deleted otherwise
+ if (render_window->parent() == nullptr)
+ delete render_window;
+
+ Pica::g_debug_context.reset();
+}
+
+void GMainWindow::InitializeWidgets() {
render_window = new GRenderWindow(this, emu_thread.get());
render_window->hide();
@@ -93,25 +124,27 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
graphicsCommandsWidget->hide();
- auto graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this);
+ graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget);
graphicsBreakpointsWidget->hide();
- auto graphicsVertexShaderWidget = new GraphicsVertexShaderWidget(Pica::g_debug_context, this);
+ graphicsVertexShaderWidget = new GraphicsVertexShaderWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsVertexShaderWidget);
graphicsVertexShaderWidget->hide();
- auto graphicsTracingWidget = new GraphicsTracingWidget(Pica::g_debug_context, this);
+ graphicsTracingWidget = new GraphicsTracingWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget);
graphicsTracingWidget->hide();
- auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica Surface Viewer"), this);
- connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this,
- SLOT(OnCreateGraphicsSurfaceViewer()));
-
waitTreeWidget = new WaitTreeWidget(this);
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
waitTreeWidget->hide();
+}
+
+void GMainWindow::InitializeDebugMenuActions() {
+ auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica Surface Viewer"), this);
+ connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this,
+ SLOT(OnCreateGraphicsSurfaceViewer()));
QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
debug_menu->addAction(graphicsSurfaceViewerAction);
@@ -129,19 +162,47 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction());
debug_menu->addAction(graphicsTracingWidget->toggleViewAction());
debug_menu->addAction(waitTreeWidget->toggleViewAction());
+}
- // Set default UI state
+void GMainWindow::InitializeRecentFileMenuActions() {
+ for (int i = 0; i < max_recent_files_item; ++i) {
+ actions_recent_files[i] = new QAction(this);
+ actions_recent_files[i]->setVisible(false);
+ connect(actions_recent_files[i], SIGNAL(triggered()), this, SLOT(OnMenuRecentFile()));
+
+ ui.menu_recent_files->addAction(actions_recent_files[i]);
+ }
+
+ UpdateRecentFiles();
+}
+
+void GMainWindow::InitializeHotkeys() {
+ RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
+ RegisterHotkey("Main Window", "Swap Screens", QKeySequence::NextChild);
+ RegisterHotkey("Main Window", "Start Emulation");
+ LoadHotkeys();
+
+ connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this,
+ SLOT(OnMenuLoadFile()));
+ connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this,
+ SLOT(OnStartGame()));
+ connect(GetHotkey("Main Window", "Swap Screens", render_window), SIGNAL(activated()), this,
+ SLOT(OnSwapScreens()));
+}
+
+void GMainWindow::SetDefaultUIGeometry() {
// geometry: 55% of the window contents are in the upper screen half, 45% in the lower half
- QDesktopWidget* desktop = ((QApplication*)QApplication::instance())->desktop();
- QRect screenRect = desktop->screenGeometry(this);
- int x, y, w, h;
- w = screenRect.width() * 2 / 3;
- h = screenRect.height() / 2;
- x = (screenRect.x() + screenRect.width()) / 2 - w / 2;
- y = (screenRect.y() + screenRect.height()) / 2 - h * 55 / 100;
+ const QRect screenRect = QApplication::desktop()->screenGeometry(this);
+
+ const int w = screenRect.width() * 2 / 3;
+ const int h = screenRect.height() / 2;
+ const int x = (screenRect.x() + screenRect.width()) / 2 - w / 2;
+ const int y = (screenRect.y() + screenRect.height()) / 2 - h * 55 / 100;
+
setGeometry(x, y, w, h);
+}
- // Restore UI state
+void GMainWindow::RestoreUIState() {
restoreGeometry(UISettings::values.geometry);
restoreState(UISettings::values.state);
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
@@ -157,20 +218,13 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
ui.actionDisplay_widget_title_bars->setChecked(UISettings::values.display_titlebar);
OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked());
+}
- // Prepare actions for recent files
- for (int i = 0; i < max_recent_files_item; ++i) {
- actions_recent_files[i] = new QAction(this);
- actions_recent_files[i]->setVisible(false);
- connect(actions_recent_files[i], SIGNAL(triggered()), this, SLOT(OnMenuRecentFile()));
-
- ui.menu_recent_files->addAction(actions_recent_files[i]);
- }
- UpdateRecentFiles();
-
- // Setup connections
+void GMainWindow::ConnectWidgetEvents() {
connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)),
Qt::DirectConnection);
+ connect(game_list, SIGNAL(OpenSaveFolderRequested(u64)), this,
+ SLOT(OnGameListOpenSaveFolder(u64)), Qt::DirectConnection);
connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(OnConfigure()));
connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()),
Qt::DirectConnection);
@@ -197,40 +251,6 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
connect(this, SIGNAL(EmulationStarting(EmuThread*)), waitTreeWidget,
SLOT(OnEmulationStarting(EmuThread*)));
connect(this, SIGNAL(EmulationStopping()), waitTreeWidget, SLOT(OnEmulationStopping()));
-
- // Setup hotkeys
- RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
- RegisterHotkey("Main Window", "Swap Screens", QKeySequence::NextChild);
- RegisterHotkey("Main Window", "Start Emulation");
- LoadHotkeys();
-
- connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this,
- SLOT(OnMenuLoadFile()));
- connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this,
- SLOT(OnStartGame()));
- connect(GetHotkey("Main Window", "Swap Screens", this), SIGNAL(activated()), this,
- SLOT(OnSwapScreens()));
-
- std::string window_title =
- Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
- setWindowTitle(window_title.c_str());
-
- show();
-
- game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
-
- QStringList args = QApplication::arguments();
- if (args.length() >= 2) {
- BootGame(args[1].toStdString());
- }
-}
-
-GMainWindow::~GMainWindow() {
- // will get automatically deleted otherwise
- if (render_window->parent() == nullptr)
- delete render_window;
-
- Pica::g_debug_context.reset();
}
void GMainWindow::OnDisplayTitleBars(bool show) {
@@ -253,7 +273,7 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
}
}
-bool GMainWindow::InitializeSystem(u32 system_mode) {
+bool GMainWindow::LoadROM(const std::string& filename) {
// Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr)
ShutdownGame();
@@ -269,54 +289,25 @@ bool GMainWindow::InitializeSystem(u32 system_mode) {
return false;
}
- // Initialize the core emulation
- System::Result system_result = System::Init(render_window, system_mode);
- if (System::Result::Success != system_result) {
- switch (system_result) {
- case System::Result::ErrorInitVideoCore:
- QMessageBox::critical(this, tr("Error while starting Citra!"),
- tr("Failed to initialize the video core!\n\n"
- "Please ensure that your GPU supports OpenGL 3.3 and that you "
- "have the latest graphics driver."));
- break;
-
- default:
- QMessageBox::critical(this, tr("Error while starting Citra!"),
- tr("Unknown error (please check the log)!"));
- break;
- }
- return false;
- }
- return true;
-}
+ Core::System& system{Core::System::GetInstance()};
-bool GMainWindow::LoadROM(const std::string& filename) {
- std::unique_ptr<Loader::AppLoader> app_loader = Loader::GetLoader(filename);
- if (!app_loader) {
- LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filename.c_str());
- QMessageBox::critical(this, tr("Error while loading ROM!"),
- tr("The ROM format is not supported."));
- return false;
- }
+ const Core::System::ResultStatus result{system.Load(render_window, filename)};
- boost::optional<u32> system_mode = app_loader->LoadKernelSystemMode();
- if (!system_mode) {
- LOG_CRITICAL(Frontend, "Failed to load ROM!");
- QMessageBox::critical(this, tr("Error while loading ROM!"),
- tr("Could not determine the system mode."));
- return false;
- }
-
- if (!InitializeSystem(system_mode.get()))
- return false;
+ if (result != Core::System::ResultStatus::Success) {
+ switch (result) {
+ case Core::System::ResultStatus::ErrorGetLoader:
+ LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filename.c_str());
+ QMessageBox::critical(this, tr("Error while loading ROM!"),
+ tr("The ROM format is not supported."));
+ break;
- Loader::ResultStatus result = app_loader->Load();
- if (Loader::ResultStatus::Success != result) {
- System::Shutdown();
- LOG_CRITICAL(Frontend, "Failed to load ROM!");
+ case Core::System::ResultStatus::ErrorSystemMode:
+ LOG_CRITICAL(Frontend, "Failed to load ROM!");
+ QMessageBox::critical(this, tr("Error while loading ROM!"),
+ tr("Could not determine the system mode."));
+ break;
- switch (result) {
- case Loader::ResultStatus::ErrorEncrypted: {
+ case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: {
// Build the MessageBox ourselves to have clickable link
QMessageBox popup_error;
popup_error.setTextFormat(Qt::RichText);
@@ -331,11 +322,10 @@ bool GMainWindow::LoadROM(const std::string& filename) {
popup_error.exec();
break;
}
- case Loader::ResultStatus::ErrorInvalidFormat:
+ case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
QMessageBox::critical(this, tr("Error while loading ROM!"),
tr("The ROM format is not supported."));
break;
- case Loader::ResultStatus::Error:
default:
QMessageBox::critical(this, tr("Error while loading ROM!"), tr("Unknown error!"));
@@ -386,6 +376,7 @@ void GMainWindow::BootGame(const std::string& filename) {
game_list->hide();
}
render_window->show();
+ render_window->setFocus();
emulation_running = true;
OnStartGame();
@@ -460,6 +451,21 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
BootGame(game_path.toStdString());
}
+void GMainWindow::OnGameListOpenSaveFolder(u64 program_id) {
+ std::string sdmc_dir = FileUtil::GetUserPath(D_SDMC_IDX);
+ std::string path = FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(sdmc_dir, program_id);
+ QString qpath = QString::fromStdString(path);
+
+ QDir dir(qpath);
+ if (!dir.exists()) {
+ QMessageBox::critical(this, tr("Error Opening Save Folder"), tr("Folder does not exist!"));
+ return;
+ }
+
+ LOG_INFO(Frontend, "Opening save data path for program_id=%" PRIu64, program_id);
+ QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
+}
+
void GMainWindow::OnMenuLoadFile() {
QString filename =
QFileDialog::getOpenFileName(this, tr("Load File"), UISettings::values.roms_path,
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index f87178227..a2fd45c47 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -9,18 +9,21 @@
#include <QMainWindow>
#include "ui_main.h"
+class CallstackWidget;
class Config;
+class DisassemblerWidget;
+class EmuThread;
class GameList;
class GImageInfo;
+class GPUCommandStreamWidget;
+class GPUCommandListWidget;
+class GraphicsBreakPointsWidget;
+class GraphicsTracingWidget;
+class GraphicsVertexShaderWidget;
class GRenderWindow;
-class EmuThread;
-class ProfilerWidget;
class MicroProfileDialog;
-class DisassemblerWidget;
+class ProfilerWidget;
class RegistersWidget;
-class CallstackWidget;
-class GPUCommandStreamWidget;
-class GPUCommandListWidget;
class WaitTreeWidget;
class GMainWindow : public QMainWindow {
@@ -60,6 +63,16 @@ signals:
void EmulationStopping();
private:
+ void InitializeWidgets();
+ void InitializeDebugMenuActions();
+ void InitializeRecentFileMenuActions();
+ void InitializeHotkeys();
+
+ void SetDefaultUIGeometry();
+ void RestoreUIState();
+
+ void ConnectWidgetEvents();
+
/**
* Initializes the emulation system.
* @param system_mode The system mode with which to intialize the kernel.
@@ -105,6 +118,7 @@ private slots:
void OnStopGame();
/// Called whenever a user selects a game in the game list widget.
void OnGameListLoadFile(QString game_path);
+ void OnGameListOpenSaveFolder(u64 program_id);
void OnMenuLoadFile();
void OnMenuLoadSymbolMap();
/// Called whenever a user selects the "File->Select Game List Root" menu item
@@ -135,6 +149,9 @@ private:
CallstackWidget* callstackWidget;
GPUCommandStreamWidget* graphicsWidget;
GPUCommandListWidget* graphicsCommandsWidget;
+ GraphicsBreakPointsWidget* graphicsBreakpointsWidget;
+ GraphicsVertexShaderWidget* graphicsVertexShaderWidget;
+ GraphicsTracingWidget* graphicsTracingWidget;
WaitTreeWidget* waitTreeWidget;
QAction* actions_recent_files[max_recent_files_item];
diff --git a/src/citra_qt/util/spinbox.h b/src/citra_qt/util/spinbox.h
index a57355cd6..2fa1db3a4 100644
--- a/src/citra_qt/util/spinbox.h
+++ b/src/citra_qt/util/spinbox.h
@@ -42,7 +42,7 @@ class CSpinBox : public QAbstractSpinBox {
Q_OBJECT
public:
- CSpinBox(QWidget* parent = nullptr);
+ explicit CSpinBox(QWidget* parent = nullptr);
void stepBy(int steps) override;
StepEnabled stepEnabled() const override;