sound_init.c (9674B)
1 #include <ultra64.h> 2 3 #include "area.h" 4 #include "audio/external.h" 5 #include "engine/graph_node.h" 6 #include "engine/math_util.h" 7 #include "level_table.h" 8 #include "level_update.h" 9 #include "main.h" 10 #include "paintings.h" 11 #include "print.h" 12 #include "profiler.h" 13 #include "save_file.h" 14 #include "seq_ids.h" 15 #include "sm64.h" 16 #include "sound_init.h" 17 #include "rumble_init.h" 18 19 #define MUSIC_NONE 0xFFFF 20 21 static Vec3f unused80339DC0; 22 static OSMesgQueue sSoundMesgQueue; 23 static OSMesg sSoundMesgBuf[1]; 24 static struct VblankHandler sSoundVblankHandler; 25 26 // Only written to, never read. 27 static u8 sMusicVolume = 0; 28 29 static u8 sBgMusicDisabled = FALSE; 30 static u16 sCurrentMusic = MUSIC_NONE; 31 static u16 sCurrentShellMusic = MUSIC_NONE; 32 static u16 sCurrentCapMusic = MUSIC_NONE; 33 static u8 sPlayingInfiniteStairs = FALSE; 34 UNUSED static u8 unused8032C6D8[16] = { 0 }; 35 static s16 sSoundMenuModeToSoundMode[] = { SOUND_MODE_STEREO, SOUND_MODE_MONO, SOUND_MODE_HEADSET }; 36 // Only the 20th array element is used. 37 static u32 sMenuSoundsExtra[] = { 38 SOUND_MOVING_TERRAIN_SLIDE + (0 << 16), 39 SOUND_MOVING_TERRAIN_SLIDE + (1 << 16), 40 SOUND_MOVING_TERRAIN_SLIDE + (2 << 16), 41 SOUND_MOVING_TERRAIN_SLIDE + (3 << 16), 42 SOUND_MOVING_TERRAIN_SLIDE + (4 << 16), 43 SOUND_MOVING_TERRAIN_SLIDE + (5 << 16), 44 SOUND_MOVING_TERRAIN_SLIDE + (6 << 16), 45 SOUND_MOVING_LAVA_BURN, 46 SOUND_MOVING_SLIDE_DOWN_TREE, 47 SOUND_MOVING_SLIDE_DOWN_POLE, 48 SOUND_MOVING_QUICKSAND_DEATH, 49 SOUND_MOVING_TERRAIN_RIDING_SHELL, 50 NO_SOUND, 51 SOUND_ENV_BOAT_ROCKING1, 52 SOUND_ENV_ELEVATOR3, 53 SOUND_ENV_UNKNOWN2, 54 SOUND_ENV_WATERFALL1, 55 SOUND_ENV_WATERFALL2, 56 SOUND_ENV_ELEVATOR1, 57 SOUND_ENV_DRONING1, 58 SOUND_ENV_DRONING2, 59 SOUND_ENV_ELEVATOR2, 60 SOUND_ENV_WIND1, 61 SOUND_ENV_WATER, 62 SOUND_AIR_BOWSER_SPIT_FIRE, 63 SOUND_MOVING_AIM_CANNON, 64 SOUND_AIR_LAKITU_FLY, 65 SOUND_AIR_AMP_BUZZ, 66 SOUND_AIR_CASTLE_OUTDOORS_AMBIENT, 67 SOUND_OBJ2_BIRD_CHIRP1, 68 SOUND_GENERAL2_BIRD_CHIRP2, 69 SOUND_OBJ_BIRD_CHIRP3, 70 SOUND_ENV_ELEVATOR2, 71 SOUND_AIR_BLOW_WIND, 72 SOUND_AIR_BLOW_FIRE, 73 SOUND_ENV_ELEVATOR4, 74 }; 75 static s8 sPaintingEjectSoundPlayed = FALSE; 76 77 void play_menu_sounds_extra(s32 a, void *b); 78 79 /** 80 * Called from threads: thread5_game_loop 81 */ 82 void reset_volume(void) { 83 sMusicVolume = 0; 84 } 85 86 /** 87 * Called from threads: thread5_game_loop 88 */ 89 void lower_background_noise(s32 a) { 90 switch (a) { 91 case 1: 92 set_audio_muted(TRUE); 93 break; 94 case 2: 95 seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); 96 break; 97 } 98 sMusicVolume |= a; 99 } 100 101 /** 102 * Called from threads: thread5_game_loop 103 */ 104 void raise_background_noise(s32 a) { 105 switch (a) { 106 case 1: 107 set_audio_muted(FALSE); 108 break; 109 case 2: 110 seq_player_unlower_volume(SEQ_PLAYER_LEVEL, 60); 111 break; 112 } 113 sMusicVolume &= ~a; 114 } 115 116 /** 117 * Called from threads: thread5_game_loop 118 */ 119 void disable_background_sound(void) { 120 if (sBgMusicDisabled == FALSE) { 121 sBgMusicDisabled = TRUE; 122 sound_banks_disable(SEQ_PLAYER_SFX, SOUND_BANKS_BACKGROUND); 123 } 124 } 125 126 /** 127 * Called from threads: thread5_game_loop 128 */ 129 void enable_background_sound(void) { 130 if (sBgMusicDisabled == TRUE) { 131 sBgMusicDisabled = FALSE; 132 sound_banks_enable(SEQ_PLAYER_SFX, SOUND_BANKS_BACKGROUND); 133 } 134 } 135 136 /** 137 * Sets the sound mode 138 * 139 * Called from threads: thread5_game_loop 140 */ 141 void set_sound_mode(u16 soundMode) { 142 if (soundMode < 3) { 143 audio_set_sound_mode(sSoundMenuModeToSoundMode[soundMode]); 144 } 145 } 146 147 /** 148 * Wrapper method by menu used to set the sound via flags. 149 * 150 * Called from threads: thread5_game_loop 151 */ 152 void play_menu_sounds(s16 soundMenuFlags) { 153 if (soundMenuFlags & SOUND_MENU_FLAG_HANDAPPEAR) { 154 play_sound(SOUND_MENU_HAND_APPEAR, gGlobalSoundSource); 155 } else if (soundMenuFlags & SOUND_MENU_FLAG_HANDISAPPEAR) { 156 play_sound(SOUND_MENU_HAND_DISAPPEAR, gGlobalSoundSource); 157 } else if (soundMenuFlags & SOUND_MENU_FLAG_UNKNOWN1) { 158 play_sound(SOUND_MENU_UNK0C, gGlobalSoundSource); 159 } else if (soundMenuFlags & SOUND_MENU_FLAG_PINCHMARIOFACE) { 160 play_sound(SOUND_MENU_PINCH_MARIO_FACE, gGlobalSoundSource); 161 } else if (soundMenuFlags & SOUND_MENU_FLAG_PINCHMARIOFACE2) { 162 play_sound(SOUND_MENU_PINCH_MARIO_FACE, gGlobalSoundSource); 163 } else if (soundMenuFlags & SOUND_MENU_FLAG_LETGOMARIOFACE) { 164 play_sound(SOUND_MENU_LET_GO_MARIO_FACE, gGlobalSoundSource); 165 } else if (soundMenuFlags & SOUND_MENU_FLAG_CAMERAZOOMIN) { 166 play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); 167 } else if (soundMenuFlags & SOUND_MENU_FLAG_CAMERAZOOMOUT) { 168 play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gGlobalSoundSource); 169 } 170 171 if (soundMenuFlags & 0x100) { 172 play_menu_sounds_extra(20, NULL); 173 } 174 #if ENABLE_RUMBLE 175 if (soundMenuFlags & SOUND_MENU_FLAG_LETGOMARIOFACE) { 176 queue_rumble_data(10, 60); 177 } 178 #endif 179 } 180 181 /** 182 * Plays the painting eject sound effect if it has not already been played 183 * 184 * Called from threads: thread5_game_loop 185 */ 186 void play_painting_eject_sound(void) { 187 if (gRipplingPainting != NULL && gRipplingPainting->state == PAINTING_ENTERED) { 188 // ripple when Mario enters painting 189 if (!sPaintingEjectSoundPlayed) { 190 play_sound(SOUND_GENERAL_PAINTING_EJECT, 191 gMarioStates[0].marioObj->header.gfx.cameraToObject); 192 } 193 sPaintingEjectSoundPlayed = TRUE; 194 } else { 195 sPaintingEjectSoundPlayed = FALSE; 196 } 197 } 198 199 /** 200 * Called from threads: thread5_game_loop 201 */ 202 void play_infinite_stairs_music(void) { 203 u8 shouldPlay = FALSE; 204 205 /* Infinite stairs? */ 206 if (gCurrLevelNum == LEVEL_CASTLE && gCurrAreaIndex == 2 && gMarioState->numStars < 70) { 207 if (gMarioState->floor != NULL && gMarioState->floor->room == 6) { 208 if (gMarioState->pos[2] < 2540.0f) { 209 shouldPlay = TRUE; 210 } 211 } 212 } 213 214 if (sPlayingInfiniteStairs ^ shouldPlay) { 215 sPlayingInfiniteStairs = shouldPlay; 216 if (shouldPlay) { 217 play_secondary_music(SEQ_EVENT_ENDLESS_STAIRS, 0, 255, 1000); 218 } else { 219 func_80321080(500); 220 } 221 } 222 } 223 224 /** 225 * Called from threads: thread5_game_loop 226 */ 227 void set_background_music(u16 a, u16 seqArgs, s16 fadeTimer) { 228 if (gResetTimer == 0 && seqArgs != sCurrentMusic) { 229 if (gCurrCreditsEntry != NULL) { 230 sound_reset(7); 231 } else { 232 sound_reset(a); 233 } 234 235 if (!gNeverEnteredCastle || seqArgs != SEQ_LEVEL_INSIDE_CASTLE) { 236 play_music(SEQ_PLAYER_LEVEL, seqArgs, fadeTimer); 237 sCurrentMusic = seqArgs; 238 } 239 } 240 } 241 242 /** 243 * Called from threads: thread3_main, thread5_game_loop 244 */ 245 void fadeout_music(s16 fadeOutTime) { 246 func_803210D4(fadeOutTime); 247 sCurrentMusic = MUSIC_NONE; 248 sCurrentShellMusic = MUSIC_NONE; 249 sCurrentCapMusic = MUSIC_NONE; 250 } 251 252 /** 253 * Called from threads: thread5_game_loop 254 */ 255 void fadeout_level_music(s16 fadeTimer) { 256 seq_player_fade_out(SEQ_PLAYER_LEVEL, fadeTimer); 257 sCurrentMusic = MUSIC_NONE; 258 sCurrentShellMusic = MUSIC_NONE; 259 sCurrentCapMusic = MUSIC_NONE; 260 } 261 262 /** 263 * Called from threads: thread5_game_loop 264 */ 265 void play_cutscene_music(u16 seqArgs) { 266 play_music(SEQ_PLAYER_LEVEL, seqArgs, 0); 267 sCurrentMusic = seqArgs; 268 } 269 270 /** 271 * Called from threads: thread5_game_loop 272 */ 273 void play_shell_music(void) { 274 play_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP | SEQ_VARIATION), 0); 275 sCurrentShellMusic = SEQUENCE_ARGS(4, SEQ_EVENT_POWERUP | SEQ_VARIATION); 276 } 277 278 /** 279 * Called from threads: thread5_game_loop 280 */ 281 void stop_shell_music(void) { 282 if (sCurrentShellMusic != MUSIC_NONE) { 283 stop_background_music(sCurrentShellMusic); 284 sCurrentShellMusic = MUSIC_NONE; 285 } 286 } 287 288 /** 289 * Called from threads: thread5_game_loop 290 */ 291 void play_cap_music(u16 seqArgs) { 292 play_music(SEQ_PLAYER_LEVEL, seqArgs, 0); 293 if (sCurrentCapMusic != MUSIC_NONE && sCurrentCapMusic != seqArgs) { 294 stop_background_music(sCurrentCapMusic); 295 } 296 sCurrentCapMusic = seqArgs; 297 } 298 299 /** 300 * Called from threads: thread5_game_loop 301 */ 302 void fadeout_cap_music(void) { 303 if (sCurrentCapMusic != MUSIC_NONE) { 304 fadeout_background_music(sCurrentCapMusic, 600); 305 } 306 } 307 308 /** 309 * Called from threads: thread5_game_loop 310 */ 311 void stop_cap_music(void) { 312 if (sCurrentCapMusic != MUSIC_NONE) { 313 stop_background_music(sCurrentCapMusic); 314 sCurrentCapMusic = MUSIC_NONE; 315 } 316 } 317 318 /** 319 * Called from threads: thread5_game_loop 320 */ 321 void play_menu_sounds_extra(s32 a, void *b) { 322 play_sound(sMenuSoundsExtra[a], b); 323 } 324 325 /** 326 * Called from threads: thread5_game_loop 327 */ 328 void audio_game_loop_tick(void) { 329 audio_signal_game_loop_tick(); 330 } 331 332 /** 333 * Sound processing thread. Runs at 60 FPS. 334 */ 335 void thread4_sound(UNUSED void *arg) { 336 audio_init(); 337 sound_init(); 338 339 // Zero-out unused vector 340 vec3f_copy(unused80339DC0, gVec3fZero); 341 342 osCreateMesgQueue(&sSoundMesgQueue, sSoundMesgBuf, ARRAY_COUNT(sSoundMesgBuf)); 343 set_vblank_handler(1, &sSoundVblankHandler, &sSoundMesgQueue, (OSMesg) 512); 344 345 while (TRUE) { 346 OSMesg msg; 347 348 osRecvMesg(&sSoundMesgQueue, &msg, OS_MESG_BLOCK); 349 if (gResetTimer < 25) { 350 struct SPTask *spTask; 351 profiler_log_thread4_time(); 352 spTask = create_next_audio_frame_task(); 353 if (spTask != NULL) { 354 dispatch_audio_sptask(spTask); 355 } 356 profiler_log_thread4_time(); 357 } 358 } 359 }