summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcus Huderle <huderlem@gmail.com>2018-10-05 23:21:03 -0500
committerGitHub <noreply@github.com>2018-10-05 23:21:03 -0500
commit2cb551cf0df29e2602d6a80c16f8bac0a136b134 (patch)
treeed6f6f0faa3a88b86d1332a70ee8b1a64778cd25 /src
parent0659d53c27fcb85b70c6f5a5065967fdc3da115d (diff)
parent4fafb81b2f2e04e910ac05eaee038ff12889d846 (diff)
Merge pull request #13 from ProjectRevoTPP/sound
decompile sound.c
Diffstat (limited to 'src')
-rw-r--r--src/m4a_2.c8
-rw-r--r--src/sound.c628
-rw-r--r--src/text.c8
3 files changed, 636 insertions, 8 deletions
diff --git a/src/m4a_2.c b/src/m4a_2.c
index 2d3c65848..0625f05d1 100644
--- a/src/m4a_2.c
+++ b/src/m4a_2.c
@@ -11,10 +11,10 @@ void *gMPlayJumpTable[36];
struct CgbChannel gCgbChans[4];
struct MusicPlayerTrack gPokemonCryTracks[MAX_POKEMON_CRIES * 2];
struct PokemonCrySong gPokemonCrySong;
-struct MusicPlayerInfo gMPlay_BGM;
-struct MusicPlayerInfo gMPlay_SE1;
-struct MusicPlayerInfo gMPlay_SE2;
-struct MusicPlayerInfo gMPlay_SE3;
+struct MusicPlayerInfo gMPlayInfo_BGM;
+struct MusicPlayerInfo gMPlayInfo_SE1;
+struct MusicPlayerInfo gMPlayInfo_SE2;
+struct MusicPlayerInfo gMPlayInfo_SE3;
u8 gMPlayMemAccArea[0x10];
u32 MidiKeyToFreq(struct WaveData *wav, u8 key, u8 fineAdjust)
diff --git a/src/sound.c b/src/sound.c
new file mode 100644
index 000000000..b8814de81
--- /dev/null
+++ b/src/sound.c
@@ -0,0 +1,628 @@
+#include "global.h"
+#include "gba/m4a_internal.h"
+#include "sound.h"
+#include "battle.h"
+#include "m4a.h"
+#include "main.h"
+#include "pokemon.h"
+#include "constants/songs.h"
+#include "task.h"
+
+struct Fanfare
+{
+ u16 songNum;
+ u16 duration;
+};
+
+// TODO: what are these
+extern u8 gUnknown_2031DD8;
+extern u8 gUnknown_203ADFA;
+extern u8 gUnknown_203F174;
+
+// ewram
+EWRAM_DATA struct MusicPlayerInfo* gMPlay_PokemonCry = NULL;
+EWRAM_DATA u8 gPokemonCryBGMDuckingCounter = 0;
+
+// iwram bss
+IWRAM_DATA static u16 sCurrentMapMusic;
+IWRAM_DATA static u16 sNextMapMusic;
+IWRAM_DATA static u8 sMapMusicState;
+IWRAM_DATA static u8 sMapMusicFadeInSpeed;
+IWRAM_DATA static u16 sFanfareCounter;
+
+// iwram common
+bool8 gDisableMusic;
+
+extern u32 gBattleTypeFlags;
+extern struct MusicPlayerInfo gMPlayInfo_BGM;
+extern struct MusicPlayerInfo gMPlayInfo_SE1;
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
+extern struct MusicPlayerInfo gMPlayInfo_SE3;
+extern struct ToneData gCryTable[];
+extern struct ToneData gCryTable2[];
+extern const struct Fanfare sFanfares[];
+
+extern u16 SpeciesToCryId(u16);
+
+static void Task_Fanfare(u8 taskId);
+static void CreateFanfareTask(void);
+static void Task_DuckBGMForPokemonCry(u8 taskId);
+static 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;
+
+ if(gUnknown_203ADFA == 2)
+ {
+ sFanfareCounter = 0xFF;
+ }
+ else
+ {
+ m4aMPlayStop(&gMPlayInfo_BGM);
+ songNum = sFanfares[fanfareNum].songNum;
+ sFanfareCounter = sFanfares[fanfareNum].duration;
+ m4aSongNumStart(songNum);
+ }
+}
+
+bool8 WaitFanfare(bool8 stop)
+{
+ if (sFanfareCounter)
+ {
+ sFanfareCounter--;
+ return FALSE;
+ }
+ else
+ {
+ if (!stop)
+ m4aMPlayContinue(&gMPlayInfo_BGM);
+ else
+ m4aSongNumStart(MUS_DUMMY);
+
+ return TRUE;
+ }
+}
+
+void StopFanfareByFanfareNum(u8 fanfareNum)
+{
+ m4aSongNumStop(sFanfares[fanfareNum].songNum);
+}
+
+void PlayFanfare(u16 songNum)
+{
+ s32 i;
+ for (i = 0; (u32)i < 14; 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(&gMPlayInfo_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(&gMPlayInfo_BGM);
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0);
+ m4aSongNumStop(songNum);
+ m4aMPlayFadeIn(&gMPlayInfo_BGM, speed);
+}
+
+void FadeOutBGMTemporarily(u8 speed)
+{
+ m4aMPlayFadeOutTemporarily(&gMPlayInfo_BGM, speed);
+}
+
+bool8 IsBGMPausedOrStopped(void)
+{
+ if (gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_PAUSE)
+ return TRUE;
+ if (!(gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_TRACK))
+ return TRUE;
+ return FALSE;
+}
+
+void FadeInBGM(u8 speed)
+{
+ m4aMPlayFadeIn(&gMPlayInfo_BGM, speed);
+}
+
+void FadeOutBGM(u8 speed)
+{
+ m4aMPlayFadeOut(&gMPlayInfo_BGM, speed);
+}
+
+bool8 IsBGMStopped(void)
+{
+ if (!(gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_TRACK))
+ return TRUE;
+ return FALSE;
+}
+
+void PlayCry1(u16 species, s8 pan)
+{
+ m4aMPlayVolumeControl(&gMPlayInfo_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(&gMPlayInfo_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(&gMPlayInfo_BGM, 0xFFFF, 85);
+ PlayCryInternal(species, pan, CRY_VOLUME, 10, mode);
+ }
+}
+
+// PlayCry5 and 6 are not in FR/LG.
+
+void PlayCry7(u16 species, u8 mode) // exclusive to FR/LG
+{
+ if((u8)(gUnknown_203ADFA - 2) >= 2)
+ {
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 85);
+ PlayCryInternal(species, 0, CRY_VOLUME, 10, mode);
+ }
+ gPokemonCryBGMDuckingCounter = 2;
+ RestoreBGMVolumeAfterPokemonCry();
+}
+
+void PlayCryInternal(u16 species, s8 pan, s8 volume, u8 priority, u8 mode)
+{
+ bool32 v0;
+ u32 release;
+ u32 length;
+ u32 pitch;
+ u32 chorus;
+ u32 index;
+ u8 table;
+
+ species--;
+ length = 140;
+ v0 = FALSE;
+ release = 0;
+ pitch = 15360;
+ chorus = 0;
+
+ switch (mode)
+ {
+ case 0:
+ break;
+ case 1:
+ length = 20;
+ release = 225;
+ break;
+ case 2:
+ release = 225;
+ pitch = 15600;
+ chorus = 20;
+ volume = 90;
+ break;
+ case 3:
+ length = 50;
+ release = 200;
+ pitch = 15800;
+ chorus = 20;
+ volume = 90;
+ break;
+ case 4:
+ length = 25;
+ v0 = TRUE;
+ release = 100;
+ pitch = 15600;
+ chorus = 192;
+ volume = 90;
+ break;
+ case 5:
+ release = 200;
+ pitch = 14440;
+ break;
+ case 6: // _08072044
+ release = 220;
+ pitch = 15555;
+ chorus = 192;
+ volume = 90; // FR/LG changed this from 70 to 90
+ break;
+ case 7:
+ length = 10;
+ release = 100;
+ pitch = 14848;
+ break;
+ case 8:
+ length = 60;
+ release = 225;
+ pitch = 15616;
+ break;
+ case 9:
+ length = 15;
+ v0 = TRUE;
+ release = 125;
+ pitch = 15200;
+ break;
+ case 10:
+ length = 100;
+ release = 225;
+ pitch = 15200;
+ break;
+ case 12:
+ length = 20;
+ release = 225;
+ case 11:
+ pitch = 15000;
+ break;
+ }
+
+ SetPokemonCryVolume(volume);
+ SetPokemonCryPanpot(pan);
+ SetPokemonCryPitch(pitch);
+ SetPokemonCryLength(length);
+ SetPokemonCryProgress(0);
+ SetPokemonCryRelease(release);
+ SetPokemonCryChorus(chorus);
+ SetPokemonCryPriority(priority);
+
+ // This is a fancy way to get a cry of a pokemon.
+ // It creates 4 sets of 128 mini cry tables.
+ // If you wish to expand pokemon, you need to
+ // append new cases to the switch.
+ species = SpeciesToCryId(species);
+ index = species & 0x7F;
+ table = species / 128;
+
+ switch (table)
+ {
+ case 0:
+ gMPlay_PokemonCry = SetPokemonCryTone(
+ v0 ? &gCryTable2[(128 * 0) + index] : &gCryTable[(128 * 0) + index]);
+ break;
+ case 1:
+ gMPlay_PokemonCry = SetPokemonCryTone(
+ v0 ? &gCryTable2[(128 * 1) + index] : &gCryTable[(128 * 1) + index]);
+ break;
+ case 2:
+ gMPlay_PokemonCry = SetPokemonCryTone(
+ v0 ? &gCryTable2[(128 * 2) + index] : &gCryTable[(128 * 2) + index]);
+ break;
+ case 3:
+ gMPlay_PokemonCry = SetPokemonCryTone(
+ v0 ? &gCryTable2[(128 * 3) + index] : &gCryTable[(128 * 3) + index]);
+ break;
+ }
+}
+
+bool8 IsCryFinished(void)
+{
+ if (FuncIsActiveTask(Task_DuckBGMForPokemonCry) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ ClearPokemonCrySongs();
+ return TRUE;
+ }
+}
+
+void StopCryAndClearCrySongs(void)
+{
+ m4aMPlayStop(gMPlay_PokemonCry);
+ ClearPokemonCrySongs();
+}
+
+void StopCry(void)
+{
+ m4aMPlayStop(gMPlay_PokemonCry);
+}
+
+bool8 IsCryPlayingOrClearCrySongs(void)
+{
+ if (IsPokemonCryPlaying(gMPlay_PokemonCry))
+ {
+ return TRUE;
+ }
+ else
+ {
+ ClearPokemonCrySongs();
+ return FALSE;
+ }
+}
+
+bool8 IsCryPlaying(void)
+{
+ if (IsPokemonCryPlaying(gMPlay_PokemonCry))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void Task_DuckBGMForPokemonCry(u8 taskId)
+{
+ if (gPokemonCryBGMDuckingCounter)
+ {
+ gPokemonCryBGMDuckingCounter--;
+ return;
+ }
+
+ if (!IsPokemonCryPlaying(gMPlay_PokemonCry))
+ {
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 256);
+ DestroyTask(taskId);
+ }
+}
+
+static void RestoreBGMVolumeAfterPokemonCry(void)
+{
+ if (FuncIsActiveTask(Task_DuckBGMForPokemonCry) != TRUE)
+ CreateTask(Task_DuckBGMForPokemonCry, 80);
+}
+
+void PlayBGM(u16 songNum)
+{
+ if (gDisableMusic)
+ songNum = 0;
+ if (songNum == 0xFFFF)
+ songNum = 0;
+ m4aSongNumStart(songNum);
+}
+
+void PlaySE(u16 songNum)
+{
+ if(gUnknown_2031DD8 == 0 && gUnknown_203ADFA != 2)
+ m4aSongNumStart(songNum);
+}
+
+void PlaySE12WithPanning(u16 songNum, s8 pan)
+{
+ m4aSongNumStart(songNum);
+ m4aMPlayImmInit(&gMPlayInfo_SE1);
+ m4aMPlayImmInit(&gMPlayInfo_SE2);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, pan);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE2, 0xFFFF, pan);
+}
+
+void PlaySE1WithPanning(u16 songNum, s8 pan)
+{
+ m4aSongNumStart(songNum);
+ m4aMPlayImmInit(&gMPlayInfo_SE1);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, pan);
+}
+
+void PlaySE2WithPanning(u16 songNum, s8 pan)
+{
+ m4aSongNumStart(songNum);
+ m4aMPlayImmInit(&gMPlayInfo_SE2);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE2, 0xFFFF, pan);
+}
+
+void SE12PanpotControl(s8 pan)
+{
+ m4aMPlayPanpotControl(&gMPlayInfo_SE1, 0xFFFF, pan);
+ m4aMPlayPanpotControl(&gMPlayInfo_SE2, 0xFFFF, pan);
+}
+
+bool8 IsSEPlaying(void)
+{
+ if ((gMPlayInfo_SE1.status & MUSICPLAYER_STATUS_PAUSE) && (gMPlayInfo_SE2.status & MUSICPLAYER_STATUS_PAUSE))
+ return FALSE;
+ if (!(gMPlayInfo_SE1.status & MUSICPLAYER_STATUS_TRACK) && !(gMPlayInfo_SE2.status & MUSICPLAYER_STATUS_TRACK))
+ return FALSE;
+ return TRUE;
+}
+
+bool8 IsBGMPlaying(void)
+{
+ if (gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_PAUSE)
+ return FALSE;
+ if (!(gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_TRACK))
+ return FALSE;
+ return TRUE;
+}
+
+bool8 IsSpecialSEPlaying(void)
+{
+ if (gMPlayInfo_SE3.status & MUSICPLAYER_STATUS_PAUSE)
+ return FALSE;
+ if (!(gMPlayInfo_SE3.status & MUSICPLAYER_STATUS_TRACK))
+ return FALSE;
+ return TRUE;
+}
+
+void sub_8072474(u16 volume)
+{
+ gUnknown_203F174 = 1;
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, volume);
+}
+
+void sub_807249C(void)
+{
+ gUnknown_203F174 = 0;
+ m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 256);
+}
diff --git a/src/text.c b/src/text.c
index 76c6dba63..7832d86f3 100644
--- a/src/text.c
+++ b/src/text.c
@@ -680,17 +680,17 @@ _08005A84:\n\
bl FillWindowPixelBuffer\n\
b _0800589E\n\
_08005A96:\n\
- ldr r0, _08005AA0 @ =gMPlay_BGM\n\
+ ldr r0, _08005AA0 @ =gMPlayInfo_BGM\n\
bl m4aMPlayStop\n\
b _0800589E\n\
.align 2, 0\n\
-_08005AA0: .4byte gMPlay_BGM\n\
+_08005AA0: .4byte gMPlayInfo_BGM\n\
_08005AA4:\n\
- ldr r0, _08005AAC @ =gMPlay_BGM\n\
+ ldr r0, _08005AAC @ =gMPlayInfo_BGM\n\
bl m4aMPlayContinue\n\
b _0800589E\n\
.align 2, 0\n\
-_08005AAC: .4byte gMPlay_BGM\n\
+_08005AAC: .4byte gMPlayInfo_BGM\n\
_08005AB0:\n\
ldr r0, [r6]\n\
ldrb r4, [r0]\n\