mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-10 05:38:49 +00:00
Ds4 Speaker Audio Rebase Fix (#3607)
* Logic update, no QT ui * Fixing errors * Gui boxes * fixes * prevent device list refreshing too fast when game not running * Removed duplicate Socket declarations in kernel/file_system.cpp and fs.h * Fixed clang-format and micDevice errors * Ran clang-format and fixed rebase compiler issues * Settings dialog fix * Addressed squidbus' concerns * Update config.cpp to adhere to clang-format * Removed a space causing clang-format to complain * Addressed squidbus' concerns and added fallbacks Concerns: - Changed dev_name construct to remove unnecessary cast - Added an invalid AudioDeviceID macro to replace magic number --------- Co-authored-by: rainmakerv2 <30595646+rainmakerv3@users.noreply.github.com>
This commit is contained in:
@@ -136,10 +136,14 @@ static ConfigEntry<bool> useSpecialPad(false);
|
|||||||
static ConfigEntry<int> specialPadClass(1);
|
static ConfigEntry<int> specialPadClass(1);
|
||||||
static ConfigEntry<bool> isMotionControlsEnabled(true);
|
static ConfigEntry<bool> isMotionControlsEnabled(true);
|
||||||
static ConfigEntry<bool> useUnifiedInputConfig(true);
|
static ConfigEntry<bool> useUnifiedInputConfig(true);
|
||||||
static ConfigEntry<string> micDevice("Default Device");
|
|
||||||
static ConfigEntry<string> defaultControllerID("");
|
static ConfigEntry<string> defaultControllerID("");
|
||||||
static ConfigEntry<bool> backgroundControllerInput(false);
|
static ConfigEntry<bool> backgroundControllerInput(false);
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
static ConfigEntry<string> micDevice("Default Device");
|
||||||
|
static ConfigEntry<string> mainOutputDevice("Default Device");
|
||||||
|
static ConfigEntry<string> padSpkOutputDevice("Default Device");
|
||||||
|
|
||||||
// GPU
|
// GPU
|
||||||
static ConfigEntry<u32> windowWidth(1280);
|
static ConfigEntry<u32> windowWidth(1280);
|
||||||
static ConfigEntry<u32> windowHeight(720);
|
static ConfigEntry<u32> windowHeight(720);
|
||||||
@@ -302,6 +306,14 @@ string getMicDevice() {
|
|||||||
return micDevice.get();
|
return micDevice.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getMainOutputDevice() {
|
||||||
|
return mainOutputDevice.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getPadSpkOutputDevice() {
|
||||||
|
return padSpkOutputDevice.get();
|
||||||
|
}
|
||||||
|
|
||||||
double getTrophyNotificationDuration() {
|
double getTrophyNotificationDuration() {
|
||||||
return trophyNotificationDuration.get();
|
return trophyNotificationDuration.get();
|
||||||
}
|
}
|
||||||
@@ -581,10 +593,18 @@ void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific) {
|
|||||||
cursorHideTimeout.set(newcursorHideTimeout, is_game_specific);
|
cursorHideTimeout.set(newcursorHideTimeout, is_game_specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMicDevice(string device, bool is_game_specific) {
|
void setMicDevice(std::string device, bool is_game_specific) {
|
||||||
micDevice.set(device, is_game_specific);
|
micDevice.set(device, is_game_specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setMainOutputDevice(std::string device, bool is_game_specific) {
|
||||||
|
mainOutputDevice.set(device, is_game_specific);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPadSpkOutputDevice(std::string device, bool is_game_specific) {
|
||||||
|
padSpkOutputDevice.set(device, is_game_specific);
|
||||||
|
}
|
||||||
|
|
||||||
void setTrophyNotificationDuration(double newTrophyNotificationDuration, bool is_game_specific) {
|
void setTrophyNotificationDuration(double newTrophyNotificationDuration, bool is_game_specific) {
|
||||||
trophyNotificationDuration.set(newTrophyNotificationDuration, is_game_specific);
|
trophyNotificationDuration.set(newTrophyNotificationDuration, is_game_specific);
|
||||||
}
|
}
|
||||||
@@ -826,10 +846,17 @@ void load(const std::filesystem::path& path, bool is_game_specific) {
|
|||||||
specialPadClass.setFromToml(input, "specialPadClass", is_game_specific);
|
specialPadClass.setFromToml(input, "specialPadClass", is_game_specific);
|
||||||
isMotionControlsEnabled.setFromToml(input, "isMotionControlsEnabled", is_game_specific);
|
isMotionControlsEnabled.setFromToml(input, "isMotionControlsEnabled", is_game_specific);
|
||||||
useUnifiedInputConfig.setFromToml(input, "useUnifiedInputConfig", is_game_specific);
|
useUnifiedInputConfig.setFromToml(input, "useUnifiedInputConfig", is_game_specific);
|
||||||
micDevice.setFromToml(input, "micDevice", is_game_specific);
|
|
||||||
backgroundControllerInput.setFromToml(input, "backgroundControllerInput", is_game_specific);
|
backgroundControllerInput.setFromToml(input, "backgroundControllerInput", is_game_specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.contains("Audio")) {
|
||||||
|
const toml::value& audio = data.at("Audio");
|
||||||
|
|
||||||
|
micDevice.setFromToml(audio, "micDevice", is_game_specific);
|
||||||
|
mainOutputDevice.setFromToml(audio, "mainOutputDevice", is_game_specific);
|
||||||
|
padSpkOutputDevice.setFromToml(audio, "padSpkOutputDevice", is_game_specific);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.contains("GPU")) {
|
if (data.contains("GPU")) {
|
||||||
const toml::value& gpu = data.at("GPU");
|
const toml::value& gpu = data.at("GPU");
|
||||||
|
|
||||||
@@ -999,10 +1026,13 @@ void save(const std::filesystem::path& path, bool is_game_specific) {
|
|||||||
cursorHideTimeout.setTomlValue(data, "Input", "cursorHideTimeout", is_game_specific);
|
cursorHideTimeout.setTomlValue(data, "Input", "cursorHideTimeout", is_game_specific);
|
||||||
isMotionControlsEnabled.setTomlValue(data, "Input", "isMotionControlsEnabled",
|
isMotionControlsEnabled.setTomlValue(data, "Input", "isMotionControlsEnabled",
|
||||||
is_game_specific);
|
is_game_specific);
|
||||||
micDevice.setTomlValue(data, "Input", "micDevice", is_game_specific);
|
|
||||||
backgroundControllerInput.setTomlValue(data, "Input", "backgroundControllerInput",
|
backgroundControllerInput.setTomlValue(data, "Input", "backgroundControllerInput",
|
||||||
is_game_specific);
|
is_game_specific);
|
||||||
|
|
||||||
|
micDevice.setTomlValue(data, "Audio", "micDevice", is_game_specific);
|
||||||
|
mainOutputDevice.setTomlValue(data, "Audio", "mainOutputDevice", is_game_specific);
|
||||||
|
padSpkOutputDevice.setTomlValue(data, "Audio", "padSpkOutputDevice", is_game_specific);
|
||||||
|
|
||||||
windowWidth.setTomlValue(data, "GPU", "screenWidth", is_game_specific);
|
windowWidth.setTomlValue(data, "GPU", "screenWidth", is_game_specific);
|
||||||
windowHeight.setTomlValue(data, "GPU", "screenHeight", is_game_specific);
|
windowHeight.setTomlValue(data, "GPU", "screenHeight", is_game_specific);
|
||||||
isNullGpu.setTomlValue(data, "GPU", "nullGpu", is_game_specific);
|
isNullGpu.setTomlValue(data, "GPU", "nullGpu", is_game_specific);
|
||||||
@@ -1036,9 +1066,8 @@ void save(const std::filesystem::path& path, bool is_game_specific) {
|
|||||||
|
|
||||||
m_language.setTomlValue(data, "Settings", "consoleLanguage", is_game_specific);
|
m_language.setTomlValue(data, "Settings", "consoleLanguage", is_game_specific);
|
||||||
|
|
||||||
// All other entries
|
|
||||||
if (!is_game_specific) {
|
if (!is_game_specific) {
|
||||||
std::vector<string> install_dirs;
|
std::vector<std::string> install_dirs;
|
||||||
std::vector<bool> install_dirs_enabled;
|
std::vector<bool> install_dirs_enabled;
|
||||||
|
|
||||||
// temporary structure for ordering
|
// temporary structure for ordering
|
||||||
@@ -1077,23 +1106,18 @@ void save(const std::filesystem::path& path, bool is_game_specific) {
|
|||||||
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
||||||
data["GUI"]["addonInstallDir"] =
|
data["GUI"]["addonInstallDir"] =
|
||||||
string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
||||||
|
|
||||||
data["Debug"]["ConfigVersion"] = config_version;
|
data["Debug"]["ConfigVersion"] = config_version;
|
||||||
data["Keys"]["TrophyKey"] = trophyKey;
|
data["Keys"]["TrophyKey"] = trophyKey;
|
||||||
|
|
||||||
// Do not save these entries in the game-specific dialog since they are not in the GUI
|
// Do not save these entries in the game-specific dialog since they are not in the GUI
|
||||||
data["General"]["defaultControllerID"] = defaultControllerID.base_value;
|
data["General"]["defaultControllerID"] = defaultControllerID.base_value;
|
||||||
|
|
||||||
data["Input"]["useSpecialPad"] = useSpecialPad.base_value;
|
data["Input"]["useSpecialPad"] = useSpecialPad.base_value;
|
||||||
data["Input"]["specialPadClass"] = specialPadClass.base_value;
|
data["Input"]["specialPadClass"] = specialPadClass.base_value;
|
||||||
data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig.base_value;
|
data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig.base_value;
|
||||||
|
|
||||||
data["GPU"]["internalScreenWidth"] = internalScreenWidth.base_value;
|
data["GPU"]["internalScreenWidth"] = internalScreenWidth.base_value;
|
||||||
data["GPU"]["internalScreenHeight"] = internalScreenHeight.base_value;
|
data["GPU"]["internalScreenHeight"] = internalScreenHeight.base_value;
|
||||||
data["GPU"]["patchShaders"] = shouldPatchShaders.base_value;
|
data["GPU"]["patchShaders"] = shouldPatchShaders.base_value;
|
||||||
|
|
||||||
data["Vulkan"]["validation_gpu"] = vkValidationGpu.base_value;
|
data["Vulkan"]["validation_gpu"] = vkValidationGpu.base_value;
|
||||||
|
|
||||||
data["Debug"]["FPSColor"] = isFpsColor.base_value;
|
data["Debug"]["FPSColor"] = isFpsColor.base_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1135,9 +1159,11 @@ void setDefaultValues(bool is_game_specific) {
|
|||||||
cursorState.set(HideCursorState::Idle, is_game_specific);
|
cursorState.set(HideCursorState::Idle, is_game_specific);
|
||||||
cursorHideTimeout.set(5, is_game_specific);
|
cursorHideTimeout.set(5, is_game_specific);
|
||||||
isMotionControlsEnabled.set(true, is_game_specific);
|
isMotionControlsEnabled.set(true, is_game_specific);
|
||||||
micDevice.set("Default Device", is_game_specific);
|
|
||||||
backgroundControllerInput.set(false, is_game_specific);
|
backgroundControllerInput.set(false, is_game_specific);
|
||||||
|
|
||||||
|
// GS - Audio
|
||||||
|
micDevice.set("Default Device", is_game_specific);
|
||||||
|
|
||||||
// GS - GPU
|
// GS - GPU
|
||||||
windowWidth.set(1280, is_game_specific);
|
windowWidth.set(1280, is_game_specific);
|
||||||
windowHeight.set(720, is_game_specific);
|
windowHeight.set(720, is_game_specific);
|
||||||
@@ -1184,11 +1210,14 @@ void setDefaultValues(bool is_game_specific) {
|
|||||||
useSpecialPad.base_value = false;
|
useSpecialPad.base_value = false;
|
||||||
specialPadClass.base_value = 1;
|
specialPadClass.base_value = 1;
|
||||||
useUnifiedInputConfig.base_value = true;
|
useUnifiedInputConfig.base_value = true;
|
||||||
overrideControllerColor = false;
|
|
||||||
controllerCustomColorRGB[0] = 0;
|
controllerCustomColorRGB[0] = 0;
|
||||||
controllerCustomColorRGB[1] = 0;
|
controllerCustomColorRGB[1] = 0;
|
||||||
controllerCustomColorRGB[2] = 255;
|
controllerCustomColorRGB[2] = 255;
|
||||||
|
|
||||||
|
// TODO: Change to be game specific
|
||||||
|
mainOutputDevice = "Default Device";
|
||||||
|
padSpkOutputDevice = "Default Device";
|
||||||
|
|
||||||
// GPU
|
// GPU
|
||||||
shouldPatchShaders.base_value = false;
|
shouldPatchShaders.base_value = false;
|
||||||
internalScreenWidth.base_value = 1280;
|
internalScreenWidth.base_value = 1280;
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ double getTrophyNotificationDuration();
|
|||||||
void setTrophyNotificationDuration(double newTrophyNotificationDuration,
|
void setTrophyNotificationDuration(double newTrophyNotificationDuration,
|
||||||
bool is_game_specific = false);
|
bool is_game_specific = false);
|
||||||
int getCursorHideTimeout();
|
int getCursorHideTimeout();
|
||||||
|
void setCursorHideTimeout(int newcursorHideTimeout);
|
||||||
|
std::string getMainOutputDevice();
|
||||||
|
void setMainOutputDevice(std::string device);
|
||||||
|
std::string getPadSpkOutputDevice();
|
||||||
|
void setPadSpkOutputDevice(std::string device);
|
||||||
std::string getMicDevice();
|
std::string getMicDevice();
|
||||||
void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific = false);
|
void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific = false);
|
||||||
void setMicDevice(std::string device, bool is_game_specific = false);
|
void setMicDevice(std::string device, bool is_game_specific = false);
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
|
|||||||
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
|
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutPort::Personal:
|
case OrbisAudioOutPort::Personal:
|
||||||
case OrbisAudioOutPort::Padspk:
|
case OrbisAudioOutPort::PadSpk:
|
||||||
state->output = 4;
|
state->output = 4;
|
||||||
state->channel = 1;
|
state->channel = 1;
|
||||||
break;
|
break;
|
||||||
@@ -328,7 +328,7 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
|||||||
LOG_ERROR(Lib_AudioOut, "Audio out not initialized");
|
LOG_ERROR(Lib_AudioOut, "Audio out not initialized");
|
||||||
return ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
|
return ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) &&
|
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::PadSpk) &&
|
||||||
(port_type != OrbisAudioOutPort::Audio3d && port_type != OrbisAudioOutPort::Aux)) {
|
(port_type != OrbisAudioOutPort::Audio3d && port_type != OrbisAudioOutPort::Aux)) {
|
||||||
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
||||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ enum class OrbisAudioOutPort {
|
|||||||
Bgm = 1,
|
Bgm = 1,
|
||||||
Voice = 2,
|
Voice = 2,
|
||||||
Personal = 3,
|
Personal = 3,
|
||||||
Padspk = 4,
|
PadSpk = 4,
|
||||||
Audio3d = 126,
|
Audio3d = 126,
|
||||||
Aux = 127,
|
Aux = 127,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <SDL3/SDL_audio.h>
|
#include <SDL3/SDL_audio.h>
|
||||||
#include <SDL3/SDL_hints.h>
|
#include <SDL3/SDL_hints.h>
|
||||||
#include <common/config.h>
|
|
||||||
|
|
||||||
|
#include "common/config.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/audio/audioout.h"
|
#include "core/libraries/audio/audioout.h"
|
||||||
#include "core/libraries/audio/audioout_backend.h"
|
#include "core/libraries/audio/audioout_backend.h"
|
||||||
|
|
||||||
|
#define SDL_INVALID_AUDIODEVICEID 0 // Defined in SDL_audio.h but not made a macro
|
||||||
namespace Libraries::AudioOut {
|
namespace Libraries::AudioOut {
|
||||||
|
|
||||||
class SDLPortBackend : public PortBackend {
|
class SDLPortBackend : public PortBackend {
|
||||||
@@ -21,8 +23,42 @@ public:
|
|||||||
.channels = port.format_info.num_channels,
|
.channels = port.format_info.num_channels,
|
||||||
.freq = static_cast<int>(port.sample_rate),
|
.freq = static_cast<int>(port.sample_rate),
|
||||||
};
|
};
|
||||||
stream =
|
|
||||||
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, nullptr, nullptr);
|
// Determine port type
|
||||||
|
std::string port_name = port.type == OrbisAudioOutPort::PadSpk
|
||||||
|
? Config::getPadSpkOutputDevice()
|
||||||
|
: Config::getMainOutputDevice();
|
||||||
|
SDL_AudioDeviceID dev_id = SDL_INVALID_AUDIODEVICEID;
|
||||||
|
if (port_name == "None") {
|
||||||
|
stream = nullptr;
|
||||||
|
return;
|
||||||
|
} else if (port_name == "Default Device") {
|
||||||
|
dev_id = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
SDL_AudioDeviceID* dev_array = SDL_GetAudioPlaybackDevices(nullptr);
|
||||||
|
for (; dev_array != 0;) {
|
||||||
|
std::string dev_name(SDL_GetAudioDeviceName(*dev_array));
|
||||||
|
if (dev_name == port_name) {
|
||||||
|
dev_id = *dev_array;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
dev_array++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dev_id == SDL_INVALID_AUDIODEVICEID) {
|
||||||
|
LOG_WARNING(Lib_AudioOut, "Audio device not found: {}", port_name);
|
||||||
|
dev_id = SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK;
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
LOG_ERROR(Lib_AudioOut, "Invalid audio output device: {}", port_name);
|
||||||
|
stream = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the audio stream
|
||||||
|
stream = SDL_OpenAudioDeviceStream(dev_id, &fmt, nullptr, nullptr);
|
||||||
if (stream == nullptr) {
|
if (stream == nullptr) {
|
||||||
LOG_ERROR(Lib_AudioOut, "Failed to create SDL audio stream: {}", SDL_GetError());
|
LOG_ERROR(Lib_AudioOut, "Failed to create SDL audio stream: {}", SDL_GetError());
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -408,8 +408,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selected == &gameConfigConfigure || selected == &gameConfigCreate) {
|
if (selected == &gameConfigConfigure || selected == &gameConfigCreate) {
|
||||||
auto settingsWindow = new SettingsDialog(m_gui_settings, m_compat_info, widget, true,
|
auto settingsWindow = new SettingsDialog(m_gui_settings, m_compat_info, widget, false,
|
||||||
serialStr.toStdString());
|
true, serialStr.toStdString());
|
||||||
settingsWindow->exec();
|
settingsWindow->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -407,7 +407,8 @@ void MainWindow::CreateConnects() {
|
|||||||
&MainWindow::StartGame);
|
&MainWindow::StartGame);
|
||||||
|
|
||||||
connect(ui->configureAct, &QAction::triggered, this, [this]() {
|
connect(ui->configureAct, &QAction::triggered, this, [this]() {
|
||||||
auto settingsDialog = new SettingsDialog(m_gui_settings, m_compat_info, this);
|
auto settingsDialog =
|
||||||
|
new SettingsDialog(m_gui_settings, m_compat_info, this, isGameRunning);
|
||||||
|
|
||||||
connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
|
connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
|
||||||
&MainWindow::OnLanguageChanged);
|
&MainWindow::OnLanguageChanged);
|
||||||
@@ -441,7 +442,8 @@ void MainWindow::CreateConnects() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
|
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
|
||||||
auto settingsDialog = new SettingsDialog(m_gui_settings, m_compat_info, this);
|
auto settingsDialog =
|
||||||
|
new SettingsDialog(m_gui_settings, m_compat_info, this, isGameRunning);
|
||||||
|
|
||||||
connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
|
connect(settingsDialog, &SettingsDialog::LanguageChanged, this,
|
||||||
&MainWindow::OnLanguageChanged);
|
&MainWindow::OnLanguageChanged);
|
||||||
|
|||||||
@@ -41,6 +41,14 @@ bool Wrapper::ProcessEvent(SDL_Event* event) {
|
|||||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||||
emit SDLEvent(SDL_EVENT_GAMEPAD_AXIS_MOTION, event->gaxis.axis, event->gaxis.value);
|
emit SDLEvent(SDL_EVENT_GAMEPAD_AXIS_MOTION, event->gaxis.axis, event->gaxis.value);
|
||||||
return true;
|
return true;
|
||||||
|
case SDL_EVENT_AUDIO_DEVICE_ADDED:
|
||||||
|
if (event->adevice.recording == 0)
|
||||||
|
emit audioDeviceChanged(true);
|
||||||
|
return true;
|
||||||
|
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
|
||||||
|
if (event->adevice.recording == 0)
|
||||||
|
emit audioDeviceChanged(false);
|
||||||
|
return true;
|
||||||
// block all other SDL events while wrapper is active
|
// block all other SDL events while wrapper is active
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void SDLEvent(int Type, int Input, int Value);
|
void SDLEvent(int Type, int Input, int Value);
|
||||||
|
void audioDeviceChanged(bool isAdd);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SdlEventWrapper
|
} // namespace SdlEventWrapper
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "core/libraries/audio/audioout.h"
|
#include "core/libraries/audio/audioout.h"
|
||||||
#include "qt_gui/compatibility_info.h"
|
#include "qt_gui/compatibility_info.h"
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/logging/filter.h"
|
#include "common/logging/filter.h"
|
||||||
#include "log_presets_dialog.h"
|
#include "log_presets_dialog.h"
|
||||||
|
#include "sdl_event_wrapper.h"
|
||||||
#include "settings_dialog.h"
|
#include "settings_dialog.h"
|
||||||
#include "ui_settings_dialog.h"
|
#include "ui_settings_dialog.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
@@ -82,18 +84,20 @@ static std::vector<QString> m_physical_devices;
|
|||||||
|
|
||||||
SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
||||||
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
|
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
|
||||||
QWidget* parent, bool is_game_specific, std::string gsc_serial)
|
QWidget* parent, bool is_running, bool is_specific,
|
||||||
|
std::string gsc_serial)
|
||||||
: QDialog(parent), ui(new Ui::SettingsDialog), m_gui_settings(std::move(gui_settings)),
|
: QDialog(parent), ui(new Ui::SettingsDialog), m_gui_settings(std::move(gui_settings)),
|
||||||
game_specific(is_game_specific), gs_serial(gsc_serial) {
|
is_game_running(is_running), is_game_specific(is_specific), gs_serial(gsc_serial) {
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->tabWidgetSettings->setUsesScrollButtons(false);
|
ui->tabWidgetSettings->setUsesScrollButtons(false);
|
||||||
|
|
||||||
initialHeight = this->height();
|
initialHeight = this->height();
|
||||||
|
|
||||||
// Add a small clear "x" button inside the Log Filter input
|
// Add a small clear "x" button inside the Log Filter input
|
||||||
ui->logFilterLineEdit->setClearButtonEnabled(true);
|
ui->logFilterLineEdit->setClearButtonEnabled(true);
|
||||||
|
|
||||||
if (game_specific) {
|
if (is_game_specific) {
|
||||||
// Paths tab
|
// Paths tab
|
||||||
ui->tabWidgetSettings->setTabVisible(5, false);
|
ui->tabWidgetSettings->setTabVisible(5, false);
|
||||||
ui->chooseHomeTabComboBox->removeItem(5);
|
ui->chooseHomeTabComboBox->removeItem(5);
|
||||||
@@ -109,7 +113,7 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path config_file =
|
std::filesystem::path config_file =
|
||||||
game_specific
|
is_game_specific
|
||||||
? Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (gs_serial + ".toml")
|
? Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (gs_serial + ".toml")
|
||||||
: Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml";
|
: Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml";
|
||||||
|
|
||||||
@@ -184,6 +188,7 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
InitializeEmulatorLanguages();
|
InitializeEmulatorLanguages();
|
||||||
|
onAudioDeviceChange(true);
|
||||||
LoadValuesFromConfig();
|
LoadValuesFromConfig();
|
||||||
|
|
||||||
defaultTextEdit = tr("Point your mouse at an option to display its description.");
|
defaultTextEdit = tr("Point your mouse at an option to display its description.");
|
||||||
@@ -194,17 +199,17 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
|||||||
connect(ui->buttonBox, &QDialogButtonBox::clicked, this,
|
connect(ui->buttonBox, &QDialogButtonBox::clicked, this,
|
||||||
[this, config_file](QAbstractButton* button) {
|
[this, config_file](QAbstractButton* button) {
|
||||||
if (button == ui->buttonBox->button(QDialogButtonBox::Save)) {
|
if (button == ui->buttonBox->button(QDialogButtonBox::Save)) {
|
||||||
is_saving = true;
|
is_game_saving = true;
|
||||||
UpdateSettings(game_specific);
|
UpdateSettings(is_game_specific);
|
||||||
Config::save(config_file, game_specific);
|
Config::save(config_file, is_game_specific);
|
||||||
QWidget::close();
|
QWidget::close();
|
||||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
|
} else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
|
||||||
UpdateSettings(game_specific);
|
UpdateSettings(is_game_specific);
|
||||||
Config::save(config_file, game_specific);
|
Config::save(config_file, is_game_specific);
|
||||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
|
} else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
|
||||||
setDefaultValues();
|
setDefaultValues();
|
||||||
Config::setDefaultValues(game_specific);
|
Config::setDefaultValues(is_game_specific);
|
||||||
Config::save(config_file, game_specific);
|
Config::save(config_file, is_game_specific);
|
||||||
LoadValuesFromConfig();
|
LoadValuesFromConfig();
|
||||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::Close)) {
|
} else if (button == ui->buttonBox->button(QDialogButtonBox::Close)) {
|
||||||
ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup);
|
ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup);
|
||||||
@@ -232,7 +237,7 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
|||||||
{
|
{
|
||||||
connect(ui->horizontalVolumeSlider, &QSlider::valueChanged, this, [this](int value) {
|
connect(ui->horizontalVolumeSlider, &QSlider::valueChanged, this, [this](int value) {
|
||||||
VolumeSliderChange(value);
|
VolumeSliderChange(value);
|
||||||
Config::setVolumeSlider(value, game_specific);
|
Config::setVolumeSlider(value, is_game_specific);
|
||||||
Libraries::AudioOut::AdjustVol();
|
Libraries::AudioOut::AdjustVol();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -526,30 +531,52 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
|||||||
ui->networkConnectedCheckBox->installEventFilter(this);
|
ui->networkConnectedCheckBox->installEventFilter(this);
|
||||||
ui->psnSignInCheckBox->installEventFilter(this);
|
ui->psnSignInCheckBox->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SdlEventWrapper::Wrapper::wrapperActive = true;
|
||||||
|
if (!is_game_running) {
|
||||||
|
SDL_InitSubSystem(SDL_INIT_EVENTS);
|
||||||
|
Polling = QtConcurrent::run(&SettingsDialog::pollSDLevents, this);
|
||||||
|
} else {
|
||||||
|
SdlEventWrapper::Wrapper* DeviceEventWrapper = SdlEventWrapper::Wrapper::GetInstance();
|
||||||
|
QObject::connect(DeviceEventWrapper, &SdlEventWrapper::Wrapper::audioDeviceChanged, this,
|
||||||
|
&SettingsDialog::onAudioDeviceChange);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::closeEvent(QCloseEvent* event) {
|
void SettingsDialog::closeEvent(QCloseEvent* event) {
|
||||||
if (!is_saving) {
|
if (!is_game_saving) {
|
||||||
ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup);
|
ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup);
|
||||||
emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup);
|
emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup);
|
||||||
ui->BGMVolumeSlider->setValue(bgm_volume_backup);
|
ui->BGMVolumeSlider->setValue(bgm_volume_backup);
|
||||||
BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup);
|
BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup);
|
||||||
SyncRealTimeWidgetstoConfig();
|
SyncRealTimeWidgetstoConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SdlEventWrapper::Wrapper::wrapperActive = false;
|
||||||
|
if (!is_game_running) {
|
||||||
|
SDL_Event quitLoop{};
|
||||||
|
quitLoop.type = SDL_EVENT_QUIT;
|
||||||
|
SDL_PushEvent(&quitLoop);
|
||||||
|
Polling.waitForFinished();
|
||||||
|
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
QDialog::closeEvent(event);
|
QDialog::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::LoadValuesFromConfig() {
|
void SettingsDialog::LoadValuesFromConfig() {
|
||||||
std::filesystem::path config_file;
|
std::filesystem::path config_file;
|
||||||
config_file =
|
config_file =
|
||||||
game_specific
|
is_game_specific
|
||||||
? Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (gs_serial + ".toml")
|
? Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (gs_serial + ".toml")
|
||||||
: Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml";
|
: Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml";
|
||||||
|
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
bool is_newly_created = false;
|
bool is_newly_created = false;
|
||||||
if (!std::filesystem::exists(config_file, error)) {
|
if (!std::filesystem::exists(config_file, error)) {
|
||||||
Config::save(config_file, game_specific);
|
Config::save(config_file, is_game_specific);
|
||||||
is_newly_created = true;
|
is_newly_created = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,7 +594,7 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||||||
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
|
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
|
||||||
|
|
||||||
// Entries with no game-specific settings
|
// Entries with no game-specific settings
|
||||||
if (!game_specific) {
|
if (!is_game_specific) {
|
||||||
const auto save_data_path = Config::GetSaveDataPath();
|
const auto save_data_path = Config::GetSaveDataPath();
|
||||||
QString save_data_path_string;
|
QString save_data_path_string;
|
||||||
Common::FS::PathToQString(save_data_path_string, save_data_path);
|
Common::FS::PathToQString(save_data_path_string, save_data_path);
|
||||||
@@ -728,6 +755,11 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||||||
toml::find_or<bool>(data, "Debug", "CollectShader", false));
|
toml::find_or<bool>(data, "Debug", "CollectShader", false));
|
||||||
ui->enableLoggingCheckBox->setChecked(toml::find_or<bool>(data, "Debug", "logEnabled", true));
|
ui->enableLoggingCheckBox->setChecked(toml::find_or<bool>(data, "Debug", "logEnabled", true));
|
||||||
|
|
||||||
|
ui->GenAudioComboBox->setCurrentText(QString::fromStdString(
|
||||||
|
toml::find_or<std::string>(data, "General", "mainOutputDevice", "")));
|
||||||
|
ui->DsAudioComboBox->setCurrentText(QString::fromStdString(
|
||||||
|
toml::find_or<std::string>(data, "General", "padSpkOutputDevice", "")));
|
||||||
|
|
||||||
std::string chooseHomeTab =
|
std::string chooseHomeTab =
|
||||||
toml::find_or<std::string>(data, "General", "chooseHomeTab", "General");
|
toml::find_or<std::string>(data, "General", "chooseHomeTab", "General");
|
||||||
QString translatedText = chooseHomeTabMap.key(QString::fromStdString(chooseHomeTab));
|
QString translatedText = chooseHomeTabMap.key(QString::fromStdString(chooseHomeTab));
|
||||||
@@ -979,76 +1011,75 @@ bool SettingsDialog::eventFilter(QObject* obj, QEvent* event) {
|
|||||||
return QDialog::eventFilter(obj, event);
|
return QDialog::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::UpdateSettings(bool game_specific) {
|
void SettingsDialog::UpdateSettings(bool is_specific) {
|
||||||
// Entries with game-specific settings, needs the game-specific arg
|
// Entries with game-specific settings, needs the game-specific arg
|
||||||
Config::setReadbacks(ui->readbacksCheckBox->isChecked(), game_specific);
|
Config::setReadbacks(ui->readbacksCheckBox->isChecked(), is_specific);
|
||||||
Config::setReadbackLinearImages(ui->readbackLinearImagesCheckBox->isChecked(), game_specific);
|
Config::setReadbackLinearImages(ui->readbackLinearImagesCheckBox->isChecked(), is_specific);
|
||||||
Config::setDirectMemoryAccess(ui->dmaCheckBox->isChecked(), game_specific);
|
Config::setDirectMemoryAccess(ui->dmaCheckBox->isChecked(), is_specific);
|
||||||
Config::setDevKitConsole(ui->devkitCheckBox->isChecked(), game_specific);
|
Config::setDevKitConsole(ui->devkitCheckBox->isChecked(), is_specific);
|
||||||
Config::setNeoMode(ui->neoCheckBox->isChecked(), game_specific);
|
Config::setNeoMode(ui->neoCheckBox->isChecked(), is_specific);
|
||||||
Config::setConnectedToNetwork(ui->networkConnectedCheckBox->isChecked(), game_specific);
|
Config::setConnectedToNetwork(ui->networkConnectedCheckBox->isChecked(), is_specific);
|
||||||
Config::setPSNSignedIn(ui->psnSignInCheckBox->isChecked(), game_specific);
|
Config::setPSNSignedIn(ui->psnSignInCheckBox->isChecked(), is_specific);
|
||||||
|
|
||||||
Config::setIsFullscreen(
|
Config::setIsFullscreen(
|
||||||
screenModeMap.value(ui->displayModeComboBox->currentText()) != "Windowed", game_specific);
|
screenModeMap.value(ui->displayModeComboBox->currentText()) != "Windowed", is_specific);
|
||||||
Config::setFullscreenMode(
|
Config::setFullscreenMode(
|
||||||
screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString(), game_specific);
|
screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString(), is_specific);
|
||||||
Config::setPresentMode(
|
Config::setPresentMode(
|
||||||
presentModeMap.value(ui->presentModeComboBox->currentText()).toStdString(), game_specific);
|
presentModeMap.value(ui->presentModeComboBox->currentText()).toStdString(), is_specific);
|
||||||
Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked(), game_specific);
|
Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked(), is_specific);
|
||||||
Config::setBackgroundControllerInput(ui->backgroundControllerCheckBox->isChecked(),
|
Config::setBackgroundControllerInput(ui->backgroundControllerCheckBox->isChecked(),
|
||||||
game_specific);
|
is_specific);
|
||||||
Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked(), game_specific);
|
Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked(), is_specific);
|
||||||
Config::setTrophyNotificationDuration(ui->popUpDurationSpinBox->value(), game_specific);
|
Config::setTrophyNotificationDuration(ui->popUpDurationSpinBox->value(), is_specific);
|
||||||
|
|
||||||
if (ui->radioButton_Top->isChecked()) {
|
if (ui->radioButton_Top->isChecked()) {
|
||||||
Config::setSideTrophy("top", game_specific);
|
Config::setSideTrophy("top", is_specific);
|
||||||
} else if (ui->radioButton_Left->isChecked()) {
|
} else if (ui->radioButton_Left->isChecked()) {
|
||||||
Config::setSideTrophy("left", game_specific);
|
Config::setSideTrophy("left", is_specific);
|
||||||
} else if (ui->radioButton_Right->isChecked()) {
|
} else if (ui->radioButton_Right->isChecked()) {
|
||||||
Config::setSideTrophy("right", game_specific);
|
Config::setSideTrophy("right", is_specific);
|
||||||
} else if (ui->radioButton_Bottom->isChecked()) {
|
} else if (ui->radioButton_Bottom->isChecked()) {
|
||||||
Config::setSideTrophy("bottom", game_specific);
|
Config::setSideTrophy("bottom", is_specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::setLoggingEnabled(ui->enableLoggingCheckBox->isChecked(), game_specific);
|
Config::setLoggingEnabled(ui->enableLoggingCheckBox->isChecked(), is_specific);
|
||||||
Config::setAllowHDR(ui->enableHDRCheckBox->isChecked(), game_specific);
|
Config::setAllowHDR(ui->enableHDRCheckBox->isChecked(), is_specific);
|
||||||
Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString(),
|
Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString(),
|
||||||
game_specific);
|
is_specific);
|
||||||
Config::setMicDevice(ui->micComboBox->currentData().toString().toStdString(), game_specific);
|
Config::setMicDevice(ui->micComboBox->currentData().toString().toStdString(), is_specific);
|
||||||
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString(), game_specific);
|
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString(), is_specific);
|
||||||
Config::setUserName(ui->userNameLineEdit->text().toStdString(), game_specific);
|
Config::setUserName(ui->userNameLineEdit->text().toStdString(), is_specific);
|
||||||
Config::setCursorState(ui->hideCursorComboBox->currentIndex(), game_specific);
|
Config::setCursorState(ui->hideCursorComboBox->currentIndex(), is_specific);
|
||||||
Config::setCursorHideTimeout(ui->hideCursorComboBox->currentIndex(), game_specific);
|
Config::setCursorHideTimeout(ui->hideCursorComboBox->currentIndex(), is_specific);
|
||||||
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1, game_specific);
|
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1, is_specific);
|
||||||
Config::setVolumeSlider(ui->horizontalVolumeSlider->value(), game_specific);
|
Config::setVolumeSlider(ui->horizontalVolumeSlider->value(), is_specific);
|
||||||
Config::setLanguage(languageIndexes[ui->consoleLanguageComboBox->currentIndex()],
|
Config::setLanguage(languageIndexes[ui->consoleLanguageComboBox->currentIndex()], is_specific);
|
||||||
game_specific);
|
Config::setWindowWidth(ui->widthSpinBox->value(), is_specific);
|
||||||
Config::setWindowWidth(ui->widthSpinBox->value(), game_specific);
|
Config::setWindowHeight(ui->heightSpinBox->value(), is_specific);
|
||||||
Config::setWindowHeight(ui->heightSpinBox->value(), game_specific);
|
Config::setVblankFreq(ui->vblankSpinBox->value(), is_specific);
|
||||||
Config::setVblankFreq(ui->vblankSpinBox->value(), game_specific);
|
Config::setDumpShaders(ui->dumpShadersCheckBox->isChecked(), is_specific);
|
||||||
Config::setDumpShaders(ui->dumpShadersCheckBox->isChecked(), game_specific);
|
Config::setNullGpu(ui->nullGpuCheckBox->isChecked(), is_specific);
|
||||||
Config::setNullGpu(ui->nullGpuCheckBox->isChecked(), game_specific);
|
Config::setFsrEnabled(ui->FSRCheckBox->isChecked(), is_specific);
|
||||||
Config::setFsrEnabled(ui->FSRCheckBox->isChecked(), game_specific);
|
Config::setRcasEnabled(ui->RCASCheckBox->isChecked(), is_specific);
|
||||||
Config::setRcasEnabled(ui->RCASCheckBox->isChecked(), game_specific);
|
Config::setRcasAttenuation(ui->RCASSlider->value(), is_specific);
|
||||||
Config::setRcasAttenuation(ui->RCASSlider->value(), game_specific);
|
Config::setShowSplash(ui->showSplashCheckBox->isChecked(), is_specific);
|
||||||
Config::setShowSplash(ui->showSplashCheckBox->isChecked(), game_specific);
|
Config::setDebugDump(ui->debugDump->isChecked(), is_specific);
|
||||||
Config::setDebugDump(ui->debugDump->isChecked(), game_specific);
|
Config::setSeparateLogFilesEnabled(ui->separateLogFilesCheckbox->isChecked(), is_specific);
|
||||||
Config::setSeparateLogFilesEnabled(ui->separateLogFilesCheckbox->isChecked(), game_specific);
|
Config::setVkValidation(ui->vkValidationCheckBox->isChecked(), is_specific);
|
||||||
Config::setVkValidation(ui->vkValidationCheckBox->isChecked(), game_specific);
|
Config::setVkSyncValidation(ui->vkSyncValidationCheckBox->isChecked(), is_specific);
|
||||||
Config::setVkSyncValidation(ui->vkSyncValidationCheckBox->isChecked(), game_specific);
|
Config::setRdocEnabled(ui->rdocCheckBox->isChecked(), is_specific);
|
||||||
Config::setRdocEnabled(ui->rdocCheckBox->isChecked(), game_specific);
|
Config::setVkHostMarkersEnabled(ui->hostMarkersCheckBox->isChecked(), is_specific);
|
||||||
Config::setVkHostMarkersEnabled(ui->hostMarkersCheckBox->isChecked(), game_specific);
|
Config::setVkGuestMarkersEnabled(ui->guestMarkersCheckBox->isChecked(), is_specific);
|
||||||
Config::setVkGuestMarkersEnabled(ui->guestMarkersCheckBox->isChecked(), game_specific);
|
Config::setVkCrashDiagnosticEnabled(ui->crashDiagnosticsCheckBox->isChecked(), is_specific);
|
||||||
Config::setVkCrashDiagnosticEnabled(ui->crashDiagnosticsCheckBox->isChecked(), game_specific);
|
Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked(), is_specific);
|
||||||
Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked(), game_specific);
|
Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked(), is_specific);
|
||||||
Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked(), game_specific);
|
|
||||||
Config::setChooseHomeTab(
|
Config::setChooseHomeTab(
|
||||||
chooseHomeTabMap.value(ui->chooseHomeTabComboBox->currentText()).toStdString(),
|
chooseHomeTabMap.value(ui->chooseHomeTabComboBox->currentText()).toStdString(),
|
||||||
game_specific);
|
is_specific);
|
||||||
|
|
||||||
// Entries with no game-specific settings
|
// Entries with no game-specific settings
|
||||||
if (!game_specific) {
|
if (!is_specific) {
|
||||||
std::vector<Config::GameInstallDir> dirs_with_states;
|
std::vector<Config::GameInstallDir> dirs_with_states;
|
||||||
for (int i = 0; i < ui->gameFoldersListWidget->count(); i++) {
|
for (int i = 0; i < ui->gameFoldersListWidget->count(); i++) {
|
||||||
QListWidgetItem* item = ui->gameFoldersListWidget->item(i);
|
QListWidgetItem* item = ui->gameFoldersListWidget->item(i);
|
||||||
@@ -1096,7 +1127,7 @@ void SettingsDialog::SyncRealTimeWidgetstoConfig() {
|
|||||||
std::filesystem::path userdir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
std::filesystem::path userdir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||||
const toml::value data = toml::parse(userdir / "config.toml");
|
const toml::value data = toml::parse(userdir / "config.toml");
|
||||||
|
|
||||||
if (!game_specific) {
|
if (!is_game_specific) {
|
||||||
ui->gameFoldersListWidget->clear();
|
ui->gameFoldersListWidget->clear();
|
||||||
if (data.contains("GUI")) {
|
if (data.contains("GUI")) {
|
||||||
const toml::value& gui = data.at("GUI");
|
const toml::value& gui = data.at("GUI");
|
||||||
@@ -1137,7 +1168,7 @@ void SettingsDialog::SyncRealTimeWidgetstoConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toml::value gs_data;
|
toml::value gs_data;
|
||||||
game_specific
|
is_game_specific
|
||||||
? gs_data = toml::parse(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
|
? gs_data = toml::parse(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
|
||||||
(gs_serial + ".toml"))
|
(gs_serial + ".toml"))
|
||||||
: gs_data = data;
|
: gs_data = data;
|
||||||
@@ -1147,8 +1178,8 @@ void SettingsDialog::SyncRealTimeWidgetstoConfig() {
|
|||||||
|
|
||||||
// Since config::set can be called for volume slider (connected to the widget) outside the save
|
// Since config::set can be called for volume slider (connected to the widget) outside the save
|
||||||
// function, need to null it out if GS GUI is closed without saving
|
// function, need to null it out if GS GUI is closed without saving
|
||||||
game_specific ? Config::resetGameSpecificValue("volumeSlider")
|
is_game_specific ? Config::resetGameSpecificValue("volumeSlider")
|
||||||
: Config::setVolumeSlider(sliderValue);
|
: Config::setVolumeSlider(sliderValue);
|
||||||
|
|
||||||
if (presenter) {
|
if (presenter) {
|
||||||
presenter->GetFsrSettingsRef().enable =
|
presenter->GetFsrSettingsRef().enable =
|
||||||
@@ -1161,7 +1192,7 @@ void SettingsDialog::SyncRealTimeWidgetstoConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::setDefaultValues() {
|
void SettingsDialog::setDefaultValues() {
|
||||||
if (!game_specific) {
|
if (!is_game_specific) {
|
||||||
m_gui_settings->SetValue(gui::gl_showBackgroundImage, true);
|
m_gui_settings->SetValue(gui::gl_showBackgroundImage, true);
|
||||||
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity, 50);
|
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity, 50);
|
||||||
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, false);
|
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, false);
|
||||||
@@ -1176,3 +1207,59 @@ void SettingsDialog::setDefaultValues() {
|
|||||||
m_gui_settings->SetValue(gui::gen_guiLanguage, "en_US");
|
m_gui_settings->SetValue(gui::gen_guiLanguage, "en_US");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::pollSDLevents() {
|
||||||
|
SDL_Event event;
|
||||||
|
while (SdlEventWrapper::Wrapper::wrapperActive) {
|
||||||
|
|
||||||
|
if (!SDL_WaitEvent(&event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == SDL_EVENT_QUIT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == SDL_EVENT_AUDIO_DEVICE_ADDED) {
|
||||||
|
onAudioDeviceChange(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == SDL_EVENT_AUDIO_DEVICE_REMOVED) {
|
||||||
|
onAudioDeviceChange(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::onAudioDeviceChange(bool isAdd) {
|
||||||
|
ui->GenAudioComboBox->clear();
|
||||||
|
ui->DsAudioComboBox->clear();
|
||||||
|
|
||||||
|
// prevent device list from refreshing too fast when game not running
|
||||||
|
if (!is_game_running && isAdd == false)
|
||||||
|
QThread::msleep(100);
|
||||||
|
|
||||||
|
int deviceCount;
|
||||||
|
QStringList deviceList;
|
||||||
|
SDL_AudioDeviceID* devices = SDL_GetAudioPlaybackDevices(&deviceCount);
|
||||||
|
|
||||||
|
if (!devices) {
|
||||||
|
LOG_ERROR(Lib_AudioOut, "Unable to retrieve audio device list {}", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < deviceCount; ++i) {
|
||||||
|
const char* name = SDL_GetAudioDeviceName(devices[i]);
|
||||||
|
std::string name_string = std::string(name);
|
||||||
|
deviceList.append(QString::fromStdString(name_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->GenAudioComboBox->addItem(tr("Default Device"), "Default Device");
|
||||||
|
ui->GenAudioComboBox->addItems(deviceList);
|
||||||
|
ui->GenAudioComboBox->setCurrentText(QString::fromStdString(Config::getMainOutputDevice()));
|
||||||
|
|
||||||
|
ui->DsAudioComboBox->addItem(tr("Default Device"), "Default Device");
|
||||||
|
ui->DsAudioComboBox->addItems(deviceList);
|
||||||
|
ui->DsAudioComboBox->setCurrentText(QString::fromStdString(Config::getPadSpkOutputDevice()));
|
||||||
|
|
||||||
|
SDL_free(devices);
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ class SettingsDialog : public QDialog {
|
|||||||
public:
|
public:
|
||||||
explicit SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
explicit SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
|
||||||
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
|
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
|
||||||
QWidget* parent = nullptr, bool is_game_specific = false,
|
QWidget* parent = nullptr, bool is_game_running = false,
|
||||||
std::string gsc_serial = "");
|
bool is_game_specific = false, std::string gsc_serial = "");
|
||||||
~SettingsDialog();
|
~SettingsDialog();
|
||||||
|
|
||||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||||
@@ -47,6 +47,8 @@ private:
|
|||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
void setDefaultValues();
|
void setDefaultValues();
|
||||||
void VolumeSliderChange(int value);
|
void VolumeSliderChange(int value);
|
||||||
|
void onAudioDeviceChange(bool isAdd);
|
||||||
|
void pollSDLevents();
|
||||||
|
|
||||||
std::unique_ptr<Ui::SettingsDialog> ui;
|
std::unique_ptr<Ui::SettingsDialog> ui;
|
||||||
|
|
||||||
@@ -55,9 +57,13 @@ private:
|
|||||||
QString defaultTextEdit;
|
QString defaultTextEdit;
|
||||||
|
|
||||||
int initialHeight;
|
int initialHeight;
|
||||||
bool is_saving = false;
|
|
||||||
bool game_specific;
|
|
||||||
std::string gs_serial;
|
std::string gs_serial;
|
||||||
|
|
||||||
|
bool is_game_running = false;
|
||||||
|
bool is_game_specific = false;
|
||||||
|
bool is_game_saving = false;
|
||||||
|
|
||||||
std::shared_ptr<gui_settings> m_gui_settings;
|
std::shared_ptr<gui_settings> m_gui_settings;
|
||||||
|
QFuture<void> Polling;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>946</width>
|
<width>946</width>
|
||||||
<height>501</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
|
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
|
||||||
@@ -381,6 +381,30 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QGroupBox" name="GenAudioGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Audio Device (general)</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="GenAudioComboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="DsSpeakerGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Audio Device (DS4 speaker)</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="DsAudioComboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1010,7 +1034,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>946</width>
|
<width>946</width>
|
||||||
<height>501</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
|
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
|
||||||
@@ -1417,7 +1441,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>946</width>
|
<width>946</width>
|
||||||
<height>501</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="userTabVLayout" stretch="0,0,1">
|
<layout class="QVBoxLayout" name="userTabVLayout" stretch="0,0,1">
|
||||||
@@ -1632,7 +1656,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>946</width>
|
<width>946</width>
|
||||||
<height>501</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0,0">
|
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0,0">
|
||||||
@@ -1918,7 +1942,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>946</width>
|
<width>946</width>
|
||||||
<height>501</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="pathsTabLayout">
|
<layout class="QVBoxLayout" name="pathsTabLayout">
|
||||||
@@ -2087,7 +2111,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>946</width>
|
<width>946</width>
|
||||||
<height>299</height>
|
<height>536</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|||||||
Reference in New Issue
Block a user