From c6c0428b39a37fba1e847a5a9e6ecd3c6e517227 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Thu, 18 Dec 2025 02:39:11 -0500 Subject: [PATCH] Implement bgm volume control and remove zelda low health beeps option --- assets/config_menu/sound.rml | 34 +-------- patches/sound_patches.c | 130 +++++++++++++++++++++++++++++++++++ patches/syms.ld | 1 + src/ui/ui_config.cpp | 3 - 4 files changed, 132 insertions(+), 36 deletions(-) create mode 100644 patches/sound_patches.c diff --git a/assets/config_menu/sound.rml b/assets/config_menu/sound.rml index badadce..c176f9f 100644 --- a/assets/config_menu/sound.rml +++ b/assets/config_menu/sound.rml @@ -35,40 +35,11 @@ type="range" min="0" max="100" - style="flex: 1; margin: 0dp; nav-up: #main_volume_input; nav-down: #lhb_on;" + style="flex: 1; margin: 0dp; nav-up: #main_volume_input;" data-value="bgm_volume" /> - -
- -
- - - - - -
-
@@ -78,9 +49,6 @@

Controls the overall volume of background music.

-

- Toggles whether or not the low-health beeping sound plays. -

diff --git a/patches/sound_patches.c b/patches/sound_patches.c new file mode 100644 index 0000000..bd40793 --- /dev/null +++ b/patches/sound_patches.c @@ -0,0 +1,130 @@ +#include "patches.h" +#include "music.h" +#include "time.h" +#include "core1/ml.h" +#include "../lib/bk-decomp/src/core1/musicplayer.h" +#include "sound.h" + +extern MusicTrack D_80281720[6]; +extern CoMusic *musicTracks; +extern int D_80276E34; + +void func_8024FCE0(u8 arg0, s16 arg1); +bool func_80250074(u8); +void func_8024FC6C(u8 arg0); +void func_8025A7DC(enum comusic_e); +void func_8024FF34(void); +void func_802599B4(CoMusic *this); + +// @recomp Patched to incorporate the bgm player volume in the setvol command for music tracks. +RECOMP_PATCH void musicTrack_setVolume(u8 arg0, s16 arg1) { + D_80281720[arg0].unk0 = arg1; + alCSPSetVol(&D_80281720[arg0].cseqp, (s16)(arg1 * recomp_get_bgm_volume())); + + if (D_80281720[arg0].unk3 && arg1) { + func_8024FCE0(arg0, arg1); + } else if (!D_80281720[arg0].unk3 && arg1 == 0) { + if (func_80250074(arg0) == 0) { + func_8024FC6C(arg0); + } + } +} + +// @recomp Patched to always set the volume of every music track in each update loop. +RECOMP_PATCH void coMusicPlayer_update(void) { + s32 temp_lo; + CoMusic *var_s0; + f32 dt; + + dt = time_getDelta(); + + for (var_s0 = musicTracks; var_s0 < &musicTracks[MAX_MUSIC_STRUCT_COUNT]; var_s0++) { + if (var_s0->track_id >= 0) { + temp_lo = var_s0 - musicTracks; + var_s0->unk4 = ml_min_f(var_s0->unk4 + dt, 600.0f); + + if ((var_s0->unk4 > 1.0f) && func_80250074(temp_lo)) { + func_8025A7DC(var_s0->track_id); + } + } + } + + func_8024FF34(); + + if (!D_80276E34) { + // @recomp If there are no pending track updates, send a volume command for each track to incorporate the BGM volume. + for (var_s0 = musicTracks; var_s0 < &musicTracks[6]; var_s0++) { + temp_lo = var_s0 - musicTracks; + alCSPSetVol(&D_80281720[temp_lo].cseqp, (s16)(var_s0->volume * recomp_get_bgm_volume())); + } + return; + } + + D_80276E34 = FALSE; + + for (var_s0 = musicTracks; var_s0 < &musicTracks[6]; var_s0++) { + if (var_s0->track_id < 0) { + continue; + } + + if (var_s0->unk12 != 0) { + temp_lo = var_s0 - musicTracks; + + if (var_s0->unk0 > 0.0f) { + var_s0->unk0 -= time_getDelta(); + D_80276E34 = TRUE; + + // @recomp Send a volume command to incorporate the current BGM volume if the track's volume wasn't changed. + alCSPSetVol(&D_80281720[temp_lo].cseqp, (s16)(var_s0->volume * recomp_get_bgm_volume())); + + continue; + } + + if (var_s0->unk12 < 0) { + var_s0->volume += var_s0->unk12; + + if (var_s0->unk15 && (var_s0->unkC == 0) && (var_s0->volume <= 0)) { + func_802599B4(var_s0); + continue; + } else { + if (var_s0->unkC >= var_s0->volume) { + var_s0->volume = var_s0->unkC; + var_s0->unk12 = 0; + } else { + D_80276E34 = TRUE; + } + musicTrack_setVolume(temp_lo, (s16)var_s0->volume); + } + + continue; + } + + if (var_s0->volume < var_s0->unkC) { + if (var_s0->volume == 0) { + var_s0->unk4 = 0.0f; + } + var_s0->volume += var_s0->unk12; + if (var_s0->volume >= var_s0->unkC) { + var_s0->volume = var_s0->unkC; + var_s0->unk12 = 0; + } else { + D_80276E34 = TRUE; + } + musicTrack_setVolume(temp_lo, (s16)var_s0->volume); + + continue; + } + + // @recomp Send a volume command to incorporate the current BGM volume if the track's volume wasn't changed. + alCSPSetVol(&D_80281720[temp_lo].cseqp, (s16)(var_s0->volume * recomp_get_bgm_volume())); + + var_s0->unk12 = 0; + } + // @recomp Always set the volume of every music track in each update loop. + else { + temp_lo = var_s0 - musicTracks; + // @recomp Send a volume command to incorporate the current BGM volume if the track's volume wasn't changed. + alCSPSetVol(&D_80281720[temp_lo].cseqp, (s16)(var_s0->volume * recomp_get_bgm_volume())); + } + } +} diff --git a/patches/syms.ld b/patches/syms.ld index cee7e96..13550c1 100644 --- a/patches/syms.ld +++ b/patches/syms.ld @@ -37,3 +37,4 @@ recomp_abort = 0x8F000080; recomp_get_target_aspect_ratio = 0x8F000084; osExQueueDisplaylistEvent_recomp = 0x8F000088; recomp_xxh3 = 0x8F00008C; +recomp_get_bgm_volume = 0x8F000090; diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp index 0dbba71..8f9ec08 100644 --- a/src/ui/ui_config.cpp +++ b/src/ui/ui_config.cpp @@ -339,11 +339,9 @@ void banjo::set_analog_camera_invert_mode(banjo::CameraInvertMode 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() { reset(); @@ -848,7 +846,6 @@ public: 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); } void make_debug_bindings(Rml::Context* context) {