more work towards a clean code

This commit is contained in:
SimoZ64
2025-04-28 23:51:34 +02:00
parent f57e15f4de
commit b319255178
15 changed files with 163 additions and 213 deletions

View File

@@ -107,8 +107,8 @@ add_subdirectory(../../external/capstone capstone)
add_executable(kaizen add_executable(kaizen
main.cpp main.cpp
KaizenQt.hpp KaizenGui.hpp
KaizenQt.cpp KaizenGui.cpp
RenderWidget.cpp RenderWidget.cpp
RenderWidget.hpp RenderWidget.hpp
EmuThread.hpp EmuThread.hpp

View File

@@ -24,6 +24,6 @@ public:
bool interruptionRequested = false, isRunning = false; bool interruptionRequested = false, isRunning = false;
std::shared_ptr<n64::Core> core; std::shared_ptr<n64::Core> core;
SettingsWindow &settings; SettingsWindow &settings;
std::string fps; std::string& fps;
std::thread thread; std::thread thread;
}; };

View File

@@ -5,7 +5,9 @@
namespace gui { namespace gui {
struct Combobox { struct Combobox {
Combobox(std::string label, const std::vector<std::string>& items, std::string preview = "") : label(label), items(items), preview(preview) {} Combobox(std::string label, std::vector<std::string> items, std::string preview = "", bool enabled = true) : label(label), items(items), preview(preview), enabled(enabled) {}
void addItem(const std::string& text) { items.push_back(text); }
bool render() { bool render() {
const char* _preview = ""; const char* _preview = "";
@@ -18,6 +20,7 @@ struct Combobox {
bool changed = false; bool changed = false;
ImGui::BeginDisabled(!enabled);
if (ImGui::BeginCombo(label.c_str(), _preview)) { if (ImGui::BeginCombo(label.c_str(), _preview)) {
for (int n = 0; n < items.size(); n++) { for (int n = 0; n < items.size(); n++) {
const bool is_selected = ((current_index) == n); const bool is_selected = ((current_index) == n);
@@ -32,14 +35,18 @@ struct Combobox {
} }
ImGui::EndCombo(); ImGui::EndCombo();
} }
ImGui::EndDisabled();
return changed; return changed;
} }
void setEnabled(bool v) { enabled = v; }
void setCurrentIndex(int v) { current_index = v; } void setCurrentIndex(int v) { current_index = v; }
int getCurrentIndex() { return current_index; } int getCurrentIndex() { return current_index; }
private: private:
const std::vector<std::string>& items; bool enabled = true;
std::vector<std::string>& items;
std::string label, preview; std::string label, preview;
int current_index = 0; int current_index = 0;
}; };

View File

@@ -0,0 +1,34 @@
#pragma once
#include <imgui.h>
#include <string>
namespace gui {
struct PushButton {
PushButton(const std::string& label, const std::string& name = "", bool enabled = true) : label(label), name(name), enabled(enabled) {}
bool render() {
if(name != "") {
ImGui::Text(name.c_str());
ImGui::SameLine();
}
ImGui::BeginDisabled(!enabled);
bool ret = ImGui::Button(label.c_str());
ImGui::EndDisabled();
return ret;
}
void setEnabled(bool v) { enabled = v; }
bool getEnabled() { return enabled; }
std::string& getName() const { return name; }
void setName(const std::string& v) { name = v; }
std::string& getLabel() const { return label; }
void setLabel(const std::string& v) { label = v; }
private:
bool enabled = true;
std::string name;
std::string label;
};
}

View File

@@ -12,7 +12,7 @@ struct Slider {
bool render() { bool render() {
return ImGui::SliderScalarN(label.c_str(), type_to_imgui(), (void*)&val, 1, (void*)&min, (void*)&max); return ImGui::SliderScalarN(label.c_str(), type_to_imgui(), (void*)&val, 1, (void*)&min, (void*)&max);
} }
T getValue() { return val; } T getValue() const { return val; }
private: private:
constexpr ImGuiDataType_ type_to_imgui() { constexpr ImGuiDataType_ type_to_imgui() {
if constexpr(std::is_same_v<T, char>) { if constexpr(std::is_same_v<T, char>) {

View File

@@ -3,81 +3,14 @@
#include <SDL3/SDL_events.h> #include <SDL3/SDL_events.h>
#include <SDL3/SDL_init.h> #include <SDL3/SDL_init.h>
InputSettings::InputSettings(nlohmann::json &settings) : QWidget(nullptr), settings(settings) { InputSettings::InputSettings(nlohmann::json &settings) : settings(settings) {
buttonLabels[0] = std::make_unique<QLabel>("A"); for(auto& kb : kbButtons) {
buttonLabels[1] = std::make_unique<QLabel>("B"); kb.setLabel(JSONGetField<std::string>(settings, "input", kb.getName()));
buttonLabels[2] = std::make_unique<QLabel>("Z");
buttonLabels[3] = std::make_unique<QLabel>("Start");
buttonLabels[4] = std::make_unique<QLabel>("L");
buttonLabels[5] = std::make_unique<QLabel>("R");
buttonLabels[6] = std::make_unique<QLabel>("Dpad Up");
buttonLabels[7] = std::make_unique<QLabel>("Dpad Down");
buttonLabels[8] = std::make_unique<QLabel>("Dpad Left");
buttonLabels[9] = std::make_unique<QLabel>("Dpad Right");
buttonLabels[10] = std::make_unique<QLabel>("C Up");
buttonLabels[11] = std::make_unique<QLabel>("C Down");
buttonLabels[12] = std::make_unique<QLabel>("C Left");
buttonLabels[13] = std::make_unique<QLabel>("C Right");
buttonLabels[14] = std::make_unique<QLabel>("Analog Up");
buttonLabels[15] = std::make_unique<QLabel>("Analog Down");
buttonLabels[16] = std::make_unique<QLabel>("Analog Left");
buttonLabels[17] = std::make_unique<QLabel>("Analog Right");
auto str = JSONGetField<std::string>(settings, "input", "A");
kbButtons[0] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "B");
kbButtons[1] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Z");
kbButtons[2] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Start");
kbButtons[3] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "L");
kbButtons[4] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "R");
kbButtons[5] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Dpad Up");
kbButtons[6] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Dpad Down");
kbButtons[7] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Dpad Left");
kbButtons[8] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Dpad Right");
kbButtons[9] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "C Up");
kbButtons[10] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "C Down");
kbButtons[11] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "C Left");
kbButtons[12] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "C Right");
kbButtons[13] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Analog Up");
kbButtons[14] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Analog Down");
kbButtons[15] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Analog Left");
kbButtons[16] = std::make_unique<QPushButton>(str.c_str());
str = JSONGetField<std::string>(settings, "input", "Analog Right");
kbButtons[17] = std::make_unique<QPushButton>(str.c_str());
for (int i = 0; i < 18; i++) {
connect(kbButtons[i].get(), &QPushButton::pressed, this, [&, i] {
devices->setEnabled(false);
for (const auto &kbButton : kbButtons) {
kbButton->setEnabled(false);
}
grabbing = true;
whichGrabbing = i;
if (devices->currentText() == "Keyboard/Mouse") {
grabKeyboard();
} else {
selectedDeviceIsNotKeyboard = true;
}
});
} }
devices.addItem("Keyboard/Mouse");
/* TODO: GAMEPAD STUFF IDK HOW TO HANDLE YET
connect(devices.get(), &QComboBox::currentTextChanged, this, [&](const QString &text) { connect(devices.get(), &QComboBox::currentTextChanged, this, [&](const QString &text) {
JSONSetField<std::string>(settings, "input", "Device", text.toStdString()); JSONSetField<std::string>(settings, "input", "Device", text.toStdString());
emit modified(); emit modified();
@@ -90,62 +23,30 @@ InputSettings::InputSettings(nlohmann::json &settings) : QWidget(nullptr), setti
connect(&pollGamepad, &QTimer::timeout, this, &InputSettings::PollGamepad); connect(&pollGamepad, &QTimer::timeout, this, &InputSettings::PollGamepad);
pollGamepad.start(16); pollGamepad.start(16);
*/
devices->addItem("Keyboard/Mouse");
deviceComboBoxLayout->addWidget(devicesLabel.get());
deviceComboBoxLayout->addWidget(devices.get());
mainLayout->addLayout(deviceComboBoxLayout.get());
AB->addWidget(buttonLabels[0].get());
AB->addWidget(kbButtons[0].get());
AB->addWidget(buttonLabels[1].get());
AB->addWidget(kbButtons[1].get());
mainLayout->addLayout(AB.get());
ZStart->addWidget(buttonLabels[2].get());
ZStart->addWidget(kbButtons[2].get());
ZStart->addWidget(buttonLabels[3].get());
ZStart->addWidget(kbButtons[3].get());
mainLayout->addLayout(ZStart.get());
LR->addWidget(buttonLabels[4].get());
LR->addWidget(kbButtons[4].get());
LR->addWidget(buttonLabels[5].get());
LR->addWidget(kbButtons[5].get());
mainLayout->addLayout(LR.get());
DupDdown->addWidget(buttonLabels[6].get());
DupDdown->addWidget(kbButtons[6].get());
DupDdown->addWidget(buttonLabels[7].get());
DupDdown->addWidget(kbButtons[7].get());
mainLayout->addLayout(DupDdown.get());
DleftDright->addWidget(buttonLabels[8].get());
DleftDright->addWidget(kbButtons[8].get());
DleftDright->addWidget(buttonLabels[9].get());
DleftDright->addWidget(kbButtons[9].get());
mainLayout->addLayout(DleftDright.get());
CupCdown->addWidget(buttonLabels[10].get());
CupCdown->addWidget(kbButtons[10].get());
CupCdown->addWidget(buttonLabels[11].get());
CupCdown->addWidget(kbButtons[11].get());
mainLayout->addLayout(CupCdown.get());
CleftCright->addWidget(buttonLabels[12].get());
CleftCright->addWidget(kbButtons[12].get());
CleftCright->addWidget(buttonLabels[13].get());
CleftCright->addWidget(kbButtons[13].get());
mainLayout->addLayout(CleftCright.get());
AupAdown->addWidget(buttonLabels[14].get());
AupAdown->addWidget(kbButtons[14].get());
AupAdown->addWidget(buttonLabels[15].get());
AupAdown->addWidget(kbButtons[15].get());
mainLayout->addLayout(AupAdown.get());
AleftAright->addWidget(buttonLabels[16].get());
AleftAright->addWidget(kbButtons[16].get());
AleftAright->addWidget(buttonLabels[17].get());
AleftAright->addWidget(kbButtons[17].get());
mainLayout->addLayout(AleftAright.get());
mainLayout->addStretch();
setLayout(mainLayout.get());
} }
bool InputSettings::render() {
int i = 0;
for(auto& kb : kbButtons) {
if(kb.render()) {
devices.setEnabled(false);
for (auto &otherKb : kbButtons) {
otherKb.setEnabled(false);
}
}
// TODO: ACTUALLY GRAB THE PRESSED INPUT
// ...
if(i % 2 != 0) // only go down every 2 buttons... just... i like it this way
ImGui::SameLine();
i++;
}
}
/* TODO: RECREATE THIS IN SDL
void InputSettings::keyPressEvent(QKeyEvent *e) { void InputSettings::keyPressEvent(QKeyEvent *e) {
if (grabbing) { if (grabbing) {
const auto k = QKeySequence(e->key()).toString().toStdString(); const auto k = QKeySequence(e->key()).toString().toStdString();
@@ -165,17 +66,21 @@ void InputSettings::keyPressEvent(QKeyEvent *e) {
} }
} }
} }
*/
std::array<Qt::Key, 18> InputSettings::GetMappedKeys() const { std::array<SDL_Keycode, 18> InputSettings::GetMappedKeys() {
std::array<Qt::Key, 18> ret{}; std::array<SDL_Keycode, 18> ret{};
int i = 0;
for (int i = 0; i < 18; i++) { for (const auto& kb : kbButtons) {
ret[i] = QKeySequence(kbButtons[i]->text().toUpper())[0].key(); ret[i++] = SDL_GetKeyFromName(kb.getLabel().c_str());
} }
return ret; return ret;
} }
/*TODO: RECREATE THIS IN SDL
void InputSettings::QueryDevices() noexcept { void InputSettings::QueryDevices() noexcept {
if (!devices->isEnabled()) if (!devices->isEnabled())
return; return;
@@ -253,3 +158,4 @@ void InputSettings::PollGamepad() noexcept {
} }
} }
} }
*/

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include <JSONUtils.hpp> #include <JSONUtils.hpp>
#include <unordered_map> #include <unordered_map>
#include <ImGuiImpl/PushButton.hpp>
#include <ImGuiImpl/Combobox.hpp>
class InputSettings final { class InputSettings final {
bool grabbing = false; bool grabbing = false;
@@ -10,6 +12,28 @@ class InputSettings final {
void PollGamepad() noexcept; void PollGamepad() noexcept;
std::unordered_map<u32, std::string> gamepadIndexes{}; std::unordered_map<u32, std::string> gamepadIndexes{};
std::array<gui::PushButton, 18> kbButtons = {
gui::PushButton{"", "A"},
gui::PushButton{"", "B"},
gui::PushButton{"", "Z"},
gui::PushButton{"", "Start"},
gui::PushButton{"", "L"},
gui::PushButton{"", "R"},
gui::PushButton{"", "Dpad Up"},
gui::PushButton{"", "Dpad Down"},
gui::PushButton{"", "Dpad Left"},
gui::PushButton{"", "Dpad Right"},
gui::PushButton{"", "C Up"},
gui::PushButton{"", "C Down"},
gui::PushButton{"", "C Left"},
gui::PushButton{"", "C Right"},
gui::PushButton{"", "Analog Up"},
gui::PushButton{"", "Analog Down"},
gui::PushButton{"", "Analog Left"},
gui::PushButton{"", "Analog Right"},
};
gui::Combobox devices{"Device:", {}};
//std::unique_ptr<QHBoxLayout> AB = std::make_unique<QHBoxLayout>(); //std::unique_ptr<QHBoxLayout> AB = std::make_unique<QHBoxLayout>();
//std::unique_ptr<QHBoxLayout> ZStart = std::make_unique<QHBoxLayout>(); //std::unique_ptr<QHBoxLayout> ZStart = std::make_unique<QHBoxLayout>();
@@ -29,8 +53,9 @@ class InputSettings final {
//std::unique_ptr<QComboBox> devices = std::make_unique<QComboBox>(); //std::unique_ptr<QComboBox> devices = std::make_unique<QComboBox>();
//Q_OBJECT //Q_OBJECT
public: public:
bool render();
bool selectedDeviceIsNotKeyboard = false; bool selectedDeviceIsNotKeyboard = false;
explicit InputSettings(nlohmann::json &); explicit InputSettings(nlohmann::json &);
nlohmann::json &settings; nlohmann::json &settings;
//std::array<Qt::Key, 18> GetMappedKeys() const; std::array<SDL_Keycode, 18> GetMappedKeys();
}; };

View File

@@ -1,28 +1,16 @@
#include <Core.hpp> #include <Core.hpp>
#include <KaizenQt.hpp> #include <KaizenGui.hpp>
namespace fs = std::filesystem; namespace fs = std::filesystem;
KaizenQt::KaizenQt() noexcept : QWidget(nullptr) { KaizenGui::KaizenGui() noexcept : mainWindow(core), emuThread(core, mainWindow.fpsCounter, mainWindow.vulkanWidget, settingsWindow) {
core = std::make_shared<n64::Core>();
mainWindow = std::make_unique<MainWindow>(core);
settingsWindow = std::make_unique<SettingsWindow>();
emuThread = std::make_unique<EmuThread>(core, *mainWindow->fpsCounter, *mainWindow->vulkanWidget, *settingsWindow);
// debugger = std::make_unique<Debugger>(); // debugger = std::make_unique<Debugger>();
ConnectMainWindowSignalsToSlots(); ConnectMainWindowSignalsToSlots();
Util::RPC::GetInstance().Update(Util::RPC::Idling); Util::RPC::GetInstance().Update(Util::RPC::Idling);
setAcceptDrops(true);
setFocusPolicy(Qt::StrongFocus);
setFocus();
grabKeyboard();
mainWindow->show();
// debugger->hide();
settingsWindow->hide();
} }
void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept { void KaizenGui::ConnectMainWindowSignalsToSlots() noexcept {
connect(settingsWindow.get(), &SettingsWindow::regrabKeyboard, this, [&] { grabKeyboard(); }); connect(settingsWindow.get(), &SettingsWindow::regrabKeyboard, this, [&] { grabKeyboard(); });
connect(settingsWindow.get(), &SettingsWindow::gotClosed, this, connect(settingsWindow.get(), &SettingsWindow::gotClosed, this,
@@ -33,14 +21,14 @@ void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept {
connect(mainWindow.get(), &MainWindow::OpenSettings, this, [this] { settingsWindow->show(); }); connect(mainWindow.get(), &MainWindow::OpenSettings, this, [this] { settingsWindow->show(); });
// connect(mainWindow.get(), &MainWindow::OpenDebugger, this, [this] { debugger->show(); }); // connect(mainWindow.get(), &MainWindow::OpenDebugger, this, [this] { debugger->show(); });
connect(mainWindow.get(), &MainWindow::OpenROM, this, &KaizenQt::LoadROM); connect(mainWindow.get(), &MainWindow::OpenROM, this, &KaizenGui::LoadROM);
connect(mainWindow.get(), &MainWindow::Exit, this, &KaizenQt::Quit); connect(mainWindow.get(), &MainWindow::Exit, this, &KaizenGui::Quit);
connect(mainWindow.get(), &MainWindow::Reset, emuThread.get(), &EmuThread::Reset); connect(mainWindow.get(), &MainWindow::Reset, emuThread.get(), &EmuThread::Reset);
connect(mainWindow.get(), &MainWindow::Stop, this, [this] { emuThread->requestInterruption(); }); connect(mainWindow.get(), &MainWindow::Stop, this, [this] { emuThread->requestInterruption(); });
connect(mainWindow.get(), &MainWindow::Pause, emuThread.get(), &EmuThread::TogglePause); connect(mainWindow.get(), &MainWindow::Pause, emuThread.get(), &EmuThread::TogglePause);
} }
void KaizenQt::LoadROM(const QString &path) const noexcept { void KaizenGui::LoadROM(const QString &path) const noexcept {
mainWindow->actionPause->setEnabled(true); mainWindow->actionPause->setEnabled(true);
mainWindow->actionReset->setEnabled(true); mainWindow->actionReset->setEnabled(true);
mainWindow->actionStop->setEnabled(true); mainWindow->actionStop->setEnabled(true);
@@ -51,7 +39,7 @@ void KaizenQt::LoadROM(const QString &path) const noexcept {
Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB); Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB);
} }
void KaizenQt::Quit() const noexcept { void KaizenGui::Quit() const noexcept {
if (emuThread) { if (emuThread) {
emuThread->requestInterruption(); emuThread->requestInterruption();
while (emuThread->isRunning) {} while (emuThread->isRunning) {}
@@ -59,7 +47,7 @@ void KaizenQt::Quit() const noexcept {
QApplication::quit(); QApplication::quit();
} }
void KaizenQt::LoadTAS(const QString &path) const noexcept { void KaizenGui::LoadTAS(const QString &path) const noexcept {
if (emuThread->core->LoadTAS(fs::path(path.toStdString()))) { if (emuThread->core->LoadTAS(fs::path(path.toStdString()))) {
const auto gameNameDB = emuThread->core->cpu->GetMem().rom.gameNameDB; const auto gameNameDB = emuThread->core->cpu->GetMem().rom.gameNameDB;
const auto movieName = fs::path(path.toStdString()).stem().string(); const auto movieName = fs::path(path.toStdString()).stem().string();
@@ -70,7 +58,7 @@ void KaizenQt::LoadTAS(const QString &path) const noexcept {
Util::panic("Could not load TAS movie {}!", path.toStdString()); Util::panic("Could not load TAS movie {}!", path.toStdString());
} }
void KaizenQt::keyPressEvent(QKeyEvent *e) { void KaizenGui::keyPressEvent(QKeyEvent *e) {
if (settingsWindow->inputSettings->selectedDeviceIsNotKeyboard) if (settingsWindow->inputSettings->selectedDeviceIsNotKeyboard)
return; return;
@@ -97,7 +85,7 @@ void KaizenQt::keyPressEvent(QKeyEvent *e) {
QWidget::keyPressEvent(e); QWidget::keyPressEvent(e);
} }
void KaizenQt::keyReleaseEvent(QKeyEvent *e) { void KaizenGui::keyReleaseEvent(QKeyEvent *e) {
if (settingsWindow->inputSettings->selectedDeviceIsNotKeyboard) if (settingsWindow->inputSettings->selectedDeviceIsNotKeyboard)
return; return;

View File

@@ -6,18 +6,19 @@
#include <log.hpp> #include <log.hpp>
#include <memory> #include <memory>
class KaizenQt { class KaizenGui {
public: public:
KaizenQt() noexcept; KaizenGui() noexcept;
void LoadTAS(const std::string &path) const noexcept; void LoadTAS(const std::string &path) const noexcept;
void LoadROM(const std::string &path) const noexcept; void LoadROM(const std::string &path) const noexcept;
int run();
private: private:
void Quit() const noexcept; void Quit() const noexcept;
void ConnectMainWindowSignalsToSlots() noexcept; void ConnectMainWindowSignalsToSlots() noexcept;
std::unique_ptr<MainWindow> mainWindow; MainWindow mainWindow;
std::unique_ptr<SettingsWindow> settingsWindow; SettingsWindow settingsWindow;
std::unique_ptr<EmuThread> emuThread; EmuThread emuThread;
// std::unique_ptr<Debugger> debugger; // std::unique_ptr<Debugger> debugger;
std::shared_ptr<n64::Core> core; std::shared_ptr<n64::Core> core;
}; };

View File

@@ -1,8 +1,7 @@
#include <MainWindow.hpp> #include <MainWindow.hpp>
#include <QLabel>
MainWindow::MainWindow(const std::shared_ptr<n64::Core> &core) noexcept { MainWindow::MainWindow(const std::shared_ptr<n64::Core> &core) noexcept : vulkanWidget(core) {
if (objectName().isEmpty()) /* if (objectName().isEmpty())
setObjectName("MainWindow"); setObjectName("MainWindow");
resize(800, 646); resize(800, 646);
actionOpenDebuggerWindow = std::make_unique<QAction>(this); actionOpenDebuggerWindow = std::make_unique<QAction>(this);
@@ -27,8 +26,6 @@ MainWindow::MainWindow(const std::shared_ptr<n64::Core> &core) noexcept {
verticalLayout->setSpacing(0); verticalLayout->setSpacing(0);
verticalLayout->setObjectName("verticalLayout"); verticalLayout->setObjectName("verticalLayout");
verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->setContentsMargins(0, 0, 0, 0);
vulkanWidget = std::make_unique<RenderWidget>(core);
vulkanWidget->setObjectName("vulkanWidget");
verticalLayout->addWidget(vulkanWidget.get()); verticalLayout->addWidget(vulkanWidget.get());
@@ -73,11 +70,11 @@ MainWindow::MainWindow(const std::shared_ptr<n64::Core> &core) noexcept {
actionReset->setDisabled(true); actionReset->setDisabled(true);
actionStop->setDisabled(true); actionStop->setDisabled(true);
vulkanWidget->hide(); vulkanWidget->hide();
ConnectSignalsToSlots(); ConnectSignalsToSlots();*/
} }
void MainWindow::Retranslate() { void MainWindow::Retranslate() {
setWindowTitle(QCoreApplication::translate("MainWindow", "Kaizen", nullptr)); /*setWindowTitle(QCoreApplication::translate("MainWindow", "Kaizen", nullptr));
actionOpenDebuggerWindow->setText(QCoreApplication::translate("MainWindow", "CPU Debugger", nullptr)); actionOpenDebuggerWindow->setText(QCoreApplication::translate("MainWindow", "CPU Debugger", nullptr));
actionOpenDebuggerWindow->setStatusTip(QCoreApplication::translate( actionOpenDebuggerWindow->setStatusTip(QCoreApplication::translate(
"MainWindow", "Open the CPU debugger window which allows you see registers, memory and disassembled code", "MainWindow", "Open the CPU debugger window which allows you see registers, memory and disassembled code",
@@ -102,10 +99,11 @@ void MainWindow::Retranslate() {
menuEmulation->setTitle(QCoreApplication::translate("MainWindow", "Emulation", nullptr)); menuEmulation->setTitle(QCoreApplication::translate("MainWindow", "Emulation", nullptr));
menuTools->setTitle(QCoreApplication::translate("MainWindow", "Tools", nullptr)); menuTools->setTitle(QCoreApplication::translate("MainWindow", "Tools", nullptr));
menuAbout->setTitle(QCoreApplication::translate("MainWindow", "Help", nullptr)); menuAbout->setTitle(QCoreApplication::translate("MainWindow", "Help", nullptr));
*/
} // retranslateUi } // retranslateUi
void MainWindow::ConnectSignalsToSlots() noexcept { void MainWindow::ConnectSignalsToSlots() noexcept {
connect(actionOpen.get(), &QAction::triggered, this, [this]() { /* connect(actionOpen.get(), &QAction::triggered, this, [this]() {
const QString file_name = QFileDialog::getOpenFileName( const QString file_name = QFileDialog::getOpenFileName(
this, "Nintendo 64 executable", QString(), this, "Nintendo 64 executable", QString(),
"All supported types (*.zip *.ZIP *.7z *.7Z *.rar *.RAR *.tar *.TAR *.n64 *.N64 *.v64 *.V64 *.z64 *.Z64)"); "All supported types (*.zip *.ZIP *.7z *.7Z *.rar *.RAR *.tar *.TAR *.n64 *.N64 *.v64 *.V64 *.z64 *.Z64)");
@@ -147,4 +145,9 @@ void MainWindow::ConnectSignalsToSlots() noexcept {
connect(actionSettings.get(), &QAction::triggered, this, [this]() { emit OpenSettings(); }); connect(actionSettings.get(), &QAction::triggered, this, [this]() { emit OpenSettings(); });
connect(actionOpenDebuggerWindow.get(), &QAction::triggered, this, [this]() { emit OpenDebugger(); }); connect(actionOpenDebuggerWindow.get(), &QAction::triggered, this, [this]() { emit OpenDebugger(); });
*/
} }
bool MainWindow::render() {
}

View File

@@ -5,6 +5,10 @@
class MainWindow final { class MainWindow final {
public: public:
explicit MainWindow(const std::shared_ptr<n64::Core> &) noexcept; explicit MainWindow(const std::shared_ptr<n64::Core> &) noexcept;
std::string fpsCounter;
RenderWidget vulkanWidget;
bool render();
//std::unique_ptr<QAction> actionOpenDebuggerWindow{}; //std::unique_ptr<QAction> actionOpenDebuggerWindow{};
//std::unique_ptr<QAction> actionAbout{}; //std::unique_ptr<QAction> actionAbout{};
@@ -30,12 +34,4 @@ private:
void ConnectSignalsToSlots() noexcept; void ConnectSignalsToSlots() noexcept;
bool textPauseToggle = false; bool textPauseToggle = false;
void OpenDebugger();
void OpenSettings();
void OpenROM(const std::string &rom_file);
void Exit();
void Reset();
void Stop();
void Pause();
}; };

View File

@@ -1,34 +1,22 @@
#include <Core.hpp> #include <Core.hpp>
#include <KaizenQt.hpp> #include <KaizenGui.hpp>
#include <RenderWidget.hpp> #include <RenderWidget.hpp>
#include <SDL3/SDL_events.h> #include <SDL3/SDL_events.h>
RenderWidget::RenderWidget(const std::shared_ptr<n64::Core> &core) : QWidget(nullptr) { RenderWidget::RenderWidget(const std::shared_ptr<n64::Core> &core) {
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_PaintOnScreen);
if (GetOSCompositorCategory() == CompositorCategory::Wayland) {
setAttribute(Qt::WA_DontCreateNativeAncestors);
}
if (GetOSCompositorCategory() == CompositorCategory::MacOS) {
windowHandle()->setSurfaceType(QWindow::MetalSurface);
} else {
windowHandle()->setSurfaceType(QWindow::VulkanSurface);
}
if (!Vulkan::Context::init_loader(nullptr)) { if (!Vulkan::Context::init_loader(nullptr)) {
Util::panic("Could not initialize Vulkan ICD"); Util::panic("Could not initialize Vulkan ICD");
} }
qtVkInstanceFactory = std::make_shared<QtInstanceFactory>(); imGuiVkInstanceFactory = std::make_shared<ImGuiInstanceFactory>();
windowHandle()->setVulkanInstance(&qtVkInstanceFactory->handle); windowHandle()->setVulkanInstance(&imGuiVkInstanceFactory->handle);
windowHandle()->create(); windowHandle()->create();
wsiPlatform = std::make_shared<QtWSIPlatform>(core, windowHandle()); wsiPlatform = std::make_shared<ImGuiWSIPlatform>(core, windowHandle());
windowInfo = std::make_shared<QtParallelRdpWindowInfo>(windowHandle()); windowInfo = std::make_shared<ImGuiParallelRdpWindowInfo>(windowHandle());
} }
void QtWSIPlatform::poll_input() { void ImGuiWSIPlatform::poll_input() {
if (!canPollEvents) if (!canPollEvents)
return; return;

View File

@@ -3,7 +3,7 @@
std::string savePath; std::string savePath;
SettingsWindow::SettingsWindow() : QWidget(nullptr) { SettingsWindow::SettingsWindow() {
settings = JSONOpenOrCreate("resources/settings.json"); settings = JSONOpenOrCreate("resources/settings.json");
savePath = JSONGetField<std::string>(settings, "general", "savePath"); savePath = JSONGetField<std::string>(settings, "general", "savePath");
@@ -18,9 +18,9 @@ SettingsWindow::SettingsWindow() : QWidget(nullptr) {
audioSettings = std::make_unique<AudioSettings>(settings); audioSettings = std::make_unique<AudioSettings>(settings);
inputSettings = std::make_unique<InputSettings>(settings); inputSettings = std::make_unique<InputSettings>(settings);
generalSettings = std::make_unique<QWidget>(); generalSettings = std::make_unique<QWidget>();
keyMap = inputSettings->GetMappedKeys(); keyMap = inputSettings.GetMappedKeys();
folderLabel = std::make_unique<QLabel>(fmt::format("{}", savePath).c_str()); savesFolder.setName(fmt::format(savesFolder.getName(), savePath));
connect(folderBtn.get(), &QPushButton::pressed, this, [&]() { connect(folderBtn.get(), &QPushButton::pressed, this, [&]() {
savePath = QFileDialog::getExistingDirectory(this, tr("Select directory")).toStdString(); savePath = QFileDialog::getExistingDirectory(this, tr("Select directory")).toStdString();

View File

@@ -5,6 +5,7 @@
#include <memory> #include <memory>
class SettingsWindow final { class SettingsWindow final {
gui::PushButton cancel{"Cancel"}, apply{"Apply", "", false}, savesFolder{"Open", "Save path: {}"};
//std::unique_ptr<QPushButton> cancel = std::make_unique<QPushButton>("Cancel"); //std::unique_ptr<QPushButton> cancel = std::make_unique<QPushButton>("Cancel");
//std::unique_ptr<QPushButton> apply = std::make_unique<QPushButton>("Apply"); //std::unique_ptr<QPushButton> apply = std::make_unique<QPushButton>("Apply");
//std::unique_ptr<QFileIconProvider> iconProv = std::make_unique<QFileIconProvider>(); //std::unique_ptr<QFileIconProvider> iconProv = std::make_unique<QFileIconProvider>();
@@ -17,14 +18,15 @@ class SettingsWindow final {
//std::unique_ptr<QVBoxLayout> mainLayout = std::make_unique<QVBoxLayout>(); //std::unique_ptr<QVBoxLayout> mainLayout = std::make_unique<QVBoxLayout>();
//std::unique_ptr<QHBoxLayout> buttonsLayout = std::make_unique<QHBoxLayout>(); //std::unique_ptr<QHBoxLayout> buttonsLayout = std::make_unique<QHBoxLayout>();
public: public:
bool render() {} // TODO
SettingsWindow(); SettingsWindow();
[[nodiscard]] float getVolumeL() const { return static_cast<float>(audioSettings->volumeL->value()) / 100.f; } [[nodiscard]] float getVolumeL() const { return audioSettings.volumeL.getValue() / 100.f; }
[[nodiscard]] float getVolumeR() const { return static_cast<float>(audioSettings->volumeR->value()) / 100.f; } [[nodiscard]] float getVolumeR() const { return audioSettings.volumeR.getValue() / 100.f; }
//std::array<ImGui::Key, 18> keyMap{}; std::array<SDL_Keycode, 18> keyMap{};
nlohmann::json settings; nlohmann::json settings;
std::unique_ptr<CPUSettings> cpuSettings{}; CPUSettings cpuSettings{settings};
std::unique_ptr<AudioSettings> audioSettings{}; AudioSettings audioSettings{settings};
std::unique_ptr<InputSettings> inputSettings{}; InputSettings inputSettings{settings};
//std::unique_ptr<QWidget> generalSettings{}; //std::unique_ptr<QWidget> generalSettings{};
}; };

View File

@@ -1,17 +1,17 @@
#include <KaizenQt.hpp> #include <KaizenGui.hpp>
#include <cflags.hpp> #include <cflags.hpp>
int main(int argc, char **argv) { int main(int argc, char **argv) {
const KaizenQt kaizenQt; KaizenGui kaizenGui;
cflags::cflags flags; cflags::cflags flags;
std::string romPath; std::string romPath;
std::string moviePath; std::string moviePath;
flags.add_string_callback('\0', "rom", [&kaizenQt](std::string v) { kaizenQt.LoadROM(v); }, "Rom to launch from command-line"); flags.add_string_callback('\0', "rom", [&kaizenGui](std::string v) { kaizenGui.LoadROM(v); }, "Rom to launch from command-line");
flags.add_string_callback('\0', "movie", [&kaizenQt](std::string v) { kaizenQt.LoadTAS(v); }, "Mupen Movie to replay"); flags.add_string_callback('\0', "movie", [&kaizenGui](std::string v) { kaizenGui.LoadTAS(v); }, "Mupen Movie to replay");
if(!flags.parse(argc, argv)) { if(!flags.parse(argc, argv)) {
return -1; return -1;
} }
return 0; return kaizenGui.run();
} }