From e3cc520fa5893ccda2ada921d4c40d8737fd89f3 Mon Sep 17 00:00:00 2001 From: Simone Date: Tue, 23 Jan 2024 11:44:46 +0100 Subject: [PATCH] Preliminary settings work --- src/frontend/CMakeLists.txt | 7 +++++- src/frontend/CPUSettings.cpp | 35 +++++++++++++++++++++++++++ src/frontend/CPUSettings.hpp | 14 +++++++++++ src/frontend/JSONUtils.hpp | 37 ++++++++++++++++++++++++++++ src/frontend/KaizenQt.cpp | 6 ++++- src/frontend/KaizenQt.hpp | 2 ++ src/frontend/MainWindow.cpp | 6 +---- src/frontend/MainWindow.hpp | 1 + src/frontend/SettingsWindow.cpp | 43 +++++++++++++++++++++++++++++++++ src/frontend/SettingsWindow.hpp | 15 ++++++++++++ 10 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 src/frontend/CPUSettings.cpp create mode 100644 src/frontend/CPUSettings.hpp create mode 100644 src/frontend/JSONUtils.hpp create mode 100644 src/frontend/SettingsWindow.cpp create mode 100644 src/frontend/SettingsWindow.hpp diff --git a/src/frontend/CMakeLists.txt b/src/frontend/CMakeLists.txt index 0442d064..d423cca5 100644 --- a/src/frontend/CMakeLists.txt +++ b/src/frontend/CMakeLists.txt @@ -59,7 +59,12 @@ add_executable(kaizen-qt EmuThread.cpp mainwindow.ui MainWindow.hpp - MainWindow.cpp) + MainWindow.cpp + SettingsWindow.hpp + SettingsWindow.cpp + CPUSettings.hpp + CPUSettings.cpp + JSONUtils.hpp) target_link_libraries(kaizen-qt PUBLIC Qt6::Core Qt6::Gui Qt6::Widgets fmt mio nlohmann_json nfd parallel-rdp backend) diff --git a/src/frontend/CPUSettings.cpp b/src/frontend/CPUSettings.cpp new file mode 100644 index 00000000..a34e43c2 --- /dev/null +++ b/src/frontend/CPUSettings.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +CPUSettings::CPUSettings(nlohmann::json& settings) : settings(settings), QWidget(nullptr) { + cpuTypes->addItems({ "Interpreter", "Dynamic Recompiler" }); + + if (JSONGetField(settings, "cpu", "type") == "jit") { + cpuTypes->setCurrentIndex(1); + } else { + cpuTypes->setCurrentIndex(0); + } + + connect(cpuTypes, &QComboBox::currentIndexChanged, this, [&]() { + if (cpuTypes->currentIndex() == 0) { + JSONSetField(settings, "cpu", "type", "interpreter"); + } else if (cpuTypes->currentIndex() == 1) { + JSONSetField(settings, "cpu", "type", "jit"); + } else { + Util::panic("Impossible CPU type!"); + } + + emit modified(); + }); + + QLabel* label = new QLabel("CPU type:"); + + QVBoxLayout* mainLayout = new QVBoxLayout; + mainLayout->addWidget(label); + mainLayout->addWidget(cpuTypes); + mainLayout->addStretch(); + setLayout(mainLayout); +} \ No newline at end of file diff --git a/src/frontend/CPUSettings.hpp b/src/frontend/CPUSettings.hpp new file mode 100644 index 00000000..664511aa --- /dev/null +++ b/src/frontend/CPUSettings.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include +#include + +class CPUSettings : public QWidget { + QComboBox* cpuTypes = new QComboBox; + Q_OBJECT +public: + CPUSettings(nlohmann::json&); + nlohmann::json& settings; +Q_SIGNALS: + void modified(); +}; \ No newline at end of file diff --git a/src/frontend/JSONUtils.hpp b/src/frontend/JSONUtils.hpp new file mode 100644 index 00000000..6158f156 --- /dev/null +++ b/src/frontend/JSONUtils.hpp @@ -0,0 +1,37 @@ +#pragma once +#include +#include +#include + +namespace fs = std::filesystem; + +static inline nlohmann::json JSONOpenOrCreate(const std::string& path) { + auto fileExists = fs::exists(path); + + if (fileExists) { + auto file = std::fstream(path, std::fstream::in | std::fstream::out); + auto json = nlohmann::json::parse(file); + file.close(); + return json; + } else { + auto file = std::fstream(path, std::fstream::in | std::fstream::out | std::fstream::trunc); + nlohmann::json json; + json["audio"]["volume"] = 0.5; + json["cpu"]["type"] = std::string("interpreter"); + + file << json; + file.close(); + + return json; + } +} + +template +static inline void JSONSetField(nlohmann::json& json, const std::string& field1, const std::string& field2, const T& value) { + json[field1][field2] = value; +} + +template +static inline const T& JSONGetField(nlohmann::json& json, const std::string& field1, const std::string& field2) { + return json[field1][field2]; +} \ No newline at end of file diff --git a/src/frontend/KaizenQt.cpp b/src/frontend/KaizenQt.cpp index efe5dbaa..53ce8073 100644 --- a/src/frontend/KaizenQt.cpp +++ b/src/frontend/KaizenQt.cpp @@ -18,12 +18,16 @@ KaizenQt::KaizenQt() noexcept : QWidget(nullptr) { setFocusPolicy(Qt::StrongFocus); setFocus(); grabKeyboard(); - mainWindow->show(); + settingsWindow = new SettingsWindow; + settingsWindow->hide(); emuThread->core = new n64::Core(); } void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept { + connect(mainWindow, &MainWindowController::OpenSettings, this, [this]() { + settingsWindow->show(); + }); connect(mainWindow, &MainWindowController::OpenROM, this, &KaizenQt::LoadROM); connect(mainWindow, &MainWindowController::Exit, this, []() { QApplication::quit(); diff --git a/src/frontend/KaizenQt.hpp b/src/frontend/KaizenQt.hpp index e32dafdd..bd478ebd 100644 --- a/src/frontend/KaizenQt.hpp +++ b/src/frontend/KaizenQt.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include enum class CompositorCategory { Windows, MacOS, XCB, Wayland @@ -34,5 +35,6 @@ public: private: void ConnectMainWindowSignalsToSlots() noexcept; MainWindowController* mainWindow; + SettingsWindow* settingsWindow; EmuThread* emuThread; }; \ No newline at end of file diff --git a/src/frontend/MainWindow.cpp b/src/frontend/MainWindow.cpp index 52fc88c7..060f8cc7 100644 --- a/src/frontend/MainWindow.cpp +++ b/src/frontend/MainWindow.cpp @@ -58,10 +58,6 @@ void MainWindowController::ConnectSignalsToSlots() noexcept { }); connect(view.actionSettings, &QAction::triggered, this, [this]() { - auto layout = new QVBoxLayout(this); - layout->addWidget(new QSlider(Qt::Horizontal)); - auto settings = new QWidget; - settings->setLayout(layout); - settings->show(); + emit OpenSettings(); }); } \ No newline at end of file diff --git a/src/frontend/MainWindow.hpp b/src/frontend/MainWindow.hpp index 0337f80c..2aaaf981 100644 --- a/src/frontend/MainWindow.hpp +++ b/src/frontend/MainWindow.hpp @@ -18,6 +18,7 @@ private: bool textPauseToggle = false; Q_SIGNALS: + void OpenSettings(); void OpenROM(const QString& rom_file); void Exit(); void Reset(); diff --git a/src/frontend/SettingsWindow.cpp b/src/frontend/SettingsWindow.cpp new file mode 100644 index 00000000..220b01f4 --- /dev/null +++ b/src/frontend/SettingsWindow.cpp @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +SettingsWindow::SettingsWindow() : QWidget(nullptr) { + settings = JSONOpenOrCreate("resources/settings.json"); + + if (objectName().isEmpty()) + setObjectName("Settings"); + + resize(500, 400); + setWindowTitle("Settings"); + + cpuSettings = new CPUSettings(settings); + + auto* tabs = new QTabWidget; + tabs->addTab(cpuSettings, tr("CPU")); + //tabs->addTab(new PermissionsTab, tr("Audio")); + + apply->setEnabled(false); + + connect(cpuSettings, &CPUSettings::modified, this, [&]() { + apply->setEnabled(true); + }); + + connect(apply, &QPushButton::pressed, this, [&]() { + apply->setEnabled(false); + std::ofstream file("resources/settings.json"); + file << settings; + file.close(); + }); + + connect(cancel, &QPushButton::pressed, this, &QWidget::hide); + + QVBoxLayout* mainLayout = new QVBoxLayout; + QHBoxLayout* buttonsLayout = new QHBoxLayout; + buttonsLayout->addWidget(apply); + buttonsLayout->addWidget(cancel); + mainLayout->addWidget(tabs); + mainLayout->addLayout(buttonsLayout); + setLayout(mainLayout); +} \ No newline at end of file diff --git a/src/frontend/SettingsWindow.hpp b/src/frontend/SettingsWindow.hpp new file mode 100644 index 00000000..005d25a9 --- /dev/null +++ b/src/frontend/SettingsWindow.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include +#include +#include + +class SettingsWindow : public QWidget { + QPushButton* cancel = new QPushButton("Cancel"); + QPushButton* apply = new QPushButton("Apply"); + Q_OBJECT +public: + SettingsWindow(); + nlohmann::json settings; + CPUSettings* cpuSettings; +}; \ No newline at end of file