Add main volume option to settings (#267)

* This commit adds the option to control the main volume game via a slider
added to the "Sound" tab in the settings menu.
This commit is contained in:
Parker 2024-05-25 21:59:15 -07:00 committed by GitHub
parent 41e737249e
commit 169155953e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 49 additions and 11 deletions

View File

@ -7,30 +7,47 @@
<!-- Options --> <!-- Options -->
<div class="config__wrapper" data-event-mouseout="set_cur_config_index(-1)"> <div class="config__wrapper" data-event-mouseout="set_cur_config_index(-1)">
<div class="config-option" data-event-mouseover="set_cur_config_index(0)"> <div class="config-option" data-event-mouseover="set_cur_config_index(0)">
<label class="config-option__title">Main Volume</label>
<div class="config-option__range-wrapper config-option__list">
<label class="config-option__range-label">{{main_volume}}%</label>
<input
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(0)"
class="nav-vert"
id="main_volume_input"
type="range"
min="0"
max="100"
style="flex: 1; margin: 0dp; nav-up: #tab_sound; nav-down: #bgm_volume_input;"
data-value="main_volume"
/>
</div>
</div>
<div class="config-option" data-event-mouseover="set_cur_config_index(1)">
<label class="config-option__title">Background Music Volume</label> <label class="config-option__title">Background Music Volume</label>
<div class="config-option__range-wrapper config-option__list"> <div class="config-option__range-wrapper config-option__list">
<label class="config-option__range-label">{{bgm_volume}}%</label> <label class="config-option__range-label">{{bgm_volume}}%</label>
<input <input
data-event-blur="set_cur_config_index(-1)" data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(0)" data-event-focus="set_cur_config_index(1)"
class="nav-vert" class="nav-vert"
id="bgm_volume_input" id="bgm_volume_input"
type="range" type="range"
min="0" min="0"
max="100" max="100"
style="flex: 1; margin: 0dp; nav-up: #tab_sound; nav-down: #lhb_on;" style="flex: 1; margin: 0dp; nav-up: #main_volume_input; nav-down: #lhb_on;"
data-value="bgm_volume" data-value="bgm_volume"
/> />
</div> </div>
</div> </div>
<div class="config-option" data-event-mouseover="set_cur_config_index(1)"> <div class="config-option" data-event-mouseover="set_cur_config_index(2)">
<label class="config-option__title">Low Health Beeps</label> <label class="config-option__title">Low Health Beeps</label>
<div class="config-option__list"> <div class="config-option__list">
<input <input
type="radio" type="radio"
data-event-blur="set_cur_config_index(-1)" data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(1)" data-event-focus="set_cur_config_index(2)"
name="lhb" name="lhb"
data-checked="low_health_beeps_enabled" data-checked="low_health_beeps_enabled"
value="1" value="1"
@ -42,7 +59,7 @@
<input <input
type="radio" type="radio"
data-event-blur="set_cur_config_index(-1)" data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(1)" data-event-focus="set_cur_config_index(2)"
name="lhb" name="lhb"
data-checked="low_health_beeps_enabled" data-checked="low_health_beeps_enabled"
value="0" value="0"
@ -55,10 +72,13 @@
</div> </div>
<!-- Descriptions --> <!-- Descriptions -->
<div class="config__wrapper"> <div class="config__wrapper">
<p data-if="cur_config_index == 0"> <p data-if="cur_config_index == 0">
Controls the main volume of the game.
</p>
<p data-if="cur_config_index == 1">
Controls the overall volume of background music. Controls the overall volume of background music.
</p> </p>
<p data-if="cur_config_index == 1"> <p data-if="cur_config_index == 2">
Toggles whether or not the low-health beeping sound plays. Toggles whether or not the low-health beeping sound plays.
</p> </p>
</div> </div>

View File

@ -3,6 +3,8 @@
namespace recomp { namespace recomp {
void reset_sound_settings(); void reset_sound_settings();
void set_main_volume(int volume);
int get_main_volume();
void set_bgm_volume(int volume); void set_bgm_volume(int volume);
int get_bgm_volume(); int get_bgm_volume();
void set_low_health_beeps_enabled(bool enabled); void set_low_health_beeps_enabled(bool enabled);

View File

@ -344,6 +344,7 @@ void load_controls_config(const std::filesystem::path& path) {
void save_sound_config(const std::filesystem::path& path) { void save_sound_config(const std::filesystem::path& path) {
nlohmann::json config_json{}; nlohmann::json config_json{};
config_json["main_volume"] = recomp::get_main_volume();
config_json["bgm_volume"] = recomp::get_bgm_volume(); config_json["bgm_volume"] = recomp::get_bgm_volume();
config_json["low_health_beeps"] = recomp::get_low_health_beeps_enabled(); 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; config_file >> config_json;
recomp::reset_sound_settings(); 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_bgm_volume, config_json, "bgm_volume");
call_if_key_exists(recomp::set_low_health_beeps_enabled, config_json, "low_health_beeps"); call_if_key_exists(recomp::set_low_health_beeps_enabled, config_json, "low_health_beeps");
} }

View File

@ -78,7 +78,6 @@ extern "C" void recomp_get_targeting_mode(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, static_cast<int>(recomp::get_targeting_mode())); _return(ctx, static_cast<int>(recomp::get_targeting_mode()));
} }
extern "C" void recomp_get_bgm_volume(uint8_t* rdram, recomp_context* ctx) { extern "C" void recomp_get_bgm_volume(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, recomp::get_bgm_volume() / 100.0f); _return(ctx, recomp::get_bgm_volume() / 100.0f);
} }

View File

@ -23,6 +23,7 @@
#include "recomp_input.h" #include "recomp_input.h"
#include "recomp_config.h" #include "recomp_config.h"
#include "recomp_game.h" #include "recomp_game.h"
#include "recomp_sound.h"
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #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 // 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. // 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) { 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 + 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); 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. // TODO handle cases where a chunk is smaller than the duplicated frame count.

View File

@ -354,10 +354,12 @@ void recomp::set_autosave_mode(recomp::AutosaveMode mode) {
} }
struct SoundOptionsContext { struct SoundOptionsContext {
std::atomic<int> main_volume; // Option to control the volume of all sound
std::atomic<int> bgm_volume; std::atomic<int> bgm_volume;
std::atomic<int> low_health_beeps_enabled; // RmlUi doesn't seem to like "true"/"false" strings for setting variants so an int is used here instead. std::atomic<int> 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() { void reset() {
bgm_volume = 100; bgm_volume = 100;
main_volume = 100;
low_health_beeps_enabled = (int)true; low_health_beeps_enabled = (int)true;
} }
SoundOptionsContext() { 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) { void recomp::set_bgm_volume(int volume) {
sound_options_context.bgm_volume.store(volume); sound_options_context.bgm_volume.store(volume);
if (sound_options_model_handle) { if (sound_options_model_handle) {
@ -852,6 +865,7 @@ public:
sound_options_model_handle = constructor.GetModelHandle(); 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, "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); bind_atomic(constructor, sound_options_model_handle, "low_health_beeps_enabled", &sound_options_context.low_health_beeps_enabled);
} }