30#define AUDIO_PARAM_REQ_DEFAULT { .target = 0, .stride = 0 }
31#define AUDIO_PARAM_DEFINE(init_val) { .current = init_val, .req = AUDIO_PARAM_REQ_DEFAULT }
41static const u32 DEFAULT_PITCH = 0x400;
42static const u32 DEFAULT_TEMPO = 0x400;
44static const u32 MUSIC_CHANGE_FRAMES = 75;
45static const u32 VOLUME_CHANGE_FRAMES = MUSIC_CHANGE_FRAMES / 3;
47static void set_audio_param_req(
AudioParam* param, s32 target, s32 steps);
48static void speed_change_update(
void);
51 .pitch = AUDIO_PARAM_DEFINE(DEFAULT_PITCH),
52 .tempo = AUDIO_PARAM_DEFINE(DEFAULT_TEMPO),
53 .volume = AUDIO_PARAM_DEFINE(DEFAULT_VOLUME),
57 STATE_INFO_UPDATE_FN_ONLY(speed_change_update),
60static StateMachine song_speed_sm = STATE_MACHINE_DEFINE(state_info, 1);
62static void set_audio_param_req(
AudioParam* param, s32 target, s32 steps)
64 int offset = target - param->current;
68 param->req.stride = offset / steps;
69 param->req.stride = !param->req.stride ?
SIGN(offset) : param->req.stride;
70 param->req.target = target;
80 if (abs(param->current - param->req.target) <= abs(param->req.stride))
82 param->current = param->req.target;
85 param->current += param->req.stride;
89static void speed_change_update(
void)
95 mmSetModuleTempo(music_player.tempo.current);
96 mmSetModulePitch(music_player.pitch.current);
97 set_volume(music_player.volume.current);
99 if (tempo_reached && pitch_reached && volume_reached)
103void play_sfx(mm_word
id, mm_word rate, mm_byte volume)
105 int adj_volume = volume * g_game_vars.sound_volume / VOLUME_OPTION_MAX;
106 mm_sound_effect sfx = {
118 const u32 slow_music_speed = 0x200;
120 u32 vol = g_game_vars.music_volume;
124 vol = (vol == 1) ? 1 : vol / 2;
127 set_audio_param_req(&music_player.pitch, slow_music_speed, MUSIC_CHANGE_FRAMES);
128 set_audio_param_req(&music_player.tempo, slow_music_speed, MUSIC_CHANGE_FRAMES);
129 set_audio_param_req(&music_player.volume, target_vol, VOLUME_CHANGE_FRAMES);
138 set_audio_param_req(&music_player.pitch, DEFAULT_PITCH, MUSIC_CHANGE_FRAMES);
139 set_audio_param_req(&music_player.tempo, DEFAULT_TEMPO, MUSIC_CHANGE_FRAMES);
140 set_audio_param_req(&music_player.volume, target_vol, VOLUME_CHANGE_FRAMES);
146void set_volume(
int volume)
148 music_player.volume.current = volume;
149 mmSetModuleVolume(volume);
void play_regular_music(void)
Play music at a normal pitch and tempo.
void play_lose_music(void)
Play music at a low pitch and slow tempo (lose screen)
void play_sfx(mm_word id, mm_word rate, mm_byte volume)
Play a sound effect, wrapper for mmEffectEx() See https://maxmod.org/ref/functions/mm_sound_effect....
static bool audio_param_update(AudioParam *param)
Update the AudioParam for the music transition state machine for audio transitions.
Utilities for using maxmod to play sound effects.
#define MM_MODULE_FULL_VOLUME
The maximum volume for maxmod module volume (main theme)
int volume_module_step_to_val(unsigned char step)
Get MaxMod module audio value from VOLUME_OPTION value.
#define SFX_DEFAULT_PAN
The default stereo pan, will always be center pan.
Game global game variables struct definition.
Interface to interact with the mgba logger.
void state_machine_remove(StateMachine *state_machine)
Remove a statemachine's update function.
void state_machine_register(StateMachine *state_machine)
Register a statemachine to run it's update function once per frame.
void state_machine_change_state(StateMachine *state_machine, int new_state)
Calls the current state's on_exit, the new state's on_init, and sets the active update fn.
Utilities relating around number string representation and protected arithmatic helper functions.
#define SIGN(x)
Get the sign (signum) of an integer.