diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in index 194ddbbb..7b68f0c4 100644 --- a/include/text_options_strings.h.in +++ b/include/text_options_strings.h.in @@ -107,6 +107,9 @@ #define TEXT_OPT_NEAREST _("Nearest") #define TEXT_OPT_LINEAR _("Linear") #define TEXT_OPT_MVOLUME _("Master Volume") +#define TEXT_OPT_MUSIC_VOLUME _("Music Volume") +#define TEXT_OPT_SFX_VOLUME _("Sfx Volume") +#define TEXT_OPT_ENV_VOLUME _("Env Volume") #define TEXT_OPT_VSYNC _("Vertical Sync") #define TEXT_OPT_DOUBLE _("Double") #define TEXT_RESET_WINDOW _("Reset Window") diff --git a/src/audio/external.c b/src/audio/external.c index a059c0b5..b0ebbb99 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -15,6 +15,7 @@ #include "seq_ids.h" #include "dialog_ids.h" #include "level_table.h" +#include "pc/configfile.h" #ifdef VERSION_EU #define EU_FLOAT(x) x ## f @@ -2061,6 +2062,10 @@ void play_dialog_sound(u8 dialogID) { #endif } +void setSequencePlayerVolume(s32 player, s32 volume){ + func_8031D838(player, 0, volume); +} + void play_music(u8 player, u16 seqArgs, u16 fadeTimer) { u8 seqId = seqArgs & 0xff; u8 priority = seqArgs >> 8; @@ -2069,11 +2074,12 @@ void play_music(u8 player, u16 seqArgs, u16 fadeTimer) { // Except for the background music player, we don't support queued // sequences. Just play them immediately, stopping any old sequence. + if (player != 0) { play_sequence(player, seqId, fadeTimer); return; } - + // Abort if the queue is already full. if (sBackgroundMusicQueueSize == MAX_BG_MUSIC_QUEUE_SIZE) { return; diff --git a/src/audio/external.h b/src/audio/external.h index 2a8d0e6d..4d763f35 100644 --- a/src/audio/external.h +++ b/src/audio/external.h @@ -37,6 +37,7 @@ void sound_banks_disable(u8 player, u16 bankMask); void sound_banks_enable(u8 player, u16 bankMask); void func_80320A4C(u8 bankIndex, u8 arg1); void play_dialog_sound(u8 dialogID); +void setSequencePlayerVolume(s32 player, s32 volume); void play_music(u8 player, u16 seqArgs, u16 fadeTimer); void stop_background_music(u16 seqId); void fadeout_background_music(u16 arg0, u16 fadeOut); diff --git a/src/audio/seqplayer.h b/src/audio/seqplayer.h index 7d91faeb..005b5193 100644 --- a/src/audio/seqplayer.h +++ b/src/audio/seqplayer.h @@ -9,6 +9,7 @@ void sequence_channel_disable(struct SequenceChannel *seqPlayer); void sequence_player_disable(struct SequencePlayer* seqPlayer); void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item); void *audio_list_pop_back(struct AudioListItem *list); +void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume); void process_sequences(s32 iterationsRemaining); void init_sequence_player(u32 player); void init_sequence_players(void); diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 5700700d..3c084c49 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -85,7 +85,10 @@ static const u8 optsVideoStr[][32] = { }; static const u8 optsAudioStr[][32] = { - { TEXT_OPT_MVOLUME }, + { TEXT_OPT_MVOLUME }, + { TEXT_OPT_MUSIC_VOLUME }, + { TEXT_OPT_SFX_VOLUME }, + { TEXT_OPT_ENV_VOLUME }, }; static const u8 optsCheatsStr[][64] = { @@ -259,6 +262,9 @@ static struct Option optsVideo[] = { static struct Option optsAudio[] = { DEF_OPT_SCROLL( optsAudioStr[0], &configMasterVolume, 0, MAX_VOLUME, 1 ), + DEF_OPT_SCROLL( optsAudioStr[1], &configMusicVolume, 0, MAX_VOLUME, 1), + DEF_OPT_SCROLL( optsAudioStr[2], &configSfxVolume, 0, MAX_VOLUME, 1), + DEF_OPT_SCROLL( optsAudioStr[3], &configEnvVolume, 0, MAX_VOLUME, 1), }; static struct Option optsCheats[] = { diff --git a/src/pc/configfile.c b/src/pc/configfile.c index f778ab76..2a85b7a6 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -51,6 +51,9 @@ ConfigWindow configWindow = { }; unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME +unsigned int configMusicVolume = MAX_VOLUME; +unsigned int configSfxVolume = MAX_VOLUME; +unsigned int configEnvVolume = MAX_VOLUME; // Keyboard mappings (VK_ values, by default keyboard/gamepad/mouse) unsigned int configKeyA[MAX_BINDS] = { 0x0026, 0x1000, 0x1103 }; @@ -99,6 +102,9 @@ static const struct ConfigOption options[] = { {.name = "vsync", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.vsync}, {.name = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering}, {.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume}, + {.name = "music_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMusicVolume}, + {.name = "sfx_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configSfxVolume}, + {.name = "env_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configEnvVolume}, {.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA}, {.name = "key_b", .type = CONFIG_TYPE_BIND, .uintValue = configKeyB}, {.name = "key_start", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStart}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 48d65379..45025141 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -21,6 +21,9 @@ typedef struct { extern ConfigWindow configWindow; extern unsigned int configFiltering; extern unsigned int configMasterVolume; +extern unsigned int configMusicVolume; +extern unsigned int configSfxVolume; +extern unsigned int configEnvVolume; extern unsigned int configKeyA[]; extern unsigned int configKeyB[]; extern unsigned int configKeyStart[]; diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index dfc62463..1baca939 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -74,11 +74,17 @@ void send_display_list(struct SPTask *spTask) { #define printf -void produce_one_frame(void) { +void produce_one_frame(void) { + gfx_start_frame(); + + setSequencePlayerVolume(SEQ_PLAYER_LEVEL, (s32)configMusicVolume); + setSequencePlayerVolume(SEQ_PLAYER_SFX, (s32)configSfxVolume); + setSequencePlayerVolume(SEQ_PLAYER_ENV, (s32)configEnvVolume); + game_loop_one_iteration(); - thread6_rumble_loop(NULL); - + thread6_rumble_loop(NULL); + int samples_left = audio_api->buffered(); u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? 544 : 528; //printf("Audio samples: %d %u\n", samples_left, num_audio_samples); @@ -90,15 +96,15 @@ void produce_one_frame(void) { u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;*/ create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples); } - //printf("Audio samples before submitting: %d\n", audio_api->buffered()); + //printf("Audio samples before submitting: %d\n", audio_api->buffered()); // scale by master volume (0-127) const s32 mod = (s32)configMasterVolume; for (u32 i = 0; i < num_audio_samples * 4; ++i) - audio_buffer[i] = ((s32)audio_buffer[i] * mod) >> VOLUME_SHIFT; + audio_buffer[i] = ((s32)audio_buffer[i] * mod) >> VOLUME_SHIFT; audio_api->play((u8*)audio_buffer, 2 * num_audio_samples * 4); - + gfx_end_frame(); }