pokeemerald/src/sound.c

359 lines
7.5 KiB
C
Raw Normal View History

2017-09-02 16:03:53 +02:00
#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();
}