From c99408c8498b44007f7cf859636d6bbe9509e15b Mon Sep 17 00:00:00 2001 From: theo3 Date: Tue, 20 Apr 2021 21:24:44 -0700 Subject: merge + fix --- src/audio.c | 1368 ++++++++++++++++++++++++++++++++ src/code_0805F9A0.c | 10 - src/debugScreen.c | 8 +- src/enemy/gyorgMale.c | 4 +- src/enemy/rope.c | 3 +- src/enemy/spinyChuchu.c | 3 +- src/enemy/vaatiBall.c | 5 +- src/enemy/waterDrop.c | 3 +- src/ezloNag.c | 3 +- src/fileScreen.c | 5 +- src/game.c | 3 +- src/gba/m4a.c | 1676 ++++++++++++++++++++++++++++++++++++++++ src/intro.c | 2 +- src/item.c | 2 - src/loadRoom.c | 6 +- src/main.c | 6 +- src/manager/manager15.c | 4 +- src/manager/manager3.c | 4 +- src/manager/manager8.c | 9 +- src/manager/manager9.c | 7 +- src/manager/managerB.c | 5 +- src/manager/managerE.c | 1 + src/npc/bigGoron.c | 1 + src/npc/bladeBrothers.c | 3 +- src/npc/ezloCap.c | 5 +- src/npc/melari.c | 1 + src/npc/rem.c | 7 +- src/npc/smith.c | 1 + src/object/bird.c | 2 +- src/object/button.c | 5 +- src/object/cloud.c | 6 +- src/object/greatFairy.c | 2 +- src/object/houseDoorExterior.c | 5 +- src/object/itemOnGround.c | 48 +- src/object/jailBars.c | 4 +- src/object/metalDoor.c | 3 +- src/object/minecart.c | 8 +- src/object/object49.c | 2 +- src/object/objectA2.c | 5 +- src/object/thoughtBubble.c | 1 + src/object/windcrest.c | 1 + src/player.c | 12 +- src/room.c | 34 +- src/save.c | 15 +- src/script.c | 23 +- src/textbox.c | 724 ++++++++++++++--- 46 files changed, 3823 insertions(+), 232 deletions(-) create mode 100644 src/audio.c create mode 100644 src/gba/m4a.c (limited to 'src') diff --git a/src/audio.c b/src/audio.c new file mode 100644 index 00000000..580a940e --- /dev/null +++ b/src/audio.c @@ -0,0 +1,1368 @@ +#include "global.h" +#include "main.h" +#include "gba/m4a.h" +#include "audio.h" +#include "utils.h" + +#define IS_BGM(song) (song) - 1 <= NUM_BGM - 1 +#define IS_SFX(song) (song) - 1 > NUM_BGM - 1 + +void InitSoundPlayingInfo(void); +s32 fade(s32 target, s32 current); +void doPlaySound(u32 sound); +void PlayFadeIn(u32 sound); +void PlayFadeOut(u32 sound); +void InitVolume(void); + +void InitSound(void) { + InitSoundPlayingInfo(); + m4aSoundInit(); +} + +void InitSoundPlayingInfo(void) { + MemClear(&gSoundPlayingInfo, sizeof(gSoundPlayingInfo)); + InitVolume(); + gSoundPlayingInfo.volumeSfx = 0x100; + gSoundPlayingInfo.unk_04 = 0x100; + m4aMPlayAllStop(); +} + +void SetMasterVolume(u32 volume) { + gSoundPlayingInfo.volumeMaster = volume; + gSoundPlayingInfo.volumeMasterTarget = volume; + doPlaySound(gSoundPlayingInfo.currentBgm); +} + +void SetBgmVolume(u32 volume) { + gSoundPlayingInfo.volumeBgmTarget = volume; + gSoundPlayingInfo.volumeBgm = volume; + doPlaySound(gSoundPlayingInfo.currentBgm); +} + +void SetSfxVolume(u32 volume) { + gSoundPlayingInfo.volumeSfx = volume; +} + +void SoundReq(Sound sound) { + u32 song; + SoundPlayingInfo* ptr; + if (gMain.field_0x7) + return; + ptr = &gSoundPlayingInfo; + song = sound & 0xffff; + switch (sound & 0xffff0000) { + case SONG_STOP_ALL: + ptr->currentBgm = 0; + m4aMPlayAllStop(); + return; + case SONG_MUTE: + SetMasterVolume(0); + return; + case SONG_PLAY_VOL_RESET_ALL: + InitVolume(); + ptr->volumeSfx = 0x100; + doPlaySound(ptr->currentBgm); + return; + case SONG_VOL_FADE_OUT: + PlayFadeOut(ptr->currentBgm); + return; + case SONG_FADE_IN: + if (song == 0) + song = ptr->currentBgm; + if (IS_SFX(song)) + return; + ptr->currentBgm = song; + m4aSongNumStart(song); + PlayFadeIn(song); + return; + case SONG_FADE_IN_CONTINUE: + if (IS_SFX(song)) + return; + ptr->currentBgm = song; + m4aSongNumStartOrContinue(song); + PlayFadeIn(song); + return; + case SONG_PLAY_TEMPO_CONTROL: + m4aMPlayTempoControl(gMusicPlayers[gSongTable[ptr->currentBgm].musicPlayerIndex].info, song); + return; + case SONG_VSYNC_OFF: + m4aMPlayAllStop(); + m4aSoundVSyncOff(); + return; + case SONG_STOP: + if (ptr->currentBgm == 0) + return; + m4aSongNumStop(ptr->currentBgm); + return; + case SONG_VSYNC_ON: + m4aSoundVSyncOn(); + case SONG_CONTINUE: + if (ptr->currentBgm == 0) + return; + m4aSongNumStartOrContinue(ptr->currentBgm); + doPlaySound(ptr->currentBgm); + return; + case SONG_PLAY_VOL_RESET: + if (IS_SFX(song)) + return; + ptr->currentBgm = song; + m4aSongNumStartOrContinue(song); + InitVolume(); + doPlaySound(song); + return; + case SONG_FADE_OUT_BGM: + ptr->volumeBgmTarget = 0; + return; + case SONG_STOP_BGM: + ptr->volumeBgmTarget = 0; + ptr->stopBgm = TRUE; + return; + case SONG_FADE_IN_BGM: + ptr->volumeBgmTarget = 0x100; + return; + case SONG_INIT: + InitVolume(); + return; + case SONG_BGM_0: + ptr->currentBgm = 0; + return; + default: + if (song != 0) { + if (IS_BGM(song)) { + ptr->currentBgm = song; + m4aSongNumStart(song); + InitVolume(); + } else { + m4aSongNumStart(song); + } + doPlaySound(song); + } + return; + } +} + +void SoundLoop(void) { + s32 fadeValue; + SoundPlayingInfo* ptr = &gSoundPlayingInfo; + + if (ptr->volumeMasterTarget != ptr->volumeMaster) { + fadeValue = fade(ptr->volumeMasterTarget, ptr->volumeMaster); + if (fadeValue == 0) { + ptr->volumeMaster = ptr->volumeMasterTarget; + } else { + ptr->volumeMaster = ptr->volumeMaster + fadeValue; + } + if (ptr->volumeMaster < 0) { + ptr->volumeMasterTarget = 0; + ptr->volumeMaster = 0; + } + doPlaySound(ptr->currentBgm); + } else { + if (ptr->volumeBgmTarget != ptr->volumeBgm) { + fadeValue = fade(ptr->volumeBgmTarget, ptr->volumeBgm); + if (fadeValue == 0) { + if (ptr->stopBgm && ptr->volumeBgmTarget == 0) { + ptr->stopBgm = FALSE; + ptr->currentBgm = 0; + m4aSongNumStop(0); + } else { + ptr->volumeBgm = ptr->volumeBgmTarget; + } + } else { + ptr->volumeBgm += fadeValue; + } + if (ptr->volumeBgm < 0) { + ptr->volumeBgmTarget = 0; + ptr->volumeBgm = 0; + } + doPlaySound(ptr->currentBgm); + } + } +} + +s32 fade(s32 target, s32 current) { + if (target - current >= 1) { + current += 4; + if (target > current) + return 4; + return 0; + } else { + current -= 4; + if (target < current) + return -4; + return 0; + } +} + +void doPlaySound(u32 sound) { + u32 volume; + u32 iVar2; + MusicPlayerInfo* musicPlayerInfo; + + if (sound == 0) + return; + + if (IS_BGM(sound)) { + volume = gSoundPlayingInfo.volumeBgm; + } else { + volume = gSoundPlayingInfo.volumeSfx; + } + iVar2 = gSoundPlayingInfo.volumeMaster; + volume = iVar2 * volume / 0x100; + musicPlayerInfo = gMusicPlayers[gSongTable[sound].musicPlayerIndex].info; + m4aMPlayImmInit(musicPlayerInfo); + m4aMPlayVolumeControl(musicPlayerInfo, 0xffff, volume); +} + +void PlayFadeIn(u32 sound) { + gSoundPlayingInfo.volumeMasterTarget = 0x100; + doPlaySound(sound); +} + +void PlayFadeOut(u32 sound) { + gSoundPlayingInfo.volumeMasterTarget = 0; + doPlaySound(sound); +} + +void InitVolume() { + gSoundPlayingInfo.volumeMasterUnk = 0x100; + gSoundPlayingInfo.volumeMaster = 0x100; + gSoundPlayingInfo.volumeMasterTarget = 0x100; + gSoundPlayingInfo.volumeBgmUnk = 0x100; + gSoundPlayingInfo.volumeBgm = 0x100; + gSoundPlayingInfo.volumeBgmTarget = 0x100; +} + +extern const SongHeader sfxNone; +extern const SongHeader bgmCastleTournament; +extern const SongHeader bgmVaatiMotif; +extern const SongHeader bgmTitleScreen; +extern const SongHeader bgmCastleMotif; +extern const SongHeader bgmElementGet; +extern const SongHeader bgmFairyFountain; +extern const SongHeader bgmFileSelect; +extern const SongHeader bgmIntorCutscene; +extern const SongHeader bgmCredits; +extern const SongHeader bgmGameover; +extern const SongHeader bgmSavingZelda; +extern const SongHeader bgmLttpTitle; +extern const SongHeader bgmVaatiTheme; +extern const SongHeader bgmEzloTheme; +extern const SongHeader bgmStory; +extern const SongHeader bgmFestivalApproach; +extern const SongHeader bgmBeatVaati; +extern const SongHeader bgmUnused; +extern const SongHeader bgmBeanstalk; +extern const SongHeader bgmHouse; +extern const SongHeader bgmCuccoMinigame; +extern const SongHeader bgmSyrupTheme; +extern const SongHeader bgmDungeon; +extern const SongHeader bgmElementTheme; +extern const SongHeader bgmHyruleField; +extern const SongHeader bgmHyruleCastle; +extern const SongHeader bgmHyruleCastleNointro; +extern const SongHeader bgmMinishVillage; +extern const SongHeader bgmMinishWoods; +extern const SongHeader bgmCrenelStorm; +extern const SongHeader bgmCastorWilds; +extern const SongHeader bgmHyruleTown; +extern const SongHeader bgmRoyalValley; +extern const SongHeader bgmCloudTops; +extern const SongHeader bgmDarkHyruleCastle; +extern const SongHeader bgmSecretCastleEntrance; +extern const SongHeader bgmDeepwoodShrine; +extern const SongHeader bgmCaveOfFlames; +extern const SongHeader bgmFortressOfWinds; +extern const SongHeader bgmTempleOfDroplets; +extern const SongHeader bgmPalaceOfWinds; +extern const SongHeader bgmEzloStory; +extern const SongHeader bgmRoyalCrypt; +extern const SongHeader bgmElementalSanctuary; +extern const SongHeader bgmFightTheme; +extern const SongHeader bgmBossTheme; +extern const SongHeader bgmVaatiReborn; +extern const SongHeader bgmVaatiTransfigured; +extern const SongHeader bgmCastleCollapse; +extern const SongHeader bgmVaatiWrath; +extern const SongHeader bgmFightTheme2; +extern const SongHeader bgmDiggingCave; +extern const SongHeader bgmSwiftbladeDojo; +extern const SongHeader bgmMinishCap; +extern const SongHeader bgmMtCrenel; +extern const SongHeader bgmPicoriFestival; +extern const SongHeader bgmLostWoods; +extern const SongHeader bgmFairyFountain2; +extern const SongHeader bgmWindRuins; +extern const SongHeader bgmLearnScroll; +extern const SongHeader bgmEzloGet; +extern const SongHeader sfxBeep; +extern const SongHeader sfxTextboxOpen; +extern const SongHeader sfxTextboxClose; +extern const SongHeader sfxTextboxNext; +extern const SongHeader sfxTextboxSwap; +extern const SongHeader sfxTextboxChoice; +extern const SongHeader sfxTextboxSelect; +extern const SongHeader sfx6B; +extern const SongHeader sfxMenuCancel; +extern const SongHeader sfxMenuError; +extern const SongHeader sfxRupeeBounce; +extern const SongHeader sfxRupeeGet; +extern const SongHeader sfxHeartBounce; +extern const SongHeader sfxHeartGet; +extern const SongHeader sfxSecret; +extern const SongHeader sfxSecretBig; +extern const SongHeader sfxMetalClink; +extern const SongHeader sfxPlyVo1; +extern const SongHeader sfxPlyVo2; +extern const SongHeader sfxPlyVo3; +extern const SongHeader sfxPlyVo4; +extern const SongHeader sfxPlyVo5; +extern const SongHeader sfxPlyVo6; +extern const SongHeader sfxPlyVo7; +extern const SongHeader sfxPlyJump; +extern const SongHeader sfxPlyLand; +extern const SongHeader sfx7E; +extern const SongHeader sfxPlyLift; +extern const SongHeader sfx80; +extern const SongHeader sfx81; +extern const SongHeader sfx82; +extern const SongHeader sfxWaterWalk; +extern const SongHeader sfxWaterSplash; +extern const SongHeader sfxFallHole; +extern const SongHeader sfx86; +extern const SongHeader sfxPlyDie; +extern const SongHeader sfx88; +extern const SongHeader sfxBarrelRelease; +extern const SongHeader sfxBarrelEnter; +extern const SongHeader sfxBarrelRoll; +extern const SongHeader sfxBarrelRollStop; +extern const SongHeader sfxVoEzlo1; +extern const SongHeader sfxVoEzlo2; +extern const SongHeader sfxVoEzlo3; +extern const SongHeader sfxVoEzlo4; +extern const SongHeader sfxVoEzlo5; +extern const SongHeader sfxVoEzlo6; +extern const SongHeader sfxVoEzlo7; +extern const SongHeader sfxVoZelda1; +extern const SongHeader sfxVoZelda2; +extern const SongHeader sfxVoZelda3; +extern const SongHeader sfxVoZelda4; +extern const SongHeader sfxVoZelda5; +extern const SongHeader sfxVoZelda6; +extern const SongHeader sfxVoZelda7; +extern const SongHeader sfx9B; +extern const SongHeader sfx9C; +extern const SongHeader sfx9D; +extern const SongHeader sfx9E; +extern const SongHeader sfx9F; +extern const SongHeader sfxA0; +extern const SongHeader sfxVoTingle1; +extern const SongHeader sfxVoTingle2; +extern const SongHeader sfxVoKing1; +extern const SongHeader sfxVoKing2; +extern const SongHeader sfxVoKing3; +extern const SongHeader sfxVoKing4; +extern const SongHeader sfxVoKing5; +extern const SongHeader sfxA8; +extern const SongHeader sfxA9; +extern const SongHeader sfxAA; +extern const SongHeader sfxSpiritsRelease; +extern const SongHeader sfxAC; +extern const SongHeader sfxVoBeedle; +extern const SongHeader sfxAE; +extern const SongHeader sfxAF; +extern const SongHeader sfxB0; +extern const SongHeader sfxMinish1; +extern const SongHeader sfxMinish2; +extern const SongHeader sfxMinish3; +extern const SongHeader sfxMinish4; +extern const SongHeader sfxB5; +extern const SongHeader sfxB6; +extern const SongHeader sfxB7; +extern const SongHeader sfxB8; +extern const SongHeader sfxB9; +extern const SongHeader sfxBA; +extern const SongHeader sfxBB; +extern const SongHeader sfxBC; +extern const SongHeader sfxBD; +extern const SongHeader sfxBE; +extern const SongHeader sfxBF; +extern const SongHeader sfxC0; +extern const SongHeader sfxC1; +extern const SongHeader sfxC2; +extern const SongHeader sfxC3; +extern const SongHeader sfxC4; +extern const SongHeader sfxC5; +extern const SongHeader sfxC6; +extern const SongHeader sfxC7; +extern const SongHeader sfxC8; +extern const SongHeader sfxC9; +extern const SongHeader sfxCA; +extern const SongHeader sfxCB; +extern const SongHeader sfxRemSleep; +extern const SongHeader sfxTaskComplete; +extern const SongHeader sfxKeyAppear; +extern const SongHeader sfxCF; +extern const SongHeader sfxD0; +extern const SongHeader sfxVoDog; +extern const SongHeader sfxVoCat; +extern const SongHeader sfxVoEpona; +extern const SongHeader sfxVoCow; +extern const SongHeader sfxVoCuccoCall; +extern const SongHeader sfxVoCheep; +extern const SongHeader sfxItemSwordCharge; +extern const SongHeader sfxItemSwordChargeFinish; +extern const SongHeader sfxD9; +extern const SongHeader sfxDA; +extern const SongHeader sfxVoSturgeon; +extern const SongHeader sfxHammer1; +extern const SongHeader sfxHammer2; +extern const SongHeader sfxHammer3; +extern const SongHeader sfxHammer4; +extern const SongHeader sfxHammer5; +extern const SongHeader sfxHammer6; +extern const SongHeader sfxCuccoMinigameBell; +extern const SongHeader sfxE3; +extern const SongHeader sfxE4; +extern const SongHeader sfxButtonDepress; +extern const SongHeader sfxThudHeavy; +extern const SongHeader sfxWind1; +extern const SongHeader sfxWind2; +extern const SongHeader sfxWind3; +extern const SongHeader sfxEA; +extern const SongHeader sfxEB; +extern const SongHeader sfxEC; +extern const SongHeader sfxED; +extern const SongHeader sfxEE; +extern const SongHeader sfxEF; +extern const SongHeader sfxF0; +extern const SongHeader sfxF1; +extern const SongHeader sfxF2; +extern const SongHeader sfxF3; +extern const SongHeader sfxSummon; +extern const SongHeader sfxF5; +extern const SongHeader sfxEvaporate; +extern const SongHeader sfxApparate; +extern const SongHeader sfxF8; +extern const SongHeader sfxTeleporter; +extern const SongHeader sfxFA; +extern const SongHeader sfxFB; +extern const SongHeader sfxFC; +extern const SongHeader sfxItemBombExplode; +extern const SongHeader sfxHit; +extern const SongHeader sfxFF; +extern const SongHeader sfx100; +extern const SongHeader sfx101; +extern const SongHeader sfx102; +extern const SongHeader sfx103; +extern const SongHeader sfx104; +extern const SongHeader sfx105; +extern const SongHeader sfx106; +extern const SongHeader sfx107; +extern const SongHeader sfx108; +extern const SongHeader sfx109; +extern const SongHeader sfx10A; +extern const SongHeader sfx10B; +extern const SongHeader sfx10C; +extern const SongHeader sfx10D; +extern const SongHeader sfx10E; +extern const SongHeader sfx10F; +extern const SongHeader sfx110; +extern const SongHeader sfx111; +extern const SongHeader sfx112; +extern const SongHeader sfx113; +extern const SongHeader sfx114; +extern const SongHeader sfx115; +extern const SongHeader sfx116; +extern const SongHeader sfx117; +extern const SongHeader sfxItemShieldBounce; +extern const SongHeader sfxItemGlovesKnockback; +extern const SongHeader sfxEmArmosOn; +extern const SongHeader sfx11B; +extern const SongHeader sfx11C; +extern const SongHeader sfx11D; +extern const SongHeader sfxEmMoblinSpear; +extern const SongHeader sfxLowHealth; +extern const SongHeader sfxChargingUp; +extern const SongHeader sfxStairs; +extern const SongHeader sfx122; +extern const SongHeader sfx123; +extern const SongHeader sfx124; +extern const SongHeader sfx125; +extern const SongHeader sfx126; +extern const SongHeader sfxBossHit; +extern const SongHeader sfxBossDie; +extern const SongHeader sfxBossExplode; +extern const SongHeader sfx12A; +extern const SongHeader sfx12B; +extern const SongHeader sfx12C; +extern const SongHeader sfx12D; +extern const SongHeader sfx12E; +extern const SongHeader sfx12F; +extern const SongHeader sfx130; +extern const SongHeader sfx131; +extern const SongHeader sfx132; +extern const SongHeader sfx133; +extern const SongHeader sfx134; +extern const SongHeader sfx135; +extern const SongHeader sfx136; +extern const SongHeader sfx137; +extern const SongHeader sfx138; +extern const SongHeader sfx139; +extern const SongHeader sfx13A; +extern const SongHeader sfx13B; +extern const SongHeader sfx13C; +extern const SongHeader sfxItemLanternOn; +extern const SongHeader sfxItemLanternOff; +extern const SongHeader sfxItemSwordBeam; +extern const SongHeader sfx140; +extern const SongHeader sfxHeartContainerSpawn; +extern const SongHeader sfxSparkles; +extern const SongHeader sfx143; +extern const SongHeader sfx144; +extern const SongHeader sfx145; +extern const SongHeader sfx146; +extern const SongHeader sfx147; +extern const SongHeader sfx148; +extern const SongHeader sfx149; +extern const SongHeader sfx14A; +extern const SongHeader sfx14B; +extern const SongHeader sfx14C; +extern const SongHeader sfx14D; +extern const SongHeader sfx14E; +extern const SongHeader sfx14F; +extern const SongHeader sfx150; +extern const SongHeader sfx151; +extern const SongHeader sfx152; +extern const SongHeader sfx153; +extern const SongHeader sfx154; +extern const SongHeader sfx155; +extern const SongHeader sfx156; +extern const SongHeader sfx157; +extern const SongHeader sfx158; +extern const SongHeader sfx159; +extern const SongHeader sfx15A; +extern const SongHeader sfx15B; +extern const SongHeader sfx15C; +extern const SongHeader sfx15D; +extern const SongHeader sfx15E; +extern const SongHeader sfx15F; +extern const SongHeader sfx160; +extern const SongHeader sfx161; +extern const SongHeader sfx162; +extern const SongHeader sfx163; +extern const SongHeader sfx164; +extern const SongHeader sfx165; +extern const SongHeader sfx166; +extern const SongHeader sfx167; +extern const SongHeader sfx168; +extern const SongHeader sfx169; +extern const SongHeader sfx16A; +extern const SongHeader sfx16B; +extern const SongHeader sfx16C; +extern const SongHeader sfx16D; +extern const SongHeader sfx16E; +extern const SongHeader sfxPlyShrinking; +extern const SongHeader sfxPlyGrow; +extern const SongHeader sfx171; +extern const SongHeader sfx172; +extern const SongHeader sfxEzloUi; +extern const SongHeader sfx174; +extern const SongHeader sfx175; +extern const SongHeader sfx176; +extern const SongHeader sfx177; +extern const SongHeader sfx178; +extern const SongHeader sfx179; +extern const SongHeader sfx17A; +extern const SongHeader sfxLavaTitleStep; +extern const SongHeader sfxLavaTitleWobble; +extern const SongHeader sfxLavaTitleSink; +extern const SongHeader sfxLavaTitleFlip; +extern const SongHeader sfxLavaTitleLand; +extern const SongHeader sfx180; +extern const SongHeader sfx181; +extern const SongHeader sfx182; +extern const SongHeader sfx183; +extern const SongHeader sfx184; +extern const SongHeader sfx185; +extern const SongHeader sfx186; +extern const SongHeader sfxStairsAscend; +extern const SongHeader sfxStairsDescend; +extern const SongHeader sfx189; +extern const SongHeader sfx18A; +extern const SongHeader sfx18B; +extern const SongHeader sfx18C; +extern const SongHeader sfx18D; +extern const SongHeader sfx18E; +extern const SongHeader sfx18F; +extern const SongHeader sfx190; +extern const SongHeader sfx191; +extern const SongHeader sfx192; +extern const SongHeader sfx193; +extern const SongHeader sfx194; +extern const SongHeader sfx195; +extern const SongHeader sfx196; +extern const SongHeader sfx197; +extern const SongHeader sfx198; +extern const SongHeader sfx199; +extern const SongHeader sfx19A; +extern const SongHeader sfx19B; +extern const SongHeader sfx19C; +extern const SongHeader sfx19D; +extern const SongHeader sfx19E; +extern const SongHeader sfx19F; +extern const SongHeader sfx1A0; +extern const SongHeader sfx1A1; +extern const SongHeader sfx1A2; +extern const SongHeader sfx1A3; +extern const SongHeader sfx1A4; +extern const SongHeader sfx1A5; +extern const SongHeader sfx1A6; +extern const SongHeader sfx1A7; +extern const SongHeader sfx1A8; +extern const SongHeader sfx1A9; +extern const SongHeader sfx1AA; +extern const SongHeader sfx1AB; +extern const SongHeader sfx1AC; +extern const SongHeader sfx1AD; +extern const SongHeader sfx1AE; +extern const SongHeader sfx1AF; +extern const SongHeader sfx1B0; +extern const SongHeader sfxIceBlockSlide; +extern const SongHeader sfxIceBlockStop; +extern const SongHeader sfxIceBlockMelt; +extern const SongHeader sfx1B4; +extern const SongHeader sfx1B5; +extern const SongHeader sfx1B6; +extern const SongHeader sfxVoGoron1; +extern const SongHeader sfxVoGoron2; +extern const SongHeader sfxVoGoron3; +extern const SongHeader sfxVoGoron4; +extern const SongHeader sfxEmDekuscrubHit; +extern const SongHeader sfx1BC; +extern const SongHeader sfx1BD; +extern const SongHeader sfx1BE; +extern const SongHeader sfx1BF; +extern const SongHeader sfx1C0; +extern const SongHeader sfx1C1; +extern const SongHeader sfx1C2; +extern const SongHeader sfx1C3; +extern const SongHeader sfx1C4; +extern const SongHeader sfx1C5; +extern const SongHeader sfx1C6; +extern const SongHeader sfx1C7; +extern const SongHeader sfx1C8; +extern const SongHeader sfx1C9; +extern const SongHeader sfx1CA; +extern const SongHeader sfx1CB; +extern const SongHeader sfx1CC; +extern const SongHeader sfxElementPlace; +extern const SongHeader sfxElementFloat; +extern const SongHeader sfxElementCharge; +extern const SongHeader sfx1D0; +extern const SongHeader sfxElementInfuse; +extern const SongHeader sfx1D2; +extern const SongHeader sfx1D3; +extern const SongHeader sfx1D4; +extern const SongHeader sfx1D5; +extern const SongHeader sfxVoCucco1; +extern const SongHeader sfxVoCucco2; +extern const SongHeader sfxVoCucco3; +extern const SongHeader sfxVoCucco4; +extern const SongHeader sfxVoCucco5; +extern const SongHeader sfx1DB; +extern const SongHeader sfx1DC; +extern const SongHeader sfx1DD; +extern const SongHeader sfx1DE; +extern const SongHeader sfx1DF; +extern const SongHeader sfx1E0; +extern const SongHeader sfx1E1; +extern const SongHeader sfx1E2; +extern const SongHeader sfx1E3; +extern const SongHeader sfx1E4; +extern const SongHeader sfx1E5; +extern const SongHeader sfx1E6; +extern const SongHeader sfx1E7; +extern const SongHeader sfx1E8; +extern const SongHeader sfx1E9; +extern const SongHeader sfx1EA; +extern const SongHeader sfx1EB; +extern const SongHeader sfx1EC; +extern const SongHeader sfx1ED; +extern const SongHeader sfx1EE; +extern const SongHeader sfx1EF; +extern const SongHeader sfx1F0; +extern const SongHeader sfx1F1; +extern const SongHeader sfx1F2; +extern const SongHeader sfx1F3; +extern const SongHeader sfx1F4; +extern const SongHeader sfx1F5; +extern const SongHeader sfx1F6; +extern const SongHeader sfx1F7; +extern const SongHeader sfx1F8; +extern const SongHeader sfx1F9; +extern const SongHeader sfx1FA; +extern const SongHeader sfx1FB; +extern const SongHeader sfx1FC; +extern const SongHeader sfx1FD; +extern const SongHeader sfx1FE; +extern const SongHeader sfx1FF; +extern const SongHeader sfx200; +extern const SongHeader sfx201; +extern const SongHeader sfx202; +extern const SongHeader sfx203; +extern const SongHeader sfx204; +extern const SongHeader sfx205; +extern const SongHeader sfx206; +extern const SongHeader sfx207; +extern const SongHeader sfx208; +extern const SongHeader sfx209; +extern const SongHeader sfx20A; +extern const SongHeader sfx20B; +extern const SongHeader sfx20C; +extern const SongHeader sfx20D; +extern const SongHeader sfx20E; +extern const SongHeader sfx20F; +extern const SongHeader sfx210; +extern const SongHeader sfx211; +extern const SongHeader sfx212; +extern const SongHeader sfx213; +extern const SongHeader sfx214; +extern const SongHeader sfx215; +extern const SongHeader sfx216; +extern const SongHeader sfx217; +extern const SongHeader sfx218; +extern const SongHeader sfx219; +extern const SongHeader sfx21A; +extern const SongHeader sfx21B; +extern const SongHeader sfx21C; +extern const SongHeader sfx21D; +extern const SongHeader sfx21E; +extern const SongHeader sfx21F; +extern const SongHeader sfx220; +extern const SongHeader sfx221; + +extern MusicPlayerTrack gMPlayTracks[]; + +extern MusicPlayerInfo gMPlayInfos[0x1C]; +extern u8 gMPlayMemAccArea[0x10]; +extern MusicPlayerInfo gMPlayInfos2[0x4]; + +typedef enum { + MUSIC_PLAYER_00, + MUSIC_PLAYER_PLY_VO, + MUSIC_PLAYER_02, + MUSIC_PLAYER_03, + MUSIC_PLAYER_04, + MUSIC_PLAYER_05, + MUSIC_PLAYER_06, + MUSIC_PLAYER_07, + MUSIC_PLAYER_08, + MUSIC_PLAYER_09, + MUSIC_PLAYER_0A, + MUSIC_PLAYER_0B, + MUSIC_PLAYER_0C, + MUSIC_PLAYER_0D, + MUSIC_PLAYER_0E, + MUSIC_PLAYER_0F, + MUSIC_PLAYER_10, + MUSIC_PLAYER_11, + MUSIC_PLAYER_12, + MUSIC_PLAYER_13, + MUSIC_PLAYER_14, + MUSIC_PLAYER_15, + MUSIC_PLAYER_16, + MUSIC_PLAYER_17, + MUSIC_PLAYER_18, + MUSIC_PLAYER_19, + MUSIC_PLAYER_1A, + MUSIC_PLAYER_1B, + MUSIC_PLAYER_1C, + MUSIC_PLAYER_1D, + MUSIC_PLAYER_1E, + MUSIC_PLAYER_BGM, +} MusicPlayerE; + +const MusicPlayer gMusicPlayers[] = { + [MUSIC_PLAYER_00] = { &gMPlayInfos[0x08], &gMPlayTracks[0x00], 2, 1 }, + [MUSIC_PLAYER_PLY_VO] = { &gMPlayInfos[0x12], &gMPlayTracks[0x02], 1, 1 }, + [MUSIC_PLAYER_02] = { &gMPlayInfos[0x13], &gMPlayTracks[0x03], 1, 1 }, + [MUSIC_PLAYER_03] = { &gMPlayInfos2[0x2], &gMPlayTracks[0x04], 2, 1 }, + [MUSIC_PLAYER_04] = { &gMPlayInfos[0x1B], &gMPlayTracks[0x06], 2, 1 }, + [MUSIC_PLAYER_05] = { &gMPlayInfos[0x03], &gMPlayTracks[0x08], 2, 1 }, + [MUSIC_PLAYER_06] = { &gMPlayInfos[0x07], &gMPlayTracks[0x0A], 2, 1 }, + [MUSIC_PLAYER_07] = { &gMPlayInfos[0x11], &gMPlayTracks[0x0C], 2, 1 }, + [MUSIC_PLAYER_08] = { &gMPlayInfos2[0x1], &gMPlayTracks[0x0E], 2, 1 }, + [MUSIC_PLAYER_09] = { &gMPlayInfos[0x06], &gMPlayTracks[0x10], 2, 1 }, + [MUSIC_PLAYER_0A] = { &gMPlayInfos[0x14], &gMPlayTracks[0x12], 2, 1 }, + [MUSIC_PLAYER_0B] = { &gMPlayInfos2[0x3], &gMPlayTracks[0x14], 2, 1 }, + [MUSIC_PLAYER_0C] = { &gMPlayInfos[0x19], &gMPlayTracks[0x16], 2, 1 }, + [MUSIC_PLAYER_0D] = { &gMPlayInfos[0x02], &gMPlayTracks[0x18], 2, 1 }, + [MUSIC_PLAYER_0E] = { &gMPlayInfos[0x0E], &gMPlayTracks[0x1A], 2, 1 }, + [MUSIC_PLAYER_0F] = { &gMPlayInfos[0x18], &gMPlayTracks[0x1C], 2, 1 }, + [MUSIC_PLAYER_10] = { &gMPlayInfos[0x05], &gMPlayTracks[0x1E], 2, 1 }, + [MUSIC_PLAYER_11] = { &gMPlayInfos[0x1A], &gMPlayTracks[0x20], 2, 1 }, + [MUSIC_PLAYER_12] = { &gMPlayInfos[0x0D], &gMPlayTracks[0x22], 2, 1 }, + [MUSIC_PLAYER_13] = { &gMPlayInfos[0x00], &gMPlayTracks[0x24], 2, 1 }, + [MUSIC_PLAYER_14] = { &gMPlayInfos[0x0A], &gMPlayTracks[0x26], 2, 1 }, + [MUSIC_PLAYER_15] = { &gMPlayInfos[0x0C], &gMPlayTracks[0x28], 2, 1 }, + [MUSIC_PLAYER_16] = { &gMPlayInfos[0x17], &gMPlayTracks[0x2A], 2, 1 }, + [MUSIC_PLAYER_17] = { &gMPlayInfos[0x01], &gMPlayTracks[0x2C], 2, 1 }, + [MUSIC_PLAYER_18] = { &gMPlayInfos[0x0B], &gMPlayTracks[0x2E], 2, 1 }, + [MUSIC_PLAYER_19] = { &gMPlayInfos[0x15], &gMPlayTracks[0x30], 2, 1 }, + [MUSIC_PLAYER_1A] = { &gMPlayInfos[0x09], &gMPlayTracks[0x32], 2, 1 }, + [MUSIC_PLAYER_1B] = { &gMPlayInfos2[0x0], &gMPlayTracks[0x34], 2, 1 }, + [MUSIC_PLAYER_1C] = { &gMPlayInfos[0x0F], &gMPlayTracks[0x36], 2, 1 }, + [MUSIC_PLAYER_1D] = { &gMPlayInfos[0x16], &gMPlayTracks[0x38], 2, 1 }, + [MUSIC_PLAYER_1E] = { &gMPlayInfos[0x04], &gMPlayTracks[0x3A], 0xc, 0 }, + [MUSIC_PLAYER_BGM] = { &gMPlayInfos[0x10], &gMPlayTracks[0x46], 0xc, 0 }, +}; + +const Song gSongTable[] = { + [SFX_NONE] = { &sfxNone, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CASTLE_TOURNAMENT] = { &bgmCastleTournament, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_VAATI_MOTIF] = { &bgmVaatiMotif, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_TITLE_SCREEN] = { &bgmTitleScreen, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CASTLE_MOTIF] = { &bgmCastleMotif, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_ELEMENT_GET] = { &bgmElementGet, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FAIRY_FOUNTAIN] = { &bgmFairyFountain, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FILE_SELECT] = { &bgmFileSelect, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_INTRO_CUTSCENE] = { &bgmIntorCutscene, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CREDITS] = { &bgmCredits, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_GAMEOVER] = { &bgmGameover, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_SAVING_ZELDA] = { &bgmSavingZelda, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_LTTP_TITLE] = { &bgmLttpTitle, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_VAATI_THEME] = { &bgmVaatiTheme, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_EZLO_THEME] = { &bgmEzloTheme, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_STORY] = { &bgmStory, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FESTIVAL_APPROACH] = { &bgmFestivalApproach, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_BEAT_VAATI] = { &bgmBeatVaati, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_UNUSED_12] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_BEANSTALK] = { &bgmBeanstalk, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_HOUSE] = { &bgmHouse, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CUCCO_MINIGAME] = { &bgmCuccoMinigame, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_SYRUP_THEME] = { &bgmSyrupTheme, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_DUNGEON] = { &bgmDungeon, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_ELEMENT_THEME] = { &bgmElementTheme, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_HYRULE_FIELD] = { &bgmHyruleField, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_HYRULE_CASTLE] = { &bgmHyruleCastle, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_HYRULE_CASTLE_NOINTRO] = { &bgmHyruleCastleNointro, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_MINISH_VILLAGE] = { &bgmMinishVillage, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_MINISH_WOODS] = { &bgmMinishWoods, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CRENEL_STORM] = { &bgmCrenelStorm, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CASTOR_WILDS] = { &bgmCastorWilds, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_HYRULE_TOWN] = { &bgmHyruleTown, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_ROYAL_VALLEY] = { &bgmRoyalValley, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CLOUD_TOPS] = { &bgmCloudTops, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_DARK_HYRULE_CASTLE] = { &bgmDarkHyruleCastle, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_SECRET_CASTLE_ENTRANCE] = { &bgmSecretCastleEntrance, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_DEEPWOOD_SHRINE] = { &bgmDeepwoodShrine, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CAVE_OF_FLAMES] = { &bgmCaveOfFlames, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FORTRESS_OF_WINDS] = { &bgmFortressOfWinds, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_TEMPLE_OF_DROPLETS] = { &bgmTempleOfDroplets, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_PALACE_OF_WINDS] = { &bgmPalaceOfWinds, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_EZLO_STORY] = { &bgmEzloStory, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_ROYAL_CRYPT] = { &bgmRoyalCrypt, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_ELEMENTAL_SANCTUARY] = { &bgmElementalSanctuary, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FIGHT_THEME] = { &bgmFightTheme, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_BOSS_THEME] = { &bgmBossTheme, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_VAATI_REBORN] = { &bgmVaatiReborn, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_VAATI_TRANSFIGURED] = { &bgmVaatiTransfigured, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_CASTLE_COLLAPSE] = { &bgmCastleCollapse, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_VAATI_WRATH] = { &bgmVaatiWrath, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FIGHT_THEME2] = { &bgmFightTheme2, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_DIGGING_CAVE] = { &bgmDiggingCave, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_SWIFTBLADE_DOJO] = { &bgmSwiftbladeDojo, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_MINISH_CAP] = { &bgmMinishCap, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_MT_CRENEL] = { &bgmMtCrenel, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_PICORI_FESTIVAL] = { &bgmPicoriFestival, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_LOST_WOODS] = { &bgmLostWoods, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_FAIRY_FOUNTAIN2] = { &bgmFairyFountain2, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_WIND_RUINS] = { &bgmWindRuins, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_UNUSED_3C] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_3D] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_3E] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_3F] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_40] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_41] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_42] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_43] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_44] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_45] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_46] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_47] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_48] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_49] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_4A] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_4B] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_4C] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_4D] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_4E] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_4F] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_50] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_51] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_52] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_53] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_54] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_55] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_56] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_57] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_58] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_59] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_5A] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_5B] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_5C] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_5D] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_LEARN_SCROLL] = { &bgmLearnScroll, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_EZLO_GET] = { &bgmEzloGet, MUSIC_PLAYER_BGM, MUSIC_PLAYER_BGM }, + [BGM_UNUSED_60] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_61] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_62] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [BGM_UNUSED_63] = { &bgmUnused, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [SFX_BEEP] = { &sfxBeep, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [SFX_TEXTBOX_OPEN] = { &sfxTextboxOpen, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_TEXTBOX_CLOSE] = { &sfxTextboxClose, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_TEXTBOX_NEXT] = { &sfxTextboxNext, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_TEXTBOX_SWAP] = { &sfxTextboxSwap, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_TEXTBOX_CHOICE] = { &sfxTextboxChoice, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_TEXTBOX_SELECT] = { &sfxTextboxSelect, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_6B] = { &sfx6B, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_MENU_CANCEL] = { &sfxMenuCancel, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_MENU_ERROR] = { &sfxMenuError, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_RUPEE_BOUNCE] = { &sfxRupeeBounce, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_RUPEE_GET] = { &sfxRupeeGet, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [SFX_HEART_BOUNCE] = { &sfxHeartBounce, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_HEART_GET] = { &sfxHeartGet, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [SFX_SECRET] = { &sfxSecret, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_SECRET_BIG] = { &sfxSecretBig, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_METAL_CLINK] = { &sfxMetalClink, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_PLY_VO1] = { &sfxPlyVo1, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_VO2] = { &sfxPlyVo2, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_VO3] = { &sfxPlyVo3, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_VO4] = { &sfxPlyVo4, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_VO5] = { &sfxPlyVo5, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_VO6] = { &sfxPlyVo6, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_VO7] = { &sfxPlyVo7, MUSIC_PLAYER_PLY_VO, MUSIC_PLAYER_PLY_VO }, + [SFX_PLY_JUMP] = { &sfxPlyJump, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_PLY_LAND] = { &sfxPlyLand, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_7E] = { &sfx7E, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_PLY_LIFT] = { &sfxPlyLift, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_80] = { &sfx80, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_81] = { &sfx81, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_82] = { &sfx82, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_WATER_WALK] = { &sfxWaterWalk, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_WATER_SPLASH] = { &sfxWaterSplash, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_FALL_HOLE] = { &sfxFallHole, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_86] = { &sfx86, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_PLY_DIE] = { &sfxPlyDie, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_88] = { &sfx88, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_BARREL_RELEASE] = { &sfxBarrelRelease, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_BARREL_ENTER] = { &sfxBarrelEnter, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_BARREL_ROLL] = { &sfxBarrelRoll, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_BARREL_ROLL_STOP] = { &sfxBarrelRollStop, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_VO_EZLO1] = { &sfxVoEzlo1, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_EZLO2] = { &sfxVoEzlo2, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_EZLO3] = { &sfxVoEzlo3, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_EZLO4] = { &sfxVoEzlo4, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_EZLO5] = { &sfxVoEzlo5, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_EZLO6] = { &sfxVoEzlo6, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_EZLO7] = { &sfxVoEzlo7, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_VO_ZELDA1] = { &sfxVoZelda1, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_VO_ZELDA2] = { &sfxVoZelda2, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_VO_ZELDA3] = { &sfxVoZelda3, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_VO_ZELDA4] = { &sfxVoZelda4, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_VO_ZELDA5] = { &sfxVoZelda5, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_VO_ZELDA6] = { &sfxVoZelda6, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_VO_ZELDA7] = { &sfxVoZelda7, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_9B] = { &sfx9B, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_9C] = { &sfx9C, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_9D] = { &sfx9D, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_9E] = { &sfx9E, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_9F] = { &sfx9F, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_A0] = { &sfxA0, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_VO_TINGLE1] = { &sfxVoTingle1, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_VO_TINGLE2] = { &sfxVoTingle2, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_VO_KING1] = { &sfxVoKing1, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_VO_KING2] = { &sfxVoKing2, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_VO_KING3] = { &sfxVoKing3, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_VO_KING4] = { &sfxVoKing4, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_VO_KING5] = { &sfxVoKing5, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_A8] = { &sfxA8, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_A9] = { &sfxA9, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_AA] = { &sfxAA, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_SPIRITS_RELEASE] = { &sfxSpiritsRelease, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_AC] = { &sfxAC, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_VO_BEEDLE] = { &sfxVoBeedle, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_AE] = { &sfxAE, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_AF] = { &sfxAF, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_B0] = { &sfxB0, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_VO_MINISH1] = { &sfxMinish1, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_VO_MINISH2] = { &sfxMinish2, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_VO_MINISH3] = { &sfxMinish3, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_VO_MINISH4] = { &sfxMinish4, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_B5] = { &sfxB5, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_B6] = { &sfxB6, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_B7] = { &sfxB7, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_B8] = { &sfxB8, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_B9] = { &sfxB9, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_BA] = { &sfxBA, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_BB] = { &sfxBB, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_BC] = { &sfxBC, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_BD] = { &sfxBD, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_BE] = { &sfxBE, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_BF] = { &sfxBF, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_C0] = { &sfxC0, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_C1] = { &sfxC1, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_C2] = { &sfxC2, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_C3] = { &sfxC3, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_C4] = { &sfxC4, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_C5] = { &sfxC5, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_C6] = { &sfxC6, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_C7] = { &sfxC7, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_C8] = { &sfxC8, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_C9] = { &sfxC9, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_CA] = { &sfxCA, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_CB] = { &sfxCB, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_REM_SLEEP] = { &sfxRemSleep, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_TASK_COMPLETE] = { &sfxTaskComplete, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_KEY_APPEAR] = { &sfxKeyAppear, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_CF] = { &sfxCF, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_D0] = { &sfxD0, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_VO_DOG] = { &sfxVoDog, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_VO_CAT] = { &sfxVoCat, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_VO_EPONA] = { &sfxVoEpona, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_VO_COW] = { &sfxVoCow, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_VO_CUCCO_CALL] = { &sfxVoCuccoCall, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_VO_CHEEP] = { &sfxVoCheep, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_ITEM_SWORD_CHARGE] = { &sfxItemSwordCharge, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_ITEM_SWORD_CHARGE_FINISH] = { &sfxItemSwordChargeFinish, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_D9] = { &sfxD9, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_DA] = { &sfxDA, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_VO_STURGEON] = { &sfxVoSturgeon, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_HAMMER1] = { &sfxHammer1, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_HAMMER2] = { &sfxHammer2, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_HAMMER3] = { &sfxHammer3, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_HAMMER4] = { &sfxHammer4, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_HAMMER5] = { &sfxHammer5, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_HAMMER6] = { &sfxHammer6, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_CUCCO_MINIGAME_BELL] = { &sfxCuccoMinigameBell, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_E3] = { &sfxE3, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_E4] = { &sfxE4, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_BUTTON_DEPRESS] = { &sfxButtonDepress, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_THUD_HEAVY] = { &sfxThudHeavy, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_WIND1] = { &sfxWind1, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_WIND2] = { &sfxWind2, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_WIND3] = { &sfxWind3, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_EA] = { &sfxEA, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_EB] = { &sfxEB, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_EC] = { &sfxEC, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_ED] = { &sfxED, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_EE] = { &sfxEE, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_EF] = { &sfxEF, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_F0] = { &sfxF0, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_F1] = { &sfxF1, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_F2] = { &sfxF2, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_F3] = { &sfxF3, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_SUMMON] = { &sfxSummon, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_F5] = { &sfxF5, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_EVAPORATE] = { &sfxEvaporate, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_APPARATE] = { &sfxApparate, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_F8] = { &sfxF8, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_TELEPORTER] = { &sfxTeleporter, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_FA] = { &sfxFA, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_FB] = { &sfxFB, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_FC] = { &sfxFC, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_ITEM_BOMB_EXPLODE] = { &sfxItemBombExplode, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_HIT] = { &sfxHit, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_FF] = { &sfxFF, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_100] = { &sfx100, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_101] = { &sfx101, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_102] = { &sfx102, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_103] = { &sfx103, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [SFX_104] = { &sfx104, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_105] = { &sfx105, MUSIC_PLAYER_1E, MUSIC_PLAYER_1E }, + [SFX_106] = { &sfx106, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_107] = { &sfx107, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_108] = { &sfx108, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_109] = { &sfx109, MUSIC_PLAYER_1E, MUSIC_PLAYER_1E }, + [SFX_10A] = { &sfx10A, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_10B] = { &sfx10B, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_10C] = { &sfx10C, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_10D] = { &sfx10D, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_10E] = { &sfx10E, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_10F] = { &sfx10F, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_110] = { &sfx110, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_111] = { &sfx111, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_112] = { &sfx112, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_113] = { &sfx113, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_114] = { &sfx114, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_115] = { &sfx115, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_116] = { &sfx116, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_117] = { &sfx117, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_ITEM_SHIELD_BOUNCE] = { &sfxItemShieldBounce, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_ITEM_GLOVES_KNOCKBACK] = { &sfxItemGlovesKnockback, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_EM_ARMOS_ON] = { &sfxEmArmosOn, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_11B] = { &sfx11B, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_11C] = { &sfx11C, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_11D] = { &sfx11D, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_EM_MOBLIN_SPEAR] = { &sfxEmMoblinSpear, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_LOW_HEALTH] = { &sfxLowHealth, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_CHARGING_UP] = { &sfxChargingUp, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_STAIRS] = { &sfxStairs, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_122] = { &sfx122, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_123] = { &sfx123, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_124] = { &sfx124, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_125] = { &sfx125, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_126] = { &sfx126, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_BOSS_HIT] = { &sfxBossHit, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_BOSS_DIE] = { &sfxBossDie, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_BOSS_EXPLODE] = { &sfxBossExplode, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_12A] = { &sfx12A, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_12B] = { &sfx12B, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_12C] = { &sfx12C, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_12D] = { &sfx12D, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_12E] = { &sfx12E, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_12F] = { &sfx12F, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_130] = { &sfx130, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_131] = { &sfx131, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_132] = { &sfx132, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_133] = { &sfx133, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_134] = { &sfx134, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_135] = { &sfx135, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_136] = { &sfx136, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_137] = { &sfx137, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_138] = { &sfx138, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_139] = { &sfx139, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_13A] = { &sfx13A, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_13B] = { &sfx13B, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_13C] = { &sfx13C, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_ITEM_LANTERN_ON] = { &sfxItemLanternOn, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_ITEM_LANTERN_OFF] = { &sfxItemLanternOff, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_ITEM_SWORD_BEAM] = { &sfxItemSwordBeam, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_140] = { &sfx140, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_HEART_CONTAINER_SPAWN] = { &sfxHeartContainerSpawn, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_SPARKLES] = { &sfxSparkles, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_143] = { &sfx143, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_144] = { &sfx144, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_145] = { &sfx145, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_146] = { &sfx146, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_147] = { &sfx147, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_148] = { &sfx148, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_149] = { &sfx149, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_14A] = { &sfx14A, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_14B] = { &sfx14B, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_14C] = { &sfx14C, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_14D] = { &sfx14D, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_14E] = { &sfx14E, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_14F] = { &sfx14F, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_150] = { &sfx150, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_151] = { &sfx151, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_152] = { &sfx152, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_153] = { &sfx153, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_154] = { &sfx154, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_155] = { &sfx155, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_156] = { &sfx156, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_157] = { &sfx157, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_158] = { &sfx158, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_159] = { &sfx159, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_15A] = { &sfx15A, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_15B] = { &sfx15B, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_15C] = { &sfx15C, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_15D] = { &sfx15D, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_15E] = { &sfx15E, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_15F] = { &sfx15F, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_160] = { &sfx160, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_161] = { &sfx161, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_162] = { &sfx162, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_163] = { &sfx163, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_164] = { &sfx164, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_165] = { &sfx165, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_166] = { &sfx166, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_167] = { &sfx167, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_168] = { &sfx168, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_169] = { &sfx169, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_16A] = { &sfx16A, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_16B] = { &sfx16B, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_16C] = { &sfx16C, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_16D] = { &sfx16D, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_16E] = { &sfx16E, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_PLY_SHRINKING] = { &sfxPlyShrinking, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_PLY_GROW] = { &sfxPlyGrow, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_171] = { &sfx171, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_172] = { &sfx172, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_EZLO_UI] = { &sfxEzloUi, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_174] = { &sfx174, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_175] = { &sfx175, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_176] = { &sfx176, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_177] = { &sfx177, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_178] = { &sfx178, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_179] = { &sfx179, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_17A] = { &sfx17A, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_LAVA_TILE_STEP] = { &sfxLavaTitleStep, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_LAVA_TILE_WOBBLE] = { &sfxLavaTitleWobble, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_LAVA_TILE_SINK] = { &sfxLavaTitleSink, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_LAVA_TILE_FLIP] = { &sfxLavaTitleFlip, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_LAVA_TILE_LAND] = { &sfxLavaTitleLand, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_180] = { &sfx180, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_181] = { &sfx181, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_182] = { &sfx182, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_183] = { &sfx183, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_184] = { &sfx184, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_185] = { &sfx185, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_186] = { &sfx186, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_STAIRS_ASCEND] = { &sfxStairsAscend, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_STAIRS_DESCEND] = { &sfxStairsDescend, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_189] = { &sfx189, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_18A] = { &sfx18A, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_18B] = { &sfx18B, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_18C] = { &sfx18C, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_18D] = { &sfx18D, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_18E] = { &sfx18E, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_18F] = { &sfx18F, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_190] = { &sfx190, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_191] = { &sfx191, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_192] = { &sfx192, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_193] = { &sfx193, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_194] = { &sfx194, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_195] = { &sfx195, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_196] = { &sfx196, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_197] = { &sfx197, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_198] = { &sfx198, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_199] = { &sfx199, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_19A] = { &sfx19A, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_19B] = { &sfx19B, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_19C] = { &sfx19C, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_19D] = { &sfx19D, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_19E] = { &sfx19E, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_19F] = { &sfx19F, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_1A0] = { &sfx1A0, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_1A1] = { &sfx1A1, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_1A2] = { &sfx1A2, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_1A3] = { &sfx1A3, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_1A4] = { &sfx1A4, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_1A5] = { &sfx1A5, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_1A6] = { &sfx1A6, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_1A7] = { &sfx1A7, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_1A8] = { &sfx1A8, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_1A9] = { &sfx1A9, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_1AA] = { &sfx1AA, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_1AB] = { &sfx1AB, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_1AC] = { &sfx1AC, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_1AD] = { &sfx1AD, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_1AE] = { &sfx1AE, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_1AF] = { &sfx1AF, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_1B0] = { &sfx1B0, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_ICE_BLOCK_SLIDE] = { &sfxIceBlockSlide, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_ICE_BLOCK_STOP] = { &sfxIceBlockStop, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_ICE_BLOCK_MELT] = { &sfxIceBlockMelt, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_1B4] = { &sfx1B4, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_1B5] = { &sfx1B5, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_1B6] = { &sfx1B6, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_VO_GORON1] = { &sfxVoGoron1, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_VO_GORON2] = { &sfxVoGoron2, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_VO_GORON3] = { &sfxVoGoron3, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_VO_GORON4] = { &sfxVoGoron4, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_EM_DEKUSCRUB_HIT] = { &sfxEmDekuscrubHit, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_1BC] = { &sfx1BC, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_1BD] = { &sfx1BD, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_1BE] = { &sfx1BE, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_1BF] = { &sfx1BF, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_1C0] = { &sfx1C0, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_1C1] = { &sfx1C1, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_1C2] = { &sfx1C2, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_1C3] = { &sfx1C3, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_1C4] = { &sfx1C4, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1C5] = { &sfx1C5, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_1C6] = { &sfx1C6, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_1C7] = { &sfx1C7, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1C8] = { &sfx1C8, MUSIC_PLAYER_00, MUSIC_PLAYER_00 }, + [SFX_1C9] = { &sfx1C9, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_1CA] = { &sfx1CA, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_1CB] = { &sfx1CB, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_1CC] = { &sfx1CC, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_ELEMENT_PLACE] = { &sfxElementPlace, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_ELEMENT_FLOAT] = { &sfxElementFloat, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_ELEMENT_CHARGE] = { &sfxElementCharge, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_1D0] = { &sfx1D0, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_ELEMENT_INFUSE] = { &sfxElementInfuse, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_1D2] = { &sfx1D2, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_1D3] = { &sfx1D3, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_1D4] = { &sfx1D4, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_1D5] = { &sfx1D5, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_VO_CUCCO1] = { &sfxVoCucco1, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_VO_CUCCO2] = { &sfxVoCucco2, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_VO_CUCCO3] = { &sfxVoCucco3, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_VO_CUCCO4] = { &sfxVoCucco4, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_VO_CUCCO5] = { &sfxVoCucco5, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_1DB] = { &sfx1DB, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_1DC] = { &sfx1DC, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_1DD] = { &sfx1DD, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_1DE] = { &sfx1DE, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1DF] = { &sfx1DF, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1E0] = { &sfx1E0, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1E1] = { &sfx1E1, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1E2] = { &sfx1E2, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1E3] = { &sfx1E3, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_1E4] = { &sfx1E4, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_1E5] = { &sfx1E5, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_1E6] = { &sfx1E6, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_1E7] = { &sfx1E7, MUSIC_PLAYER_02, MUSIC_PLAYER_02 }, + [SFX_1E8] = { &sfx1E8, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_1E9] = { &sfx1E9, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_1EA] = { &sfx1EA, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_1EB] = { &sfx1EB, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_1EC] = { &sfx1EC, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_1ED] = { &sfx1ED, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_1EE] = { &sfx1EE, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_1EF] = { &sfx1EF, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_1F0] = { &sfx1F0, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_1F1] = { &sfx1F1, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_1F2] = { &sfx1F2, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_1F3] = { &sfx1F3, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_1F4] = { &sfx1F4, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_1F5] = { &sfx1F5, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_1F6] = { &sfx1F6, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_1F7] = { &sfx1F7, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_1F8] = { &sfx1F8, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_1F9] = { &sfx1F9, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_1FA] = { &sfx1FA, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_1FB] = { &sfx1FB, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_1FC] = { &sfx1FC, MUSIC_PLAYER_12, MUSIC_PLAYER_12 }, + [SFX_1FD] = { &sfx1FD, MUSIC_PLAYER_13, MUSIC_PLAYER_13 }, + [SFX_1FE] = { &sfx1FE, MUSIC_PLAYER_14, MUSIC_PLAYER_14 }, + [SFX_1FF] = { &sfx1FF, MUSIC_PLAYER_15, MUSIC_PLAYER_15 }, + [SFX_200] = { &sfx200, MUSIC_PLAYER_16, MUSIC_PLAYER_16 }, + [SFX_201] = { &sfx201, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, + [SFX_202] = { &sfx202, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_203] = { &sfx203, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_204] = { &sfx204, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_205] = { &sfx205, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_206] = { &sfx206, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_207] = { &sfx207, MUSIC_PLAYER_11, MUSIC_PLAYER_11 }, + [SFX_208] = { &sfx208, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_209] = { &sfx209, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_20A] = { &sfx20A, MUSIC_PLAYER_06, MUSIC_PLAYER_06 }, + [SFX_20B] = { &sfx20B, MUSIC_PLAYER_07, MUSIC_PLAYER_07 }, + [SFX_20C] = { &sfx20C, MUSIC_PLAYER_08, MUSIC_PLAYER_08 }, + [SFX_20D] = { &sfx20D, MUSIC_PLAYER_09, MUSIC_PLAYER_09 }, + [SFX_20E] = { &sfx20E, MUSIC_PLAYER_0A, MUSIC_PLAYER_0A }, + [SFX_20F] = { &sfx20F, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_210] = { &sfx210, MUSIC_PLAYER_0C, MUSIC_PLAYER_0C }, + [SFX_211] = { &sfx211, MUSIC_PLAYER_0D, MUSIC_PLAYER_0D }, + [SFX_212] = { &sfx212, MUSIC_PLAYER_0E, MUSIC_PLAYER_0E }, + [SFX_213] = { &sfx213, MUSIC_PLAYER_0F, MUSIC_PLAYER_0F }, + [SFX_214] = { &sfx214, MUSIC_PLAYER_10, MUSIC_PLAYER_10 }, + [SFX_215] = { &sfx215, MUSIC_PLAYER_05, MUSIC_PLAYER_05 }, + [SFX_216] = { &sfx216, MUSIC_PLAYER_1E, MUSIC_PLAYER_1E }, + [SFX_217] = { &sfx217, MUSIC_PLAYER_1E, MUSIC_PLAYER_1E }, + [SFX_218] = { &sfx218, MUSIC_PLAYER_04, MUSIC_PLAYER_04 }, + [SFX_219] = { &sfx219, MUSIC_PLAYER_03, MUSIC_PLAYER_03 }, + [SFX_21A] = { &sfx21A, MUSIC_PLAYER_0B, MUSIC_PLAYER_0B }, + [SFX_21B] = { &sfx21B, MUSIC_PLAYER_1D, MUSIC_PLAYER_1D }, + [SFX_21C] = { &sfx21C, MUSIC_PLAYER_1C, MUSIC_PLAYER_1C }, + [SFX_21D] = { &sfx21D, MUSIC_PLAYER_1B, MUSIC_PLAYER_1B }, + [SFX_21E] = { &sfx21E, MUSIC_PLAYER_1A, MUSIC_PLAYER_1A }, + [SFX_21F] = { &sfx21F, MUSIC_PLAYER_19, MUSIC_PLAYER_19 }, + [SFX_220] = { &sfx220, MUSIC_PLAYER_18, MUSIC_PLAYER_18 }, + [SFX_221] = { &sfx221, MUSIC_PLAYER_17, MUSIC_PLAYER_17 }, +}; diff --git a/src/code_0805F9A0.c b/src/code_0805F9A0.c index 66ac2ba9..856357d5 100644 --- a/src/code_0805F9A0.c +++ b/src/code_0805F9A0.c @@ -21,16 +21,6 @@ typedef struct { u8 unk1; } UStruct; -typedef struct { - u8 unk0; - u8 unk1; - u8 unk2; - u8 unk3; - u16 unk4; - u16 unk6; - void* unk8; -} WStruct; - void sub_0805F820(WStruct* r0, u32* r1); u32 sub_0805F7DC(u32 r0, WStruct* r1) { diff --git a/src/debugScreen.c b/src/debugScreen.c index bc034e8e..b75181f2 100644 --- a/src/debugScreen.c +++ b/src/debugScreen.c @@ -7,8 +7,6 @@ #include "structures.h" #include "textbox.h" -extern u8 gBG3Buffer[]; - extern void (*const gUnk_08109A30[])(); void HandleDebugTextScreen() { @@ -17,8 +15,8 @@ void HandleDebugTextScreen() { void sub_0805FA04(void) { DispReset(1); - MemClear(&gBG0Buffer, sizeof(BGBuffer)); - MemClear(&gBG3Buffer, 0x1000); + MemClear(&gBG0Buffer, sizeof(gBG0Buffer)); + MemClear(&gBG3Buffer, sizeof(gBG3Buffer)); gScreen.lcd.displayControl = 0x940; gScreen.bg.bg0xOffset = 0; gScreen.bg.bg0yOffset = 0; @@ -33,7 +31,7 @@ void sub_0805FA04(void) { sub_08053320(); sub_0801D79C(0, 0x1144); gMain.funcIndex = 1; - sub_080A3210(); + InitSoundPlayingInfo(); sub_08050008(); } diff --git a/src/enemy/gyorgMale.c b/src/enemy/gyorgMale.c index 4b73349a..9c703777 100644 --- a/src/enemy/gyorgMale.c +++ b/src/enemy/gyorgMale.c @@ -908,7 +908,7 @@ void sub_08047BA4(Entity* this) { } else { this->field_0x76.HWORD = 0x88; } - SoundReq(0x1B5); + SoundReq(SFX_1B5); sub_08047BF0(this); } @@ -938,7 +938,7 @@ void sub_08047BF0(Entity* this) { if (this->y.HALF.HI > gRoomControls.roomOriginY + 0x270) { this->subAction = 2; this->field_0x7c.HALF.HI = 0xAA; - SoundReq(0x12D); + SoundReq(SFX_12D); InitAnimationForceUpdate(this, 1); } } else { diff --git a/src/enemy/rope.c b/src/enemy/rope.c index 0859bae6..1b196527 100644 --- a/src/enemy/rope.c +++ b/src/enemy/rope.c @@ -2,6 +2,7 @@ #include "entity.h" #include "enemy.h" #include "random.h" +#include "audio.h" #include "functions.h" extern void (*const gRope[6])(Entity*); @@ -83,7 +84,7 @@ void sub_08031480(Entity* this) { this->spriteSettings.b.draw = 3; this->spriteRendering.b3 = 1; this->spriteOrientation.flipY = 1; - SoundReq(0x12d); + SoundReq(SFX_12D); } } else { if (sub_08003FC4(this, 0x1800) == 0) { diff --git a/src/enemy/spinyChuchu.c b/src/enemy/spinyChuchu.c index 21396115..bd0ca141 100644 --- a/src/enemy/spinyChuchu.c +++ b/src/enemy/spinyChuchu.c @@ -1,6 +1,7 @@ #include "enemy.h" #include "entity.h" #include "random.h" +#include "audio.h" #include "functions.h" extern void sub_08001318(Entity*); @@ -123,7 +124,7 @@ void sub_08022654(Entity* this) { if (--this->field_0xf) return; this->subAction = 1; - SoundReq(0x12d); + SoundReq(SFX_12D); InitializeAnimation(this, 0); /* fallthrough */ case 1: diff --git a/src/enemy/vaatiBall.c b/src/enemy/vaatiBall.c index 3907e270..7420c131 100644 --- a/src/enemy/vaatiBall.c +++ b/src/enemy/vaatiBall.c @@ -2,6 +2,7 @@ #include "player.h" #include "screen.h" #include "createObject.h" +#include "audio.h" #include "functions.h" typedef struct { @@ -39,7 +40,7 @@ void VaatiBall(Entity* this) { this->currentHealth = -1; parent->field_0x80.HALF.LO--; CreateDust(this); - SoundReq(0x1c3); + SoundReq(SFX_1C3); } } } @@ -368,7 +369,7 @@ void sub_08044B04(Entity* this) { if (this->actionDelay) { if (--this->actionDelay == 0) { this->speed = 1280; - SoundReq(0x14f); + SoundReq(SFX_14F); } } if (this->field_0x78.HALF.HI == 3) diff --git a/src/enemy/waterDrop.c b/src/enemy/waterDrop.c index f994b564..918ab7d4 100644 --- a/src/enemy/waterDrop.c +++ b/src/enemy/waterDrop.c @@ -3,12 +3,11 @@ #include "screen.h" #include "random.h" #include "functions.h" +#include "structures.h" void sub_0802A39C(Entity*); void sub_0802A334(Entity*); -extern u16 gBG3Buffer[]; - extern void (*const gUnk_080CD030[])(Entity*); extern const u8 gUnk_080CD03C[]; extern const s8 gUnk_080CD040[]; diff --git a/src/ezloNag.c b/src/ezloNag.c index 0ad98db7..5d3ec162 100644 --- a/src/ezloNag.c +++ b/src/ezloNag.c @@ -1,6 +1,5 @@ -#include "audio.h" #include "global.h" -#include "functions.h" +#include "audio.h" #include "textbox.h" #include "structures.h" diff --git a/src/fileScreen.c b/src/fileScreen.c index b55977ca..717db8a6 100644 --- a/src/fileScreen.c +++ b/src/fileScreen.c @@ -6,6 +6,7 @@ #include "menu.h" #include "random.h" #include "textbox.h" +#include "functions.h" // copy, erase, start #define NUM_FILE_OPERATIONS 3 @@ -190,7 +191,7 @@ static void HandleFileScreenEnter(void) { u32 i; DispReset(1); - sub_080A3210(); + InitSoundPlayingInfo(); MemClear((void*)VRAM, 0x80); // clear palettes MessageInitialize(); EraseAllEntities(); @@ -498,7 +499,7 @@ void sub_08050AFC(u32 idx) { SetActiveSave(idx); MemClear(&gBG1Buffer, sizeof(gBG1Buffer)); if (gUnk_02019EE0.saveStatus[idx] == SAVE_VALID) { - sub_08050B3C(&gBG1Buffer.unk29C); + sub_08050B3C(&gBG1Buffer[0x14E]); } gScreen.bg.bg1Updated = 1; } diff --git a/src/game.c b/src/game.c index 91940328..2b9e9e32 100644 --- a/src/game.c +++ b/src/game.c @@ -1,6 +1,5 @@ #include "global.h" #include "screen.h" -#include "structures.h" #include "screen.h" #include "entity.h" #include "player.h" @@ -10,7 +9,9 @@ #include "save.h" #include "utils.h" #include "fileScreen.h" +#include "menu.h" #include "functions.h" +#include "structures.h" extern u8 gArea; extern Entity gPlayerEntity; diff --git a/src/gba/m4a.c b/src/gba/m4a.c new file mode 100644 index 00000000..82dbb39e --- /dev/null +++ b/src/gba/m4a.c @@ -0,0 +1,1676 @@ +#include "global.h" +#include "gba/m4a.h" + +#include "gba/gba.h" + +// ASCII encoding of 'Smsh' in reverse +// This is presumably short for SMASH, the developer of MKS4AGB. +#define ID_NUMBER 'hsmS' + +#define C_V 0x40 // center value for PAN, BEND, and TUNE + +#define SOUND_MODE_REVERB_VAL 0x0000007F +#define SOUND_MODE_REVERB_SET 0x00000080 +#define SOUND_MODE_MAXCHN 0x00000F00 +#define SOUND_MODE_MAXCHN_SHIFT 8 +#define SOUND_MODE_MASVOL 0x0000F000 +#define SOUND_MODE_MASVOL_SHIFT 12 +#define SOUND_MODE_FREQ_05734 0x00010000 +#define SOUND_MODE_FREQ_07884 0x00020000 +#define SOUND_MODE_FREQ_10512 0x00030000 +#define SOUND_MODE_FREQ_13379 0x00040000 +#define SOUND_MODE_FREQ_15768 0x00050000 +#define SOUND_MODE_FREQ_18157 0x00060000 +#define SOUND_MODE_FREQ_21024 0x00070000 +#define SOUND_MODE_FREQ_26758 0x00080000 +#define SOUND_MODE_FREQ_31536 0x00090000 +#define SOUND_MODE_FREQ_36314 0x000A0000 +#define SOUND_MODE_FREQ_40137 0x000B0000 +#define SOUND_MODE_FREQ_42048 0x000C0000 +#define SOUND_MODE_FREQ 0x000F0000 +#define SOUND_MODE_FREQ_SHIFT 16 +#define SOUND_MODE_DA_BIT_9 0x00800000 +#define SOUND_MODE_DA_BIT_8 0x00900000 +#define SOUND_MODE_DA_BIT_7 0x00A00000 +#define SOUND_MODE_DA_BIT_6 0x00B00000 +#define SOUND_MODE_DA_BIT 0x00B00000 +#define SOUND_MODE_DA_BIT_SHIFT 20 + +typedef void (*MPlayFunc)(); +typedef void (*PlyNoteFunc)(u32, MusicPlayerInfo*, MusicPlayerTrack*); +typedef void (*CgbSoundFunc)(void); +typedef void (*CgbOscOffFunc)(u8); +typedef u32 (*MidiKeyToCgbFreqFunc)(u8, u8, u8); +typedef void (*ExtVolPitFunc)(void); +typedef void (*XcmdFunc)(MusicPlayerInfo*, MusicPlayerTrack*); + +typedef struct CgbChannel { + u8 statusFlags; + u8 type; + u8 rightVolume; + u8 leftVolume; + u8 attack; + u8 decay; + u8 sustain; + u8 release; + u8 key; + u8 envelopeVolume; + u8 envelopeGoal; + u8 envelopeCounter; + u8 echoVolume; + u8 echoLength; + u8 unk0; + u8 unk1; + u8 gateTime; + u8 midiKey; + u8 velocity; + u8 priority; + u8 rhythmPan; + u8 unk2[3]; + u8 unk3; + u8 sustainGoal; + u8 n4; // NR[1-4]4 register (initial, length bit) + u8 pan; + u8 panMask; + u8 modify; + u8 length; + u8 sweep; + u32 frequency; + u32* nextWave; + u32* currentWave; + u32 track; + u32 prev; + u32 next; + u8 unk4[8]; +} CgbChannel; + +#define MAX_DIRECTSOUND_CHANNELS 12 + +#define PCM_DMA_BUF_SIZE 1584 // size of Direct Sound buffer + +typedef struct SoundInfo { + // This field is normally equal to ID_NUMBER but it is set to other + // values during sensitive operations for locking purposes. + // This field should be volatile but isn't. This could potentially cause + // race conditions. + u32 ident; + + vu8 pcmDmaCounter; + + // Direct Sound + u8 reverb; + u8 maxChannels; + u8 masterVolume; + u8 frequency; + + u8 mode; + u8 c15; // periodically counts from 14 down to 0 (15 states) + u8 pcmDmaPeriod; // number of V-blanks per PCM DMA + u8 maxLines; + u8 gap[3]; + s32 pcmSamplesPerVBlank; + s32 pcmFreqency; + s32 divFreq; + CgbChannel* cgbChannels; + MPlayMainFunc MPlayMainHead; + void* intp; + void (*CgbSound)(void); + void (*CgbOscOff)(u8); + u32 (*MidiKeyToCgbFreq)(u8, u8, u8); + void* MPlayJumpTable; + void* plynote; + void (*ExtVolPit)(void); + u8 gap2[16]; + SoundChannel chans[MAX_DIRECTSOUND_CHANNELS]; + s8 pcmBuffer[PCM_DMA_BUF_SIZE]; +} SoundInfo; + +#define MUSICPLAYER_STATUS_TRACK 0x0000ffff +#define MUSICPLAYER_STATUS_PAUSE 0x80000000 + +#define MAX_MUSICPLAYER_TRACKS 16 + +#define TEMPORARY_FADE 0x0001 +#define FADE_IN 0x0002 +#define FADE_VOL_MAX 64 +#define FADE_VOL_SHIFT 2 + +extern u8 gMPlayMemAccArea[]; + +extern char SoundMainRAM[]; + +extern void* gMPlayJumpTable[]; + +extern CgbChannel gCgbChans[]; + +extern char gNumMusicPlayers[]; +extern char gMaxLines[]; + +#define NUM_MUSIC_PLAYERS ((u16)gNumMusicPlayers) +#define MAX_LINES ((u32)gMaxLines) + +u32 umul3232H32(u32 multiplier, u32 multiplicand); +void SoundMain(void); +void SoundMainBTM(void); +void TrackStop(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track); +void MPlayMain(); +void RealClearChain(void* x); + +void MPlayContinue(MusicPlayerInfo* mplayInfo); +void MPlayStart(MusicPlayerInfo* mplayInfo, const SongHeader* songHeader); +void MPlayStop(MusicPlayerInfo* mplayInfo); +void FadeOutBody(MusicPlayerInfo* mplayInfo); +void TrkVolPitSet(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track); +void MPlayFadeOut(MusicPlayerInfo* mplayInfo, u16 speed); +void ClearChain(void* x); +void Clear64byte(void* addr); +void SoundInit(SoundInfo* soundInfo); +void MPlayExtender(CgbChannel* cgbChans); +void m4aSoundMode(u32 mode); +void MPlayOpen(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track, u8 trackCount); +void CgbSound(void); +void CgbOscOff(u8); +u32 MidiKeyToCgbFreq(u8, u8, u8); +void nullsub_141(void); +void MPlayJumpTableCopy(void** mplayJumpTable); +void SampleFreqSet(u32 freq); + +void m4aMPlayVolumeControl(MusicPlayerInfo* mplayInfo, u16 trackBits, u16 volume); +void m4aMPlayPitchControl(MusicPlayerInfo* mplayInfo, u16 trackBits, s16 pitch); +void m4aMPlayPanpotControl(MusicPlayerInfo* mplayInfo, u16 trackBits, s8 pan); +void ClearModM(MusicPlayerTrack* track); +void m4aMPlayModDepthSet(MusicPlayerInfo* mplayInfo, u16 trackBits, u8 modDepth); +void m4aMPlayLFOSpeedSet(MusicPlayerInfo* mplayInfo, u16 trackBits, u8 lfoSpeed); + +// sound command handler functions +void ply_fine(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_goto(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_patt(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_pend(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_rept(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_memacc(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_prio(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_tempo(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_keysh(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_voice(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_vol(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_pan(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_bend(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_bendr(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_lfos(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_lfodl(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_mod(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_modt(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_tune(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_port(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xcmd(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_endtie(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_note(MusicPlayerInfo*, MusicPlayerTrack*); + +// extended sound command handler functions +void ply_xxx(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xwave(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xtype(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xatta(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xdeca(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xsust(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xrele(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xiecv(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xiecl(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xleng(MusicPlayerInfo*, MusicPlayerTrack*); +void ply_xswee(MusicPlayerInfo*, MusicPlayerTrack*); + +u8 SoundMainRAM_Buffer[0x380]; +extern SoundInfo gSoundInfo; + +#define SOUND_CHANNEL_SF_START 0x80 +#define SOUND_CHANNEL_SF_STOP 0x40 +#define SOUND_CHANNEL_SF_LOOP 0x10 +#define SOUND_CHANNEL_SF_IEC 0x04 +#define SOUND_CHANNEL_SF_ENV 0x03 +#define SOUND_CHANNEL_SF_ENV_ATTACK 0x03 +#define SOUND_CHANNEL_SF_ENV_DECAY 0x02 +#define SOUND_CHANNEL_SF_ENV_SUSTAIN 0x01 +#define SOUND_CHANNEL_SF_ENV_RELEASE 0x00 +#define SOUND_CHANNEL_SF_ON \ + (SOUND_CHANNEL_SF_START | SOUND_CHANNEL_SF_STOP | SOUND_CHANNEL_SF_IEC | SOUND_CHANNEL_SF_ENV) + +#define CGB_CHANNEL_MO_PIT 0x02 +#define CGB_CHANNEL_MO_VOL 0x01 + +#define CGB_NRx2_ENV_DIR_DEC 0x00 +#define CGB_NRx2_ENV_DIR_INC 0x08 + +void* const gMPlayJumpTableTemplate[] = { + ply_fine, ply_goto, ply_patt, ply_pend, ply_rept, ply_fine, ply_fine, ply_fine, ply_fine, + ply_prio, ply_tempo, ply_keysh, ply_voice, ply_vol, ply_pan, ply_bend, ply_bendr, ply_lfos, + ply_lfodl, ply_mod, ply_modt, ply_fine, ply_fine, ply_tune, ply_fine, ply_fine, ply_fine, + ply_port, ply_fine, ply_endtie, SampleFreqSet, TrackStop, FadeOutBody, TrkVolPitSet, RealClearChain, SoundMainBTM, +}; + +const u8 gScaleTable[] = { + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, + 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, + 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, +}; + +const u32 gFreqTable[] = { + 2147483648u, 2275179671u, 2410468894u, 2553802834u, 2705659852u, 2866546760u, + 3037000500u, 3217589947u, 3408917802u, 3611622603u, 3826380858u, 4053909305u, +}; + +const u16 gPcmSamplesPerVBlankTable[] = { + 96, 132, 176, 224, 264, 304, 352, 448, 528, 608, 672, 704, +}; + +const u8 gCgbScaleTable[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4A, 0x4B, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, + 0x7B, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, +}; + +const s16 gCgbFreqTable[] = { + -2004, -1891, -1785, -1685, -1591, -1501, -1417, -1337, -1262, -1192, -1125, -1062, +}; + +const u8 gNoiseTable[] = { + 0xD7, 0xD6, 0xD5, 0xD4, 0xC7, 0xC6, 0xC5, 0xC4, 0xB7, 0xB6, 0xB5, 0xB4, 0xA7, 0xA6, 0xA5, + 0xA4, 0x97, 0x96, 0x95, 0x94, 0x87, 0x86, 0x85, 0x84, 0x77, 0x76, 0x75, 0x74, 0x67, 0x66, + 0x65, 0x64, 0x57, 0x56, 0x55, 0x54, 0x47, 0x46, 0x45, 0x44, 0x37, 0x36, 0x35, 0x34, 0x27, + 0x26, 0x25, 0x24, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, +}; + +const u8 gCgb3Vol[] = { + 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x40, 0x40, 0x40, 0x40, 0x80, 0x80, 0x80, 0x80, 0x20, 0x20, +}; + +const u8 gClockTable[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1C, 0x1E, 0x20, 0x24, 0x28, 0x2A, 0x2C, 0x30, 0x34, + 0x36, 0x38, 0x3C, 0x40, 0x42, 0x44, 0x48, 0x4C, 0x4E, 0x50, 0x54, 0x58, 0x5A, 0x5C, 0x60, +}; + +const XcmdFunc gXcmdTable[] = { + ply_xxx, ply_xwave, ply_xtype, ply_xxx, ply_xatta, ply_xdeca, + ply_xsust, ply_xrele, ply_xiecv, ply_xiecl, ply_xleng, ply_xswee, +}; + +void nullsub_544(); + +u32 MidiKeyToFreq(WaveData* wav, u8 key, u8 fineAdjust) { + u32 val1; + u32 val2; + u32 fineAdjustShifted = fineAdjust << 24; + + if (key > 178) { + key = 178; + fineAdjustShifted = 255 << 24; + } + + val1 = gScaleTable[key]; + val1 = gFreqTable[val1 & 0xF] >> (val1 >> 4); + + val2 = gScaleTable[key + 1]; + val2 = gFreqTable[val2 & 0xF] >> (val2 >> 4); + + return umul3232H32(wav->freq, val1 + umul3232H32(val2 - val1, fineAdjustShifted)); +} + +void nullsub_543() { +} + +void MPlayContinue(MusicPlayerInfo* mplayInfo) { + if (mplayInfo->ident == ID_NUMBER) { + mplayInfo->ident++; + mplayInfo->status &= ~MUSICPLAYER_STATUS_PAUSE; + mplayInfo->ident = ID_NUMBER; + } +} + +void MPlayFadeOut(MusicPlayerInfo* mplayInfo, u16 speed) { + if (mplayInfo->ident == ID_NUMBER) { + mplayInfo->ident++; + mplayInfo->fadeOC = speed; + mplayInfo->fadeOI = speed; + mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT); + mplayInfo->ident = ID_NUMBER; + } +} + +void m4aSoundInit(void) { + s32 i; + + CpuCopy32((void*)((s32)SoundMainRAM & ~1), SoundMainRAM_Buffer, sizeof(SoundMainRAM_Buffer)); + + SoundInit(&gSoundInfo); + MPlayExtender(gCgbChans); + m4aSoundMode(SOUND_MODE_DA_BIT_8 | SOUND_MODE_FREQ_15768 | (0xf << SOUND_MODE_MASVOL_SHIFT) | + (8 << SOUND_MODE_MAXCHN_SHIFT)); + + for (i = 0; i < NUM_MUSIC_PLAYERS; i++) { + MusicPlayerInfo* mplayInfo = gMusicPlayers[i].info; + MPlayOpen(mplayInfo, gMusicPlayers[i].tracks, gMusicPlayers[i].nTracks); + mplayInfo->unk_B = gMusicPlayers[i].unk_A; + mplayInfo->memAccArea = gMPlayMemAccArea; + } +} + +void m4aSoundMain(void) { + SoundMain(); +} + +void m4aSongNumStart(u16 n) { + const MusicPlayer* mplayTable = gMusicPlayers; + const Song* songTable = gSongTable; + const Song* song = &songTable[n]; + const MusicPlayer* mplay = &mplayTable[song->musicPlayerIndex]; + + MPlayStart(mplay->info, song->header); +} + +void m4aSongNumStartOrChange(u16 n) { + const MusicPlayer* mplayTable = gMusicPlayers; + const Song* songTable = gSongTable; + const Song* song = &songTable[n]; + const MusicPlayer* mplay = &mplayTable[song->musicPlayerIndex]; + + if (mplay->info->songHeader != song->header) { + MPlayStart(mplay->info, song->header); + } else { + if ((mplay->info->status & MUSICPLAYER_STATUS_TRACK) == 0 || (mplay->info->status & MUSICPLAYER_STATUS_PAUSE)) { + MPlayStart(mplay->info, song->header); + } + } +} + +void m4aSongNumStartOrContinue(u16 n) { + const MusicPlayer* mplayTable = gMusicPlayers; + const Song* songTable = gSongTable; + const Song* song = &songTable[n]; + const MusicPlayer* mplay = &mplayTable[song->musicPlayerIndex]; + + if (mplay->info->songHeader != song->header) + MPlayStart(mplay->info, song->header); + else if ((mplay->info->status & MUSICPLAYER_STATUS_TRACK) == 0) + MPlayStart(mplay->info, song->header); + else if (mplay->info->status & MUSICPLAYER_STATUS_PAUSE) + MPlayContinue(mplay->info); +} + +void m4aSongNumStop(u16 n) { + const MusicPlayer* mplayTable = gMusicPlayers; + const Song* songTable = gSongTable; + const Song* song = &songTable[n]; + const MusicPlayer* mplay = &mplayTable[song->musicPlayerIndex]; + + if (mplay->info->songHeader == song->header) + MPlayStop(mplay->info); +} + +void m4aSongNumContinue(u16 n) { + const MusicPlayer* mplayTable = gMusicPlayers; + const Song* songTable = gSongTable; + const Song* song = &songTable[n]; + const MusicPlayer* mplay = &mplayTable[song->musicPlayerIndex]; + + if (mplay->info->songHeader == song->header) + MPlayContinue(mplay->info); +} + +void m4aMPlayAllStop(void) { + s32 i; + + for (i = 0; i < NUM_MUSIC_PLAYERS; i++) + MPlayStop(gMusicPlayers[i].info); +} + +void m4aMPlayContinue(MusicPlayerInfo* mplayInfo) { + MPlayContinue(mplayInfo); +} + +void m4aMPlayAllContinue(void) { + s32 i; + + for (i = 0; i < NUM_MUSIC_PLAYERS; i++) + MPlayContinue(gMusicPlayers[i].info); +} + +void m4aMPlayFadeOut(MusicPlayerInfo* mplayInfo, u16 speed) { + MPlayFadeOut(mplayInfo, speed); +} + +void m4aMPlayFadeOutTemporarily(MusicPlayerInfo* mplayInfo, u16 speed) { + if (mplayInfo->ident == ID_NUMBER) { + mplayInfo->ident++; + mplayInfo->fadeOC = speed; + mplayInfo->fadeOI = speed; + mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT) | TEMPORARY_FADE; + mplayInfo->ident = ID_NUMBER; + } +} + +void m4aMPlayFadeIn(MusicPlayerInfo* mplayInfo, u16 speed) { + if (mplayInfo->ident == ID_NUMBER) { + mplayInfo->ident++; + mplayInfo->fadeOC = speed; + mplayInfo->fadeOI = speed; + mplayInfo->fadeOV = (0 << FADE_VOL_SHIFT) | FADE_IN; + mplayInfo->status &= ~MUSICPLAYER_STATUS_PAUSE; + mplayInfo->ident = ID_NUMBER; + } +} + +void m4aMPlayImmInit(MusicPlayerInfo* mplayInfo) { + s32 trackCount; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + trackCount = mplayInfo->trackCount; + track = mplayInfo->tracks; + + while (trackCount > 0) { + if (track->flags & MPT_FLG_EXIST) { + if (track->flags & MPT_FLG_START) { + Clear64byte(track); + track->flags = MPT_FLG_EXIST; + track->bendRange = 2; + track->volX = 64; + track->lfoSpeed = 22; + track->tone.type = 1; + } + } + + trackCount--; + track++; + } + mplayInfo->ident = ID_NUMBER; +} + +void MPlayExtender(CgbChannel* cgbChans) { + SoundInfo* soundInfo; + u32 ident; + + REG_SOUNDCNT_X = SOUND_MASTER_ENABLE | SOUND_4_ON | SOUND_3_ON | SOUND_2_ON | SOUND_1_ON; + REG_SOUNDCNT_L = 0; // set master volume to zero + REG_NR12 = 0x8; + REG_NR22 = 0x8; + REG_NR42 = 0x8; + REG_NR14 = 0x80; + REG_NR24 = 0x80; + REG_NR44 = 0x80; + REG_NR30 = 0; + REG_NR50 = 0x77; + + soundInfo = SOUND_INFO_PTR; + + ident = soundInfo->ident; + + if (ident != ID_NUMBER) + return; + + soundInfo->ident++; + + gMPlayJumpTable[8] = ply_memacc; + gMPlayJumpTable[17] = ply_lfos; + gMPlayJumpTable[19] = ply_mod; + gMPlayJumpTable[28] = ply_xcmd; + gMPlayJumpTable[29] = ply_endtie; + gMPlayJumpTable[30] = SampleFreqSet; + gMPlayJumpTable[31] = TrackStop; + gMPlayJumpTable[32] = FadeOutBody; + gMPlayJumpTable[33] = TrkVolPitSet; + + soundInfo->cgbChannels = cgbChans; + soundInfo->CgbSound = CgbSound; + soundInfo->CgbOscOff = CgbOscOff; + soundInfo->MidiKeyToCgbFreq = MidiKeyToCgbFreq; + soundInfo->maxLines = MAX_LINES; + + CpuFill32(0, cgbChans, sizeof(CgbChannel) * 4); + + cgbChans[0].type = 1; + cgbChans[0].panMask = 0x11; + cgbChans[1].type = 2; + cgbChans[1].panMask = 0x22; + cgbChans[2].type = 3; + cgbChans[2].panMask = 0x44; + cgbChans[3].type = 4; + cgbChans[3].panMask = 0x88; + + soundInfo->ident = ident; +} + +void MusicPlayerJumpTableCopy(void) { + asm("swi 0x2A"); +} + +void ClearChain(void* x) { + void (*func)(void*) = *(&gMPlayJumpTable[34]); + func(x); +} + +void Clear64byte(void* addr) { + void (*func)(void*) = *(&gMPlayJumpTable[35]); + func(addr); +} + +void SoundInit(SoundInfo* soundInfo) { + soundInfo->ident = 0; + + if (REG_DMA1CNT & (DMA_REPEAT << 16)) + REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4; + + REG_DMA1CNT_H = DMA_32BIT; + REG_SOUNDCNT_X = SOUND_MASTER_ENABLE | SOUND_4_ON | SOUND_3_ON | SOUND_2_ON | SOUND_1_ON; + REG_SOUNDCNT_H = + SOUND_A_FIFO_RESET | SOUND_A_TIMER_0 | SOUND_A_LEFT_OUTPUT | SOUND_A_RIGHT_OUTPUT | SOUND_ALL_MIX_FULL; + REG_SOUNDBIAS_H = (REG_SOUNDBIAS_H & 0x3F) | 0x40; + + REG_DMA1SAD = (s32)soundInfo->pcmBuffer; + REG_DMA1DAD = (s32)®_FIFO_A; + + SOUND_INFO_PTR = soundInfo; + CpuFill32(0, soundInfo, sizeof(SoundInfo)); + + soundInfo->maxChannels = 8; + soundInfo->masterVolume = 15; + soundInfo->plynote = ply_note; + soundInfo->CgbSound = nullsub_544; + soundInfo->CgbOscOff = (CgbOscOffFunc)nullsub_544; + soundInfo->MidiKeyToCgbFreq = (MidiKeyToCgbFreqFunc)nullsub_544; + soundInfo->ExtVolPit = (ExtVolPitFunc)nullsub_544; + + MPlayJumpTableCopy(gMPlayJumpTable); + + soundInfo->MPlayJumpTable = gMPlayJumpTable; + + SampleFreqSet(SOUND_MODE_FREQ_13379); + + soundInfo->ident = ID_NUMBER; +} + +void SampleFreqSet(u32 freq) { + SoundInfo* soundInfo; + m4aSoundVSyncOff(); + soundInfo = SOUND_INFO_PTR; + + freq = (freq & 0xF0000) >> 16; + soundInfo->frequency = freq; + soundInfo->pcmSamplesPerVBlank = gPcmSamplesPerVBlankTable[freq - 1]; + soundInfo->pcmDmaPeriod = PCM_DMA_BUF_SIZE / soundInfo->pcmSamplesPerVBlank; + + // LCD refresh rate 59.7275Hz + soundInfo->pcmFreqency = (597275 * soundInfo->pcmSamplesPerVBlank + 5000) / 10000; + + // CPU frequency 16.78Mhz + soundInfo->divFreq = (16777216 / soundInfo->pcmFreqency + 1) >> 1; + + m4aSoundVSyncOn(); +} + +void m4aSoundMode(u32 mode) { + SoundInfo* soundInfo = SOUND_INFO_PTR; + u32 temp; + + if (soundInfo->ident != ID_NUMBER) + return; + + soundInfo->ident++; + + temp = mode & (SOUND_MODE_REVERB_SET | SOUND_MODE_REVERB_VAL); + + if (temp) + soundInfo->reverb = temp & SOUND_MODE_REVERB_VAL; + + temp = mode & SOUND_MODE_MAXCHN; + + if (temp) { + SoundChannel* chan; + + soundInfo->maxChannels = temp >> SOUND_MODE_MAXCHN_SHIFT; + + temp = MAX_DIRECTSOUND_CHANNELS; + chan = &soundInfo->chans[0]; + + while (temp != 0) { + chan->statusFlags = 0; + temp--; + chan++; + } + } + + temp = mode & SOUND_MODE_MASVOL; + + if (temp) + soundInfo->masterVolume = temp >> SOUND_MODE_MASVOL_SHIFT; + + temp = mode & SOUND_MODE_DA_BIT; + + if (temp) { + temp = (temp & 0x300000) >> 14; + REG_SOUNDBIAS_H = (REG_SOUNDBIAS_H & 0x3F) | temp; + } + + temp = mode & SOUND_MODE_FREQ; + + if (temp) { + SampleFreqSet(temp); + } + + soundInfo->ident = ID_NUMBER; +} + +void SoundClear(void) { + SoundInfo* soundInfo = SOUND_INFO_PTR; + s32 i; + void* chan; + + if (soundInfo->ident != ID_NUMBER) + return; + + soundInfo->ident++; + + i = MAX_DIRECTSOUND_CHANNELS; + chan = &soundInfo->chans[0]; + + while (i > 0) { + ((SoundChannel*)chan)->statusFlags = 0; + i--; + chan = (void*)((s32)chan + sizeof(SoundChannel)); + } + + chan = soundInfo->cgbChannels; + + if (chan) { + i = 1; + + while (i <= 4) { + soundInfo->CgbOscOff(i); + ((CgbChannel*)chan)->statusFlags = 0; + i++; + chan = (void*)((s32)chan + sizeof(CgbChannel)); + } + } + + soundInfo->ident = ID_NUMBER; +} + +void m4aSoundVSyncOff(void) { + SoundInfo* soundInfo = SOUND_INFO_PTR; + + if (soundInfo->ident >= ID_NUMBER && soundInfo->ident <= ID_NUMBER + 1) { + soundInfo->ident += 10; + + REG_TM0CNT_H = 0; + + if (REG_DMA1CNT & (DMA_REPEAT << 16)) + REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4; + + REG_DMA1CNT_H = DMA_32BIT; + + CpuFill32(0, soundInfo->pcmBuffer, sizeof(soundInfo->pcmBuffer)); + } +} + +#define REG_VCOUNT_8 (*(vu8*)REG_ADDR_VCOUNT) + +void m4aSoundVSyncOn(void) { + SoundInfo* soundInfo = SOUND_INFO_PTR; + u32 ident = soundInfo->ident; + + if (ident == ID_NUMBER) + return; + + REG_DMA1CNT_H = DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT; + + soundInfo->pcmDmaCounter = 0; + soundInfo->ident = ident - 10; + + while (REG_VCOUNT_8 == 0x9f) {} + while (REG_VCOUNT_8 != 0x9f) {} + + REG_TM0CNT_L = -(0x44940 / soundInfo->pcmSamplesPerVBlank); + REG_TM0CNT_H = 0x80; +} + +void m4aSoundVSync(void) { + SoundInfo* soundInfo = SOUND_INFO_PTR; + + if (soundInfo->ident - ID_NUMBER > 1) + return; + + soundInfo->pcmDmaCounter--; + if ((s8)soundInfo->pcmDmaCounter > 0) + return; + soundInfo->pcmDmaCounter = soundInfo->pcmDmaPeriod; + if (REG_DMA1CNT & (DMA_REPEAT << 16)) { + REG_DMA1CNT = ((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4; + } + REG_DMA1CNT_H = DMA_32BIT; + REG_DMA1CNT_H = DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT; +} + +void MPlayOpen(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* tracks, u8 trackCount) { + SoundInfo* soundInfo; + + if (trackCount == 0) + return; + + if (trackCount > MAX_MUSICPLAYER_TRACKS) + trackCount = MAX_MUSICPLAYER_TRACKS; + + soundInfo = SOUND_INFO_PTR; + + if (soundInfo->ident != ID_NUMBER) + return; + + soundInfo->ident++; + + Clear64byte(mplayInfo); + + mplayInfo->tracks = tracks; + mplayInfo->trackCount = trackCount; + mplayInfo->status = MUSICPLAYER_STATUS_PAUSE; + + while (trackCount != 0) { + tracks->flags = 0; + trackCount--; + tracks++; + } + + // append music player and MPlayMain to linked list + + if (soundInfo->MPlayMainHead != NULL) { + mplayInfo->func = soundInfo->MPlayMainHead; + mplayInfo->intp = soundInfo->intp; + // NULL assignment semantically useless, but required for match + soundInfo->MPlayMainHead = NULL; + } + + soundInfo->intp = mplayInfo; + soundInfo->MPlayMainHead = MPlayMain; + soundInfo->ident = ID_NUMBER; + mplayInfo->ident = ID_NUMBER; +} + +void MPlayStart(MusicPlayerInfo* mplayInfo, const SongHeader* songHeader) { + s32 i; + u8 unk_B; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + mplayInfo->ident++; + + unk_B = mplayInfo->unk_B; + + if (!unk_B || + ((!mplayInfo->songHeader || !(mplayInfo->tracks[0].flags & MPT_FLG_START)) && + ((mplayInfo->status & MUSICPLAYER_STATUS_TRACK) == 0 || (mplayInfo->status & MUSICPLAYER_STATUS_PAUSE))) || + (mplayInfo->priority <= songHeader->priority)) { + mplayInfo->status = 0; + mplayInfo->songHeader = songHeader; + mplayInfo->tone = songHeader->tone; + mplayInfo->priority = songHeader->priority; + mplayInfo->clock = 0; + mplayInfo->tempoD = 150; + mplayInfo->tempoI = 150; + mplayInfo->tempoU = 0x100; + mplayInfo->tempoC = 0; + mplayInfo->fadeOI = 0; + + i = 0; + track = mplayInfo->tracks; + + while (i < songHeader->trackCount && i < mplayInfo->trackCount) { + TrackStop(mplayInfo, track); + track->flags = MPT_FLG_EXIST | MPT_FLG_START; + track->chan = 0; + track->cmdPtr = songHeader->part[i]; + i++; + track++; + } + + while (i < mplayInfo->trackCount) { + TrackStop(mplayInfo, track); + track->flags = 0; + i++; + track++; + } + + if (songHeader->reverb & SOUND_MODE_REVERB_SET) + m4aSoundMode(songHeader->reverb); + } + mplayInfo->ident = ID_NUMBER; +} + +void MPlayStop(MusicPlayerInfo* mplayInfo) { + s32 i; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + mplayInfo->status |= MUSICPLAYER_STATUS_PAUSE; + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + + while (i > 0) { + TrackStop(mplayInfo, track); + i--; + track++; + } + + mplayInfo->ident = ID_NUMBER; +} + +void FadeOutBody(MusicPlayerInfo* mplayInfo) { + s32 i; + MusicPlayerTrack* track; + u16 fadeOV; + + if (mplayInfo->fadeOI == 0) + return; + if (--mplayInfo->fadeOC != 0) + return; + + mplayInfo->fadeOC = mplayInfo->fadeOI; + + if (mplayInfo->fadeOV & FADE_IN) { + if ((u16)(mplayInfo->fadeOV += (4 << FADE_VOL_SHIFT)) >= (64 << FADE_VOL_SHIFT)) { + mplayInfo->fadeOV = (64 << FADE_VOL_SHIFT); + mplayInfo->fadeOI = 0; + } + } else { + if ((s16)(mplayInfo->fadeOV -= (4 << FADE_VOL_SHIFT)) <= 0) { + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + + while (i > 0) { + u32 val; + + TrackStop(mplayInfo, track); + + fadeOV = mplayInfo->fadeOV; + val = TEMPORARY_FADE; + val &= fadeOV; + + if (!val) + track->flags = 0; + + i--; + track++; + } + + if (mplayInfo->fadeOV & TEMPORARY_FADE) + mplayInfo->status |= MUSICPLAYER_STATUS_PAUSE; + else + mplayInfo->status = MUSICPLAYER_STATUS_PAUSE; + + mplayInfo->fadeOI = 0; + return; + } + } + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + + while (i > 0) { + if (track->flags & MPT_FLG_EXIST) { + fadeOV = mplayInfo->fadeOV; + + track->volX = (fadeOV >> FADE_VOL_SHIFT); + track->flags |= MPT_FLG_VOLCHG; + } + + i--; + track++; + } +} + +void TrkVolPitSet(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + if (track->flags & MPT_FLG_VOLSET) { + s32 x; + s32 y; + + x = (u32)(track->vol * track->volX) >> 5; + + if (track->modT == 1) + x = (u32)(x * (track->modM + 128)) >> 7; + + y = 2 * track->pan + track->panX; + + if (track->modT == 2) + y += track->modM; + + if (y < -128) + y = -128; + else if (y > 127) + y = 127; + + track->volMR = (u32)((y + 128) * x) >> 8; + track->volML = (u32)((127 - y) * x) >> 8; + } + + if (track->flags & MPT_FLG_PITSET) { + s32 bend = track->bend * track->bendRange; + s32 x = (track->tune + bend) * 4 + (track->keyShift << 8) + (track->keyShiftX << 8) + track->pitX; + + if (track->modT == 0) + x += 16 * track->modM; + + track->keyM = x >> 8; + track->pitM = x; + } + + track->flags &= ~(MPT_FLG_PITSET | MPT_FLG_VOLSET); +} + +u32 MidiKeyToCgbFreq(u8 chanNum, u8 key, u8 fineAdjust) { + if (chanNum == 4) { + if (key <= 20) { + key = 0; + } else { + key -= 21; + if (key > 59) + key = 59; + } + + return gNoiseTable[key]; + } else { + s32 val1; + s32 val2; + + if (key <= 35) { + fineAdjust = 0; + key = 0; + } else { + key -= 36; + if (key > 130) { + key = 130; + fineAdjust = 255; + } + } + + val1 = gCgbScaleTable[key]; + val1 = gCgbFreqTable[val1 & 0xF] >> (val1 >> 4); + + val2 = gCgbScaleTable[key + 1]; + val2 = gCgbFreqTable[val2 & 0xF] >> (val2 >> 4); + + return val1 + ((fineAdjust * (val2 - val1)) >> 8) + 2048; + } +} + +void CgbOscOff(u8 chanNum) { + switch (chanNum) { + case 1: + REG_NR12 = 8; + REG_NR14 = 0x80; + break; + case 2: + REG_NR22 = 8; + REG_NR24 = 0x80; + break; + case 3: + REG_NR30 = 0; + break; + default: + REG_NR42 = 8; + REG_NR44 = 0x80; + } +} + +static inline int CgbPan(CgbChannel* chan) { + u32 rightVolume = chan->rightVolume; + u32 leftVolume = chan->leftVolume; + u8 rightVolume2 = rightVolume; + u8 leftVolume2 = leftVolume; + if (rightVolume2 >= leftVolume2) { + if (rightVolume2 / 2 >= leftVolume2) { + chan->pan = 0x0F; + return 1; + } + } else { + if (leftVolume2 / 2 >= rightVolume2) { + chan->pan = 0xF0; + return 1; + } + } + return 0; +} + +void CgbModVol(CgbChannel* chan) { + SoundInfo* soundInfo = SOUND_INFO_PTR; + + if (!CgbPan(chan)) { + chan->pan = 0xFF; + chan->envelopeGoal = (u32)(chan->rightVolume + chan->leftVolume) >> 4; + } else { + // Force chan->rightVolume and chan->leftVolume to be read from memory again, + // even though there is no reason to do so. + // The command line option "-fno-gcse" achieves the same result as this. +#ifndef NONMATCHING + asm("" : : : "memory"); +#endif + + chan->envelopeGoal = (u32)(chan->rightVolume + chan->leftVolume) >> 4; + if (chan->envelopeGoal > 15) + chan->envelopeGoal = 15; + } + + chan->sustainGoal = (chan->envelopeGoal * chan->sustain + 15) >> 4; + chan->pan &= chan->panMask; +} + +NONMATCH("asm/non_matching/m4a/CgbSound.inc", void CgbSound(void)) { + s32 ch; + CgbChannel* channels; + s32 envelopeStepTimeAndDir; + s32 prevC15; + SoundInfo* soundInfo = SOUND_INFO_PTR; + vu8* nrx0ptr; + vu8* nrx1ptr; + vu8* nrx2ptr; + vu8* nrx3ptr; + vu8* nrx4ptr; + + // Most comparision operations that cast to s8 perform 'and' by 0xFF. + int mask = 0xff; + + if (soundInfo->c15) + soundInfo->c15--; + else + soundInfo->c15 = 14; + + for (ch = 1, channels = soundInfo->cgbChannels; ch <= 4; ch++, channels++) { + if (!(channels->statusFlags & SOUND_CHANNEL_SF_ON)) + continue; + + /* 1. determine hardware channel registers */ + switch (ch) { + case 1: + nrx0ptr = (vu8*)(REG_ADDR_NR10); + nrx1ptr = (vu8*)(REG_ADDR_NR11); + nrx2ptr = (vu8*)(REG_ADDR_NR12); + nrx3ptr = (vu8*)(REG_ADDR_NR13); + nrx4ptr = (vu8*)(REG_ADDR_NR14); + break; + case 2: + nrx0ptr = (vu8*)(REG_ADDR_NR10 + 1); + nrx1ptr = (vu8*)(REG_ADDR_NR21); + nrx2ptr = (vu8*)(REG_ADDR_NR22); + nrx3ptr = (vu8*)(REG_ADDR_NR23); + nrx4ptr = (vu8*)(REG_ADDR_NR24); + break; + case 3: + nrx0ptr = (vu8*)(REG_ADDR_NR30); + nrx1ptr = (vu8*)(REG_ADDR_NR31); + nrx2ptr = (vu8*)(REG_ADDR_NR32); + nrx3ptr = (vu8*)(REG_ADDR_NR33); + nrx4ptr = (vu8*)(REG_ADDR_NR34); + break; + default: + nrx0ptr = (vu8*)(REG_ADDR_NR30 + 1); + nrx1ptr = (vu8*)(REG_ADDR_NR41); + nrx2ptr = (vu8*)(REG_ADDR_NR42); + nrx3ptr = (vu8*)(REG_ADDR_NR43); + nrx4ptr = (vu8*)(REG_ADDR_NR44); + break; + } + + prevC15 = soundInfo->c15; + envelopeStepTimeAndDir = *nrx2ptr; + + /* 2. calculate envelope volume */ + if (channels->statusFlags & SOUND_CHANNEL_SF_START) { + if (!(channels->statusFlags & SOUND_CHANNEL_SF_STOP)) { + channels->statusFlags = SOUND_CHANNEL_SF_ENV_ATTACK; + channels->modify = CGB_CHANNEL_MO_PIT | CGB_CHANNEL_MO_VOL; + CgbModVol(channels); + switch (ch) { + case 1: + *nrx0ptr = channels->sweep; + // fallthrough + case 2: + *nrx1ptr = ((u32)channels->nextWave << 6) + channels->length; + goto init_env_step_time_dir; + case 3: + if (channels->nextWave != channels->currentWave) { + *nrx0ptr = 0x40; + REG_WAVE_RAM0 = channels->nextWave[0]; + REG_WAVE_RAM1 = channels->nextWave[1]; + REG_WAVE_RAM2 = channels->nextWave[2]; + REG_WAVE_RAM3 = channels->nextWave[3]; + channels->currentWave = channels->nextWave; + } + *nrx0ptr = 0; + *nrx1ptr = channels->length; + if (channels->length) + channels->n4 = 0xC0; + else + channels->n4 = 0x80; + break; + default: + *nrx1ptr = channels->length; + *nrx3ptr = (u32)channels->nextWave << 3; + init_env_step_time_dir: + envelopeStepTimeAndDir = channels->attack + CGB_NRx2_ENV_DIR_INC; + if (channels->length) + channels->n4 = 0x40; + else + channels->n4 = 0x00; + break; + } + channels->envelopeCounter = channels->attack; + if ((s8)(channels->attack & mask)) { + channels->envelopeVolume = 0; + goto envelope_step_complete; + } else { + // skip attack phase if attack is instantaneous (=0) + goto envelope_decay_start; + } + } else { + goto oscillator_off; + } + } else if (channels->statusFlags & SOUND_CHANNEL_SF_IEC) { + channels->echoLength--; + if ((s8)(channels->echoLength & mask) <= 0) { + oscillator_off: + CgbOscOff(ch); + channels->statusFlags = 0; + goto channel_complete; + } + goto envelope_complete; + } else if ((channels->statusFlags & SOUND_CHANNEL_SF_STOP) && (channels->statusFlags & SOUND_CHANNEL_SF_ENV)) { + channels->statusFlags &= ~SOUND_CHANNEL_SF_ENV; + channels->envelopeCounter = channels->release; + if ((s8)(channels->release & mask)) { + channels->modify |= CGB_CHANNEL_MO_VOL; + if (ch != 3) + envelopeStepTimeAndDir = channels->release | CGB_NRx2_ENV_DIR_DEC; + goto envelope_step_complete; + } else { + goto envelope_pseudoecho_start; + } + } else { + envelope_step_repeat: + if (channels->envelopeCounter == 0) { + if (ch == 3) + channels->modify |= CGB_CHANNEL_MO_VOL; + + CgbModVol(channels); + if ((channels->statusFlags & SOUND_CHANNEL_SF_ENV) == SOUND_CHANNEL_SF_ENV_RELEASE) { + channels->envelopeVolume--; + if ((s8)(channels->envelopeVolume & mask) <= 0) { + envelope_pseudoecho_start: + channels->envelopeVolume = ((channels->envelopeGoal * channels->echoVolume) + 0xFF) >> 8; + if (channels->envelopeVolume) { + channels->statusFlags |= SOUND_CHANNEL_SF_IEC; + channels->modify |= CGB_CHANNEL_MO_VOL; + if (ch != 3) + envelopeStepTimeAndDir = 0 | CGB_NRx2_ENV_DIR_INC; + goto envelope_complete; + } else { + goto oscillator_off; + } + } else { + channels->envelopeCounter = channels->release; + } + } else if ((channels->statusFlags & SOUND_CHANNEL_SF_ENV) == SOUND_CHANNEL_SF_ENV_SUSTAIN) { + envelope_sustain: + channels->envelopeVolume = channels->sustainGoal; + channels->envelopeCounter = 7; + } else if ((channels->statusFlags & SOUND_CHANNEL_SF_ENV) == SOUND_CHANNEL_SF_ENV_DECAY) { + int envelopeVolume, sustainGoal; + + channels->envelopeVolume--; + envelopeVolume = (s8)(channels->envelopeVolume & mask); + sustainGoal = (s8)(channels->sustainGoal); + if (envelopeVolume <= sustainGoal) { + envelope_sustain_start: + if (channels->sustain == 0) { + channels->statusFlags &= ~SOUND_CHANNEL_SF_ENV; + goto envelope_pseudoecho_start; + } else { + channels->statusFlags--; + channels->modify |= CGB_CHANNEL_MO_VOL; + if (ch != 3) + envelopeStepTimeAndDir = 0 | CGB_NRx2_ENV_DIR_INC; + goto envelope_sustain; + } + } else { + channels->envelopeCounter = channels->decay; + } + } else { + channels->envelopeVolume++; + if ((u8)(channels->envelopeVolume & mask) >= channels->envelopeGoal) { + envelope_decay_start: + channels->statusFlags--; + channels->envelopeCounter = channels->decay; + if ((u8)(channels->envelopeCounter & mask)) { + channels->modify |= CGB_CHANNEL_MO_VOL; + channels->envelopeVolume = channels->envelopeGoal; + if (ch != 3) + envelopeStepTimeAndDir = channels->decay | CGB_NRx2_ENV_DIR_DEC; + } else { + goto envelope_sustain_start; + } + } else { + channels->envelopeCounter = channels->attack; + } + } + } + } + + envelope_step_complete: + // every 15 frames, envelope calculation has to be done twice + // to keep up with the hardware envelope rate (1/64 s) + channels->envelopeCounter--; + if (prevC15 == 0) { + prevC15--; + goto envelope_step_repeat; + } + + envelope_complete: + /* 3. apply pitch to HW registers */ + if (channels->modify & CGB_CHANNEL_MO_PIT) { + if (ch < 4 && (channels->type & TONEDATA_TYPE_FIX)) { + int dac_pwm_rate = REG_SOUNDBIAS_H; + + if (dac_pwm_rate < 0x40) // if PWM rate = 32768 Hz + channels->frequency = (channels->frequency + 2) & 0x7fc; + else if (dac_pwm_rate < 0x80) // if PWM rate = 65536 Hz + channels->frequency = (channels->frequency + 1) & 0x7fe; + } + + if (ch != 4) + *nrx3ptr = channels->frequency; + else + *nrx3ptr = (*nrx3ptr & 0x08) | channels->frequency; + channels->n4 = (channels->n4 & 0xC0) + (*((u8*)(&channels->frequency) + 1)); + *nrx4ptr = (s8)(channels->n4 & mask); + } + + /* 4. apply envelope & volume to HW registers */ + if (channels->modify & CGB_CHANNEL_MO_VOL) { + REG_NR51 = (REG_NR51 & ~channels->panMask) | channels->pan; + if (ch == 3) { + *nrx2ptr = gCgb3Vol[channels->envelopeVolume]; + if (channels->n4 & 0x80) { + *nrx0ptr = 0x80; + *nrx4ptr = channels->n4; + channels->n4 &= 0x7f; + } + } else { + envelopeStepTimeAndDir &= 0xf; + *nrx2ptr = (channels->envelopeVolume << 4) + envelopeStepTimeAndDir; + *nrx4ptr = channels->n4 | 0x80; + if (ch == 1 && !(*nrx0ptr & 0x08)) + *nrx4ptr = channels->n4 | 0x80; + } + } + + channel_complete: + channels->modify = 0; + } +} +END_NONMATCH + +void m4aMPlayTempoControl(MusicPlayerInfo* mplayInfo, u16 tempo) { + if (mplayInfo->ident == ID_NUMBER) { + mplayInfo->ident++; + mplayInfo->tempoU = tempo; + mplayInfo->tempoI = (mplayInfo->tempoD * mplayInfo->tempoU) >> 8; + mplayInfo->ident = ID_NUMBER; + } +} + +void m4aMPlayVolumeControl(MusicPlayerInfo* mplayInfo, u16 trackBits, u16 volume) { + s32 i; + u32 bit; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + bit = 1; + + while (i > 0) { + if (trackBits & bit) { + if (track->flags & MPT_FLG_EXIST) { + track->volX = volume / 4; + track->flags |= MPT_FLG_VOLCHG; + } + } + + i--; + track++; + bit <<= 1; + } + + mplayInfo->ident = ID_NUMBER; +} + +void m4aMPlayPitchControl(MusicPlayerInfo* mplayInfo, u16 trackBits, s16 pitch) { + s32 i; + u32 bit; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + bit = 1; + + while (i > 0) { + if (trackBits & bit) { + if (track->flags & MPT_FLG_EXIST) { + track->keyShiftX = pitch >> 8; + track->pitX = pitch; + track->flags |= MPT_FLG_PITCHG; + } + } + + i--; + track++; + bit <<= 1; + } + + mplayInfo->ident = ID_NUMBER; +} + +void m4aMPlayPanpotControl(MusicPlayerInfo* mplayInfo, u16 trackBits, s8 pan) { + s32 i; + u32 bit; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + bit = 1; + + while (i > 0) { + if (trackBits & bit) { + if (track->flags & MPT_FLG_EXIST) { + track->panX = pan; + track->flags |= MPT_FLG_VOLCHG; + } + } + + i--; + track++; + bit <<= 1; + } + + mplayInfo->ident = ID_NUMBER; +} + +void ClearModM(MusicPlayerTrack* track) { + track->lfoSpeedC = 0; + track->modM = 0; + + if (track->modT == 0) + track->flags |= MPT_FLG_PITCHG; + else + track->flags |= MPT_FLG_VOLCHG; +} + +void m4aMPlayModDepthSet(MusicPlayerInfo* mplayInfo, u16 trackBits, u8 modDepth) { + s32 i; + u32 bit; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + bit = 1; + + while (i > 0) { + if (trackBits & bit) { + if (track->flags & MPT_FLG_EXIST) { + track->mod = modDepth; + + if (!track->mod) + ClearModM(track); + } + } + + i--; + track++; + bit <<= 1; + } + + mplayInfo->ident = ID_NUMBER; +} + +void m4aMPlayLFOSpeedSet(MusicPlayerInfo* mplayInfo, u16 trackBits, u8 lfoSpeed) { + s32 i; + u32 bit; + MusicPlayerTrack* track; + + if (mplayInfo->ident != ID_NUMBER) + return; + + mplayInfo->ident++; + + i = mplayInfo->trackCount; + track = mplayInfo->tracks; + bit = 1; + + while (i > 0) { + if (trackBits & bit) { + if (track->flags & MPT_FLG_EXIST) { + track->lfoSpeed = lfoSpeed; + + if (!track->lfoSpeed) + ClearModM(track); + } + } + + i--; + track++; + bit <<= 1; + } + + mplayInfo->ident = ID_NUMBER; +} + +#define MEMACC_COND_JUMP(cond) \ + if (cond) \ + goto cond_true; \ + else \ + goto cond_false; + +void ply_memacc(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + u32 op; + u8* addr; + u8 data; + + op = *track->cmdPtr; + track->cmdPtr++; + + addr = mplayInfo->memAccArea + *track->cmdPtr; + track->cmdPtr++; + + data = *track->cmdPtr; + track->cmdPtr++; + + switch (op) { + case 0: + *addr = data; + return; + case 1: + *addr += data; + return; + case 2: + *addr -= data; + return; + case 3: + *addr = mplayInfo->memAccArea[data]; + return; + case 4: + *addr += mplayInfo->memAccArea[data]; + return; + case 5: + *addr -= mplayInfo->memAccArea[data]; + return; + case 6: + MEMACC_COND_JUMP(*addr == data) + return; + case 7: + MEMACC_COND_JUMP(*addr != data) + return; + case 8: + MEMACC_COND_JUMP(*addr > data) + return; + case 9: + MEMACC_COND_JUMP(*addr >= data) + return; + case 10: + MEMACC_COND_JUMP(*addr <= data) + return; + case 11: + MEMACC_COND_JUMP(*addr < data) + return; + case 12: + MEMACC_COND_JUMP(*addr == mplayInfo->memAccArea[data]) + return; + case 13: + MEMACC_COND_JUMP(*addr != mplayInfo->memAccArea[data]) + return; + case 14: + MEMACC_COND_JUMP(*addr > mplayInfo->memAccArea[data]) + return; + case 15: + MEMACC_COND_JUMP(*addr >= mplayInfo->memAccArea[data]) + return; + case 16: + MEMACC_COND_JUMP(*addr <= mplayInfo->memAccArea[data]) + return; + case 17: + MEMACC_COND_JUMP(*addr < mplayInfo->memAccArea[data]) + return; + default: + return; + } + +cond_true : { + // *& is required for matching + ((MPlayFunc)(*&gMPlayJumpTable[1]))(mplayInfo, track); + return; +} + +cond_false: + track->cmdPtr += 4; +} + +void ply_xcmd(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + u32 n = *track->cmdPtr; + track->cmdPtr++; + + gXcmdTable[n](mplayInfo, track); +} + +void ply_xxx(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + ((MPlayFunc)(gMPlayJumpTable[0]))(mplayInfo, track); +} + +#define READ_XCMD_BYTE(var, n) \ + { \ + u32 byte = track->cmdPtr[(n)]; \ + byte <<= n * 8; \ + (var) &= ~(0xFF << (n * 8)); \ + (var) |= byte; \ + } + +void ply_xwave(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + u32 wav; + + READ_XCMD_BYTE(wav, 0) // UB: uninitialized variable + READ_XCMD_BYTE(wav, 1) + READ_XCMD_BYTE(wav, 2) + READ_XCMD_BYTE(wav, 3) + + track->tone.wav = (WaveData*)wav; + track->cmdPtr += 4; +} + +void ply_xtype(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.type = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xatta(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.attack = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xdeca(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.decay = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xsust(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.sustain = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xrele(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.release = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xiecv(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->echoVolume = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xiecl(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->echoLength = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xleng(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.length = *track->cmdPtr; + track->cmdPtr++; +} + +void ply_xswee(MusicPlayerInfo* mplayInfo, MusicPlayerTrack* track) { + track->tone.pan_sweep = *track->cmdPtr; + track->cmdPtr++; +} + +void nullsub_544() { +} \ No newline at end of file diff --git a/src/intro.c b/src/intro.c index e3ee0f9d..6d24d922 100644 --- a/src/intro.c +++ b/src/intro.c @@ -158,7 +158,7 @@ static void HandleTitlescreen(void) { gIntroState.swordBgScaleRatio = 0x10; UpdateSwordBgAffineData(); } - sub_080A3210(); + InitSoundPlayingInfo(); SoundReq(BGM_TITLE_SCREEN); DoFade(6, 8); break; diff --git a/src/item.c b/src/item.c index 35193c97..8ba2e848 100644 --- a/src/item.c +++ b/src/item.c @@ -1,7 +1,5 @@ #include "global.h" -#include "entity.h" #include "item.h" -#include "functions.h" // TODO - How does this relate to PlayerItemFunctions? Is this just a lookup table? void (*const gItemFunctions[])(ItemBehavior*, u32) = { diff --git a/src/loadRoom.c b/src/loadRoom.c index 0bd68f75..eaf41966 100644 --- a/src/loadRoom.c +++ b/src/loadRoom.c @@ -10,7 +10,7 @@ extern Entity* LoadRoomEntity(EntityData*); extern void* GetRoomProperty(u32, u32, u32); extern u32 gUnk_02017654; -extern u32* gAreaEntities; +extern u32* gAreaTable; extern void sub_080186EC(); extern void sub_0804B16C(); @@ -74,7 +74,7 @@ void sub_0804B0B0(u32 arg0, u32 arg1) { void SetCurrentRoomPropertyList(u32 arg0, u32 arg1) { u32** arr; gUnk_02017654 = 0; - arr = &gAreaEntities; + arr = &gAreaTable; if (arr[arg0] != 0) { gUnk_02017654 = arr[arg0][arg1]; } @@ -94,7 +94,7 @@ void* GetRoomProperty(u32 arg0, u32 arg1, u32 arg2) { u32 temp; u32** arr; temp = 0; - arr = &gAreaEntities; + arr = &gAreaTable; if (arr[arg0] != NULL) { temp = arr[arg0][arg1]; if (temp != 0) { diff --git a/src/main.c b/src/main.c index 651187da..78e9fdd0 100644 --- a/src/main.c +++ b/src/main.c @@ -73,7 +73,7 @@ void AgbMain(void) { sScreenHandlers[gMain.screen](); MessageUpdate(); sub_08050154(); - sub_080A3480(); + SoundLoop(); break; } PrepNextFrame(); @@ -206,7 +206,7 @@ u32 sub_08056134(void) { } void InitDMA() { - SoundReq(SND_VSYNC_OFF); + SoundReq(SONG_VSYNC_OFF); gScreen._6d = gScreen._6c; gScreen._6c = 0; @@ -219,7 +219,7 @@ void InitDMA() { } void sub_08056208() { - SoundReq(SND_VSYNC_ON); + SoundReq(SONG_VSYNC_ON); gScreen._6c = gScreen._6d; gScreen._6d = 0; } diff --git a/src/manager/manager15.c b/src/manager/manager15.c index 295f14c7..0d6a3363 100644 --- a/src/manager/manager15.c +++ b/src/manager/manager15.c @@ -81,7 +81,7 @@ void sub_0805A370(Manager15* this) { if (this->manager.unk_0d) { LoadRoomEntityList((EntityData*)&gUnk_080E4C08); this->manager.action = 3; - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); } } @@ -426,8 +426,6 @@ void sub_0805A94C(Manager15* this) { gScreen.controls.window1VerticalDimensions = (tmp1 << 8 | tmp2); } -extern u8 gBG3Buffer[]; - #ifdef NON_MATCHING void sub_0805A9CC(Manager15* this) { int tmp1, tmp2; diff --git a/src/manager/manager3.c b/src/manager/manager3.c index acd83825..5be578f2 100644 --- a/src/manager/manager3.c +++ b/src/manager/manager3.c @@ -5,7 +5,7 @@ #include "room.h" #include "player.h" #include "random.h" -#include "functions.h" +#include "audio.h" // Facilitates the usage of minish portals. @@ -58,7 +58,7 @@ void sub_080576C0(Manager3* this) { this->manager.unk_0e); if (!this->manager.unk_0f) { this->manager.unk_0f = 1; - SoundReq(0x152); + SoundReq(SFX_152); } } } diff --git a/src/manager/manager8.c b/src/manager/manager8.c index aa80b627..582d5640 100644 --- a/src/manager/manager8.c +++ b/src/manager/manager8.c @@ -39,7 +39,6 @@ void sub_08057EFC(Manager8* this) { void sub_08058004(u32, void*, void*); -extern u8 gBG3Buffer[]; extern u8 gUnk_02006F00[]; void sub_08057F20(Manager8* this) { @@ -59,8 +58,8 @@ void sub_08057F20(Manager8* this) { tmp = tmp + (tmp >> 2) + ((0x400 - gRoomControls.width) / 2); gScreen.bg.bg1xOffset = tmp & 0xF; gScreen.bg.bg1yOffset = 0x30 - ((0x30 - (gRoomControls.roomScrollY - gRoomControls.roomOriginY)) >> 1); - gScreen.bg.bg1Tilemap = gBG3Buffer + 0x800; - sub_08058004(tmp, gUnk_02006F00 + 0x2000, gBG3Buffer + 0x800); + gScreen.bg.bg1Tilemap = gBG3Buffer + 0x400; + sub_08058004(tmp, gUnk_02006F00 + 0x2000, gBG3Buffer + 0x400); tmp = ((tmp >> 4) << 1); if (this->unk_3c != tmp) { this->unk_3c = tmp; @@ -123,11 +122,11 @@ void sub_080580B0(u32 unk1) { gScreen.affine.bg3Updated = 1; tmp = gRoomControls.roomScrollX - gRoomControls.roomOriginX; // r7 tmp = tmp + (tmp >> 2) + (0x400 - gRoomControls.width) / 2; - sub_08058004(tmp, gUnk_02006F00 + 0x2000, gBG3Buffer + 0x800); + sub_08058004(tmp, gUnk_02006F00 + 0x2000, gBG3Buffer + 0x400); gScreen.bg.bg1xOffset = tmp & 0xF; gScreen.bg.bg1yOffset = 0x30 - ((0x30 - (gRoomControls.roomScrollY - gRoomControls.roomOriginY)) >> 1); //? gScreen.bg.bg1Control = 0x1E09; - gScreen.bg.bg1Tilemap = gBG3Buffer + 0x800; + gScreen.bg.bg1Tilemap = gBG3Buffer + 0x400; gScreen.bg.bg1Updated = 1; gScreen.controls.layerFXControl = 0x3C48; gScreen.controls.alphaBlend = 0x609; diff --git a/src/manager/manager9.c b/src/manager/manager9.c index aebc9a96..1baa8d98 100644 --- a/src/manager/manager9.c +++ b/src/manager/manager9.c @@ -13,11 +13,10 @@ typedef struct { void sub_08058204(Manager9*); void sub_08058210(Manager9*); u32 sub_08058244(int); -void sub_080582A0(u32, u32*, u8*); +void sub_080582A0(u32, u32*, u16*); void sub_080582F8(u8*, u8*); extern u32 gUnk_02006F00[]; -extern u8 gBG3Buffer[]; const u16 gUnk_081081EC[] = { 0x30, 0x30, 0x30, 0x38 }; @@ -55,13 +54,13 @@ u32 sub_08058244(int i) { return tmp; } -void sub_080582A0(u32 unk, u32* unk2, u8* unk3) { +void sub_080582A0(u32 unk, u32* unk2, u16* unk3) { int i = 0x20; unk2 += unk >> 4; for (; i != 0; i--) { DmaSet(3, unk2, unk3, 0x80000020); unk2 += 0x40; - unk3 += 0x40; + unk3 += 0x20; } } diff --git a/src/manager/managerB.c b/src/manager/managerB.c index ca298178..470ef89d 100644 --- a/src/manager/managerB.c +++ b/src/manager/managerB.c @@ -5,6 +5,7 @@ #include "room.h" #include "area.h" #include "utils.h" +#include "audio.h" #include "functions.h" /* @@ -18,7 +19,7 @@ void (*const ManagerB_ActionFuncs[])(Manager*); void sub_080585F0(Manager* this) { - // make a distincion if this is a controller (unk_0a = 0) or a helper (unk_0a = 1) + // make a distincion if this is a controller (volumeMasterTarget = 0) or a helper (volumeMasterTarget = 1) ManagerB_ActionFuncs[this->unk_0a](this); } @@ -140,7 +141,7 @@ void ManagerBHelper_Monitor(ManagerBHelper* this, Entity* ent, u32 index) { this->manager.unk_0e++; } -// case unk_0a is 1: The manager is a helper +// case volumeMasterTarget is 1: The manager is a helper void ManagerBHelper_Main(Manager* this) { u8 i, anyRemaining; diff --git a/src/manager/managerE.c b/src/manager/managerE.c index 44bfb5a7..200a52d5 100644 --- a/src/manager/managerE.c +++ b/src/manager/managerE.c @@ -3,6 +3,7 @@ #include "manager.h" #include "flags.h" #include "room.h" +#include "audio.h" #include "functions.h" void sub_08058E60(ManagerE* this) { diff --git a/src/npc/bigGoron.c b/src/npc/bigGoron.c index 3123b036..c3032d54 100644 --- a/src/npc/bigGoron.c +++ b/src/npc/bigGoron.c @@ -4,6 +4,7 @@ #include "structures.h" #include "script.h" #include "random.h" +#include "audio.h" #include "functions.h" extern void (*gUnk_081140D4[])(Entity*); diff --git a/src/npc/bladeBrothers.c b/src/npc/bladeBrothers.c index 49a86dfc..7bb1fdc3 100644 --- a/src/npc/bladeBrothers.c +++ b/src/npc/bladeBrothers.c @@ -7,6 +7,7 @@ #include "save.h" #include "script.h" #include "npc.h" +#include "audio.h" #include "functions.h" extern void (*gUnk_081115C0[])(Entity*); @@ -168,7 +169,7 @@ void sub_08068BEC(Entity* this, u32 unused) { if (target) { target->spritePriority.b0 = 1; PositionRelative(this, target, 0, -0x100000); - SoundReq(0xfa); + SoundReq(SFX_FA); } } diff --git a/src/npc/ezloCap.c b/src/npc/ezloCap.c index a7b5593e..1dd254cb 100644 --- a/src/npc/ezloCap.c +++ b/src/npc/ezloCap.c @@ -1,9 +1,10 @@ #include "global.h" #include "entity.h" -#include "functions.h" #include "flags.h" #include "save.h" #include "script.h" +#include "audio.h" +#include "functions.h" extern Hitbox gUnk_080FD170; extern void script_08016030; // Cutscene data type? @@ -184,7 +185,7 @@ void sub_0806DAE8(Entity* this) { break; } - SoundReq(0xcd); + SoundReq(SFX_TASK_COMPLETE); } void sub_0806DB44(Entity* this, ScriptExecutionContext* context) { diff --git a/src/npc/melari.c b/src/npc/melari.c index a62b837b..1e911439 100644 --- a/src/npc/melari.c +++ b/src/npc/melari.c @@ -4,6 +4,7 @@ #include "textbox.h" #include "script.h" #include "random.h" +#include "audio.h" #include "functions.h" extern void sub_08068780(Entity*); diff --git a/src/npc/rem.c b/src/npc/rem.c index a6059865..de3e0fb5 100644 --- a/src/npc/rem.c +++ b/src/npc/rem.c @@ -1,7 +1,8 @@ #include "global.h" -#include "functions.h" #include "entity.h" #include "script.h" +#include "audio.h" +#include "functions.h" extern void sub_0806A8C8(Entity*); @@ -26,11 +27,11 @@ void sub_0806a370(Entity* this) { pbVar1 = &this->frames.all; if (*pbVar1 == 1) { *pbVar1 = 0; - SoundReq(0x218); + SoundReq(SFX_218); } if (*pbVar1 == 2) { *pbVar1 = 0; - SoundReq(0x219); + SoundReq(SFX_219); } } } diff --git a/src/npc/smith.c b/src/npc/smith.c index 6b55c1f7..c15b1219 100644 --- a/src/npc/smith.c +++ b/src/npc/smith.c @@ -5,6 +5,7 @@ #include "script.h" #include "random.h" #include "npc.h" +#include "audio.h" #include "functions.h" extern void sub_08078850(Entity*, u32, u32, u32*); diff --git a/src/object/bird.c b/src/object/bird.c index fcf03eab..6e8cf037 100644 --- a/src/object/bird.c +++ b/src/object/bird.c @@ -34,7 +34,7 @@ void sub_0809CF54(Entity* this) { this->direction = 8; this->collisionLayer = 2; this->x.HALF.HI = gRoomControls.roomScrollX; - SoundReq(0x123); + SoundReq(SFX_123); UpdateSpriteForCollisionLayer(this); InitAnimationForceUpdate(this, 0); target = CreateObject(0x95, 1, 0); diff --git a/src/object/button.c b/src/object/button.c index e545953c..0530d52f 100644 --- a/src/object/button.c +++ b/src/object/button.c @@ -2,6 +2,7 @@ #include "entity.h" #include "flags.h" #include "room.h" +#include "audio.h" #include "functions.h" extern void (*const gUnk_0811EE38[])(Entity*); @@ -94,7 +95,7 @@ void sub_08081C30(Entity* this) { this->action = 2; ClearFlag(this->field_0x86.HWORD); SetTileType(0x77, this->field_0x74.HWORD, this->collisionLayer); - SoundReq(0x10C); + SoundReq(SFX_10C); } } @@ -260,7 +261,7 @@ u32 sub_08081F7C(Entity* this, u32 r7) { SetFlag(this->field_0x86.HWORD); SetTileType(r7, this->field_0x74.HWORD, this->collisionLayer); sub_08081F24(this); - SoundReq(0x10C); + SoundReq(SFX_10C); if (this->field_0x70.HALF_U.LO != 0xFFFF) SetTile(this->field_0x70.HALF_U.LO, this->field_0x74.HWORD, this->collisionLayer); return 0; diff --git a/src/object/cloud.c b/src/object/cloud.c index 56b55984..20247c76 100644 --- a/src/object/cloud.c +++ b/src/object/cloud.c @@ -46,7 +46,7 @@ void sub_0809F548(Entity* this) { if (--this->actionDelay == 0) { this->action = 2; this->actionDelay = 90; - SoundReq(285); + SoundReq(SFX_11D); sub_0809F814((((this->x.HALF.HI - gRoomControls.roomOriginX) >> 4) & 63) | (((this->y.HALF.HI - gRoomControls.roomOriginY) >> 4) & 63) << 6); } else { @@ -94,7 +94,7 @@ void sub_0809F61C(Entity* this) { if (--this->actionDelay == 0) { this->action = 3; this->actionDelay = 120; - SoundReq(285); + SoundReq(SFX_11D); sub_0809F814((((this->x.HALF.HI - gRoomControls.roomOriginX) >> 4) & 63) | (((this->y.HALF.HI - gRoomControls.roomOriginY) >> 4) & 63) << 6); } else { @@ -178,7 +178,7 @@ void sub_0809F7BC(Entity* this) { void sub_0809F7F4(Entity* this) { if (--this->field_0x68.HALF.LO == 0) { this->field_0x68.HALF.LO = 12; - SoundReq(388); + SoundReq(SFX_184); } } diff --git a/src/object/greatFairy.c b/src/object/greatFairy.c index 87afa483..08ac1cd2 100644 --- a/src/object/greatFairy.c +++ b/src/object/greatFairy.c @@ -105,7 +105,7 @@ void GreatFairy_SpawningUpdate(Entity* this) { if (mini != NULL) { CopyPosition(this, mini); DoFade(6, 4); - SoundReq(325); + SoundReq(SFX_145); this->action = 4; this->actionDelay = 60; this->spriteSettings.b.draw = 1; diff --git a/src/object/houseDoorExterior.c b/src/object/houseDoorExterior.c index 32232c44..c800b29a 100644 --- a/src/object/houseDoorExterior.c +++ b/src/object/houseDoorExterior.c @@ -1,9 +1,10 @@ #include "global.h" #include "entity.h" #include "flags.h" -#include "functions.h" #include "room.h" #include "script.h" +#include "audio.h" +#include "functions.h" typedef struct { /*0x00*/ u16 unk0; @@ -111,7 +112,7 @@ void sub_0808681C(Entity* this) { this->action++; this->frameIndex = 1; sub_08078AC0(16, 0, 1); - SoundReq(0x111); + SoundReq(SFX_111); } break; } diff --git a/src/object/itemOnGround.c b/src/object/itemOnGround.c index 351b21bd..4ed95a19 100644 --- a/src/object/itemOnGround.c +++ b/src/object/itemOnGround.c @@ -5,16 +5,16 @@ #include "functions.h" #include "player.h" -static void sub_08081150(Entity*); -static u8 sub_0808147C(u32); -static void sub_080814A4(Entity*); -static u32 sub_080814C0(Entity*); -static void sub_08081500(Entity*); -static void sub_0808153C(Entity*); -static void sub_08081598(Entity*); -static void sub_080813BC(Entity*); -static void sub_080810FC(Entity*); -static bool32 CheckShouldPlayItemGetCutscene(Entity*); +void sub_08081150(Entity*); +u8 sub_0808147C(u32); +void sub_080814A4(Entity*); +u32 sub_080814C0(Entity*); +void sub_08081500(Entity*); +void sub_0808153C(Entity*); +void sub_08081598(Entity*); +void sub_080813BC(Entity*); +void sub_080810FC(Entity*); +bool32 CheckShouldPlayItemGetCutscene(Entity*); extern u32 sub_080002D0(Entity*); extern u32 sub_080177A0(Entity*, Entity*); @@ -137,7 +137,7 @@ void sub_08080F20(Entity* this) { } } -static void sub_080810A8(Entity* this) { +void sub_080810A8(Entity* this) { this->action = 1; sub_080814A4(this); if (this->direction & 0x80) { @@ -158,7 +158,7 @@ static void sub_080810A8(Entity* this) { } } -static void sub_080810FC(Entity* this) { +void sub_080810FC(Entity* this) { if (this->type != 0x5F) { sub_08081598(this); } else { @@ -176,16 +176,16 @@ void sub_08081134(Entity* this) { sub_08081150(this); } -static void sub_08081150(Entity* this) { +void sub_08081150(Entity* this) { this->action = 2; this->flags |= 0x80; this->height.HALF.HI = -0x80; this->spriteOrientation.flipY = 1; this->spriteRendering.b3 = 1; - SoundReq(0x12D); + SoundReq(SFX_12D); } -static void sub_08081188(Entity* this) { +void sub_08081188(Entity* this) { this->action = 2; this->flags |= 0x80; if (this->collisionLayer == 2) { @@ -206,7 +206,7 @@ void sub_080811C8(Entity* this) { void sub_080811D8(Entity* this) { sub_08081188(this); - SoundReq(0x215); + SoundReq(SFX_215); } void sub_080811EC(Entity* this) { @@ -304,7 +304,7 @@ void sub_0808136C(Entity* this) { } } -static void sub_080813BC(Entity* this) { +void sub_080813BC(Entity* this) { gUnk_0811E840[this->subAction](this); } @@ -343,7 +343,7 @@ bool32 sub_08081420(Entity* this) { } } -static bool32 CheckShouldPlayItemGetCutscene(Entity* this) { +bool32 CheckShouldPlayItemGetCutscene(Entity* this) { bool32 result = FALSE; if ((gUnk_080FD5B4[this->type].unk0[3] & 0x2) || !GetInventoryValue(this->type)) { result = TRUE; @@ -351,7 +351,7 @@ static bool32 CheckShouldPlayItemGetCutscene(Entity* this) { return result; } -static u8 sub_0808147C(u32 arg0) { +u8 sub_0808147C(u32 arg0) { const Unk_0811E84C* var0 = &gUnk_0811E84C[arg0]; return var0->unk4; } @@ -363,7 +363,7 @@ void sub_0808148C(u32 arg0) { } } -static void sub_080814A4(Entity* this) { +void sub_080814A4(Entity* this) { if (this->field_0x68.HALF.HI == 10) { this->field_0x6c.HWORD = 120; } else { @@ -371,7 +371,7 @@ static void sub_080814A4(Entity* this) { } } -static u32 sub_080814C0(Entity* this) { +u32 sub_080814C0(Entity* this) { if (!sub_0805E40C(this)) { if (--this->field_0x6c.HWORD == 0) { return TRUE; @@ -385,7 +385,7 @@ static u32 sub_080814C0(Entity* this) { return FALSE; } -static void sub_08081500(Entity* this) { +void sub_08081500(Entity* this) { if (this->field_0x68.HALF.LO == 0) { u32 var0 = sub_080044EC(this, 0x2800); if (var0 == 0) { @@ -401,7 +401,7 @@ static void sub_08081500(Entity* this) { } } -static void sub_0808153C(Entity* this) { +void sub_0808153C(Entity* this) { if (this->field_0x68.HALF.LO > 1) return; @@ -420,7 +420,7 @@ static void sub_0808153C(Entity* this) { } } -static void sub_08081598(Entity* this) { +void sub_08081598(Entity* this) { if (this->currentHealth == 0) { sub_08081404(this, 1); } diff --git a/src/object/jailBars.c b/src/object/jailBars.c index 505ca8e2..fd534907 100644 --- a/src/object/jailBars.c +++ b/src/object/jailBars.c @@ -2,7 +2,7 @@ #include "entity.h" #include "flags.h" #include "room.h" -#include "functions.h" +#include "audio.h" extern void sub_080A0960(Entity*, u32); extern void sub_0801AF18(u8*, u32, u32); @@ -33,7 +33,7 @@ void sub_080A0910(Entity* this) { if (CheckFlags(this->field_0x86.HWORD) != 0) { this->action = 2; sub_080A0960(this, 1); - SoundReq(0x10b); + SoundReq(SFX_10B); } } diff --git a/src/object/metalDoor.c b/src/object/metalDoor.c index a2a18bff..475a35ac 100644 --- a/src/object/metalDoor.c +++ b/src/object/metalDoor.c @@ -2,6 +2,7 @@ #include "entity.h" #include "room.h" #include "flags.h" +#include "audio.h" #include "functions.h" extern u32 sub_08083734(Entity*, u32); @@ -76,7 +77,7 @@ void sub_080A07BC(Entity* this) { this->direction = 0x10; this->y.HALF.HI += 2; sub_080A0870(this); - SoundReq(0x10b); + SoundReq(SFX_10B); } } diff --git a/src/object/minecart.c b/src/object/minecart.c index af74c357..7578a6b2 100644 --- a/src/object/minecart.c +++ b/src/object/minecart.c @@ -63,7 +63,7 @@ void sub_080917DC(Entity* this) { this->field_0x20 = 0x2a000; this->action = 7; InitAnimationForceUpdate(this, this->type2 + 4 + this->animationState); - SoundReq(0x13b); + SoundReq(SFX_13B); } else { if (sub_0800445C(this) != 0) { if (((gPlayerState.flags.all & 0x40080) == 0) && (gPlayerState.field_0x1c == 0) && @@ -113,7 +113,7 @@ void sub_080918A4(Entity* this) { this->field_0x44 = 8; sub_0801766C(this); sub_0807BA8C(COORD_TO_TILE(this), this->collisionLayer); - SoundReq(0x137); + SoundReq(SFX_137); } } else { gPlayerEntity.direction = GetFacingDirection(&gPlayerEntity, this); @@ -149,7 +149,7 @@ void sub_080919AC(Entity* this) { gPlayerEntity.spritePriority.b0 = this->spritePriority.b0 - 1; if (!sub_08091DDC(this)) { if ((gScreenTransition.frameCount & 0xf) == 0) { - SoundReq(0x138); + SoundReq(SFX_138); } if (--this->field_0xf == 0xff) { @@ -183,7 +183,7 @@ void sub_080919AC(Entity* this) { sub_08004168(this); InitAnimationForceUpdate(this, this->animationState + 0xc); SoundReq(SFX_PLY_VO4); - SoundReq(0x139); + SoundReq(SFX_139); return; case 0x67: case 0x68: diff --git a/src/object/object49.c b/src/object/object49.c index c631a81c..c945f632 100644 --- a/src/object/object49.c +++ b/src/object/object49.c @@ -218,7 +218,7 @@ void sub_0808F498(Entity* this) { if (this->action != 0) { if (sub_0806F3E4(this)) { if (gScreenTransition.frameCount % 16 == 0) { - SoundReq(0xEF); + SoundReq(SFX_EF); } DeleteThisEntity(); } diff --git a/src/object/objectA2.c b/src/object/objectA2.c index 0c3307d3..701a12d5 100644 --- a/src/object/objectA2.c +++ b/src/object/objectA2.c @@ -2,6 +2,7 @@ #include "object.h" #include "menu.h" #include "random.h" +#include "audio.h" #include "structures.h" #include "functions.h" @@ -48,7 +49,7 @@ void sub_0809F374(Entity* this) { this->height.WORD = 0; this->action = 2; InitializeAnimation(this, 1); - SoundReq(0x186); + SoundReq(SFX_186); } else { this->actionDelay++; } @@ -64,7 +65,7 @@ void sub_0809F374(Entity* this) { case 1: this->actionDelay = 0; sub_0809F448(this); - SoundReq(0x186); + SoundReq(SFX_186); } } } diff --git a/src/object/thoughtBubble.c b/src/object/thoughtBubble.c index 5e77d9e1..70ad3c73 100644 --- a/src/object/thoughtBubble.c +++ b/src/object/thoughtBubble.c @@ -1,5 +1,6 @@ #include "global.h" #include "entity.h" +#include "audio.h" #include "functions.h" extern void (*const ThoughtBubble_Behaviors[])(Entity*); diff --git a/src/object/windcrest.c b/src/object/windcrest.c index b21c5ee0..91bdb37a 100644 --- a/src/object/windcrest.c +++ b/src/object/windcrest.c @@ -3,6 +3,7 @@ #include "entity.h" #include "save.h" #include "script.h" +#include "functions.h" extern void sub_08078850(Entity*, u32, u32, u8*); diff --git a/src/player.c b/src/player.c index 14239724..232b5d21 100644 --- a/src/player.c +++ b/src/player.c @@ -185,7 +185,7 @@ void sub_08070D38(Entity* this) { } gPlayerState.jumpStatus = 0x80; - SoundReq(0x14c); + SoundReq(SFX_14C); ResetPlayer(); sub_08078F60(); } @@ -467,7 +467,7 @@ void sub_0807127C(Entity* this) { if (gPlayerState.flags.all & 0x80) { this->actionDelay = 0x3c; gPlayerState.field_0x8 = 0xc19; - SoundReq(0x84); + SoundReq(SFX_WATER_SPLASH); } else { if ((gPlayerState.flags.all & 0x10000) == 0) sub_08004168(this); @@ -528,7 +528,7 @@ static void PlayerUsePortal(Entity* this) { this->subAction = 7; this->actionDelay = 30; DoFade(7, 16); - SoundReq(0xf8); + SoundReq(SFX_F8); } else { sub_0804ACF8(); } @@ -641,7 +641,7 @@ void PortalShrinkInit(Entity* this) { sub_0805EC9C(this, 0x100, 0x100, 0); gPlayerState.field_0x8 = 0x2c3; gPlayerState.flags.all |= 0x80; - SoundReq(0x16f); + SoundReq(SFX_PLY_SHRINKING); } // horrible @@ -912,7 +912,7 @@ void sub_08071BDC(Entity* this) { gPlayerState.pushedObject = 0; sub_0800451C(this); ResetPlayer(); - SoundReq(0x87); + SoundReq(SFX_PLY_DIE); } void sub_08071CAC(Entity* this) { @@ -927,7 +927,7 @@ void sub_08071CAC(Entity* this) { this->subAction = 2; this->actionDelay = 0xf0; - SoundReq(0x7b); + SoundReq(SFX_PLY_VO7); } } diff --git a/src/room.c b/src/room.c index 0797da1d..3529459b 100644 --- a/src/room.c +++ b/src/room.c @@ -1027,7 +1027,7 @@ void sub_0804C018(void) { if (CheckGlobalFlag(MAZE_CLEAR)) if (gScreenTransition.playerStartPos.WORD == 0x2780078) // todo: wtf - SoundReq(0x72); + SoundReq(SFX_SECRET); ClearGlobalFlag(MAZE_CLEAR); } @@ -2241,7 +2241,7 @@ void sub_0804CD48(void) { if (CheckGlobalFlag(LV1_CLEAR)) { LoadRoomEntityList(&gUnk_080DF94C); } else { - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); gArea.musicIndex = gArea.pMusicIndex; } } @@ -2429,7 +2429,7 @@ void sub_0804CED8(void) { sub_0807AABC(&gPlayerEntity); LoadRoomEntityList(&gUnk_080E1814); } else { - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); gArea.musicIndex = gArea.pMusicIndex; } } @@ -2523,7 +2523,7 @@ void sub_0804CFB0(void) { if (!CheckFlags(0x31)) { if (gScreenTransition.field_0x38 == 0) { - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); } else { if (gScreenTransition.field_0x39 == 0) { SoundReq(SONG_STOP); @@ -2761,7 +2761,7 @@ void sub_0804D140(void) { if (CheckGlobalFlag(LV4_CLEAR)) { LoadRoomEntityList(&gUnk_080E49F4); } else { - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); gArea.musicIndex = gArea.pMusicIndex; } } @@ -3090,7 +3090,7 @@ void sub_0804D384(void) { sub_08078A90(3); LoadRoomEntityList(&gUnk_080E72E4); gArea.musicIndex = gArea.pMusicIndex; - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); } } } @@ -3498,7 +3498,7 @@ u32 sub_0804D6C4() { } void sub_0804D6C8(void) { - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); gArea.musicIndex = gArea.pMusicIndex; } @@ -4506,7 +4506,7 @@ void sub_0804E3C4() { index = 0xE; } sub_0804B3C4(&gUnk_080F0E1C[index]); - SoundReq(SONG_RESET_UNK); + SoundReq(SONG_STOP_BGM); } u32 sub_0804E45C() { @@ -4714,7 +4714,7 @@ extern EntityData gUnk_080F2E2C; void sub_0804E6E8(void) { if (!CheckGlobalFlag(OUTDOOR)) { gArea.musicIndex = gArea.pMusicIndex; - SoundReq(SONG_VOL_RESET | BGM_MINISH_CAP); + SoundReq(SONG_PLAY_VOL_RESET | BGM_MINISH_CAP); } if (!CheckGlobalFlag(START)) { LoadRoomEntityList(&gUnk_080F2E2C); @@ -4731,7 +4731,7 @@ extern EntityData gUnk_080F2EC4; void sub_0804E72C(void) { if (!CheckGlobalFlag(OUTDOOR)) { gArea.musicIndex = gArea.pMusicIndex; - SoundReq(SONG_VOL_RESET | BGM_MINISH_CAP); + SoundReq(SONG_PLAY_VOL_RESET | BGM_MINISH_CAP); } if (!CheckGlobalFlag(START)) { LoadRoomEntityList(&gUnk_080F2E94); @@ -4783,7 +4783,7 @@ void sub_0804E7DC(void) { } if (!CheckGlobalFlag(OUTDOOR)) { gArea.musicIndex = gArea.pMusicIndex; - SoundReq(SONG_VOL_RESET | BGM_MINISH_CAP); + SoundReq(SONG_PLAY_VOL_RESET | BGM_MINISH_CAP); } if ((gPlayerState.flags.all & 8) == 0) { LoadRoomEntityList(&gUnk_080F31D8); @@ -5595,7 +5595,7 @@ extern void sub_0804F5E8(); extern u32 gUnk_080F7C80; extern void sub_0804F4E4(); -u32 sub_0804F468(void) { +u32 Vars_HyruleField_OutsideCastle(void) { if (CheckGlobalFlag(TABIDACHI) && !GetInventoryValue(0x11)) { gRoomVars.field_0x6c = &gUnk_080F7CD0; gRoomVars.field_0x88 = sub_0804F5E8; @@ -5618,7 +5618,7 @@ void sub_0804F4E4() { extern EntityData gUnk_080F7D70; -void sub_0804F4F4(void) { +void Load_HyruleField_OutsideCastle(void) { sub_0804F4E4(); if (!CheckLocalFlag(0x8b)) { LoadRoomEntityList(&gUnk_080F7D70); @@ -5781,13 +5781,13 @@ void sub_0804F9C8(void) { sub_0807BA8C(0x4d9, 1); } -u32 sub_0804F9FC() { +u32 Vars_HyruleField_OutsideCastleWest() { return 1; } extern EntityData gUnk_080F806C; -void sub_0804FA00(void) { +void Load_HyruleField_OutsideCastleWest(void) { sub_0805ADD8(0); if ((gSave.unk8 > 3) && CheckGlobalFlag(TINGLE_TALK1ST)) { @@ -5795,13 +5795,13 @@ void sub_0804FA00(void) { } } -u32 sub_0804FA2C() { +u32 Vars_HyruleField_TrilbyHighlands() { return 1; } extern EntityData gUnk_080F82E0; -void sub_0804FA30(void) { +void Load_HyruleField_TrilbyHighlands(void) { sub_0805ADD8(0); if (CheckGlobalFlag(LV2_CLEAR) && GetInventoryValue(0x3) && !CheckLocalFlag(0x9c)) { diff --git a/src/save.c b/src/save.c index 7cbf89aa..749b6730 100644 --- a/src/save.c +++ b/src/save.c @@ -1,5 +1,8 @@ #include "save.h" #include "gba/eeprom.h" +#include "audio.h" +#include "menu.h" +#include "functions.h" typedef struct SaveFileStatus { u16 checksum1; @@ -58,8 +61,6 @@ const SaveFileEEPROMAddresses gSaveFileEEPROMAddresses[] = { { 0x500, 0x30, 0x10 { 0x20, 0x60, 0x1060, 0xf80, 0x1f80 }, { 0x8, 0xfa0, 0x1fa0, 0xfa0, 0x1fa0 } }; -extern s16 gUnk_02021EE0[6]; - void sub_0807CD9C() { sub_080530C8(); } @@ -69,8 +70,8 @@ SaveResult HandleSave(u32 arg0) { } SaveResult HandleSaveInit(u32 arg0) { - gUnk_02021EE0[5] -= 8; - if (gUnk_02021EE0[4] <= 0) { + gSoundPlayingInfo.volumeMasterTarget -= 8; + if (gSoundPlayingInfo.volumeMaster <= 0) { gMenu.field_0xa = 8; gMenu.storyPanelIndex = SAVE_IN_PROGRESS; } @@ -107,9 +108,9 @@ SaveResult HandleSaveDone(u32 arg0) { SaveResult result; result = SAVE_BUSY; - gUnk_02021EE0[5] += 8; - if (gUnk_02021EE0[3] <= gUnk_02021EE0[5]) { - gUnk_02021EE0[5] = gUnk_02021EE0[3]; + gSoundPlayingInfo.volumeMasterTarget += 8; + if (gSoundPlayingInfo.volumeMasterUnk <= gSoundPlayingInfo.volumeMasterTarget) { + gSoundPlayingInfo.volumeMasterTarget = gSoundPlayingInfo.volumeMasterUnk; sub_08050384(); gMenu.storyPanelIndex = SAVE_INIT; if (gMenu.field_0xa == 1) { diff --git a/src/script.c b/src/script.c index 0710080c..105f7af2 100644 --- a/src/script.c +++ b/src/script.c @@ -9,6 +9,7 @@ #include "utils.h" #include "save.h" #include "random.h" +#include "audio.h" #include "functions.h" void InitScriptForEntity(Entity*, ScriptExecutionContext*, u16*); @@ -137,10 +138,10 @@ void ScriptCommand_0807EEF4(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_0807EF3C(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_DoPostScriptAction(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_DoPostScriptAction2(Entity* entity, ScriptExecutionContext* context); +void ScriptCommand_PlaySound(Entity* entity, ScriptExecutionContext* context); +void ScriptCommand_PlayBgm(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_SoundReq(Entity* entity, ScriptExecutionContext* context); -void ScriptCommand_SoundReq2(Entity* entity, ScriptExecutionContext* context); -void ScriptCommand_SoundReq3(Entity* entity, ScriptExecutionContext* context); -void ScriptCommand_SoundReq0x80100000(Entity* entity, ScriptExecutionContext* context); +void ScriptCommand_StopBgm(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_ModRupees(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_ModHealth(Entity* entity, ScriptExecutionContext* context); void ScriptCommand_IncreaseMaxHealth(Entity* entity, ScriptExecutionContext* context); @@ -283,10 +284,10 @@ const ScriptCommand gScriptCommands[] = { ScriptCommandNop, ScriptCommand_0807EF3C, ScriptCommand_DoPostScriptAction, ScriptCommand_DoPostScriptAction2, + ScriptCommand_PlaySound, + ScriptCommand_PlayBgm, ScriptCommand_SoundReq, - ScriptCommand_SoundReq2, - ScriptCommand_SoundReq3, - ScriptCommand_SoundReq0x80100000, + ScriptCommand_StopBgm, ScriptCommand_ModRupees, ScriptCommand_ModHealth, ScriptCommand_IncreaseMaxHealth, @@ -1450,11 +1451,11 @@ void ScriptCommand_DoPostScriptAction2(Entity* entity, ScriptExecutionContext* c context->postScriptActions |= 1 << context->scriptInstructionPointer[1]; } -void ScriptCommand_SoundReq(Entity* entity, ScriptExecutionContext* context) { +void ScriptCommand_PlaySound(Entity* entity, ScriptExecutionContext* context) { SoundReq(context->scriptInstructionPointer[1]); } -void ScriptCommand_SoundReq2(Entity* entity, ScriptExecutionContext* context) { +void ScriptCommand_PlayBgm(Entity* entity, ScriptExecutionContext* context) { if (context->scriptInstructionPointer[1] >= 100) { SoundReq(gArea.musicIndex); } else { @@ -1462,12 +1463,12 @@ void ScriptCommand_SoundReq2(Entity* entity, ScriptExecutionContext* context) { } } -void ScriptCommand_SoundReq3(Entity* entity, ScriptExecutionContext* context) { +void ScriptCommand_SoundReq(Entity* entity, ScriptExecutionContext* context) { SoundReq(GetNextScriptCommandWordAfterCommandMetadata(context->scriptInstructionPointer)); } -void ScriptCommand_SoundReq0x80100000(Entity* entity, ScriptExecutionContext* context) { - SoundReq(SONG_RESET_UNK); +void ScriptCommand_StopBgm(Entity* entity, ScriptExecutionContext* context) { + SoundReq(SONG_STOP_BGM); } void ScriptCommand_ModRupees(Entity* entity, ScriptExecutionContext* context) { diff --git a/src/textbox.c b/src/textbox.c index 6a9cf031..54ec12f8 100644 --- a/src/textbox.c +++ b/src/textbox.c @@ -8,15 +8,50 @@ #include "structures.h" #include "save.h" -u32 sub_080564DC(void); -u32 sub_080564EC(void); -u32 sub_08056654(void); -u32 sub_080565B4(void); -u32 sub_080565F8(void); -u32 sub_08056640(void); - -u32 (*const gUnk_08107BC8[])(void) = { - sub_080564DC, sub_080564EC, sub_08056654, sub_080565B4, sub_080565F8, sub_08056640, +#define TEXTBOX_ADVANCE_KEYS (A_BUTTON | B_BUTTON | DPAD_ANY | R_BUTTON) +#define TEXTBOX_PRESS_ANY_ADVANCE_KEYS ((gInput.newKeys & TEXTBOX_ADVANCE_KEYS) != 0) + +#define TEXTBOX_WIDTH 0x20 +#define TEXTBOX_POSITION_INDEX(window) ((window).yPos * TEXTBOX_WIDTH + (window).xPos) + +extern void WriteBit(u32*, u32); +extern void sub_0805EF40(u8*, u8*); +extern void sub_0801C4A0(u32, u32); +extern void sub_0801C494(void); +extern void sub_0805F918(u32, u32, u32); +extern u32 sub_0801D51C(u32, u8*, u32); + +u32 sub_08056FEC(u32, u8*); + +u16 sub_08056750(CurrentTextBox*); +u32 sub_0805EFE8(u8*); +void sub_08056ABC(u32, u32); +void sub_080569C4(CurrentTextBox*, u32); +u16 sub_0805F7DC(u32, u8*); +u32 sub_GetFontStrWidth(u8*, u32); +void sub_08056FBC(CurrentTextBox*); +void SetDoTextBox(u32 doTextbox); +void Load_02000D00_Asyc(void); + +void DeleteWindow(void); +void CreateWindow(void); +u32 CalcWindowSize(u32 fade); + +void DispMessageFrame(u16*, u32, u32, u32); +void DispString(void); +void DispCursor(void); + +typedef u32 (*TextBoxFunction)(void); + +u32 TextBoxFunction0(void); +u32 TextBoxFunction1(void); +u32 HandleTextBox(void); +u32 TextBoxFunctionOpen(void); +u32 TextBoxFunctionClose(void); +u32 TextBoxFunction5(void); + +const TextBoxFunction gTextBoxFunctions[] = { + TextBoxFunction0, TextBoxFunction1, HandleTextBox, TextBoxFunctionOpen, TextBoxFunctionClose, TextBoxFunction5, }; extern u8 gUnk_020227DC, gUnk_020227E8, gUnk_020227F0, gUnk_020227F8, gUnk_02022800; @@ -24,22 +59,49 @@ u8* const gUnk_08107BE0[] = { &gUnk_020227DC, &gUnk_020227E8, &gUnk_020227F0, &gUnk_020227F8, &gUnk_02022800, }; -void sub_08056684(struct_02022780*); -void sub_080566B8(struct_02022780*); -void sub_08056BA0(struct_02022780*); -void sub_08056B1C(struct_02022780*); -void sub_08056B7C(struct_02022780*); -void sub_080569D4(struct_02022780*); +typedef void (*TextBoxHandler)(CurrentTextBox*); -void (*const gUnk_08107BF4[])(struct_02022780*) = { - sub_08056684, sub_080566B8, sub_08056BA0, sub_08056B1C, sub_08056B7C, sub_080569D4, +void TextBoxHandler0(CurrentTextBox* this); +void TextBoxHandler1(CurrentTextBox* param_1); +void TextBoxHandlerAdvance(CurrentTextBox* ctb); +void TextBoxHandlerNextBox(CurrentTextBox* ctb); +void TextBoxHandler4(CurrentTextBox* ctb); +void TextBoxHandlerQuestion(CurrentTextBox* ctb); + +const TextBoxHandler gTextBoxHandlers[] = { + TextBoxHandler0, TextBoxHandler1, TextBoxHandlerAdvance, + TextBoxHandlerNextBox, TextBoxHandler4, TextBoxHandlerQuestion, }; -extern u32 gUnk_02036A40; -extern u32 gUnk_02036A38; -extern u8 gUnk_02024030; +typedef struct Window { + u8 unk0; + u8 unk1; + u8 unk2; + u8 unk3; + u8 xPos; + u8 yPos; + u8 width; + u8 height; +} Window; +extern Window gCurrentWindow; +extern Window gNewWindow; + +extern struct { + u8 unk_00; + u8 unk_01[1]; + s8 unk_02; + s8 unk_03; + u8 unk_04[4]; + u16 unk_08[4]; + u16 unk_10[4]; +} gUnk_02024030; + +extern u32 gUnk_0200005C; + extern u8 gUnk_020227A0; -extern u8 gUnk_02000D00; +extern u8 gUnk_02000D00[0xD00]; + +extern const u8 gUnk_08107C0C[]; s32 sub_08056338(void) { s32 result; @@ -52,7 +114,7 @@ s32 sub_08056338(void) { void sub_08056360(void) { if ((gTextBox.doTextBox & 0x7f) != 0) { - gTextBox.doTextBox = 0x80 | 0x8; + gTextBox.doTextBox = 0x88; } } @@ -64,22 +126,22 @@ void TextboxNoOverlapFollow(u32 index) { } } -void TextboxNoOverlap(u32 index, Entity* ent) { +void TextboxNoOverlap(u32 index, Entity* entity) { s16 y; - s16 h; + s16 height; ShowTextbox(index); - y = ent->y.HALF.HI; - h = ent->height.HALF.HI; + y = entity->y.HALF.HI; + height = entity->height.HALF.HI; - if (((y + h) - gRoomControls.roomScrollY) > 0x58) { + if (((y + height) - gRoomControls.roomScrollY) > 0x58) { gTextBox.textWindowPosY = 1; } } -void sub_080563C8(u32 param_1, u32 param_2) { - TextboxAtPosition(param_1, 1, param_2); +void TextBoxAtYPosition(u32 index, u32 y) { + TextboxAtPosition(index, 1, y); } void TextboxAtPosition(u32 index, u32 x, u32 y) { @@ -89,7 +151,7 @@ void TextboxAtPosition(u32 index, u32 x, u32 y) { } void ShowTextbox(u32 index) { - MemClear(&gTextBox, 32); + MemClear(&gTextBox, sizeof(gTextBox)); gTextBox.textIndex = index; gTextBox.textSpeed = 99; gTextBox.textWindowWidth = 26; @@ -100,10 +162,10 @@ void ShowTextbox(u32 index) { } void MessageInitialize(void) { - MemClear(&gTextBox, 32); - MemClear(&gUnk_02022780, 168); - MemClear(&gUnk_02036A40, 8); - MemClear(&gUnk_02036A38, 8); + MemClear(&gTextBox, sizeof(gTextBox)); + MemClear(&gCurrentTextBox, sizeof(gCurrentTextBox)); + MemClear(&gNewWindow, sizeof(gNewWindow)); + MemClear(&gCurrentWindow, sizeof(gCurrentWindow)); MemClear(&gUnk_02000040, 4); } @@ -111,125 +173,609 @@ void MessageUpdate(void) { int iVar1; if (gTextBox.doTextBox == 1) { - MemClear((u32*)&gUnk_02022780, sizeof(gUnk_02022780)); + MemClear((u32*)&gCurrentTextBox, sizeof(gCurrentTextBox)); sub_080564C8(1); } - if (gUnk_02022780._8a != 0) { - gUnk_02022780._8a--; + if (gCurrentTextBox._8a != 0) { + gCurrentTextBox._8a--; } else { do { - iVar1 = gUnk_08107BC8[gUnk_02022780._88](); + iVar1 = gTextBoxFunctions[gCurrentTextBox._88](); } while (iVar1 != 0); } - if (gUnk_02022780._9d != 0) { - gUnk_02022780._9d = 0; - sub_08056F70(); + if (gCurrentTextBox._9d != 0) { + gCurrentTextBox._9d = 0; + Load_02000D00_Asyc(); } DeleteWindow(); CreateWindow(); } -void sub_080564C8(u32 a1) { - gUnk_02022780._88 = a1; - gUnk_02022780._89 = 0; +void sub_080564C8(u32 unk) { + gCurrentTextBox._88 = unk; + gCurrentTextBox.state = 0; } -u32 sub_080564DC(void) { - gUnk_02022780._99 = 0; +u32 TextBoxFunction0(void) { + gCurrentTextBox._98.bytes.b1 = 0; return 0; } // regalloc in loop -NONMATCH("asm/non_matching/textbox/sub_080564EC.inc", u32 sub_080564EC(void)) { +NONMATCH("asm/non_matching/textbox/TextBoxFunction1.inc", u32 TextBoxFunction1(void)) { u32 uVar1; char* dest; u32 i; char c; - MemClear((void*)&gUnk_02036A40, 8); + MemClear((void*)&gNewWindow, 8); MemClear((void*)&gUnk_02024030, 0x18); - MemClear((void*)&gUnk_02022780, 0xa8); - MemCopy(&gTextBox, &gUnk_02022780, 32); - if (gUnk_02022780._2 == 0x63) { - gUnk_02022780._2 = gUnk_02000000->messageSpeed; - } - gUnk_02022780._9c = 0xff; - sub_0805EEB4(&gUnk_02022780._20, gUnk_02022780._8, 32); - gUnk_02022780._5c = 2; - gUnk_02022780._5d = 0xe; - dest = gUnk_02022780._5e; - - for (i = 0; i < 6; ++i) { + MemClear((void*)&gCurrentTextBox, sizeof(gCurrentTextBox)); + MemCopy(&gTextBox, &gCurrentTextBox, sizeof(gTextBox)); + if (gCurrentTextBox.textBox.textSpeed == 0x63) { + gCurrentTextBox.textBox.textSpeed = gUnk_02000000->messageSpeed; + } + gCurrentTextBox._9c = 0xff; + sub_0805EEB4(&gCurrentTextBox._20, gCurrentTextBox.textBox.textIndex); + gCurrentTextBox.playerName[0] = 2; + gCurrentTextBox.playerName[1] = 0xe; + dest = &gCurrentTextBox.playerName[2]; + + for (i = 0; i < FILENAME_LENGTH; ++i) { c = gSave.playerName[i]; if (c == '\0') break; - dest[i] = c; + *dest = c; + dest++; } dest[0] = 2; dest[1] = 15; dest[2] = 0; - sub_08056FBC(&gUnk_02022780); - gUnk_02022780._2c = &gUnk_08107BE0; - gUnk_02022780._58 = &gUnk_02000D00; - gUnk_02022780._54 = 0xd0; - sub_08056C54(2); + sub_08056FBC(&gCurrentTextBox); + gCurrentTextBox._2c = &gUnk_08107BE0; + gCurrentTextBox._50.unk8 = gUnk_02000D00; + gCurrentTextBox._50.unk4 = 0xd0; + SetDoTextBox(2); sub_08056BDC(0); sub_080564C8(2); return 1; } END_NONMATCH -u32 sub_080565B4(void) { - if (gUnk_02022780._89 == 0) { - gUnk_02022780._89 = 1; - gUnk_02022780._99 = 1; - sub_08056F88(gUnk_02022780._3[0], gUnk_02022780._53); +u32 TextBoxFunctionOpen(void) { + if (gCurrentTextBox.state == 0) { + gCurrentTextBox.state = 1; + gCurrentTextBox._98.bytes.b1 = 1; + sub_08056F88(gCurrentTextBox.textBox.unk3, gCurrentTextBox._50.unk3); SoundReq(SFX_TEXTBOX_OPEN); } - if (sub_08056CC0(1)) { - gUnk_02022780._99 = 2; + if (CalcWindowSize(1)) { + gCurrentTextBox._98.bytes.b1 = 2; sub_080564C8(2); } return 0; } -u32 sub_080565F8(void) { - if (gUnk_02022780._89 == 0) { - gUnk_02022780._89 = 1; - gUnk_02022780._99 = 3; +u32 TextBoxFunctionClose(void) { + if (gCurrentTextBox.state == 0) { + gCurrentTextBox.state = 1; + gCurrentTextBox._98.bytes.b1 = 3; sub_08056BDC(0); SoundReq(SFX_TEXTBOX_CLOSE); } - if (sub_08056CC0(-1)) { - gUnk_02022780._99 = 0; + if (CalcWindowSize(-1)) { + gCurrentTextBox._98.bytes.b1 = 0; sub_080564C8(2); } return 0; } -u32 sub_08056640() { - sub_08056C54(0); +u32 TextBoxFunction5(void) { + SetDoTextBox(0); sub_080564C8(0); return 0; } -u32 sub_08056654(void) { - sub_08056C54(4); - gUnk_08107BF4[gUnk_02022780._89](&gUnk_02022780); - sub_08056CC0(0); +u32 HandleTextBox(void) { + SetDoTextBox(4); + gTextBoxHandlers[gCurrentTextBox.state](&gCurrentTextBox); + CalcWindowSize(0); return 0; } -void sub_08056684(struct_02022780* this) { - if ((gUnk_02022780._20 & 1) == 0) { - if (gUnk_02022780._99 == '\0') { +void TextBoxHandler0(CurrentTextBox* this) { + if ((gCurrentTextBox._20 & 1) == 0) { + if (gCurrentTextBox._98.bytes.b1 == 0) { sub_080564C8(5); } } else { - this->_89 = 1; + this->state = 1; + } +} + +void TextBoxHandler1(CurrentTextBox* param_1) { + u32 uVar3; + s32 iVar4; + int iVar5; + int iVar6; + + if (param_1->_95 != 0) { + param_1->_95--; + } else { + if ((gInput.heldKeys & B_BUTTON) != 0) { + iVar4 = 8; + } else { + iVar4 = 1; + } + param_1->_92 -= iVar4; + if (param_1->_92 < 1) { + iVar5 = 0; + do { + iVar5++; + param_1->_92 += gUnk_08107C0C[param_1->textBox.textSpeed]; + } while (param_1->_92 < 1); + iVar6 = 0; + do { + uVar3 = sub_08056750(param_1); + if (((uVar3 == 0) || (param_1->_95 != 0)) || (param_1->_8a != 0)) + break; + iVar6 += uVar3; + iVar5--; + } while (0 < iVar5); + if (iVar6 != 0) { + gCurrentTextBox._9d = 1; + } else { + param_1->_92 = 0; + } + } + } +} + +NONMATCH("asm/non_matching/textbox/sub_08056750.inc", u16 sub_08056750(CurrentTextBox* param_1)) { + s32 r0, r1, r2, r3; + u32 r7; + s32 tmp; + u32 t; + u32* t2; + + r7 = param_1->_24; + + if (r7 == 0) { + r7 = sub_0805EFE8(¶m_1->_20); + switch (r7) { + case 0: + if (gUnk_02000040.unk_00 == 1) { + param_1->state = 5; + sub_08056ABC(0, 0); + } else { + param_1->state = 2; + } + break; + case 1: + param_1->_8a = 2; + if (param_1->_98.bytes.b0 == 0) { + sub_08056BDC(1); + } else { + param_1->state = 3; + } + break; + case 2: + sub_080564C8(3); + break; + case 3: + sub_080564C8(4); + break; + case 4: + param_1->_50.unk6 += + (param_1->_50.unk4 - param_1->_50.unk6 - sub_GetFontStrWidth(¶m_1->_20, 0)) / 2; + break; + case 5: + gTextBox.unk = param_1->_22; + break; + case 6: + t2 = &gUnk_0200005C; + t = param_1->_22; + WriteBit(t2, 0x1f & t); + break; + case 7: + switch (param_1->_22) { + case 0xe: + param_1->_91 = param_1->_8f; + r3 = 2; + break; + case 0xf: + r3 = param_1->_91; + break; + default: + r3 = param_1->_22; + break; + } + param_1->_90 = 0; + sub_080569C4(param_1, r3); + break; + case 8: + SoundReq(param_1->_22); + break; + case 9: + gCurrentTextBox.textBox.unk3 = param_1->_22; + sub_08056F88(param_1->_22, param_1->_50.unk3); + break; + case 10: + param_1->textBox.textWindowPosY = param_1->_22; + break; + case 12: + if (gUnk_02000040.unk_00 != 1) { + MemClear(&gUnk_02000040, 4); + MemClear(&gUnk_02024030, sizeof(gUnk_02024030)); + gUnk_02024030.unk_00 = 1; + gUnk_02000040.unk_00 = 1; + } + if (gUnk_02024030.unk_02 > 3) + break; + + gUnk_02024030.unk_10[gUnk_02024030.unk_02] = param_1->_26; + gUnk_02024030.unk_08[gUnk_02024030.unk_02] = param_1->_50.unk6; + gUnk_02024030.unk_02++; + param_1->_50.unk6 += 8; + break; + case 13: + switch (param_1->_22) { + case 0xff: + param_1->_8e = 1; + break; + case 0xfe: + param_1->_8e = 2; + break; + default: + param_1->_95 = param_1->_22; + break; + } + break; + case 14: + r1 = param_1->_22; + param_1->_94 = r1; + break; + default: + break; + } + if (r7 >> 8 == 0) + return 0; + } + if (gCurrentTextBox._98.bytes.b1 != 2) { + sub_080564C8(3); + return 0; + } + if (gTextBox.unk == 0) { + gTextBox.unk = 0x80; + } + param_1->_24 = 0; + if (r7 >> 8 == 7) { + param_1->_90 = param_1->_8f | 0x80; + sub_080569C4(param_1, 0); + } else { + if ((param_1->_90 & 0x80) != 0) { + r3 = param_1->_90; + param_1->_90 = 0; + sub_080569C4(param_1, r3); + } + } + return sub_0805F7DC(r7, ¶m_1->_30[0x20]); +} +END_NONMATCH + +void sub_080569C4(CurrentTextBox* ctb, u32 unk) { + u32 temp = unk & 0x7; + ctb->_8f = temp; + ctb->_50.unk2 = temp; +} + +extern u8 gUnk_08107C14; +extern u8 gUnk_08107C0F; +void TextBoxHandlerQuestion(CurrentTextBox* ctb) { + s32 r1, r5, r6; + u32 error; + u8* ptr1; + u8* ptr2; + + r5 = gUnk_02024030.unk_03; + switch (gInput.newKeys) { + case START_BUTTON: + case A_BUTTON: + r1 = gUnk_02024030.unk_10[r5]; + if (r1 == 0) { + ptr2 = &gUnk_08107C14; + ptr1 = &ctb->_20; + } else { + ctb->textBox.textIndex = r1; + sub_0805EEB4(&ctb->_20, r1); + ptr2 = &gUnk_08107C0F; + ptr1 = &ctb->_20; + } + sub_0805EF40(ptr1, ptr2); + gUnk_02000040.unk_01 = gUnk_02024030.unk_03; + gUnk_02000040.unk_00 = 3; + MemClear(&gUnk_02024030, sizeof(gUnk_02024030)); + SoundReq(0x6a); // SFX_TEXTBOX_SELECT + ctb->state = 1; + break; + case DPAD_LEFT: + r5--; + break; + case DPAD_RIGHT: + r5++; + break; + default: + break; + } + r5 = (r5 + gUnk_02024030.unk_02) % gUnk_02024030.unk_02; + r6 = gUnk_02024030.unk_03; + if (r5 != r6) { + gUnk_02024030.unk_03 = r5; + SoundReq(0x69); // SFX_TEXTBOX_CHOICE + error = 1; + } else { + error = 0; + } + if (gUnk_02000040.unk_00 == 1) { + gUnk_02024030.unk_00 = gUnk_02000040.unk_00 = 2; + error = 1; + } + if (error != 0) { + sub_08056ABC(r5, r6); } } + +void sub_08056ABC(u32 unk_0, u32 unk_1) { + u16 t; + t = gCurrentTextBox._50.unk6; + gCurrentTextBox._50.unk6 = gUnk_02024030.unk_08[unk_1]; + sub_0805F8E4(0, &gCurrentTextBox._50); + gCurrentTextBox._50.unk6 = gUnk_02024030.unk_08[unk_0]; + sub_0805F8E4(1, &gCurrentTextBox._50); + gCurrentTextBox._50.unk6 = t; + gCurrentTextBox._9d = 1; +} + +void TextBoxHandlerNextBox(CurrentTextBox* ctb) { + u32 t; + u8* ptr; + gTextBox.unk = 0; + if (ctb->_94 != 0) { + ctb->_94--; + if (ctb->_94 != 0) + return; + ptr = &ctb->state; + t = 4; + } else { + if (TEXTBOX_PRESS_ANY_ADVANCE_KEYS) { + SoundReq(0x68); // SFX_TEXTBOX_SWAP + ctb->_98.bytes.b2 = 0; + ptr = &ctb->state; + t = 4; + } else { + ptr = &ctb->_98.bytes.b2; + t = *ptr + 1; + } + } + *ptr = t; +} + +void TextBoxHandler4(CurrentTextBox* ctb) { + sub_08056BDC(0); + sub_080569C4(ctb, ctb->_8f | 0x40); + ctb->state = 1; +} + +void TextBoxHandlerAdvance(CurrentTextBox* ctb) { + gTextBox.unk = 0; + SetDoTextBox(7); + if ((ctb->_8e != 1) && (ctb->_8e == 2 || TEXTBOX_PRESS_ANY_ADVANCE_KEYS)) { + sub_080564C8(4); + } +} + +void sub_08056BDC(u32 unk) { + gCurrentTextBox._98.bytes.b0 = unk; + if (unk == 0) { + MemFill32(0xFFFFFFFF, gUnk_02000D00, sizeof(gUnk_02000D00)); + Load_02000D00_Asyc(); + gCurrentTextBox._9e = 0xf082; + gCurrentTextBox._a0 = 0xf083; + gCurrentTextBox._a2 = 0xf0b6; + gCurrentTextBox._a4 = 0xf0b7; + gCurrentTextBox._50.unk6 = 0; + gCurrentTextBox._50.unk4 = 0xd0; + } else { + gCurrentTextBox._50.unk6 = 0xd0; + gCurrentTextBox._50.unk4 = 0x1a0; + } + sub_080569C4(&gCurrentTextBox, gCurrentTextBox._8f | 0x40); +} + +void SetDoTextBox(u32 doTextbox) { + gTextBox.doTextBox = gCurrentTextBox.textBox.doTextBox = doTextbox; +} + +void DeleteWindow(void) { + u16* ptr; + int i, j; + + Window* window = &gCurrentWindow; + + if (window->unk1 != 0) { + window->unk1 = 0; + ptr = &gBG0Buffer[TEXTBOX_POSITION_INDEX(*window)]; + i = window->height + 2; + do { + j = 0; + do { + ptr[j] = 0; + } while (j++, j < window->width + 2); + ptr += TEXTBOX_WIDTH; + i--; + } while (i > 0); + sub_0801C4A0(window->yPos, window->height); + sub_0801C494(); + } +} + +u32 CalcWindowSize(u32 fade) { + u32 scale; + u32 ret; + Window* window; + + ret = 0; + + gCurrentTextBox._98.bytes.sizeScale += fade; + if (gCurrentTextBox._98.bytes.sizeScale < 1) { + gCurrentTextBox._98.bytes.sizeScale = 0; + } else { + if (gCurrentTextBox._98.bytes.sizeScale < 8) + goto LAB_08056cee; + gCurrentTextBox._98.bytes.sizeScale = 8; + } + ret = 1; +LAB_08056cee: + window = &gNewWindow; + if (gCurrentTextBox._98.bytes.sizeScale != 0) { + scale = gCurrentTextBox._98.bytes.sizeScale; + window->width = (scale * (gCurrentTextBox.textBox.textWindowWidth << 1)) / 16; + if ((window->width & 1) != 0) { + window->width++; + } + window->xPos = ((gCurrentTextBox.textBox.textWindowWidth / 2) + gCurrentTextBox.textBox.textWindowPosX) - + (window->width / 2); + + window->height = (scale * (gCurrentTextBox.textBox.textWindowHeight << 1)) / 16; + if ((window->height & 1) != 0) { + window->height++; + } + window->yPos = ((gCurrentTextBox.textBox.textWindowHeight / 2) + gCurrentTextBox.textBox.textWindowPosY) - + (window->height / 2); + } else { + window->yPos = -1; + window->xPos = -1; + window->height = -1; + window->width = -1; + } + window->unk1 = 1; + return ret; +} + +void CreateWindow(void) { + s32 r0, r3; + u16* ptr; + + r0 = gCurrentTextBox._98.bytes.sizeScale; + if (r0 <= 0) + return; + ptr = &gBG0Buffer[TEXTBOX_POSITION_INDEX(gNewWindow)]; + r3 = 0xf07b; + DispMessageFrame(ptr, gNewWindow.width, gNewWindow.height, r3); + DispString(); + DispCursor(); + gCurrentWindow = gNewWindow; + sub_0801C494(); +} + +NONMATCH("asm/non_matching/textbox/DispMessageFrame.inc", + void DispMessageFrame(u16* buffer, u32 width_, u32 height_, u32 flags_)) { +} +END_NONMATCH + +extern u16 gUnk_02034CB2[]; +extern u16 gUnk_0202281E[]; + +void DispString(void) { + u32 r0, r2, r4; + u16 *ptr, *ptr2; + s32 i, j; + + Window* window = &gNewWindow; + + if (window->width != 0) { + if (window->height != 0) { + r4 = window->height; + ptr = &gUnk_02034CB2[TEXTBOX_POSITION_INDEX(*window)]; + i = (s32)(4 - r4) / 2; + do { + j = window->width; + r2 = gUnk_0202281E[i]; + ptr += TEXTBOX_WIDTH; + r0 = i + 1; + r4--; + ptr2 = ptr; + do { + *ptr2 = r2; + ptr2++; + r2 += 2; + j--; + } while (j > 0); + i = r0; + } while (r4 != 0); + } + } +} + +void DispCursor(void) { + u32 offset; + u16* ptr; + + if ((gCurrentTextBox._98.word & 0x10ff00) == 0x100200) { + ptr = &gBG0Buffer[TEXTBOX_POSITION_INDEX(gNewWindow)]; + offset = (((gNewWindow.height + 1) * TEXTBOX_WIDTH) - 2); + offset += gNewWindow.width; + ptr += offset; + *ptr = 0xf080; + } +} + +void Load_02000D00_Asyc(void) { + LoadResourceAsync(gUnk_02000D00, 0x0600D040, sizeof(gUnk_02000D00)); +} + +void sub_08056F88(u32 unk_1, u32 unk_2) { + u32 uVar1; + + if (0xf < unk_1) { + unk_1 = 0; + } + uVar1 = unk_1 << 4 | unk_2; + if (gCurrentTextBox._9c != uVar1) { + gCurrentTextBox._9c = uVar1; + sub_0805F918(unk_1, unk_2, 0x0600CF60); + } +} + +void sub_08056FBC(CurrentTextBox* ctb) { + sub_08056FEC(ctb->textBox.field_0x10, &ctb->_66[0x2]); + sub_08056FEC(ctb->textBox.field_0x14, &ctb->_66[0xa]); + sub_08056FEC(ctb->textBox.field_0x18, &ctb->_77[0x1]); + sub_08056FEC(ctb->textBox.field_0x1c, &ctb->_77[0x9]); +} + +NONMATCH("asm/non_matching/textbox/sub_08056FEC.inc", u32 sub_08056FEC(u32 param_1, u8* param_2)) { + u32 uVar1; + int iVar2; + int iVar3; + int iVar4; + u8 local_1c[8]; + + uVar1 = sub_0801D51C(param_1, param_2, param_1); + uVar1 = uVar1 & 0xfffffff; + iVar4 = 0; + do { + local_1c[iVar4++] = uVar1 & 0xf; + uVar1 = uVar1 / 16; + } while (uVar1 != 0); + for (iVar3 = 0; --iVar4 >= 0; iVar3++) { + param_2[iVar3] = local_1c[iVar4] | 0x30; + } + param_2[iVar3] = 0; + return iVar4; +} +END_NONMATCH -- cgit v1.2.3