diff --git a/include/text_strings.h.in b/include/text_strings.h.in index ee4508b7..a577a161 100644 --- a/include/text_strings.h.in +++ b/include/text_strings.h.in @@ -17,6 +17,7 @@ #define TEXT_OPT_CAMERA _("CAMERA") #define TEXT_OPT_CONTROLS _("CONTROLS") #define TEXT_OPT_VIDEO _("DISPLAY") +#define TEXT_OPT_AUDIO _("SOUND") #define TEXT_OPT_HIGHLIGHT _("O") #define TEXT_OPT_ANALOGUE _("Analogue Camera") #define TEXT_OPT_MOUSE _("Mouse Look") @@ -24,6 +25,7 @@ #define TEXT_OPT_FSCREEN _("Fullscreen") #define TEXT_OPT_NEAREST _("Nearest") #define TEXT_OPT_LINEAR _("Linear") +#define TEXT_OPT_MVOLUME _("Master Volume") #define TEXT_OPT_UNBOUND _("NONE") #define TEXT_OPT_PRESSKEY _("...") diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 4184dbab..c9feeb39 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -44,6 +44,7 @@ static const u8 menuStr[][32] = { { TEXT_OPT_CAMERA }, { TEXT_OPT_CONTROLS }, { TEXT_OPT_VIDEO }, + { TEXT_OPT_AUDIO }, { TEXT_EXIT_GAME }, }; @@ -65,6 +66,10 @@ static const u8 optsVideoStr[][32] = { { TEXT_OPT_LINEAR }, }; +static const u8 optsAudioStr[][32] = { + { TEXT_OPT_MVOLUME }, +}; + static const u8 bindStr[][32] = { { TEXT_OPT_UNBOUND }, { TEXT_OPT_PRESSKEY }, @@ -190,11 +195,16 @@ static struct Option optsVideo[] = { DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ), }; +static struct Option optsAudio[] = { + DEF_OPT_SCROLL( optsAudioStr[0], &configMasterVolume, 0, MAX_VOLUME, 1 ), +}; + /* submenu definitions */ -static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[4], optsCamera ); +static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[4], optsCamera ); static struct SubMenu menuControls = DEF_SUBMENU( menuStr[5], optsControls ); -static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo ); +static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo ); +static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[7], optsAudio ); /* main options menu definition */ @@ -202,7 +212,8 @@ static struct Option optsMain[] = { DEF_OPT_SUBMENU( menuStr[4], &menuCamera ), DEF_OPT_SUBMENU( menuStr[5], &menuControls ), DEF_OPT_SUBMENU( menuStr[6], &menuVideo ), - DEF_OPT_BUTTON ( menuStr[7], optmenu_act_exit ), + DEF_OPT_SUBMENU( menuStr[7], &menuAudio ), + DEF_OPT_BUTTON ( menuStr[8], optmenu_act_exit ), }; static struct SubMenu menuMain = DEF_SUBMENU( menuStr[3], optsMain ); @@ -308,7 +319,7 @@ static void optmenu_opt_change(struct Option *opt, s32 val) { break; case OPT_SCROLL: - *opt->uval = wrap_add(*opt->uval, val, opt->scrMin, opt->scrMax); + *opt->uval = wrap_add(*opt->uval, opt->scrStep * val, opt->scrMin, opt->scrMax); break; case OPT_SUBMENU: diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 67308815..df05b1d5 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -32,8 +32,11 @@ struct ConfigOption { *Config options and default values */ -bool configFullscreen = false; -unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point +// Video/audio stuff +bool configFullscreen = false; +unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point +unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME + // Keyboard mappings (VK_ values, by default keyboard/gamepad/mouse) unsigned int configKeyA[MAX_BINDS] = { 0x0026, 0x1000, 0x1103 }; unsigned int configKeyB[MAX_BINDS] = { 0x0033, 0x1002, 0x1101 }; @@ -66,6 +69,7 @@ unsigned int configSkipIntro = 0; static const struct ConfigOption options[] = { {.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen}, {.name = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering}, + {.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume}, {.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 de277fba..39a020e8 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -4,10 +4,14 @@ #include #define CONFIG_FILE "sm64config.txt" -#define MAX_BINDS 3 + +#define MAX_BINDS 3 +#define MAX_VOLUME 127 +#define VOLUME_SHIFT 7 extern bool configFullscreen; extern unsigned int configFiltering; +extern unsigned int configMasterVolume; 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 ca7adf51..52d8339b 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -73,7 +73,13 @@ void produce_one_frame(void) { create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples); } //printf("Audio samples before submitting: %d\n", audio_api->buffered()); - audio_api->play(audio_buffer, 2 * num_audio_samples * 4); + + // 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_api->play((u8*)audio_buffer, 2 * num_audio_samples * 4); gfx_end_frame(); }