launcher: dualsense vibration/volume setting (#973)

* pad: send DualSense speaker and haptic audio over Bluetooth

* ci: fix Opus clang-cl build and macOS memory tracker test

* docs: remove Bluetooth notes from project README

* pad: keep Bluetooth audio work off emulation timing path

* pad: smooth DualSense speaker audio on USB and Bluetooth

* tests: find available macOS guest range for page manager

* pad: keep haptic waveform when Bluetooth queue overflows

* audio: reject zero output sample frequency

* Simplify DualSense audio routing and fix Bluetooth batching

* controller: add global DualSense volume and vibration controls

* Simplify global controller settings

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
Pyxellator
2026-10-03 16:02:59 +02:00
committed by GitHub
parent 45f55413e0
commit 820856b301
12 changed files with 224 additions and 49 deletions
+27 -5
View File
@@ -46,6 +46,30 @@ QString EnumToText(T value) {
: key);
}
struct ControllerSettings {
QString color;
int speaker_volume = 100;
int vibration_intensity = 100;
void WriteSettings(QSettings* s) const {
s->setValue("controller_color", color);
s->setValue("controller_speaker_volume", speaker_volume);
s->setValue("controller_vibration_intensity", vibration_intensity);
}
void ReadSettings(QSettings* s) {
const QColor saved_color(s->value("controller_color").toString());
color = saved_color.isValid() ? saved_color.name(QColor::HexRgb) : QString {};
const auto read_percent = [s](const char* key) {
bool ok = false;
const int value = s->value(key, 100).toInt(&ok);
return ok ? qBound(0, value, 100) : 100;
};
speaker_volume = read_percent("controller_speaker_volume");
vibration_intensity = read_percent("controller_vibration_intensity");
}
};
class Configuration: public QObject {
Q_OBJECT
@@ -85,11 +109,13 @@ public:
GameStatus game_status = GameStatus::Unknown;
QString game_comment;
// Controller preferences always come from the global configuration.
ControllerSettings controller;
Resolution screen_resolution = Resolution::R1280X720;
QString user_name = "Kyty";
int user_id = Config::DEFAULT_USER_ID;
QString audio_input_device;
QString controller_color;
PresentMode present_mode = PresentMode::Mailbox;
int gpu_index = -1;
bool fullscreen_enabled = false;
@@ -121,7 +147,6 @@ public:
user_name = other.user_name;
user_id = other.user_id;
audio_input_device = other.audio_input_device;
controller_color = other.controller_color;
present_mode = other.present_mode;
gpu_index = other.gpu_index;
fullscreen_enabled = other.fullscreen_enabled;
@@ -168,7 +193,6 @@ public:
KYTY_CFG_SET(user_name);
KYTY_CFG_SET(user_id);
KYTY_CFG_SET(audio_input_device);
KYTY_CFG_SET(controller_color);
KYTY_CFG_SET(present_mode);
KYTY_CFG_SET(gpu_index);
KYTY_CFG_SET(fullscreen_enabled);
@@ -208,8 +232,6 @@ public:
? saved_user_id
: Config::DEFAULT_USER_ID;
audio_input_device = s->value("audio_input_device", audio_input_device).toString();
const QColor color(s->value("controller_color", controller_color).toString());
controller_color = color.isValid() ? color.name(QColor::HexRgb) : QString {};
KYTY_CFG_GET(present_mode);
gpu_index = s->value("gpu_index", -1).toInt();
if (EnumToText(present_mode).isEmpty()) {
@@ -28,7 +28,7 @@ public:
static void WriteSettings(QSettings& s);
static void ReadSettings(QSettings& s);
void SetGameDirectories(const QStringList& dirs);
void SetGlobalSettings(const QStringList& dirs);
[[nodiscard]] QStringList GetGameDirectories() const;
signals:
@@ -40,7 +40,7 @@ private:
QGroupBox* m_game_dirs_group = nullptr;
QListWidget* m_game_dirs_list = nullptr;
QToolButton* m_remove_game_dir_button = nullptr;
bool m_show_game_dirs = false;
bool m_global_settings = false;
protected:
void Init(const Configuration& info);
@@ -34,7 +34,7 @@ public:
[[nodiscard]] const QString& GetSettingsFile() const { return m_settings_file; }
[[nodiscard]] const QString& GetGlobalControllerColor() const {
return m_global_info.controller_color;
return m_global_info.controller.color;
}
[[nodiscard]] std::unique_ptr<Configuration>
CreateConfiguration(const ConfigurationItem& item) const;