-
+
+ Controls the main volume of the game.
+
+
Controls the overall volume of background music.
-
+
Toggles whether or not the low-health beeping sound plays.
diff --git a/include/recomp_sound.h b/include/recomp_sound.h
index 04408e0..f33ed4a 100644
--- a/include/recomp_sound.h
+++ b/include/recomp_sound.h
@@ -3,6 +3,8 @@
namespace recomp {
void reset_sound_settings();
+ void set_main_volume(int volume);
+ int get_main_volume();
void set_bgm_volume(int volume);
int get_bgm_volume();
void set_low_health_beeps_enabled(bool enabled);
diff --git a/src/game/config.cpp b/src/game/config.cpp
index 7c37d2a..2ea2646 100644
--- a/src/game/config.cpp
+++ b/src/game/config.cpp
@@ -344,6 +344,7 @@ void load_controls_config(const std::filesystem::path& path) {
void save_sound_config(const std::filesystem::path& path) {
nlohmann::json config_json{};
+ config_json["main_volume"] = recomp::get_main_volume();
config_json["bgm_volume"] = recomp::get_bgm_volume();
config_json["low_health_beeps"] = recomp::get_low_health_beeps_enabled();
@@ -357,8 +358,8 @@ void load_sound_config(const std::filesystem::path& path) {
config_file >> config_json;
-
recomp::reset_sound_settings();
+ call_if_key_exists(recomp::set_main_volume, config_json, "main_volume");
call_if_key_exists(recomp::set_bgm_volume, config_json, "bgm_volume");
call_if_key_exists(recomp::set_low_health_beeps_enabled, config_json, "low_health_beeps");
}
diff --git a/src/game/recomp_api.cpp b/src/game/recomp_api.cpp
index 84d7000..5563501 100644
--- a/src/game/recomp_api.cpp
+++ b/src/game/recomp_api.cpp
@@ -78,7 +78,6 @@ extern "C" void recomp_get_targeting_mode(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, static_cast
(recomp::get_targeting_mode()));
}
-
extern "C" void recomp_get_bgm_volume(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, recomp::get_bgm_volume() / 100.0f);
}
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 42b382f..e2a60f5 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -23,6 +23,7 @@
#include "recomp_input.h"
#include "recomp_config.h"
#include "recomp_game.h"
+#include "recomp_sound.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@@ -191,9 +192,10 @@ void queue_samples(int16_t* audio_data, size_t sample_count) {
// Convert the audio from 16-bit values to floats and swap the audio channels into the
// swap buffer to correct for the address xor caused by endianness handling.
+ float cur_main_volume = recomp::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
for (size_t i = 0; i < sample_count; i += input_channels) {
- swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f);
- swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f);
+ swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f) * cur_main_volume;
+ swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f) * cur_main_volume;
}
// TODO handle cases where a chunk is smaller than the duplicated frame count.
diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp
index 1891fec..a436120 100644
--- a/src/ui/ui_config.cpp
+++ b/src/ui/ui_config.cpp
@@ -354,10 +354,12 @@ void recomp::set_autosave_mode(recomp::AutosaveMode mode) {
}
struct SoundOptionsContext {
+ std::atomic main_volume; // Option to control the volume of all sound
std::atomic bgm_volume;
std::atomic low_health_beeps_enabled; // RmlUi doesn't seem to like "true"/"false" strings for setting variants so an int is used here instead.
void reset() {
bgm_volume = 100;
+ main_volume = 100;
low_health_beeps_enabled = (int)true;
}
SoundOptionsContext() {
@@ -374,6 +376,17 @@ void recomp::reset_sound_settings() {
}
}
+void recomp::set_main_volume(int volume) {
+ sound_options_context.main_volume.store(volume);
+ if (sound_options_model_handle) {
+ sound_options_model_handle.DirtyVariable("main_volume");
+ }
+}
+
+int recomp::get_main_volume() {
+ return sound_options_context.main_volume.load();
+}
+
void recomp::set_bgm_volume(int volume) {
sound_options_context.bgm_volume.store(volume);
if (sound_options_model_handle) {
@@ -852,6 +865,7 @@ public:
sound_options_model_handle = constructor.GetModelHandle();
+ bind_atomic(constructor, sound_options_model_handle, "main_volume", &sound_options_context.main_volume);
bind_atomic(constructor, sound_options_model_handle, "bgm_volume", &sound_options_context.bgm_volume);
bind_atomic(constructor, sound_options_model_handle, "low_health_beeps_enabled", &sound_options_context.low_health_beeps_enabled);
}