#include "global.h" #include "gba/m4a_internal.h" #include "sound.h" #include "battle.h" #include "m4a.h" #include "main.h" #include "pokemon.h" #include "songs.h" #include "task.h" struct Fanfare { u16 songNum; u16 duration; }; extern u32 gBattleTypeFlags; extern struct MusicPlayerInfo *gMPlay_PokemonCry; extern u8 gPokemonCryBGMDuckingCounter; extern u16 sCurrentMapMusic; extern u16 sNextMapMusic; extern u8 sMapMusicState; extern u8 sMapMusicFadeInSpeed; extern u16 sFanfareCounter; extern bool8 gDisableMusic; extern struct MusicPlayerInfo gMPlay_BGM; extern struct MusicPlayerInfo gMPlay_SE1; extern struct MusicPlayerInfo gMPlay_SE2; extern struct MusicPlayerInfo gMPlay_SE3; extern struct ToneData voicegroup_8452590[]; extern struct ToneData voicegroup_8452B90[]; extern struct ToneData voicegroup_8453190[]; extern struct ToneData voicegroup_8453790[]; extern struct ToneData voicegroup_84537C0[]; extern struct ToneData voicegroup_8453DC0[]; extern struct ToneData voicegroup_84543C0[]; extern struct ToneData voicegroup_84549C0[]; extern const struct Fanfare sFanfares[]; static void Task_Fanfare(u8 taskId); static void CreateFanfareTask(void); void PlayCryInternal(u16 species, s8 pan, s8 volume, u8 priority, u8 mode); static void Task_DuckBGMForPokemonCry(u8 taskId); void RestoreBGMVolumeAfterPokemonCry(void); #define CRY_VOLUME 120 // was 125 in R/S void InitMapMusic(void) { gDisableMusic = FALSE; ResetMapMusic(); } void MapMusicMain(void) { switch (sMapMusicState) { case 0: break; case 1: sMapMusicState = 2; PlayBGM(sCurrentMapMusic); break; case 2: case 3: case 4: break; case 5: if (IsBGMStopped()) { sNextMapMusic = 0; sMapMusicState = 0; } break; case 6: if (IsBGMStopped() && IsFanfareTaskInactive()) { sCurrentMapMusic = sNextMapMusic; sNextMapMusic = 0; sMapMusicState = 2; PlayBGM(sCurrentMapMusic); } break; case 7: if (IsBGMStopped() && IsFanfareTaskInactive()) { FadeInNewBGM(sNextMapMusic, sMapMusicFadeInSpeed); sCurrentMapMusic = sNextMapMusic; sNextMapMusic = 0; sMapMusicState = 2; sMapMusicFadeInSpeed = 0; } break; } } void ResetMapMusic(void) { sCurrentMapMusic = 0; sNextMapMusic = 0; sMapMusicState = 0; sMapMusicFadeInSpeed = 0; } u16 GetCurrentMapMusic(void) { return sCurrentMapMusic; } void PlayNewMapMusic(u16 songNum) { sCurrentMapMusic = songNum; sNextMapMusic = 0; sMapMusicState = 1; } void StopMapMusic(void) { sCurrentMapMusic = 0; sNextMapMusic = 0; sMapMusicState = 1; } void FadeOutMapMusic(u8 speed) { if (IsNotWaitingForBGMStop()) FadeOutBGM(speed); sCurrentMapMusic = 0; sNextMapMusic = 0; sMapMusicState = 5; } void FadeOutAndPlayNewMapMusic(u16 songNum, u8 speed) { FadeOutMapMusic(speed); sCurrentMapMusic = 0; sNextMapMusic = songNum; sMapMusicState = 6; } void FadeOutAndFadeInNewMapMusic(u16 songNum, u8 fadeOutSpeed, u8 fadeInSpeed) { FadeOutMapMusic(fadeOutSpeed); sCurrentMapMusic = 0; sNextMapMusic = songNum; sMapMusicState = 7; sMapMusicFadeInSpeed = fadeInSpeed; } void FadeInNewMapMusic(u16 songNum, u8 speed) { FadeInNewBGM(songNum, speed); sCurrentMapMusic = songNum; sNextMapMusic = 0; sMapMusicState = 2; sMapMusicFadeInSpeed = 0; } bool8 IsNotWaitingForBGMStop(void) { if (sMapMusicState == 6) return FALSE; if (sMapMusicState == 5) return FALSE; if (sMapMusicState == 7) return FALSE; return TRUE; } void PlayFanfareByFanfareNum(u8 fanfareNum) { u16 songNum; m4aMPlayStop(&gMPlay_BGM); songNum = sFanfares[fanfareNum].songNum; sFanfareCounter = sFanfares[fanfareNum].duration; m4aSongNumStart(songNum); } bool8 WaitFanfare(bool8 stop) { if (sFanfareCounter) { sFanfareCounter--; return FALSE; } else { if (!stop) m4aMPlayContinue(&gMPlay_BGM); else m4aSongNumStart(SE_STOP); return TRUE; } } void StopFanfareByFanfareNum(u8 fanfareNum) { m4aSongNumStop(sFanfares[fanfareNum].songNum); } void PlayFanfare(u16 songNum) { s32 i; for (i = 0; (u32)i < 18; i++) { if (sFanfares[i].songNum == songNum) { PlayFanfareByFanfareNum(i); CreateFanfareTask(); return; } } PlayFanfareByFanfareNum(0); CreateFanfareTask(); } bool8 IsFanfareTaskInactive(void) { if (FuncIsActiveTask(Task_Fanfare) == TRUE) return FALSE; return TRUE; } static void Task_Fanfare(u8 taskId) { if (sFanfareCounter) { sFanfareCounter--; } else { m4aMPlayContinue(&gMPlay_BGM); DestroyTask(taskId); } } static void CreateFanfareTask(void) { if (FuncIsActiveTask(Task_Fanfare) != TRUE) CreateTask(Task_Fanfare, 80); } void FadeInNewBGM(u16 songNum, u8 speed) { if (gDisableMusic) songNum = 0; if (songNum == 0xFFFF) songNum = 0; m4aSongNumStart(songNum); m4aMPlayImmInit(&gMPlay_BGM); m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0); m4aSongNumStop(songNum); m4aMPlayFadeIn(&gMPlay_BGM, speed); } void FadeOutBGMTemporarily(u8 speed) { m4aMPlayFadeOutTemporarily(&gMPlay_BGM, speed); } bool8 IsBGMPausedOrStopped(void) { if (gMPlay_BGM.status & MUSICPLAYER_STATUS_PAUSE) return TRUE; if (!(gMPlay_BGM.status & MUSICPLAYER_STATUS_TRACK)) return TRUE; return FALSE; } void FadeInBGM(u8 speed) { m4aMPlayFadeIn(&gMPlay_BGM, speed); } void FadeOutBGM(u8 speed) { m4aMPlayFadeOut(&gMPlay_BGM, speed); } bool8 IsBGMStopped(void) { if (!(gMPlay_BGM.status & MUSICPLAYER_STATUS_TRACK)) return TRUE; return FALSE; } void PlayCry1(u16 species, s8 pan) { m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85); PlayCryInternal(species, pan, CRY_VOLUME, 10, 0); gPokemonCryBGMDuckingCounter = 2; RestoreBGMVolumeAfterPokemonCry(); } void PlayCry2(u16 species, s8 pan, s8 volume, u8 priority) { PlayCryInternal(species, pan, volume, priority, 0); } void PlayCry3(u16 species, s8 pan, u8 mode) { if (mode == 1) { PlayCryInternal(species, pan, CRY_VOLUME, 10, 1); } else { m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85); PlayCryInternal(species, pan, CRY_VOLUME, 10, mode); gPokemonCryBGMDuckingCounter = 2; RestoreBGMVolumeAfterPokemonCry(); } } void PlayCry4(u16 species, s8 pan, u8 mode) { if (mode == 1) { PlayCryInternal(species, pan, CRY_VOLUME, 10, 1); } else { if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85); PlayCryInternal(species, pan, CRY_VOLUME, 10, mode); } } void PlayCry6(u16 species, s8 pan, u8 mode) // not present in R/S { if (mode == 1) { PlayCryInternal(species, pan, CRY_VOLUME, 10, 1); } else { m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85); PlayCryInternal(species, pan, CRY_VOLUME, 10, mode); gPokemonCryBGMDuckingCounter = 2; } } void PlayCry5(u16 species, u8 mode) { m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 85); PlayCryInternal(species, 0, CRY_VOLUME, 10, mode); gPokemonCryBGMDuckingCounter = 2; RestoreBGMVolumeAfterPokemonCry(); }