From 545ac81d81b92bba22dbc3fe8fde8de7f9590d94 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Mon, 2 Dec 2024 19:41:51 +0200 Subject: [PATCH 1/2] Qt: Add SkyEmu duck icon (#657) --- CMakeLists.txt | 2 +- docs/img/skyemu_icon.png | Bin 0 -> 15327 bytes include/frontend_settings.hpp | 1 + src/frontend_settings.cpp | 7 +++---- src/panda_qt/config_window.cpp | 2 ++ 5 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 docs/img/skyemu_icon.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 33faba5f6..224fea7c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -698,7 +698,7 @@ if(NOT BUILD_HYDRA_CORE AND NOT BUILD_LIBRETRO_CORE) docs/img/rsob_icon.png docs/img/rstarstruck_icon.png docs/img/rpog_icon.png docs/img/rsyn_icon.png docs/img/settings_icon.png docs/img/display_icon.png docs/img/speaker_icon.png docs/img/sparkling_icon.png docs/img/battery_icon.png docs/img/sdcard_icon.png - docs/img/rnap_icon.png docs/img/rcow_icon.png + docs/img/rnap_icon.png docs/img/rcow_icon.png docs/img/skyemu_icon.png ) else() set(FRONTEND_SOURCE_FILES src/panda_sdl/main.cpp src/panda_sdl/frontend_sdl.cpp src/panda_sdl/mappings.cpp) diff --git a/docs/img/skyemu_icon.png b/docs/img/skyemu_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f3b9d4ca4f285e0b79f0c859514efb4e6de977 GIT binary patch literal 15327 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

I3=#I+05% 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 literal 0 HcmV?d00001 diff --git a/include/frontend_settings.hpp b/include/frontend_settings.hpp index aaf9eaf0e..1a78ab66f 100644 --- a/include/frontend_settings.hpp +++ b/include/frontend_settings.hpp @@ -19,6 +19,7 @@ struct FrontendSettings { Rsyn = 1, Rnap = 2, Rcow = 3, + SkyEmu = 4, }; Theme theme = Theme::Dark; diff --git a/src/frontend_settings.cpp b/src/frontend_settings.cpp index 16bae3615..498ba5004 100644 --- a/src/frontend_settings.cpp +++ b/src/frontend_settings.cpp @@ -38,10 +38,8 @@ FrontendSettings::WindowIcon FrontendSettings::iconFromString(std::string inStri std::transform(inString.begin(), inString.end(), inString.begin(), [](unsigned char c) { return std::tolower(c); }); static const std::unordered_map map = { - {"rpog", WindowIcon::Rpog}, - {"rsyn", WindowIcon::Rsyn}, - {"rcow", WindowIcon::Rcow}, - {"rnap", WindowIcon::Rnap}, + {"rpog", WindowIcon::Rpog}, {"rsyn", WindowIcon::Rsyn}, {"rcow", WindowIcon::Rcow}, + {"rnap", WindowIcon::Rnap}, {"skyemu", WindowIcon::SkyEmu}, }; if (auto search = map.find(inString); search != map.end()) { @@ -57,6 +55,7 @@ const char* FrontendSettings::iconToString(WindowIcon icon) { case WindowIcon::Rsyn: return "rsyn"; case WindowIcon::Rcow: return "rcow"; case WindowIcon::Rnap: return "rnap"; + case WindowIcon::SkyEmu: return "skyemu"; case WindowIcon::Rpog: default: return "rpog"; diff --git a/src/panda_qt/config_window.cpp b/src/panda_qt/config_window.cpp index 92fa0741e..60ec3ed26 100644 --- a/src/panda_qt/config_window.cpp +++ b/src/panda_qt/config_window.cpp @@ -85,6 +85,7 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win iconSelect->addItem(tr("Happy panda (colourful)")); iconSelect->addItem(tr("Sleepy panda")); iconSelect->addItem(tr("Cow panda")); + iconSelect->addItem(tr("The penguin from SkyEmu")); iconSelect->setCurrentIndex(static_cast(config.frontendSettings.icon)); connect(iconSelect, &QComboBox::currentIndexChanged, this, [&](int index) { @@ -398,6 +399,7 @@ void ConfigWindow::setIcon(WindowIcon icon) { case WindowIcon::Rsyn: updateIcon(":/docs/img/rsyn_icon.png"); break; case WindowIcon::Rnap: updateIcon(":/docs/img/rnap_icon.png"); break; case WindowIcon::Rcow: updateIcon(":/docs/img/rcow_icon.png"); break; + case WindowIcon::SkyEmu: updateIcon(":/docs/img/skyemu_icon.png"); break; case WindowIcon::Rpog: default: updateIcon(":/docs/img/rpog_icon.png"); break; From 5f822b32d501b3ec3a9c66a188feccdbf32c46cd Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:16:57 +0200 Subject: [PATCH 2/2] Add volume curve setting (#658) * Add volume curve setting * Qt: Add missing translations --- include/config.hpp | 14 +++++++++++++- src/config.cpp | 27 +++++++++++++++++++++++++++ src/core/audio/miniaudio_device.cpp | 6 ++++++ src/panda_qt/cheats_window.cpp | 4 ++-- src/panda_qt/config_window.cpp | 10 ++++++++++ src/panda_qt/patch_window.cpp | 2 +- src/panda_qt/text_editor.cpp | 2 +- 7 files changed, 60 insertions(+), 5 deletions(-) diff --git a/include/config.hpp b/include/config.hpp index 7361a40d1..6041286dc 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -1,12 +1,21 @@ #pragma once #include +#include #include "audio/dsp_core.hpp" -#include "renderer.hpp" #include "frontend_settings.hpp" +#include "renderer.hpp" struct AudioDeviceConfig { + // Audio curve to use for volumes between 0-100 + enum class VolumeCurve : int { + Cubic = 0, // Samples are scaled by volume ^ 3 + Linear = 1, // Samples are scaled by volume + }; + float volumeRaw = 1.0f; + VolumeCurve volumeCurve = VolumeCurve::Cubic; + bool muteAudio = false; float getVolume() const { @@ -16,6 +25,9 @@ struct AudioDeviceConfig { return volumeRaw; } + + static VolumeCurve volumeCurveFromString(std::string inString); + static const char* volumeCurveToString(VolumeCurve curve); }; // Remember to initialize every field here to its default value otherwise bad things will happen diff --git a/src/config.cpp b/src/config.cpp index a8c88a68f..fd4d969d4 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,5 +1,7 @@ #include "config.hpp" +#include +#include #include #include #include @@ -105,6 +107,7 @@ void EmulatorConfig::load() { // Our volume ranges from 0.0 (muted) to 2.0 (boosted, using a logarithmic scale). 1.0 is the "default" volume, ie we don't adjust the PCM // samples at all. audioDeviceConfig.volumeRaw = float(std::clamp(toml::find_or(audio, "AudioVolume", 1.0), 0.0, 2.0)); + audioDeviceConfig.volumeCurve = AudioDeviceConfig::volumeCurveFromString(toml::find_or(audio, "VolumeCurve", "cubic")); } } @@ -188,6 +191,7 @@ void EmulatorConfig::save() { data["Audio"]["EnableAACAudio"] = aacEnabled; data["Audio"]["MuteAudio"] = audioDeviceConfig.muteAudio; data["Audio"]["AudioVolume"] = double(audioDeviceConfig.volumeRaw); + data["Audio"]["VolumeCurve"] = std::string(AudioDeviceConfig::volumeCurveToString(audioDeviceConfig.volumeCurve)); data["Audio"]["PrintDSPFirmware"] = printDSPFirmware; data["Battery"]["ChargerPlugged"] = chargerPlugged; @@ -203,3 +207,26 @@ void EmulatorConfig::save() { file << data; file.close(); } + +AudioDeviceConfig::VolumeCurve AudioDeviceConfig::volumeCurveFromString(std::string inString) { + // Transform to lower-case to make the setting case-insensitive + std::transform(inString.begin(), inString.end(), inString.begin(), [](unsigned char c) { return std::tolower(c); }); + + if (inString == "cubic") { + return VolumeCurve::Cubic; + } else if (inString == "linear") { + return VolumeCurve::Linear; + } + + // Default to cubic curve + return VolumeCurve::Cubic; +} + +const char* AudioDeviceConfig::volumeCurveToString(AudioDeviceConfig::VolumeCurve curve) { + switch (curve) { + case VolumeCurve::Linear: return "linear"; + + case VolumeCurve::Cubic: + default: return "cubic"; + } +} \ No newline at end of file diff --git a/src/core/audio/miniaudio_device.cpp b/src/core/audio/miniaudio_device.cpp index b513450ed..550fb039d 100644 --- a/src/core/audio/miniaudio_device.cpp +++ b/src/core/audio/miniaudio_device.cpp @@ -134,6 +134,12 @@ void MiniAudioDevice::init(Samples& samples, bool safe) { } else { // If our volume is in [0.0, 1.0) then just multiply by the volume. No need to clamp, since there is no danger of our samples wrapping // around due to overflow + + // If we're applying cubic volume curve, raise volume to the power of 3 + if (self->audioSettings.volumeCurve == AudioDeviceConfig::VolumeCurve::Cubic) { + audioVolume = audioVolume * audioVolume * audioVolume; + } + for (usize i = 0; i < samplesWritten; i += 2) { s16 l = s16(float(sample[0]) * audioVolume); s16 r = s16(float(sample[1]) * audioVolume); diff --git a/src/panda_qt/cheats_window.cpp b/src/panda_qt/cheats_window.cpp index 2d7e6b4cb..2485c677f 100644 --- a/src/panda_qt/cheats_window.cpp +++ b/src/panda_qt/cheats_window.cpp @@ -69,7 +69,7 @@ void CheatEntryWidget::editClicked() { } CheatEditDialog::CheatEditDialog(Emulator* emu, CheatEntryWidget& cheatEntry) : QDialog(), emu(emu), cheatEntry(cheatEntry) { - setWindowTitle("Edit Cheat"); + setWindowTitle(tr("Edit Cheat")); setAttribute(Qt::WA_DeleteOnClose); setModal(true); @@ -161,7 +161,7 @@ void CheatEditDialog::rejected() { CheatsWindow::CheatsWindow(Emulator* emu, const std::filesystem::path& cheatPath, QWidget* parent) : QWidget(parent, Qt::Window), emu(emu), cheatPath(cheatPath) { - setWindowTitle("Cheats"); + setWindowTitle(tr("Cheats")); mainWindow = static_cast(parent); QVBoxLayout* layout = new QVBoxLayout; diff --git a/src/panda_qt/config_window.cpp b/src/panda_qt/config_window.cpp index 60ec3ed26..99b38b24d 100644 --- a/src/panda_qt/config_window.cpp +++ b/src/panda_qt/config_window.cpp @@ -240,6 +240,16 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win connectCheckbox(muteAudio, config.audioDeviceConfig.muteAudio); audioLayout->addRow(muteAudio); + QComboBox* volumeCurveType = new QComboBox; + volumeCurveType->addItem(tr("Cubic")); + volumeCurveType->addItem(tr("Linear")); + volumeCurveType->setCurrentIndex(static_cast(config.audioDeviceConfig.volumeCurve)); + connect(volumeCurveType, &QComboBox::currentIndexChanged, this, [&](int index) { + config.audioDeviceConfig.volumeCurve = static_cast(index); + updateConfig(); + }); + audioLayout->addRow(tr("Volume curve"), volumeCurveType); + QSpinBox* volumeRaw = new QSpinBox(); volumeRaw->setRange(0, 200); volumeRaw->setValue(config.audioDeviceConfig.volumeRaw * 100); diff --git a/src/panda_qt/patch_window.cpp b/src/panda_qt/patch_window.cpp index 6ba73e842..6096d89aa 100644 --- a/src/panda_qt/patch_window.cpp +++ b/src/panda_qt/patch_window.cpp @@ -12,7 +12,7 @@ #include "io_file.hpp" PatchWindow::PatchWindow(QWidget* parent) : QWidget(parent, Qt::Window) { - setWindowTitle("ROM patcher"); + setWindowTitle(tr("ROM patcher")); QVBoxLayout* layout = new QVBoxLayout; layout->setContentsMargins(6, 6, 6, 6); diff --git a/src/panda_qt/text_editor.cpp b/src/panda_qt/text_editor.cpp index 24febd0d1..7ac1d5f28 100644 --- a/src/panda_qt/text_editor.cpp +++ b/src/panda_qt/text_editor.cpp @@ -9,7 +9,7 @@ using namespace Zep; TextEditorWindow::TextEditorWindow(QWidget* parent, const std::string& filename, const std::string& initialText) : QDialog(parent), zepWidget(this, qApp->applicationDirPath().toStdString(), fontSize) { - setWindowTitle("Lua Editor"); + setWindowTitle(tr("Lua Editor")); resize(600, 600); // Register our extensions