Qt6 frontend
Reviewed-on: #1 Co-authored-by: iris <iris.kaizen@pm.me> Co-committed-by: iris <iris.kaizen@pm.me>
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,38 +1,22 @@
|
||||
#include <AudioSettings.hpp>
|
||||
#include <imgui.h>
|
||||
#include <Options.hpp>
|
||||
|
||||
AudioSettings::AudioSettings() {
|
||||
lockChannels = Options::GetInstance().GetValue<bool>("audio", "lock");
|
||||
volumeL = Options::GetInstance().GetValue<float>("audio", "volumeL") * 100;
|
||||
volumeR = Options::GetInstance().GetValue<float>("audio", "volumeR") * 100;
|
||||
AudioSettings::AudioSettings() : settings(QSettings::UserScope) {
|
||||
volumePercent = new QLabel();
|
||||
volumePercent->setText(std::format("Volume: {:.2f}%", Options::GetVolume() * 100.f).c_str());
|
||||
volume = new QSlider(Qt::Horizontal);
|
||||
volume->setRange(0, 100);
|
||||
volume->setValue(Options::GetVolume() * 100.f);
|
||||
connect(volume, &QSlider::valueChanged, this, [&] {
|
||||
float newValue = float(volume->value()) / 100.f;
|
||||
volumePercent->setText(std::format("Volume: {:.2f}%", Options::GetVolume() * 100.f).c_str());
|
||||
Options::SetVolume(newValue);
|
||||
settings.setValue("audio/volume", newValue);
|
||||
settings.sync();
|
||||
});
|
||||
|
||||
v = new QVBoxLayout();
|
||||
v->addWidget(volume);
|
||||
v->addWidget(volumePercent);
|
||||
setLayout(v);
|
||||
}
|
||||
|
||||
void AudioSettings::render() {
|
||||
if(ImGui::Checkbox("Lock channels:", &lockChannels)) {
|
||||
Options::GetInstance().SetValue("audio", "lock", lockChannels);
|
||||
if(lockChannels) {
|
||||
volumeR = volumeL;
|
||||
Options::GetInstance().SetValue("audio", "volumeR", volumeR / 100.f);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if(ImGui::SliderFloat("Volume L", &volumeL, 0.f, 100.f, "%.2f")) {
|
||||
Options::GetInstance().SetValue("audio", "volumeL", volumeL / 100.f);
|
||||
if (lockChannels) {
|
||||
volumeR = volumeL;
|
||||
Options::GetInstance().SetValue("audio", "volumeR", volumeR / 100.f);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(lockChannels);
|
||||
if(ImGui::SliderFloat("Volume R", &volumeR, 0.f, 100.f, "%.2f")) {
|
||||
Options::GetInstance().SetValue("audio", "volumeR", volumeR / 100.f);
|
||||
modified = true;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
#pragma once
|
||||
#include <SettingsTab.hpp>
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QSlider>
|
||||
#include <QSettings>
|
||||
#include <QLabel>
|
||||
|
||||
struct AudioSettings final : SettingsTab {
|
||||
bool lockChannels = false;
|
||||
float volumeL{};
|
||||
float volumeR{};
|
||||
class AudioSettings final : public QWidget {
|
||||
Q_OBJECT
|
||||
QVBoxLayout *v;
|
||||
QSlider *volume;
|
||||
QLabel *volumePercent;
|
||||
QSettings settings;
|
||||
|
||||
explicit AudioSettings();
|
||||
void render() override;
|
||||
public:
|
||||
explicit AudioSettings();
|
||||
};
|
||||
|
||||
@@ -1,56 +1,55 @@
|
||||
#include <CPUSettings.hpp>
|
||||
#include <Options.hpp>
|
||||
#include <log.hpp>
|
||||
#include <imgui.h>
|
||||
#include <Core.hpp>
|
||||
|
||||
CPUSettings::CPUSettings() {
|
||||
auto selectedCpuType = Options::GetInstance().GetValue<std::string>("cpu", "type");
|
||||
if (selectedCpuType == "cached_interpreter") {
|
||||
selectedCpuTypeIndex = 1;
|
||||
CPUSettings::CPUSettings() : settings(QSettings::UserScope) {
|
||||
types = new QComboBox();
|
||||
idleSkip = new QCheckBox("Idle skipping");
|
||||
idleSkip->setToolTip("Whether to enable idle skipping.<br><br>"
|
||||
"Note: idle skipping is a technique used in emulators<br>"
|
||||
"that enables skipping the execution of certain blocks of guest code<br>"
|
||||
"when it's determined that the aforementioned is used to wait on a certain<br>"
|
||||
"event to occur; the code gets skipped, the event is executed immediately by<br>"
|
||||
"the emulator so that the game never actually waits, progressing immediately and making "
|
||||
"emulation much faster.<br><br>"
|
||||
"This feature is not available when the pure interpreter is selected<br>"
|
||||
"because the information regarding instructions would be too limited to<br>"
|
||||
"perform the evaluation described above.");
|
||||
|
||||
idleSkip->setChecked(settings.value("cpu/idle_skip", false).value<bool>());
|
||||
v = new QVBoxLayout();
|
||||
h = new QHBoxLayout();
|
||||
|
||||
types->addItems({"Interpreter", "Cached Interpreter"});
|
||||
if (Options::GetCpuType() == 0) {
|
||||
idleSkip->hide();
|
||||
} else {
|
||||
selectedCpuTypeIndex = 0;
|
||||
idleSkip->show();
|
||||
}
|
||||
types->setCurrentIndex(Options::GetCpuType());
|
||||
|
||||
idleSkip = Options::GetInstance().GetValue<bool>("cpu", "idleSkip");
|
||||
}
|
||||
connect(types, &QComboBox::currentIndexChanged, this, [&] {
|
||||
int index = types->currentIndex();
|
||||
if (index == 0)
|
||||
idleSkip->hide();
|
||||
else
|
||||
idleSkip->show();
|
||||
|
||||
void CPUSettings::render() {
|
||||
const char *items[] = {"Interpreter", "Cached Interpreter"};
|
||||
Options::SetCpuType(index);
|
||||
settings.setValue("cpu/type", index);
|
||||
settings.sync();
|
||||
emit cpuTypeChanged();
|
||||
});
|
||||
|
||||
const char *combo_preview_value = items[selectedCpuTypeIndex];
|
||||
if (ImGui::BeginCombo("CPU Type", combo_preview_value)) {
|
||||
for (int n = 0; n < IM_ARRAYSIZE(items); n++) {
|
||||
const bool is_selected = (selectedCpuTypeIndex == n);
|
||||
if (ImGui::Selectable(items[n], is_selected)) {
|
||||
selectedCpuTypeIndex = n;
|
||||
modified = true;
|
||||
}
|
||||
connect(idleSkip, &QCheckBox::checkStateChanged, this, [&] {
|
||||
Options::SetIdleSkip(idleSkip->checkState());
|
||||
settings.setValue("cpu/idle_skip", idleSkip->checkState());
|
||||
settings.sync();
|
||||
emit idleSkipChanged();
|
||||
});
|
||||
|
||||
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
bool showIdleSkipping = std::string(items[selectedCpuTypeIndex]) == "Cached Interpreter";
|
||||
if (showIdleSkipping)
|
||||
if (ImGui::Checkbox("Idle skipping", &idleSkip))
|
||||
modified = true;
|
||||
|
||||
if (modified) {
|
||||
if (selectedCpuTypeIndex == 0) {
|
||||
Options::GetInstance().SetValue<std::string>("cpu", "type", "interpreter");
|
||||
idleSkip = false;
|
||||
Options::GetInstance().SetValue<bool>("cpu", "idleSkip", idleSkip);
|
||||
n64::Core::GetInstance().cpuType = n64::Core::PlainInterpreter;
|
||||
n64::Core::GetInstance().idleSkip = idleSkip;
|
||||
} else {
|
||||
Options::GetInstance().SetValue<std::string>("cpu", "type", "cached_interpreter");
|
||||
Options::GetInstance().SetValue<bool>("cpu", "idleSkip", idleSkip);
|
||||
n64::Core::GetInstance().cpuType = n64::Core::CachedInterpreter;
|
||||
n64::Core::GetInstance().idleSkip = idleSkip;
|
||||
}
|
||||
}
|
||||
h->addWidget(idleSkip);
|
||||
v->addWidget(types);
|
||||
v->addLayout(h);
|
||||
setLayout(v);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
#pragma once
|
||||
#include <SettingsTab.hpp>
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QSettings>
|
||||
|
||||
struct CPUSettings final : SettingsTab {
|
||||
int selectedCpuTypeIndex = 0;
|
||||
bool idleSkip = false;
|
||||
void render() override;
|
||||
class CPUSettings final : public QWidget {
|
||||
Q_OBJECT
|
||||
QComboBox *types;
|
||||
QCheckBox *idleSkip;
|
||||
QVBoxLayout *v;
|
||||
QHBoxLayout *h;
|
||||
QSettings settings;
|
||||
|
||||
public:
|
||||
explicit CPUSettings();
|
||||
signals:
|
||||
void cpuTypeChanged();
|
||||
void idleSkipChanged();
|
||||
};
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
#include <GeneralSettings.hpp>
|
||||
#include <Options.hpp>
|
||||
#include <imgui.h>
|
||||
#include <QFileDialog>
|
||||
#include <QCoreApplication>
|
||||
#include <log.hpp>
|
||||
|
||||
GeneralSettings::GeneralSettings(gui::NativeWindow& window) : window(window) {
|
||||
savesPath = Options::GetInstance().GetValue<std::string>("general", "savePath");
|
||||
GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) {
|
||||
description = new QLabel("Path:");
|
||||
description->setToolTip("Path where game saves are stored.");
|
||||
selectedFolderLabel = new QLabel(Options::GetSavesPath().c_str());
|
||||
selectedFolderLabel->setDisabled(true);
|
||||
folderSelectButton = new QPushButton("Choose...");
|
||||
|
||||
connect(folderSelectButton, &QPushButton::clicked, this, [&] {
|
||||
auto dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QCoreApplication::applicationDirPath(),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks |
|
||||
QFileDialog::DontUseNativeDialog);
|
||||
selectedFolderLabel->setText(dir);
|
||||
Options::SetSavesPath(dir.toStdString());
|
||||
settings.setValue("general/saves_path", dir);
|
||||
settings.sync();
|
||||
});
|
||||
|
||||
h = new QHBoxLayout();
|
||||
|
||||
h->addWidget(description);
|
||||
h->addWidget(selectedFolderLabel);
|
||||
h->addWidget(folderSelectButton);
|
||||
|
||||
v = new QVBoxLayout(this);
|
||||
v->addLayout(h);
|
||||
setLayout(v);
|
||||
}
|
||||
|
||||
void GeneralSettings::render() {
|
||||
if(ImGui::Button("Pick...")) {
|
||||
SDL_ShowOpenFolderDialog([](void *userdata, const char * const *filelist, int _) {
|
||||
auto* general = static_cast<GeneralSettings*>(userdata);
|
||||
|
||||
if (!filelist) {
|
||||
panic("An error occurred: {}", SDL_GetError());
|
||||
}
|
||||
|
||||
if (!*filelist) {
|
||||
warn("The user did not select any file.");
|
||||
warn("Most likely, the dialog was canceled.");
|
||||
general->modified = false;
|
||||
return;
|
||||
}
|
||||
|
||||
general->savesPath = fs::absolute(*filelist).string();
|
||||
Options::GetInstance().SetValue<std::string>("general", "savePath", general->savesPath);
|
||||
general->modified = true;
|
||||
}, this, window.getHandle(), nullptr, false);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::InputText("Save Path", const_cast<char*>(savesPath.c_str()), savesPath.length());
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
@@ -1,11 +1,19 @@
|
||||
#pragma once
|
||||
#include <SettingsTab.hpp>
|
||||
#include <NativeWindow.hpp>
|
||||
#include <QWidget>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QSettings>
|
||||
|
||||
struct GeneralSettings final : SettingsTab {
|
||||
void render() override;
|
||||
explicit GeneralSettings(gui::NativeWindow&);
|
||||
private:
|
||||
gui::NativeWindow& window;
|
||||
std::string savesPath;
|
||||
};
|
||||
class GeneralSettings final : public QWidget {
|
||||
Q_OBJECT
|
||||
QLabel *description;
|
||||
QPushButton *folderSelectButton;
|
||||
QLabel *selectedFolderLabel;
|
||||
QVBoxLayout *v;
|
||||
QHBoxLayout *h;
|
||||
QSettings settings;
|
||||
|
||||
public:
|
||||
explicit GeneralSettings();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user