diff options
| author | engineer124 <47598039+engineer124@users.noreply.github.com> | 2022-08-03 22:21:50 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-04 05:21:50 +0100 |
| commit | e75d7020a94a90b01b05d0396164057058a12542 (patch) | |
| tree | 19f3fe422ccb481c0fd0893a0ad47c7349ae7dc2 /src/code | |
| parent | 26c8cdd2219454ef8b81859bc4c1454a97a9c018 (diff) | |
AudioOcarina (1 NonMatching) (#911)
* AudioOcarina OK
* rm some comments
* PR Suggestions
* Add define
* cleanup
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/audio/code_8019AF00.c | 1763 | ||||
| -rw-r--r-- | src/code/audio/code_801A5BD0.c | 8 | ||||
| -rw-r--r-- | src/code/z_actor.c | 6 | ||||
| -rw-r--r-- | src/code/z_demo.c | 3 | ||||
| -rw-r--r-- | src/code/z_sram_NES.c | 6 |
5 files changed, 1576 insertions, 210 deletions
diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c index 2e7cc91e1..65c3a6de8 100644 --- a/src/code/audio/code_8019AF00.c +++ b/src/code/audio/code_8019AF00.c @@ -66,7 +66,7 @@ typedef struct { /* 0xC */ s32 remainingFrames; } FreqLerp; // size = 0x10 -s32 AudioOcarina_MemoryGameGenerateNotes(void); +s32 AudioOcarina_MemoryGameNextNote(void); s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume); void func_801A3238(s8 playerIndex, u16 seqId, u8 fadeTimer, s8 arg3, u8 arg4); @@ -131,18 +131,18 @@ u16 D_801FD438; OcarinaStaff sPlayingStaff; OcarinaStaff sPlaybackStaff; OcarinaStaff sRecordingStaff; -u32 sOcarinaUpdateTaskCurrent; +u32 sOcarinaUpdateTaskStart; OcarinaControlStick sOcarinaInputStickRel; u32 sOcarinaInputButtonCur; u32 sOcarinaInputButtonStart; u32 sOcarinaInputButtonPrev; -s32 sOcaInputBtnPress; -u8 sOcarinaResetDelay; -u8 sOcarinaResetUnused; +s32 sOcarinaInputButtonPress; +u8 sOcarinaDisableTimer; +u8 sOcarinaUnused; u8 sOcarinaHasStartedSong; u8 sFirstOcarinaSongIndex; u8 sLastOcarinaSongIndex; -u32 sOcarinaAvailSongs; +u32 sOcarinaAvailableSongFlags; u8 sOcarinaStaffPlayingPos; u16 sMusicStaffPos[OCARINA_SONG_MAX]; u16 sMusicStaffCurHeldLength[OCARINA_SONG_MAX]; @@ -150,7 +150,7 @@ u16 sMusicStaffExpectedLength[OCARINA_SONG_MAX]; u8 sMusicStaffExpectedPitch[OCARINA_SONG_MAX]; // Next required pitch in song playback u8 D_801FD518[OCARINA_SONG_MAX]; u32 D_801FD530[OCARINA_SONG_MAX]; -OcarinaNote sRecordingSongNote; +OcarinaNote sScarecrowsLongSongSecondNote; u16 sCustomSequencePc; // Sfx Data @@ -987,35 +987,35 @@ NatureAmbienceDataIO sNatureAmbienceData[20] = { u8 sIsOcarinaInputEnabled = false; s8 sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF; u8 sCurOcarinaPitch = OCARINA_PITCH_NONE; -u8 sPrevOcarinaPitch = 0; -u8 sCurOcarinaButtonIndex = 0; -u8 sMusicStaffPrevPitch = 0; +u8 sPrevOcarinaPitch = OCARINA_PITCH_C4; +u8 sCurOcarinaButtonIndex = OCARINA_BTN_A; +u8 sMusicStaffPrevPitch = OCARINA_PITCH_C4; f32 sCurOcarinaBendFreq = 1.0f; -f32 sDefaultOcarinaVolume = 0.68503935f; +f32 sDefaultOcarinaVolume = 87.0f / 127.0f; s8 sCurOcarinaBendIndex = 0; -s8 sCurOcarinaVolume = 0x57; +s8 sCurOcarinaVolume = 87; s8 sCurOcarinaVibrato = 0; u8 sPlaybackState = 0; -u8 D_801D6FE4 = 0xFF; -u8 D_801D6FE8 = 0xFF; +u8 sPlaybackStaffStopPos = 0xFF; +u8 sPlaybackStaffStartPos = 0xFF; u32 sOcarinaFlags = 0; s32 sPlaybackNoteTimer = 0; u16 sPlaybackNotePos = 0; u16 sPlaybackStaffPos = 0; -u32 sPrevOcarinaSongFlags = 0; // Stores sOcarinaFlags but never used -u8 sPlaybackNoteValue = OCARINA_PITCH_NONE; +u32 sPrevOcarinaWithMusicStaffFlags = 0; // Stores sOcarinaFlags but never used +u8 sPlaybackPitch = OCARINA_PITCH_NONE; // Pitch + PitchFlags u8 sNotePlaybackVolume = 0; u8 sNotePlaybackVibrato = 0; s8 sNotePlaybackBend = 0; -f32 sNormalizedNotePlaybackTone = 1.0f; -f32 sNormalizedNotePlaybackVolume = 1.0f; +f32 sRelativeNotePlaybackBend = 1.0f; +f32 sRelativeNotePlaybackVolume = 1.0f; u32 sOcarinaPlaybackTaskStart = 0; u32 sOcarinaWallCounter = 0; -u8 sCurOcarinaSong[8] = { +u8 sCurOcarinaSongWithoutMusicStaff[8] = { OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, }; -u8 sOcarinaSongAppendPos = 0; +u8 sOcarinaWithoutMusicStaffPos = 0; u8 sOcarinaSongStartingPos = 0; u8 sButtonToPitchMap[5] = { @@ -1027,10 +1027,10 @@ u8 sButtonToPitchMap[5] = { }; u8 sOcarinaMemoryGameAppendPos = 0; -u8 sOcaMemoryGameEndPos = 0; -u8 sOcaMemoryGameNumNotes[] = { 5, 6, 8 }; +u8 sOcarinaMemoryGameEndPos = 0; +u8 sOcarinaMemoryGameNumNotes[] = { 5, 6, 8 }; OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { - // 0: Sonata of Awakening + // OCARINA_SONG_SONATA { { OCARINA_PITCH_D5, 19, 92, 0, 0, 0 }, { OCARINA_PITCH_B4, 19, 90, 0, 0, 0 }, @@ -1042,7 +1042,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 86, 0, 0, 0 }, }, - // 1: Goron Lullaby + // OCARINA_SONG_GORON_LULLABY { { OCARINA_PITCH_D4, 41, 80, 0, 0, 0 }, { OCARINA_PITCH_A4, 40, 72, 0, 0, 0 }, @@ -1056,7 +1056,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 2: New Wave Bossa Nova + // OCARINA_SONG_NEW_WAVE { { OCARINA_PITCH_B4, 64, 74, 0, 0, 0 }, { OCARINA_PITCH_D5, 13, 88, 0, 0, 0 }, @@ -1068,7 +1068,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 3: Elegy of Emptyness + // OCARINA_SONG_ELEGY { { OCARINA_PITCH_A4, 85, 93, 0, 0, 0 }, { OCARINA_PITCH_B4, 43, 91, 0, 0, 0 }, @@ -1080,7 +1080,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 94, 0, 0, 0 }, }, - // 4: Oath to Order + // OCARINA_SONG_OATH { { OCARINA_PITCH_A4, 97, 104, 0, 0, 0 }, { OCARINA_PITCH_F4, 48, 88, 0, 0, 0 }, @@ -1092,7 +1092,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { }, - // 5: Sarias Song + // OCARINA_SONG_SARIAS { { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, @@ -1103,7 +1103,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 6: Song of Time + // OCARINA_SONG_TIME { { OCARINA_PITCH_A4, 32, 84, 0, 0, 0 }, { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, @@ -1114,7 +1114,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 7: Song of Healing + // OCARINA_SONG_HEALING { { OCARINA_PITCH_B4, 32, 88, 0, 0, 0 }, { OCARINA_PITCH_A4, 33, 88, 0, 0, 0 }, @@ -1126,7 +1126,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 8: Eponas Song + // OCARINA_SONG_EPONAS { { OCARINA_PITCH_D5, 18, 84, 0, 0, 0 }, { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, @@ -1137,7 +1137,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 9: Song of Soaring + // OCARINA_SONG_SOARING { { OCARINA_PITCH_F4, 18, 84, 0, 0, 0 }, { OCARINA_PITCH_B4, 18, 80, 0, 0, 0 }, @@ -1148,7 +1148,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 10: Song of Storms + // OCARINA_SONG_STORMS { { OCARINA_PITCH_D4, 11, 84, 0, 0, 0 }, { OCARINA_PITCH_F4, 11, 88, 0, 0, 0 }, @@ -1159,7 +1159,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 11: Suns Song + // OCARINA_SONG_SUNS { { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, @@ -1171,7 +1171,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 12: Inverted Song of Time + // OCARINA_SONG_INVERTED_TIME { { OCARINA_PITCH_F4, 32, 84, 0, 0, 0 }, { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, @@ -1182,7 +1182,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 13: Song of Double Time + // OCARINA_SONG_DOUBLE_TIME { { OCARINA_PITCH_A4, 29, 84, 0, 0, 0 }, { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, @@ -1198,7 +1198,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, }, - // 14: Goron Lullaby Intro + // OCARINA_SONG_GORON_LULLABY_INTRO { { OCARINA_PITCH_D4, 32, 78, 0, 0, 0 }, { OCARINA_PITCH_A4, 33, 90, 0, 0, 0 }, @@ -1209,7 +1209,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 15: Milk Bar Jam "Ballad of the Wind Fish" Human + // OCARINA_SONG_WIND_FISH_HUMAN { { OCARINA_PITCH_D5, 89, 80, 0, 0, 0 }, { OCARINA_PITCH_A4, 41, 72, 0, 0, 0 }, @@ -1219,7 +1219,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 16: Milk Bar Jam "Ballad of the Wind Fish" Goron + // OCARINA_SONG_WIND_FISH_GORON { { OCARINA_PITCH_D4, 52, 80, 0, 0, 0 }, { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, @@ -1238,7 +1238,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 17: Milk Bar Jam "Ballad of the Wind Fish" Zora + // OCARINA_SONG_WIND_FISH_ZORA { { OCARINA_PITCH_D5, 11, 80, 0, 0, 0 }, { OCARINA_PITCH_A4, 11, 72, 0, 0, 0 }, @@ -1251,7 +1251,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 18: Milk Bar Jam "Ballad of the Wind Fish" Deku + // OCARINA_SONG_WIND_FISH_DEKU { { OCARINA_PITCH_A4, 54, 80, 0, 0, 0 }, { OCARINA_PITCH_D4, 77, 72, 0, 0, 0 }, @@ -1261,7 +1261,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 19: Evan HP (Zora Band Leader) Song Part 1 + // OCARINA_SONG_EVAN_PART1 { { OCARINA_PITCH_A4, 33, 100, 0, 0, 0 }, { OCARINA_PITCH_NONE, 3, 92, 0, 0, 0 }, @@ -1276,7 +1276,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 20: Evan HP (Zora Band Leader) Song Part 2 + // OCARINA_SONG_EVAN_PART2 { { OCARINA_PITCH_B4, 33, 107, 0, 0, 0 }, { OCARINA_PITCH_NONE, 3, 100, 0, 0, 0 }, @@ -1291,7 +1291,7 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, }, - // 21: Zeldas Lullaby + // OCARINA_SONG_ZELDAS_LULLABY { { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, @@ -1302,13 +1302,13 @@ OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, }, - // 22: Scarecrow + // OCARINA_SONG_SCARECROW_SPAWN { { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, }, - // 23: Termina Field 2D Song Buttons Appearing on Wall (In OoT, this is Ocarina Memory Game) + // OCARINA_SONG_TERMINA_WALL { { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, @@ -1434,7 +1434,7 @@ u8 sOoTOcarinaSongsNumNotes[] = { 6, // Suns Song }; -OcarinaNote* sPlaybackSong = sOcarinaSongNotes[OCARINA_SONG_SONATA]; +OcarinaNote* sPlaybackSong = sOcarinaSongNotes[0]; u8 sFrogsSongNotes[14] = { OCARINA_BTN_A, OCARINA_BTN_C_LEFT, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_C_LEFT, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, @@ -1453,7 +1453,7 @@ u8 sPlayedOcarinaSongIndexPlusOne = 0; u8 sMusicStaffNumNotesPerTest = 0; u8 D_801D8530 = false; u32 D_801D8534 = 0; -u8 sIsOcarinaNoteChanged = false; +u8 sOcarinaDropInputTimer = 0; OcarinaNote sScarecrowsLongSongNotes[108] = { { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, @@ -1461,38 +1461,81 @@ OcarinaNote sScarecrowsLongSongNotes[108] = { }; OcarinaNote* gScarecrowLongSongPtr = sScarecrowsLongSongNotes; -u8* gScarecrowSpawnSongPtr = (u8*)&sOcarinaSongNotes[OCARINA_SONG_SCARECROW]; +u8* gScarecrowSpawnSongPtr = (u8*)&sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN]; OcarinaNote* sTerminaWallSongPtr = sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL]; u8 sPitchToButtonMap[16] = { - OCARINA_BTN_A, // OCARINA_PITCH_C4 - OCARINA_BTN_A, // OCARINA_PITCH_DFLAT4 - OCARINA_BTN_A, // OCARINA_PITCH_D4 - OCARINA_BTN_A, // OCARINA_PITCH_EFLAT4 - OCARINA_BTN_C_DOWN, // OCARINA_PITCH_E4 - OCARINA_BTN_C_DOWN, // OCARINA_PITCH_F4 - OCARINA_BTN_C_DOWN, // OCARINA_PITCH_GFLAT4 - OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_G4 - OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_AFLAT4 - OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_A4 - OCARINA_BTN_C_RIGHT + OCARINA_BTN_C_LEFT, // OCARINA_PITCH_BFLAT4: Interface/Overlap between C_RIGHT and C_LEFT - OCARINA_BTN_C_LEFT, // OCARINA_PITCH_B4 - OCARINA_BTN_C_LEFT, // OCARINA_PITCH_C5 - OCARINA_BTN_C_UP, // OCARINA_PITCH_DFLAT5 - OCARINA_BTN_C_UP, // OCARINA_PITCH_D5 - OCARINA_BTN_C_UP, // OCARINA_PITCH_EFLAT5 + OCARINA_BTN_A, // OCARINA_PITCH_C4 + OCARINA_BTN_A, // OCARINA_PITCH_DFLAT4 + OCARINA_BTN_A, // OCARINA_PITCH_D4 + OCARINA_BTN_A, // OCARINA_PITCH_EFLAT4 + OCARINA_BTN_C_DOWN, // OCARINA_PITCH_E4 + OCARINA_BTN_C_DOWN, // OCARINA_PITCH_F4 + OCARINA_BTN_C_DOWN, // OCARINA_PITCH_GFLAT4 + OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_G4 + OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_AFLAT4 + OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_A4 + OCARINA_BTN_C_RIGHT_OR_C_LEFT, // OCARINA_PITCH_BFLAT4: Interface/Overlap between C_RIGHT and C_LEFT + OCARINA_BTN_C_LEFT, // OCARINA_PITCH_B4 + OCARINA_BTN_C_LEFT, // OCARINA_PITCH_C5 + OCARINA_BTN_C_UP, // OCARINA_PITCH_DFLAT5 + OCARINA_BTN_C_UP, // OCARINA_PITCH_D5 + OCARINA_BTN_C_UP, // OCARINA_PITCH_EFLAT5 }; // seqData written in the music macro language // Only used in unused functions +// clang-format off u8 sCustomSequenceScript[400] = { - 0xFE, 0xFE, 0xD3, 0x20, 0xD7, 0x00, 0x01, 0xCC, 0x00, 0x70, 0x90, 0x00, 0x16, 0xDB, 0x64, 0xDD, 0x78, - 0xFE, 0x00, 0xF3, 0xFC, 0xFF, 0xC3, 0x88, 0x00, 0x29, 0x89, 0x00, 0x2B, 0xDF, 0x7F, 0xE9, 0x0F, 0xDD, - 0x37, 0xD4, 0x40, 0xC1, 0x52, 0xFE, 0x80, 0xF3, 0xFC, 0xFF, 0xC2, 0xFB, 0xC0, 0x00, 0xC1, 0x57, 0xC9, + /* 0 */ 0xFE, // delay1 + /* 1 */ 0xFE, // delay1 + /* 2 */ 0xD3, 0x20, // mutebhv 0x20 + /* 4 */ 0xD7, 0x00, 0x01, // initchan 0x0001 + /* 7 */ 0xCC, 0x00, // ldi 0 + /* 9 */ 0x70, // stio 0 + /* 10 */ 0x90, 0x00, 22, // ldchan 0, chan0 + /* 13 */ 0xDB, 100, // vol 100 + /* 15 */ 0xDD, 120, // tempo 120 + + // .sequence seq_loop + /* 17 */ 0xFE, // delay1 + /* 18 */ 0x00, // testchan 0 + /* 19 */ 0xF3, -4, // rbeqz seq_loop + /* 21 */ 0xFF, // end + + // .channel chan0 + /* 22 */ 0xC3, // short + /* 23 */ 0x88, 0x00, 41, // ldlayer 0, layer0 + /* 26 */ 0x89, 0x00, 43, // ldlayer 1, layer1 + /* 29 */ 0xDF, 127, // vol 127 + /* 31 */ 0xE9, 0x0F, // notepri 0x0F + /* 33 */ 0xDD, 55, // pan 55 + /* 35 */ 0xD4, 64, // reverb 64 + /* 37 */ 0xC1, 82, // instr 82 + + // .channel chan_loop + /* 39 */ 0xFE, // delay1 + /* 40 */ 0x80, // testlayer 0 + + // (no end or loop; channel script seems to run into the note layers?) + + // .layer layer0 + /* 41 */ 0xF3, -4, // rbeqz chan_loop + + // .layer layer1 + /* 43 */ 0xFF, // end + + // .layer layer2? + /* 44 */ 0xC2, -5, // transpose -5 + /* 46 */ 0xC0, 0, // ldelay 0 + /* 48 */ 0xC1, 87, // shortvel 87 + /* 50 */ 0xC9, 0, // shortgate 0 + /* 52 */ 0, // empty until the end }; +// clang-format on OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { - // 0: Sonata of Awakening + // OCARINA_SONG_SONATA { 7, { @@ -1506,7 +1549,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 1: Goron Lullaby + // OCARINA_SONG_GORON_LULLABY { 8, { @@ -1521,7 +1564,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 2: New Wave Bossa Nova + // OCARINA_SONG_NEW_WAVE { 7, { @@ -1535,7 +1578,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 3: Elegy of Emptyness + // OCARINA_SONG_ELEGY { 7, { @@ -1549,7 +1592,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 4: Oath to Order + // OCARINA_SONG_OATH { 6, { @@ -1562,7 +1605,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 5; Sarias Song + // OCARINA_SONG_SARIAS { 6, { @@ -1575,7 +1618,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 6: Song of Time + // OCARINA_SONG_TIME { 6, { @@ -1588,7 +1631,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 7: Song of Healing + // OCARINA_SONG_HEALING { 6, { @@ -1601,7 +1644,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 8: Eponas Song + // OCARINA_SONG_EPONAS { 6, { @@ -1614,7 +1657,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 9: Song of Soaring + // OCARINA_SONG_SOARING { 6, { @@ -1627,7 +1670,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 10: Song of Storms + // OCARINA_SONG_STORMS { 6, { @@ -1640,7 +1683,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 11: Suns Song + // OCARINA_SONG_SUNS { 6, { @@ -1653,7 +1696,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 12: Inverted Song of Time + // OCARINA_SONG_INVERTED_TIME { 6, { @@ -1666,7 +1709,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 13; Song of Double Time + // OCARINA_SONG_DOUBLE_TIME { 6, { @@ -1679,7 +1722,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 14: Goron Lullaby Intro + // OCARINA_SONG_GORON_LULLABY_INTRO { 6, { @@ -1692,7 +1735,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 15: Milk Bar Jam "Ballad of the Wind Fish" Human + // OCARINA_SONG_WIND_FISH_HUMAN { 4, { @@ -1703,7 +1746,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 16: Milk Bar Jam "Ballad of the Wind Fish" Goron + // OCARINA_SONG_WIND_FISH_GORON { 8, { @@ -1718,7 +1761,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 17: Milk Bar Jam "Ballad of the Wind Fish" Zora + // OCARINA_SONG_WIND_FISH_ZORA { 8, { @@ -1733,7 +1776,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 18: Milk Bar Jam "Ballad of the Wind Fish" Deku + // OCARINA_SONG_WIND_FISH_DEKU { 5, { @@ -1745,7 +1788,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 19: Evan HP (Zora Band Leader) Song Part 1 + // OCARINA_SONG_EVAN_PART1 { 8, { @@ -1760,7 +1803,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 20: Evan HP (Zora Band Leader) Song Part 2 + // OCARINA_SONG_EVAN_PART2 { 8, { @@ -1775,7 +1818,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 21: Zeldas Lullaby + // OCARINA_SONG_ZELDAS_LULLABY { 6, { @@ -1788,7 +1831,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 22: Scarecrow + // OCARINA_SONG_SCARECROW_SPAWN { 8, { @@ -1803,7 +1846,7 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }, - // 23: Termina Field 2D Song Buttons Appearing on Wall (In OoT, this is Ocarina Memory Game) + // OCARINA_SONG_TERMINA_WALL { 8, { @@ -1819,26 +1862,6 @@ OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { }, }; -// Static In-Function Data -u8 sScarecrowAfterCreditsState = 0; -u8 sScarecrowAfterCreditsIntrumentId = OCARINA_INSTRUMENT_DEFAULT; -u16 sScarecrowAfterCreditsTimer = 1200; -u8 sRequestCustomSequence = false; -s8 D_801D8B30[] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, - 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, -}; -f32 sBigBellsVolume[8] = { - 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f, -}; -u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB }; -f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f }; - -// OoT's soundEffects from EnRiverSound const u16 gAudioEnvironmentalSfx[] = { NA_SE_EV_RIVER_STREAM - SFX_FLAG, NA_SE_EV_WAVE - SFX_FLAG, NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, NA_SE_EV_WATER_WALL - SFX_FLAG, @@ -1853,8 +1876,6 @@ const u16 gAudioEnvironmentalSfx[] = { NA_SE_EV_WAVE_S - SFX_FLAG, NA_SE_EV_WAVE_S - SFX_FLAG, }; -extern const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX]; -/** const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { true, // OCARINA_SONG_SONATA true, // OCARINA_SONG_GORON_LULLABY @@ -1878,90 +1899,1125 @@ const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { true, // OCARINA_SONG_EVAN_PART1 true, // OCARINA_SONG_EVAN_PART2 false, // OCARINA_SONG_ZELDAS_LULLABY - true, // OCARINA_SONG_SCARECROW + true, // OCARINA_SONG_SCARECROW_SPAWN false, // OCARINA_SONG_TERMINA_WALL }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AF00.s") +const char sAudioOcarinaUnusedText0[] = "key step is too long !!! %d:%d>%d\n"; +const char sAudioOcarinaUnusedText1[] = "You played %d Melody !!! (last step:%d)\n"; +const char sAudioOcarinaUnusedText2[] = "pass 0\n"; +const char sAudioOcarinaUnusedText3[] = "pass 1\n"; +const char sAudioOcarinaUnusedText4[] = "pass 2\n"; +const char sAudioOcarinaUnusedText5[] = "last key is bad !!! %d %d %02X %02X\n"; +const char sAudioOcarinaUnusedText6[] = "last key step is too short !!! %d:%d %d<%d\n"; +const char sAudioOcarinaUnusedText7[] = "check is over!!! %d %d %d\n"; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AF58.s") +void AudioOcarina_ReadControllerInput(void) { + Input inputs[4]; + Input* input = &inputs[0]; + u32 ocarinaInputButtonPrev = sOcarinaInputButtonCur; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AFE8.s") + Padmgr_GetInput2(inputs, 0); + sOcarinaInputButtonCur = input->cur.button; + sOcarinaInputButtonPrev = ocarinaInputButtonPrev; + sOcarinaInputStickRel.x = input->rel.stick_x; + sOcarinaInputStickRel.y = input->rel.stick_y; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B02C.s") +/** + * Looks up the frequency to bend the pitch by. + * The pitch will bend up to a maximum of 2 semitones + * in each direction giving a total range of 4 semitones + */ +f32 AudioOcarina_BendPitchTwoSemitones(s8 bendIndex) { + s8 adjBendIndex; + f32 bendFreq; + + if (bendIndex > 64) { + adjBendIndex = 127; + } else if (bendIndex < -64) { + adjBendIndex = -128; + } else if (bendIndex >= 0) { + adjBendIndex = (bendIndex * 127) / 64; + } else { + adjBendIndex = (bendIndex * 128) / 64; + } -void AudioOcarina_MapSongFromNotesToButtons(u8 noteSongIndex, u8 buttonSongIndex, u8 numButtons); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_MapSongFromNotesToButtons.s") + /** + * index 128 is in the middle of the table and + * contains the value 1.0f i.e. no bend + * absolute indices above 128 will bend the pitch 2 semitones upwards + * absolute indices below 128 will bend the pitch 2 semitones downwards + */ + bendFreq = gBendPitchTwoSemitonesFrequencies[adjBendIndex + 128]; + return bendFreq; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B144.s") +/** + * If an available song has been played, then return that song index + * If the ocarina is on, but no song has been played then return 0xFE + * If the ocarina is off, return 0xFF + */ +u8 AudioOcarina_GetPlayingState(void) { + u8 playedOcarinaSongIndex; + + if (sPlayedOcarinaSongIndexPlusOne != 0) { + playedOcarinaSongIndex = sPlayedOcarinaSongIndexPlusOne - 1; + sPlayedOcarinaSongIndexPlusOne = 0; + } else if (sOcarinaFlags != 0) { + playedOcarinaSongIndex = 0xFE; + } else { + playedOcarinaSongIndex = 0xFF; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B378.s") + return playedOcarinaSongIndex; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B38C.s") +u8 AudioOcarina_MapPitchToButton(u8 pitchAndBFlatFlag) { + u8 buttonIndex = sPitchToButtonMap[pitchAndBFlatFlag & 0x3F]; + + /** + * Special case for bFlat4: + * CRIGHT and CLEFT are the only two pitches that are 2 semitones apart + * which are pitches A4 and B4 respectively + * bFlat4 is in the middle of those two and is the only pitch that can not + * be resolved between the two buttons without external information. + * That information is stored as flags in pitch with the mask: + * (pitchAndBFlatFlag & 0xC0) + */ + if (buttonIndex == OCARINA_BTN_C_RIGHT_OR_C_LEFT) { + if (pitchAndBFlatFlag & OCARINA_BUTTON_FLAG_BFLAT_RAISE) { + return OCARINA_BTN_C_RIGHT; + } + // OCARINA_BUTTON_FLAG_BFLAT_LOWER + return OCARINA_BTN_C_LEFT; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B3D0.s") + return buttonIndex; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B4B8.s") +void AudioOcarina_MapSongFromPitchToButton(u8 noteSongIndex, u8 buttonSongIndex, u8 numButtons) { + u8 buttonSongPos = 0; + u8 noteSongPos = 0; + u8 pitch; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_StartDefault.s") + while ((buttonSongPos < numButtons) && (noteSongPos < 16)) { + pitch = sOcarinaSongNotes[noteSongIndex][noteSongPos++].pitch; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B568.s") + if (pitch != OCARINA_PITCH_NONE) { + gOcarinaSongButtons[buttonSongIndex].buttonIndex[buttonSongPos++] = sPitchToButtonMap[pitch]; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B5AC.s") + gOcarinaSongButtons[buttonSongIndex].numButtons = numButtons; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B5EC.s") +/** + * Ocarina flags: + * bitmask 0x3FFF: + * - Ocarina song id + * bitmask 0xC000: + * - 0x0000: Limits the notes to 8 notes at a time. Not playing a correct song after 8 notes will cause an ocarina + * error + * - 0x4000: (Identical to 0xC000) + * - 0x8000: Limits the notes to 1 note at a time. A single incorrect note will cause an ocarina error + * - 0xC000: Free-play, no limitations to the number of notes to play + * bitmask 0x7FFF0000: + * - ocarina action (only used to make flags != 0) + * bitmask 0x80000000: + * - unused (only used to make flags != 0) + */ -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B618.s") +// The ocarina songs that can be performed at any time = 0x3FFF +#define OCARINA_SONGS_PLAYABLE_FLAGS \ + ((1 << OCARINA_SONG_SONATA) | (1 << OCARINA_SONG_GORON_LULLABY) | (1 << OCARINA_SONG_NEW_WAVE) | \ + (1 << OCARINA_SONG_ELEGY) | (1 << OCARINA_SONG_OATH) | (1 << OCARINA_SONG_SARIAS) | (1 << OCARINA_SONG_TIME) | \ + (1 << OCARINA_SONG_HEALING) | (1 << OCARINA_SONG_EPONAS) | (1 << OCARINA_SONG_SOARING) | \ + (1 << OCARINA_SONG_STORMS) | (1 << OCARINA_SONG_SUNS) | (1 << OCARINA_SONG_INVERTED_TIME) | \ + (1 << OCARINA_SONG_DOUBLE_TIME)) -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B654.s") +void AudioOcarina_Start(u32 ocarinaFlags) { + u8 songIndex; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B6B4.s") + if ((sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF) && + ((ocarinaFlags & OCARINA_SONGS_PLAYABLE_FLAGS) == OCARINA_SONGS_PLAYABLE_FLAGS)) { + ocarinaFlags |= (1 << OCARINA_SONG_SCARECROW_SPAWN); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019BC44.s") + if ((ocarinaFlags == (0xC0000000 | OCARINA_SONGS_PLAYABLE_FLAGS)) && + (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) { + ocarinaFlags = (0xC0000000 | OCARINA_SONGS_PLAYABLE_FLAGS); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019BE98.s") + if ((ocarinaFlags == OCARINA_SONGS_PLAYABLE_FLAGS) && + (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) { + ocarinaFlags = OCARINA_SONGS_PLAYABLE_FLAGS; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C1C0.s") + if (ocarinaFlags != 0xFFFF) { + sOcarinaFlags = 0x80000000 + ocarinaFlags; + sFirstOcarinaSongIndex = 0; + sLastOcarinaSongIndex = OCARINA_SONG_MAX; + sOcarinaAvailableSongFlags = ocarinaFlags & 0xFFFFFF; + sMusicStaffNumNotesPerTest = 8; // Ocarina Check + sOcarinaHasStartedSong = false; + sPlayedOcarinaSongIndexPlusOne = 0; + sOcarinaStaffPlayingPos = 0; + sPlayingStaff.state = AudioOcarina_GetPlayingState(); + sIsOcarinaInputEnabled = true; + sPrevOcarinaWithMusicStaffFlags = 0; + + // Reset music staff song check + for (songIndex = OCARINA_SONG_SONATA; songIndex <= OCARINA_SONG_EVAN_PART2; songIndex++) { + for (sMusicStaffPos[songIndex] = 0; + sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].pitch == OCARINA_PITCH_NONE;) { + sMusicStaffPos[songIndex]++; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C1D0.s") + sMusicStaffCurHeldLength[songIndex] = 0; + sMusicStaffExpectedLength[songIndex] = 0; + sMusicStaffExpectedPitch[songIndex] = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C268.s") + if (D_801D8530) { + if ((1 << songIndex) & ocarinaFlags) { + D_801FD518[songIndex] = 0; + } else { + D_801FD518[songIndex] = 0xFF; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C2E4.s") + if (ocarinaFlags & 0x80000000) { + sMusicStaffNumNotesPerTest = 0; // Ocarina Playback + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_SetInstrumentId.s") + if (ocarinaFlags & 0x40000000) { + sOcarinaWithoutMusicStaffPos = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C398.s") + if (ocarinaFlags & 0xC0400000) { + AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_SCARECROW_SPAWN, OCARINA_SONG_SCARECROW_SPAWN, 8); + } + } else { + sOcarinaFlags = 0; + sIsOcarinaInputEnabled = false; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C5A0.s") +#undef OCARINA_SONGS_PLAYABLE_FLAGS -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C8D8.s") +void AudioOcarina_SetSongStartingPos(void) { + sOcarinaSongStartingPos = sOcarinaWithoutMusicStaffPos; +} -const char sAudioOcarinaUnusedText0[] = "key step is too long !!! %d:%d>%d\n"; -const char sAudioOcarinaUnusedText1[] = "You played %d Melody !!! (last step:%d)\n"; -const char sAudioOcarinaUnusedText2[] = "pass 0\n"; -const char sAudioOcarinaUnusedText3[] = "pass 1\n"; -const char sAudioOcarinaUnusedText4[] = "pass 2\n"; -const char sAudioOcarinaUnusedText5[] = "last key is bad !!! %d %d %02X %02X\n"; -const char sAudioOcarinaUnusedText6[] = "last key step is too short !!! %d:%d %d<%d\n"; -const char sAudioOcarinaUnusedText7[] = "check is over!!! %d %d %d\n"; +void AudioOcarina_StartAtSongStartingPos(u32 ocarinaFlags) { + D_801D8530 = false; + AudioOcarina_Start(ocarinaFlags); + if (sOcarinaSongStartingPos != 0) { + sOcarinaWithoutMusicStaffPos = sOcarinaSongStartingPos; + sOcarinaSongStartingPos = 0; + } +} + +void AudioOcarina_StartForSongCheck(u32 ocarinaFlags, u8 ocarinaStaffPlayingPosStart) { + u8 songIndex; + u8 j; + + AudioOcarina_Start(ocarinaFlags); + sMusicStaffNumNotesPerTest = 8; + sOcarinaStaffPlayingPos = ocarinaStaffPlayingPosStart; + + for (songIndex = 0; songIndex <= OCARINA_SONG_EVAN_PART2; songIndex++) { + for (j = 0; j < ocarinaStaffPlayingPosStart;) { + if (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].pitch != OCARINA_PITCH_NONE) { + j++; + } + sMusicStaffPos[songIndex]++; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CD08.s") + if (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].pitch == OCARINA_PITCH_NONE) { + sMusicStaffPos[songIndex]++; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CE34.s") +void AudioOcarina_StartWithSongNoteLengths(u32 ocarinaFlags) { + u8 songIndex; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CE6C.s") + for (songIndex = 0; songIndex < OCARINA_SONG_MAX; songIndex++) { + if ((1 << songIndex) & ocarinaFlags) { + D_801FD530[songIndex] = 0; + } else { + D_801FD530[songIndex] = 0xFF; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CEBC.s") + D_801D8530 = true; + D_801D8534 = ocarinaFlags; + AudioOcarina_Start(ocarinaFlags); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF6C.s") +void AudioOcarina_StartDefault(u32 ocarinaFlags) { + D_801D8530 = false; + AudioOcarina_Start(ocarinaFlags); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF78.s") +u8 func_8019B568(void) { + u32 temp_v0 = D_801D8534; + u8 songIndex; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_GetPlaybackStaff.s") + for (songIndex = OCARINA_SONG_SONATA; !((temp_v0 >> songIndex) & 1) && (songIndex < OCARINA_SONG_MAX); + songIndex++) {} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CFA8.s") + return songIndex; +} + +u8 func_8019B5AC(void) { + u8 songIndex = func_8019B568(); + + if (songIndex < OCARINA_SONG_MAX) { + return D_801FD518[songIndex]; + } + + return 0xFF; +} + +u8 func_8019B5EC(void) { + return D_801FD530[func_8019B568()]; +} + +void AudioOcarina_CheckIfStartedSong(void) { + if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && !sOcarinaHasStartedSong) { + sOcarinaHasStartedSong = true; + sMusicStaffPrevPitch = OCARINA_PITCH_NONE; + } +} + +void AudioOcarina_UpdateCurOcarinaSong(void) { + u8 i; + + if (sOcarinaWithoutMusicStaffPos == 8) { + for (i = 0; i < ARRAY_COUNT(sCurOcarinaSongWithoutMusicStaff) - 1; i++) { + sCurOcarinaSongWithoutMusicStaff[i] = sCurOcarinaSongWithoutMusicStaff[i + 1]; + } + } else { + sOcarinaWithoutMusicStaffPos++; + } +} + +/** + * Checks for ocarina songs from user input with a music staff prompt + * Type 1) Playback: tests note-by-note (ocarinaFlag & 0xC000 == 0x8000) eg: + * - learning a new song + * - playing the ocarina memory game + * Type 2) Check: tests in 8-note chunks (ocarinaFlag & 0xC000 == 0x0000) eg: + * - validating scarecrow spawn song as adult + * - ocarina prompt for zelda's lullaby, saria's song, Storms, Song of Time, etc... + */ +void AudioOcarina_CheckSongsWithMusicStaff(void) { + u32 curOcarinaSongFlag; + s32 pad; + u8 noNewValidInput = false; + s16 pad2; + s8 staffOcarinaPlayingPosOffset = 0; + u8 songIndex; + OcarinaNote* curNote; + OcarinaNote* nextNote; + + AudioOcarina_CheckIfStartedSong(); + + if (!sOcarinaHasStartedSong) { + return; + } + + if (ABS_ALT(sCurOcarinaBendIndex) > 20) { + sOcarinaFlags = 0; + for (songIndex = OCARINA_SONG_SONATA; songIndex < OCARINA_SONG_MAX; songIndex++) { + D_801FD518[songIndex] = 4; + } + sIsOcarinaInputEnabled = false; + return; + } + + if ((sPrevOcarinaPitch == sCurOcarinaPitch) || (sCurOcarinaPitch == OCARINA_PITCH_NONE)) { + noNewValidInput = true; + } else { + AudioOcarina_UpdateCurOcarinaSong(); + sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = sCurOcarinaPitch; + } + + for (songIndex = sFirstOcarinaSongIndex; songIndex < sLastOcarinaSongIndex; songIndex++) { + curOcarinaSongFlag = 1 << songIndex; + + if (sOcarinaAvailableSongFlags & curOcarinaSongFlag) { + if (D_801D8530) { + sMusicStaffCurHeldLength[songIndex] += sOcarinaUpdateTaskStart - sOcarinaPlaybackTaskStart; + } else { + sMusicStaffCurHeldLength[songIndex] = sMusicStaffExpectedLength[songIndex] + 9; + } + + if (noNewValidInput) { + if ((sMusicStaffCurHeldLength[songIndex] > 8) && + (sMusicStaffPrevPitch != sMusicStaffExpectedPitch[songIndex])) { + sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; + if (D_801D8530) { + D_801FD518[songIndex] = 1; + } + } + + if (D_801D8530 && ((sMusicStaffExpectedLength[songIndex] + 9) < sMusicStaffCurHeldLength[songIndex])) { + sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; + D_801FD518[songIndex] = 3; + } else if ((sMusicStaffCurHeldLength[songIndex] >= (sMusicStaffExpectedLength[songIndex] - 9)) && + (sMusicStaffCurHeldLength[songIndex] >= sMusicStaffExpectedLength[songIndex]) && + (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].length == 0) && + (sMusicStaffPrevPitch == sMusicStaffExpectedPitch[songIndex])) { + // This case is taken if the song is finished and successfully played + // (i.e. .length == 0 indicates that the song is at the end) + sPlayedOcarinaSongIndexPlusOne = songIndex + 1; + sIsOcarinaInputEnabled = false; + sOcarinaFlags = 0; + if (D_801D8530) { + D_801FD518[songIndex] = 5; + } + } + } else if (sMusicStaffCurHeldLength[songIndex] >= (sMusicStaffExpectedLength[songIndex] - 9)) { + // This else-if statement always holds true, taken if a new note is played + if (sMusicStaffPrevPitch != OCARINA_PITCH_NONE) { + // New note is played + if (sMusicStaffPrevPitch == sMusicStaffExpectedPitch[songIndex]) { + // Note is part of expected song + if (D_801D8530) { + D_801FD530[songIndex] += + ABS_ALT(sMusicStaffExpectedLength[songIndex] - sMusicStaffCurHeldLength[songIndex]); + } + sMusicStaffCurHeldLength[songIndex] = 0; + } else { + // Note is not part of expected song, so this song is no longer available as an option in this + // playback + sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; + if (D_801D8530) { + D_801FD518[songIndex] = 1; + } + } + } + + curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]]; + nextNote = &sOcarinaSongNotes[songIndex][++sMusicStaffPos[songIndex]]; + sMusicStaffExpectedLength[songIndex] = curNote->length; + sMusicStaffExpectedPitch[songIndex] = curNote->pitch; + + while ((curNote->pitch == nextNote->pitch) || + ((nextNote->pitch == OCARINA_PITCH_NONE) && (nextNote->length != 0))) { + sMusicStaffExpectedLength[songIndex] += nextNote->length; + curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]]; + nextNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex] + 1]; + sMusicStaffPos[songIndex]++; + } + } else if (sMusicStaffCurHeldLength[songIndex] < 9) { + // case never taken + staffOcarinaPlayingPosOffset = -1; + sMusicStaffCurHeldLength[songIndex] = 0; + sMusicStaffPrevPitch = sCurOcarinaPitch; + } else { + // case never taken + if (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].length == 0) { + D_801FD518[songIndex] = 1; + } else if (D_801D8530) { + D_801FD518[songIndex] = 2; + } + sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; + } + } + + // if a note is played that doesn't match a song, the song bit in sAvailOcarinaSongFlags is turned off + // if there are no more songs remaining that it could be and the maximum position has been exceeded, then + if ((sOcarinaAvailableSongFlags == 0) && (sOcarinaStaffPlayingPos >= sMusicStaffNumNotesPerTest)) { + sIsOcarinaInputEnabled = false; + if (!D_801D8530) { + if ((sOcarinaFlags & 0x40000000) && (sCurOcarinaPitch == sOcarinaSongNotes[songIndex][0].pitch)) { + // case never taken, this function is not called if (sOcarinaFlags & 0x40000000) is set + sPrevOcarinaWithMusicStaffFlags = sOcarinaFlags; + } + } + sOcarinaFlags = 0; + return; + } + } + + if (!noNewValidInput) { + sMusicStaffPrevPitch = sCurOcarinaPitch; + sOcarinaStaffPlayingPos += staffOcarinaPlayingPosOffset + 1; + } +} + +/** + * Checks for ocarina songs from user input with no music staff prompt. + * Includes ocarina actions such as free play, no warp + */ +void AudioOcarina_CheckSongsWithoutMusicStaff(void) { + u32 pitch; + u8 ocarinaStaffPlayingPosStart; + u8 songIndex; + u8 j; + u8 k; + + if (CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_L) && + CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)) { + AudioOcarina_StartDefault(sOcarinaFlags); + return; + } + + AudioOcarina_CheckIfStartedSong(); + + if (!sOcarinaHasStartedSong) { + return; + } + + ocarinaStaffPlayingPosStart = sOcarinaStaffPlayingPos; + if ((sPrevOcarinaPitch != sCurOcarinaPitch) && (sCurOcarinaPitch != OCARINA_PITCH_NONE)) { + sOcarinaStaffPlayingPos++; + if (sOcarinaStaffPlayingPos > ARRAY_COUNT(sCurOcarinaSongWithoutMusicStaff)) { + sOcarinaStaffPlayingPos = 1; + } + + AudioOcarina_UpdateCurOcarinaSong(); + + if ((ABS_ALT(sCurOcarinaBendIndex) > 20) && (ocarinaStaffPlayingPosStart != sOcarinaStaffPlayingPos)) { + sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = OCARINA_PITCH_NONE; + } else { + sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = sCurOcarinaPitch; + } + + // This nested for-loop tests to see if the notes from the ocarina are identical + // to any of the songIndex from sFirstOcarinaSongIndex to sLastOcarinaSongIndex + + // Loop through each of the songs + for (songIndex = sFirstOcarinaSongIndex; songIndex < sLastOcarinaSongIndex; songIndex++) { + // Checks to see if the song is available to be played + if ((u32)sOcarinaAvailableSongFlags & (1 << songIndex)) { + // Loops through all possible starting indices? + // Loops through the notes of the song? + for (j = 0, k = 0; j < gOcarinaSongButtons[songIndex].numButtons && k == 0 && + sOcarinaWithoutMusicStaffPos >= gOcarinaSongButtons[songIndex].numButtons;) { + + pitch = sCurOcarinaSongWithoutMusicStaff[(sOcarinaWithoutMusicStaffPos - + gOcarinaSongButtons[songIndex].numButtons) + + j]; + + if (pitch == sButtonToPitchMap[gOcarinaSongButtons[songIndex].buttonIndex[j]]) { + j++; + } else { + k++; + } + } + + // This conditional is true if songIndex = i is detected + if (j == gOcarinaSongButtons[songIndex].numButtons) { + sPlayedOcarinaSongIndexPlusOne = songIndex + 1; + sIsOcarinaInputEnabled = false; + sOcarinaFlags = 0; + } + } + } + } +} + +void AudioOcarina_PlayControllerInput(u8 isOcarinaSfxSuppressedWhenCancelled) { + u32 ocarinaBtnsHeld; + + // Prevents two different ocarina notes from being played on two consecutive frames + if ((sOcarinaFlags != 0) && (sOcarinaDropInputTimer != 0)) { + sOcarinaDropInputTimer--; + return; + } + + // Ensures the button pressed to start the ocarina does not also play an ocarina note + if ((sOcarinaInputButtonStart == 0) || + ((sOcarinaInputButtonStart & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)) != + (sOcarinaInputButtonCur & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)))) { + sOcarinaInputButtonStart = 0; + if (1) {} + sCurOcarinaPitch = OCARINA_PITCH_NONE; + sCurOcarinaButtonIndex = OCARINA_BTN_INVALID; + ocarinaBtnsHeld = (sOcarinaInputButtonCur & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)) & + (sOcarinaInputButtonPrev & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)); + + if (!(sOcarinaInputButtonPress & ocarinaBtnsHeld) && (sOcarinaInputButtonCur != 0)) { + sOcarinaInputButtonPress = sOcarinaInputButtonCur; + } else { + sOcarinaInputButtonPress &= ocarinaBtnsHeld; + } + + // Interprets and transforms controller input into ocarina buttons and notes + if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_A)) { + sCurOcarinaPitch = OCARINA_PITCH_D4; + sCurOcarinaButtonIndex = OCARINA_BTN_A; + + } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CDOWN)) { + sCurOcarinaPitch = OCARINA_PITCH_F4; + sCurOcarinaButtonIndex = OCARINA_BTN_C_DOWN; + + } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CRIGHT)) { + sCurOcarinaPitch = OCARINA_PITCH_A4; + sCurOcarinaButtonIndex = OCARINA_BTN_C_RIGHT; + + } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CLEFT)) { + sCurOcarinaPitch = OCARINA_PITCH_B4; + sCurOcarinaButtonIndex = OCARINA_BTN_C_LEFT; + + } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CUP)) { + sCurOcarinaPitch = OCARINA_PITCH_D5; + sCurOcarinaButtonIndex = OCARINA_BTN_C_UP; + } + + if (sOcarinaInputButtonCur) {} + + // Pressing the R Button will raise the pitch by 1 semitone + if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_R) && + (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) { + sCurOcarinaButtonIndex += OCARINA_BUTTON_FLAG_BFLAT_RAISE; // Flag to resolve B Flat 4 + sCurOcarinaPitch++; // Raise the pitch by 1 semitone + } + + // Pressing the Z Button will lower the pitch by 1 semitone + if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_Z) && + (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) { + sCurOcarinaButtonIndex += OCARINA_BUTTON_FLAG_BFLAT_LOWER; // Flag to resolve B Flat 4 + sCurOcarinaPitch--; // Lower the pitch by 1 semitone + } + + if (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN) { + // Bend the pitch of the note based on y control stick + sCurOcarinaBendIndex = sOcarinaInputStickRel.y; + sCurOcarinaBendFreq = AudioOcarina_BendPitchTwoSemitones(sCurOcarinaBendIndex); + + // Add vibrato of the ocarina note based on the x control stick + sCurOcarinaVibrato = ABS_ALT(sOcarinaInputStickRel.x) >> 2; + // Sets vibrato to io port 6 + Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sCurOcarinaVibrato); + } else { + // no bending or vibrato for recording state OCARINA_RECORD_SCARECROW_SPAWN + sCurOcarinaBendIndex = 0; + sCurOcarinaVibrato = 0; + sCurOcarinaBendFreq = 1.0f; // No bend + } + + // Processes new and valid notes + if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && (sPrevOcarinaPitch != sCurOcarinaPitch)) { + // Sets ocarina instrument Id to io port 7, which is used + // as an index in seq 0 to get the true instrument Id + Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7, sOcarinaInstrumentId - 1); + // Sets pitch to io port 5 + Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, sCurOcarinaPitch); + Audio_PlaySfxGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sCurOcarinaBendFreq, &sDefaultOcarinaVolume, + &gSfxDefaultReverb); + } else if ((sPrevOcarinaPitch != OCARINA_PITCH_NONE) && (sCurOcarinaPitch == OCARINA_PITCH_NONE) && + !isOcarinaSfxSuppressedWhenCancelled) { + // Stops ocarina sound when transitioning from playing to not playing a note + Audio_StopSfxById(NA_SE_OC_OCARINA); + } + } +} + +/** + * Directly enable the ocarina to receive input without + * properly resetting it based on an ocarina instrument id + * Unused. + */ +void AudioOcarina_EnableInput(u8 inputEnabled) { + sIsOcarinaInputEnabled = inputEnabled; +} + +/** + * Resets ocarina properties + */ +void AudioOcarina_ResetAndMute(void) { + sOcarinaInputButtonCur = 0; + sOcarinaInputButtonPrev = 0; + sOcarinaInputButtonPress = 0; + + sOcarinaInputButtonStart = 0xFFFF; + + AudioOcarina_PlayControllerInput(false); + Audio_StopSfxById(NA_SE_OC_OCARINA); + + if (gAudioSpecId != 12) { + Audio_SetSfxBanksMute(0); + } + + sPlaybackState = 0; + sPlaybackStaffPos = 0; + sIsOcarinaInputEnabled = false; + + sOcarinaFlags = 0; + + // return to full volume for both bgm players after ocarina is finished + Audio_ClearFlagForBgmVolumeLow(SFX_CHANNEL_OCARINA); + // return to full volume for all sfx channels except system & ocarina banks + Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x7F); +} + +void AudioOcarina_ResetAndReadInput(void) { + sOcarinaInputButtonCur = 0; + sOcarinaInputButtonPrev = 0; + sOcarinaInputButtonPress = 0; + + sOcarinaInputButtonStart = 0xFFFF; + + AudioOcarina_PlayControllerInput(true); + + sPlaybackState = 0; + sPlaybackStaffPos = 0; + sIsOcarinaInputEnabled = false; + + sOcarinaFlags = 0; + + sOcarinaInputButtonCur = 0; + + AudioOcarina_ReadControllerInput(); + sOcarinaInputButtonStart = sOcarinaInputButtonCur; +} + +/** + * Set a timer that will disable the ocarina once the timer reaches 0 + */ +void AudioOcarina_SetOcarinaDisableTimer(u8 unused, u8 timer) { + sOcarinaDisableTimer = timer; + sOcarinaUnused = unused; +} + +u32 AudioOcarina_SetInstrument(u8 ocarinaInstrumentId) { + if ((sOcarinaInstrumentId != ocarinaInstrumentId) || (ocarinaInstrumentId == OCARINA_INSTRUMENT_DEFAULT)) { + Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_SFX) << 24) | ((u32)(1) << 16) | + ((u32)(SFX_CHANNEL_OCARINA) << 8) | (u32)(ocarinaInstrumentId)); + sOcarinaInstrumentId = ocarinaInstrumentId; + + if (ocarinaInstrumentId == OCARINA_INSTRUMENT_OFF) { + AudioOcarina_ResetAndMute(); + } else { + sOcarinaInputButtonCur = 0; + AudioOcarina_ReadControllerInput(); + sOcarinaInputButtonStart = sOcarinaInputButtonCur; + // lowers volume of all sfx channels except system & ocarina banks + Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x40); + // lowers volume of bgm players while playing ocarina + Audio_SetFlagForBgmVolumeLow(SFX_CHANNEL_OCARINA); + } + } +} + +void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, u8 playbackState) { + u8 i = 0; + + if (songIndexPlusOne == 0) { + sPlaybackState = 0; + Audio_StopSfxById(NA_SE_OC_OCARINA); + return; + } + + if (songIndexPlusOne < (OCARINA_SONG_MAX + 1)) { + sPlaybackSong = sOcarinaSongNotes[songIndexPlusOne - 1]; + } else { + sPlaybackSong = sScarecrowsLongSongNotes; + } + + sPlaybackNotePos = 0; + if (playbackState & 0x80) { + sPlaybackState = 1; + sPlaybackStaffStopPos = playbackState & 0xF; + sPlaybackStaffStartPos = 0xFF; + } else if (playbackState & 0x40) { + sPlaybackState = 1; + sPlaybackStaffStartPos = playbackState & 0xF; + sPlaybackStaffStopPos = 0xFF; + while (i < sPlaybackStaffStartPos) { + if (sOcarinaSongNotes[songIndexPlusOne - 1][sPlaybackNotePos].pitch != OCARINA_PITCH_NONE) { + i++; + } + sPlaybackNotePos++; + } + } else { + sPlaybackState = playbackState; + sPlaybackStaffStopPos = 0xFF; + sPlaybackStaffStartPos = 0xFF; + } + + sPlaybackNoteTimer = 0; + sPlaybackPitch = OCARINA_PITCH_NONE; + sPlaybackStaffPos = 0; + + if (sPlaybackStaffStartPos == 0xFF) { + while ((sPlaybackSong[sPlaybackNotePos].pitch == OCARINA_PITCH_NONE) && + (songIndexPlusOne > (OCARINA_SONG_EVAN_PART2 + 1))) { + sPlaybackNotePos++; + } + } +} + +/** + * Play a song with the ocarina to the user that is + * based on OcarinaNote data and not user input + */ +void AudioOcarina_PlaybackSong(void) { + s32 noteTimerStep; + s32 nextNoteTimerStep; + + if (sPlaybackState == 0) { + return; + } + + if (sPlaybackStaffPos == 0) { + noteTimerStep = 3; + } else { + noteTimerStep = sOcarinaUpdateTaskStart - sOcarinaPlaybackTaskStart; + } + + if (noteTimerStep < sPlaybackNoteTimer) { + sPlaybackNoteTimer -= noteTimerStep; + } else { + nextNoteTimerStep = noteTimerStep - sPlaybackNoteTimer; + sPlaybackNoteTimer = 0; + } + + if (sPlaybackNoteTimer == 0) { + + if (sPlaybackStaffPos == sPlaybackStaffStopPos) { + sPlaybackState = 0; + return; + } + + sPlaybackNoteTimer = sPlaybackSong[sPlaybackNotePos].length; + + if (sPlaybackNotePos == 1) { + sPlaybackNoteTimer++; + } + + if (sPlaybackNoteTimer == 0) { + sPlaybackState--; + if (sPlaybackState != 0) { + sPlaybackNotePos = 0; + sPlaybackStaffPos = 0; + sPlaybackPitch = OCARINA_PITCH_NONE; + } else { + Audio_StopSfxById(NA_SE_OC_OCARINA); + } + return; + } else { + sPlaybackNoteTimer -= nextNoteTimerStep; + } + + // Update volume + if (sNotePlaybackVolume != sPlaybackSong[sPlaybackNotePos].volume) { + sNotePlaybackVolume = sPlaybackSong[sPlaybackNotePos].volume; + sRelativeNotePlaybackVolume = sNotePlaybackVolume / 127.0f; + } + + // Update vibrato + sNotePlaybackVibrato = sPlaybackSong[sPlaybackNotePos].vibrato; + // Sets vibrato to io port 6 + Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sNotePlaybackVibrato); + + // Update bend + if (sNotePlaybackBend != sPlaybackSong[sPlaybackNotePos].bend) { + sNotePlaybackBend = sPlaybackSong[sPlaybackNotePos].bend; + sRelativeNotePlaybackBend = AudioOcarina_BendPitchTwoSemitones(sNotePlaybackBend); + } + + // No changes in volume, vibrato, or bend between notes + if ((sPlaybackSong[sPlaybackNotePos].volume == sPlaybackSong[sPlaybackNotePos - 1].volume && + (sPlaybackSong[sPlaybackNotePos].vibrato == sPlaybackSong[sPlaybackNotePos - 1].vibrato) && + (sPlaybackSong[sPlaybackNotePos].bend == sPlaybackSong[sPlaybackNotePos - 1].bend))) { + sPlaybackPitch = 0xFE; + } + + if (sPlaybackPitch != sPlaybackSong[sPlaybackNotePos].pitch) { + u8 pitch = sPlaybackSong[sPlaybackNotePos].pitch; + + // As bFlat4 is exactly in the middle of notes B & A, a flag is + // added to the pitch to resolve which button to map Bflat4 to + if (pitch == OCARINA_PITCH_BFLAT4) { + sPlaybackPitch = pitch + sPlaybackSong[sPlaybackNotePos].bFlat4Flag; + } else { + sPlaybackPitch = pitch; + } + + if (sPlaybackPitch != OCARINA_PITCH_NONE) { + sPlaybackStaffPos++; + // Sets ocarina instrument Id to io port 7, which is used + // as an index in seq 0 to get the true instrument Id + Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7, + sOcarinaInstrumentId - 1); + Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, + sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH); + Audio_PlaySfxGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend, + &sRelativeNotePlaybackVolume, &gSfxDefaultReverb); + } else { + Audio_StopSfxById(NA_SE_OC_OCARINA); + } + } + sPlaybackNotePos++; + } +} + +void AudioOcarina_SetRecordingSong(u8 isRecordingComplete) { + u16 i; + u16 i2; + u16 pad; + u8 pitch; + OcarinaNote* note; + u8 j; + u8 k; + s32 t; + OcarinaNote* recordedSong; + + if (sRecordingState == OCARINA_RECORD_SCARECROW_LONG) { + recordedSong = gScarecrowLongSongPtr; + } else { + /** + * OCARINA_RECORD_SCARECROW_SPAWN + * + * The notes for scarecrows spawn song are first recorded into the ocarina termina + * wall address to act as a buffer. That way, if a new scarecrow spawn song is + * rejected, the previous scarecrow spawn song is not overwritten. If the scarecrow + * spawn song is accepted, then the notes are copied over to the scarecrow spawn + * song address + */ + recordedSong = sTerminaWallSongPtr; + } + + recordedSong[sRecordSongPos].pitch = sRecordOcarinaPitch; + recordedSong[sRecordSongPos].length = sOcarinaUpdateTaskStart - sOcarinaRecordTaskStart; + recordedSong[sRecordSongPos].volume = sRecordOcarinaVolume; + recordedSong[sRecordSongPos].vibrato = sRecordOcarinaVibrato; + recordedSong[sRecordSongPos].bend = sRecordOcarinaBendIndex; + recordedSong[sRecordSongPos].bFlat4Flag = sRecordOcarinaButtonIndex & OCARINA_BUTTON_MASK_FLAG; + + sRecordOcarinaPitch = sCurOcarinaPitch; + sRecordOcarinaVolume = sCurOcarinaVolume; + sRecordOcarinaVibrato = sCurOcarinaVibrato; + sRecordOcarinaBendIndex = sCurOcarinaBendIndex; + sRecordOcarinaButtonIndex = sCurOcarinaButtonIndex; + + sRecordSongPos++; + + if ((sRecordSongPos != (ARRAY_COUNT(sScarecrowsLongSongNotes) - 1)) && !isRecordingComplete) { + // Continue recording + return; + } + + // Recording is complete + + i = sRecordSongPos; + pitch = OCARINA_PITCH_NONE; + while (i != 0 && pitch == OCARINA_PITCH_NONE) { + i--; + pitch = recordedSong[i].pitch; + } + + if (sRecordSongPos != (i + 1)) { + sRecordSongPos = i + 2; + recordedSong[sRecordSongPos - 1].length = 0; + } + + recordedSong[sRecordSongPos].length = 0; + + if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { + if (sOcarinaStaffPlayingPos >= 8) { + for (i = 0; i < sRecordSongPos; i++) { + recordedSong[i] = recordedSong[i + 1]; + } + + // Copies Notes from buffer into scarecrows spawn buttons to be tested for acceptance or rejection + AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_SCARECROW_SPAWN, 8); + + // Tests to see if the notes from the scarecrow song contain identical + // notes within its song to any of the reserved songIndex from 0 to 21 + + // Loop through each of the songs + for (i = 0; i < OCARINA_SONG_SCARECROW_SPAWN; i++) { + // Checks to see if the song is reserved + if (sIsOcarinaSongReserved[i]) { + // Loops through all possible starting indices + for (j = 0; (j < 9 - gOcarinaSongButtons[i].numButtons); j++) { + // Loops through the notes of the song + for (k = 0; (k < gOcarinaSongButtons[i].numButtons) && (k + j < 8) && + (gOcarinaSongButtons[i].buttonIndex[k] == + gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonIndex[k + j]); + k++) { + ; + } + + // This conditional is true if the recorded song contains a reserved song + // recorded song is cancelled + if (k == gOcarinaSongButtons[i].numButtons) { + sRecordingState = OCARINA_RECORD_REJECTED; + sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF; + return; + } + } + } + } + + // Counts how many times a note is repeated + i = 1; + while (i < 8) { + if (gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonIndex[0] != + gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonIndex[i]) { + i = 9; // break + } else { + i++; + } + } + + // This condition is true if all 8 notes are the same pitch + if (i == 8) { + sRecordingState = OCARINA_RECORD_REJECTED; + sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF; + return; + } + + // The scarecrow spawn song is accepted and copied from the buffer to the scarecrow spawn notes + for (i = 0; i < sRecordSongPos; i++) { + sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][i] = sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i]; + } + + sIsOcarinaInputEnabled = false; + } else { + sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF; + } + } + + sRecordingState = OCARINA_RECORD_OFF; +} + +/** + * recordingState = OCARINA_RECORD_OFF, end + * recordingState = OCARINA_RECORD_SCARECROW_LONG, start long scarecrows song + * recordingState = OCARINA_RECORD_SCARECROW_SPAWN, start spawn scarecrows song + */ +void AudioOcarina_SetRecordingState(u8 recordingState) { + if ((u32)recordingState == sRecordingState) { + return; + } + + if (recordingState != OCARINA_RECORD_OFF) { + sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart; + sRecordOcarinaPitch = OCARINA_PITCH_NONE; + sRecordOcarinaVolume = 0x57; + sRecordOcarinaVibrato = 0; + sRecordOcarinaBendIndex = 0; + sRecordOcarinaButtonIndex = 0; + sRecordSongPos = 0; + sIsOcarinaInputEnabled = true; + sOcarinaStaffPlayingPos = 0; + sScarecrowsLongSongSecondNote = sScarecrowsLongSongNotes[1]; + } else { + if (sRecordSongPos == 0) { + sScarecrowsLongSongNotes[1] = sScarecrowsLongSongSecondNote; + } else { + if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { + sOcarinaStaffPlayingPos = 1; + } + + AudioOcarina_SetRecordingSong(true); + } + + sIsOcarinaInputEnabled = false; + sOcarinaStaffPlayingPos = 0; + } + + sRecordingState = recordingState; +} + +void AudioOcarina_UpdateRecordingStaff(void) { + sRecordingStaff.state = sRecordingState; + sRecordingStaff.pos = sOcarinaStaffPlayingPos; + if (sRecordingState == OCARINA_RECORD_REJECTED) { + sRecordingState = OCARINA_RECORD_OFF; + } +} + +void AudioOcarina_UpdatePlayingStaff(void) { + if (sCurOcarinaButtonIndex != OCARINA_BTN_INVALID) { + sPlayingStaff.buttonIndex = sCurOcarinaButtonIndex & OCARINA_BUTTON_MASK_PITCH; + } + sPlayingStaff.state = AudioOcarina_GetPlayingState(); + sPlayingStaff.pos = sOcarinaStaffPlayingPos; +} + +void AudioOcarina_UpdatePlaybackStaff(void) { + if ((sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH) <= OCARINA_PITCH_EFLAT5) { + sPlaybackStaff.buttonIndex = AudioOcarina_MapPitchToButton(sPlaybackPitch); + } + + sPlaybackStaff.state = sPlaybackState; + + if (sPlaybackSong != sScarecrowsLongSongNotes) { + sPlaybackStaff.pos = sPlaybackStaffPos; + } else if (sPlaybackStaffPos == 0) { + sPlaybackStaff.pos = 0; + } else { + sPlaybackStaff.pos = ((sPlaybackStaffPos - 1) % 8) + 1; + } +} + +OcarinaStaff* AudioOcarina_GetRecordingStaff(void) { + return &sRecordingStaff; +} + +OcarinaStaff* AudioOcarina_GetPlayingStaff(void) { + if (sPlayingStaff.state < 0xFE) { + sOcarinaFlags = 0; + } + + return &sPlayingStaff; +} + +OcarinaStaff* AudioOcarina_GetPlaybackStaff(void) { + return &sPlaybackStaff; +} + +void AudioOcarina_RecordSong(void) { + s32 noteChanged; + + if ((sRecordingState != OCARINA_RECORD_OFF) && ((sOcarinaUpdateTaskStart - sOcarinaRecordTaskStart) >= 3)) { + noteChanged = false; + if (sRecordOcarinaPitch != sCurOcarinaPitch) { + if (sCurOcarinaPitch != OCARINA_PITCH_NONE) { + sRecordingStaff.buttonIndex = sCurOcarinaButtonIndex & OCARINA_BUTTON_MASK_PITCH; + sOcarinaStaffPlayingPos++; + } else if ((sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) && (sOcarinaStaffPlayingPos == 8)) { + AudioOcarina_SetRecordingSong(true); + return; + } + + if (sOcarinaStaffPlayingPos > 8) { + if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { + // notes played are over 8 and in recording mode. + AudioOcarina_SetRecordingSong(true); + return; + } + sOcarinaStaffPlayingPos = 1; + } + noteChanged = true; + } else if (sRecordOcarinaVolume != sCurOcarinaVolume) { + noteChanged = true; + } else if (sRecordOcarinaVibrato != sCurOcarinaVibrato) { + if (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN) { + noteChanged = true; + } + } else if ((sRecordOcarinaBendIndex != sCurOcarinaBendIndex) && + (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) { + noteChanged = true; + } + + if (noteChanged) { + AudioOcarina_SetRecordingSong(false); + sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart; + } + } +} /** * Tests to see if the notes from songIndex contain identical notes @@ -2007,7 +3063,7 @@ s32 AudioOcarina_TerminaWallValidateNotes(u8 songIndex, u8 maxSongIndex) { */ void AudioOcarina_TerminaWallGenerateNotes(void) { OcarinaNote* ocarinaNote; - u8 randButtonIndex; + u8 randomButtonIndex; u8 i; u8 j; @@ -2017,8 +3073,8 @@ void AudioOcarina_TerminaWallGenerateNotes(void) { j = 0; for (; i < 8; i++) { - randButtonIndex = Audio_NextRandom() % ARRAY_COUNT(sButtonToPitchMap); - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = sButtonToPitchMap[randButtonIndex]; + randomButtonIndex = Audio_NextRandom() % ARRAY_COUNT(sButtonToPitchMap); + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = sButtonToPitchMap[randomButtonIndex]; sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 19; sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 80; sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; @@ -2036,7 +3092,7 @@ void AudioOcarina_TerminaWallGenerateNotes(void) { sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j - 1].length = 22; sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].pitch = OCARINA_PITCH_NONE; sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].length = 0; - AudioOcarina_MapSongFromNotesToButtons(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, 8); + AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, 8); } else { j = Audio_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes); ocarinaNote = sOoTOcarinaSongNotes[j]; @@ -2047,8 +3103,8 @@ void AudioOcarina_TerminaWallGenerateNotes(void) { sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i].pitch = OCARINA_PITCH_NONE; sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i].length = 0; - AudioOcarina_MapSongFromNotesToButtons(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, - sOoTOcarinaSongsNumNotes[j]); + AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, + sOoTOcarinaSongsNumNotes[j]); } } while (AudioOcarina_TerminaWallValidateNotes(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL) != 0); } @@ -2056,7 +3112,7 @@ void AudioOcarina_TerminaWallGenerateNotes(void) { /** * Unused remnant of OoT */ -void AudioOcarina_MemoryGameSetNumNotes(u8 minigameRound) { +void AudioOcarina_MemoryGameInit(u8 minigameRound) { u8 i; if (minigameRound > 2) { @@ -2064,10 +3120,10 @@ void AudioOcarina_MemoryGameSetNumNotes(u8 minigameRound) { } sOcarinaMemoryGameAppendPos = 0; - sOcaMemoryGameEndPos = sOcaMemoryGameNumNotes[minigameRound]; + sOcarinaMemoryGameEndPos = sOcarinaMemoryGameNumNotes[minigameRound]; for (i = 0; i < 3; i++) { - AudioOcarina_MemoryGameGenerateNotes(); + AudioOcarina_MemoryGameNextNote(); } } @@ -2075,52 +3131,363 @@ void AudioOcarina_MemoryGameSetNumNotes(u8 minigameRound) { * Unused remnant of OoT, Id 14 now represent Goron Lullaby Intro instead of the OoT ocarina memory game * //! @bug calling this function in MM will overwrite Goron Lullaby Intro */ -#define OCARINA_SONG_MEMORYGAME 14 -s32 AudioOcarina_MemoryGameGenerateNotes(void) { - u32 randButtonIndex; - u8 randPitch; +#define OCARINA_SONG_MEMORY_GAME 14 +s32 AudioOcarina_MemoryGameNextNote(void) { + u32 randomButtonIndex; + u8 randomPitch; - if (sOcarinaMemoryGameAppendPos == sOcaMemoryGameEndPos) { + if (sOcarinaMemoryGameAppendPos == sOcarinaMemoryGameEndPos) { return true; } - randButtonIndex = Audio_NextRandom(); - randPitch = sButtonToPitchMap[randButtonIndex % ARRAY_COUNT(sButtonToPitchMap)]; + randomButtonIndex = Audio_NextRandom(); + randomPitch = sButtonToPitchMap[randomButtonIndex % ARRAY_COUNT(sButtonToPitchMap)]; - if (sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos - 1].pitch == randPitch) { - randPitch = sButtonToPitchMap[(randButtonIndex + 1) % ARRAY_COUNT(sButtonToPitchMap)]; + if (sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos - 1].pitch == randomPitch) { + randomPitch = sButtonToPitchMap[(randomButtonIndex + 1) % ARRAY_COUNT(sButtonToPitchMap)]; } - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].pitch = randPitch; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].length = 45; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].volume = 0x50; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].bend = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].pitch = randomPitch; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].length = 45; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].volume = 0x50; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].bend = 0; sOcarinaMemoryGameAppendPos++; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].length = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos + 1].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos + 1].length = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].length = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos + 1].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos + 1].length = 0; if (1) {} return false; } -#undef OCARINA_SONG_MEMORYGAME +#undef OCARINA_SONG_MEMORY_GAME + +void AudioOcarina_Update(void) { + sOcarinaUpdateTaskStart = gAudioContext.totalTaskCount; + if (sOcarinaInstrumentId != OCARINA_INSTRUMENT_OFF) { + if (sIsOcarinaInputEnabled == true) { + AudioOcarina_ReadControllerInput(); + } + + if ((sPlaybackState == 0) && (sIsOcarinaInputEnabled == true)) { + AudioOcarina_PlayControllerInput(false); + } + + if (sOcarinaFlags != 0) { + if (sOcarinaFlags & 0x40000000) { + AudioOcarina_CheckSongsWithoutMusicStaff(); + } else { + AudioOcarina_CheckSongsWithMusicStaff(); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D600.s") + AudioOcarina_PlaybackSong(); + sOcarinaPlaybackTaskStart = sOcarinaUpdateTaskStart; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D758.s") + if (sPlaybackState == 0) { + AudioOcarina_RecordSong(); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D864.s") + if ((sOcarinaFlags != 0) && (sPrevOcarinaPitch != sCurOcarinaPitch)) { + sOcarinaDropInputTimer = 1; // Drops ocarina input for 1 frame + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D8B4.s") + sPrevOcarinaPitch = sCurOcarinaPitch; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D8E4.s") + if (sOcarinaDisableTimer != 0) { + sOcarinaDisableTimer--; + if (sOcarinaDisableTimer == 0) { + AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DF28.s") + AudioOcarina_UpdatePlayingStaff(); + AudioOcarina_UpdatePlaybackStaff(); + AudioOcarina_UpdateRecordingStaff(); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DF64.s") +#define OCARINA_INSTRUMENT_OOT_MAX 7 + +void AudioOcarina_PlayLongScarecrowAfterCredits(void) { + static u8 sScarecrowAfterCreditsState = 0; + static u8 sScarecrowAfterCreditsIntrumentId = OCARINA_INSTRUMENT_DEFAULT; + static u16 sScarecrowAfterCreditsTimer = 1200; + + switch (sScarecrowAfterCreditsState) { + case 0: + if (sScarecrowAfterCreditsTimer-- == 0) { + // OoT originally had 7 Ocarina instruments + // MM has more so this does not go all the way to the max + if (sScarecrowAfterCreditsIntrumentId < OCARINA_INSTRUMENT_OOT_MAX) { + // set next ocarina instrument and restart + sScarecrowAfterCreditsState++; + } else { + // finished + sScarecrowAfterCreditsState = 3; + AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); + } + sScarecrowAfterCreditsTimer = 1200; + } + break; + + case 1: + Audio_SetSfxBanksMute(0); + AudioOcarina_SetInstrument(sScarecrowAfterCreditsIntrumentId); + AudioOcarina_SetPlaybackSong(OCARINA_SONG_SCARECROW_LONG + 1, 1); + sScarecrowAfterCreditsIntrumentId++; + sScarecrowAfterCreditsState++; + break; + + case 2: + if (AudioOcarina_GetPlaybackStaff()->state == 0) { + sScarecrowAfterCreditsState = 0; + } + break; + } +} + +u8 sRequestCustomSequence = false; + +void AudioOcarina_SetCustomSequence(void) { + // Never passes true as sRequestCustomSequence is never set true + if (sRequestCustomSequence && gAudioContext.seqPlayers[SEQ_PLAYER_FANFARE].enabled && + ((u8)gAudioContext.seqPlayers[SEQ_PLAYER_FANFARE].soundScriptIO[0] == 0xFF)) { + gAudioContext.seqPlayers[SEQ_PLAYER_FANFARE].seqData = sCustomSequenceScript; + sRequestCustomSequence = false; + } +} + +// Called by unused function +void AudioOcarina_PlayCustomSequence(void) { + sRequestCustomSequence = true; + Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_FANFARE) << 24) | ((u32)(0) << 0x10) | + (u32)(NA_BGM_DUNGEON_APPEAR)); +} + +// Unused +// Regalloc Swap https://decomp.me/scratch/QEovr +#ifdef NON_MATCHING +s32 AudioOcarina_CreateCustomSequence(void) { + OcarinaNote* prevNote; + u16 i; + u16 phi_s4; + u16 temp_a0; // delay1 + u16 phi_a2; // delay2 + u8 absPitch; + s8 phi_a0; // adjBendIndex + s8 phi_s2; // prevBend + u8 phi_t1; // vibrato + u8 phi_t5; // isLegato + u16 temp_t4; // prevNoteLength + + phi_a2 = 0; + phi_t1 = 0; + phi_s2 = 0; + phi_t5 = 0; + phi_s4 = 0; + + sCustomSequencePc = 39; // .channel chan_loop + + prevNote = &sScarecrowsLongSongNotes[0]; + for (i = 1; ((prevNote->pitch == OCARINA_PITCH_NONE) && (prevNote->length != 0)); i++) { + prevNote = &sScarecrowsLongSongNotes[i]; + } + + for (; (prevNote->length != 0) && (sCustomSequencePc < 394); i++) { + + temp_a0 = ((prevNote->length * 48) / 30); + + if (phi_t1 != prevNote->vibrato) { + sCustomSequenceScript[sCustomSequencePc++] = 0xFD; // delay cmd + + if (phi_a2 >= 0x80) { + // Store as compressed u16 + sCustomSequenceScript[sCustomSequencePc++] = (((phi_a2 >> 8) & 0xFF) & 0x7F) + 0x80; // delay arg + sCustomSequenceScript[sCustomSequencePc++] = phi_a2 & 0xFF; // delay arg + } else { + // Store as u8 + sCustomSequenceScript[sCustomSequencePc++] = phi_a2; // delay arg + } + + sCustomSequenceScript[sCustomSequencePc++] = 0xD8; // vibdepth cmd + sCustomSequenceScript[sCustomSequencePc++] = prevNote->vibrato; // vibdepth arg + + phi_a2 = temp_a0; + phi_t1 = prevNote->vibrato; + } else { + phi_a2 += temp_a0; + } + + prevNote = &sScarecrowsLongSongNotes[i]; + } + + if (phi_a2 != 0) { + sCustomSequenceScript[sCustomSequencePc++] = 0xFD; // delay cmd + if (phi_a2 >= 0x80) { + // Store as compressed u16 + sCustomSequenceScript[sCustomSequencePc++] = (((phi_a2 >> 8) & 0xFF) & 0x7F) + 0x80; // delay arg + sCustomSequenceScript[sCustomSequencePc++] = phi_a2 & 0xFF; // delay arg + } else { + // Store as u8 + sCustomSequenceScript[sCustomSequencePc++] = phi_a2; // delay arg + } + } + + sCustomSequenceScript[sCustomSequencePc++] = 0xFF; // end cmd + + // ldlayer 0, layer0 + sCustomSequenceScript[24] = sCustomSequencePc >> 8; + sCustomSequenceScript[25] = sCustomSequencePc & 0xFF; + + // ldlayer 1, layer1 + sCustomSequenceScript[27] = (sCustomSequencePc + 4) >> 8; + sCustomSequenceScript[28] = (sCustomSequencePc + 4) & 0xFF; + + sCustomSequenceScript[sCustomSequencePc++] = 0xC2; // transpose cmd + sCustomSequenceScript[sCustomSequencePc++] = -5; // transpose arg + + sCustomSequenceScript[sCustomSequencePc++] = 0xC0; // ldelay cmd + sCustomSequenceScript[sCustomSequencePc++] = 8; // ldelay arg + + sCustomSequenceScript[sCustomSequencePc++] = 0xC1; // shortvel cmd + sCustomSequenceScript[sCustomSequencePc++] = 87; // shortvel arg + + sCustomSequenceScript[sCustomSequencePc++] = 0xC9; // shortgate cmd + sCustomSequenceScript[sCustomSequencePc++] = 0; // shortgate arg + + if (1) {} + if (1) {} // TODO: Needed? + + prevNote = &sScarecrowsLongSongNotes[0]; + + for (i = 1; ((prevNote->pitch == OCARINA_PITCH_NONE) && (prevNote->length != 0)); i++) { + prevNote = &sScarecrowsLongSongNotes[i]; + } + + for (; ((temp_t4 = prevNote->length) != 0) && (sCustomSequencePc < 394); i++) { + + if (prevNote->pitch == sScarecrowsLongSongNotes[i].pitch) { + if ((sScarecrowsLongSongNotes[i].length != 0) && (phi_t5 == 0)) { + sCustomSequenceScript[sCustomSequencePc++] = 0xC4; // legato cmd + phi_t5 = 1; + } + } else if ((phi_t5 == 1) && (sScarecrowsLongSongNotes[i].pitch != OCARINA_PITCH_NONE) && + (sScarecrowsLongSongNotes[i].pitch != OCARINA_PITCH_C4)) { + sCustomSequenceScript[sCustomSequencePc++] = 0xC5; // nolegato cmd + phi_t5 = 0; + } + + if (phi_s2 != prevNote->bend) { + sCustomSequenceScript[sCustomSequencePc++] = 0xCE; // bendfine cmd + + if (ABS_ALT(prevNote->bend) > 64) { + phi_a0 = 127; + } else if (prevNote->bend < 0) { + phi_a0 = -prevNote->bend; + } else { + phi_a0 = ((prevNote->bend * 127) / 64); + } + + if (prevNote->bend < 0) { + phi_a0 *= -1; + } + + sCustomSequenceScript[sCustomSequencePc++] = phi_a0; // bendfine arg + + phi_s2 = prevNote->bend; + } + + absPitch = prevNote->pitch + 39; // convert ocarina pitch to absolute pitch, + PITCH_C4 (Middle C) + if (prevNote->pitch != OCARINA_PITCH_NONE) { + sCustomSequenceScript[sCustomSequencePc++] = absPitch; // shortdvg cmd, shortdvg arg + } else { + sCustomSequenceScript[sCustomSequencePc++] = 0xC0; // ldelay cmd + } + + // delay/duration + temp_a0 = ((temp_t4 * 48) + phi_s4) / 30; + + if (temp_a0 < 0x80) { + // Store as u8 + sCustomSequenceScript[sCustomSequencePc++] = temp_a0; // shortdvg/ldelay arg + } else { + // Store as compressed u16 + sCustomSequenceScript[sCustomSequencePc++] = (((temp_a0 >> 8) & 0xFF) & 0x7F) + 0x80; // shortdvg/ldelay arg + sCustomSequenceScript[sCustomSequencePc++] = temp_a0 & 0xFF; // shortdvg/ldelay arg + } + + if (1) {} + + phi_s4 = ((temp_t4 * 48) + phi_s4) - (temp_a0 * 30); + + prevNote = &sScarecrowsLongSongNotes[i]; + } + + sCustomSequenceScript[sCustomSequencePc++] = 0xFF; // end cmd + + AudioOcarina_PlayCustomSequence(); + + if (i >= 394) { + return -1; + } + + return 0; +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_CreateCustomSequence.s") +#endif + +void AudioOcarina_ResetInstrument(void) { + if (sOcarinaInstrumentId != OCARINA_INSTRUMENT_OFF) { + Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_SFX) << 24) | ((u32)(1) << 16) | + ((u32)(SFX_CHANNEL_OCARINA) << 8) | (u32)(0)); + sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF; + AudioOcarina_ResetAndMute(); + } +} + +void AudioOcarina_ResetStaffs(void) { + u8 songIndex; + + sPlayingStaff.buttonIndex = OCARINA_BTN_INVALID; + sPlayingStaff.state = 0xFF; + sPlayingStaff.pos = 0; + + sPlaybackStaff.buttonIndex = OCARINA_BTN_INVALID; + sPlaybackStaff.state = 0; + sPlaybackStaff.pos = 0; + + sRecordingStaff.buttonIndex = OCARINA_BTN_INVALID; + sRecordingStaff.state = 0xFF; + sRecordingStaff.pos = 0; + + sOcarinaDisableTimer = 0; + sOcarinaDropInputTimer = 0; + + for (songIndex = OCARINA_SONG_SONATA; songIndex < OCARINA_SONG_MAX; songIndex++) { + D_801FD518[songIndex] = 0xFF; + D_801FD530[songIndex] = 0; + } + + D_801D8534 = 0; +} + +s8 D_801D8B30[] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, + 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, +}; +f32 sBigBellsVolume[8] = { + 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f, +}; +u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB }; +f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f }; #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DFF8.s") @@ -2226,7 +3593,7 @@ void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) { sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40; } Audio_PlaySfxGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &D_801DB4B0, - &D_801DB4B8); + &gSfxDefaultReverb); } /** @@ -2242,7 +3609,7 @@ void Audio_PlaySfxForWaterfall(Vec3f* pos, f32 freqScale) { sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40; } Audio_PlaySfxGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value, - &sWaterfallFreqScaleLerp.value, &D_801DB4B8); + &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb); } /** @@ -2664,7 +4031,7 @@ void Audio_ClearSariaBgm2(void) { #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4348.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4380.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetSfxVolumeExceptSystemAndOcarinaBanks.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4428.s") diff --git a/src/code/audio/code_801A5BD0.c b/src/code/audio/code_801A5BD0.c index 8397fd52e..38e4ff187 100644 --- a/src/code/audio/code_801A5BD0.c +++ b/src/code/audio/code_801A5BD0.c @@ -1,10 +1,10 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5BD0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_SetSfxBanksMute.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5C28.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_SetFlagForBgmVolumeLow.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5C8C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_ClearFlagForBgmVolumeLow.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_PlaySfxGeneral.s") @@ -30,7 +30,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7484.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A75E8.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_StopSfxById.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7720.s") diff --git a/src/code/z_actor.c b/src/code/z_actor.c index d792b276a..53341c783 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -2128,7 +2128,7 @@ void func_800B8E58(Player* player, u16 sfxId) { if (player->currentMask == PLAYER_MASK_GIANT) { func_8019F170(&player->actor.projectedPos, sfxId); } else { - Audio_PlaySfxGeneral(sfxId, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); + Audio_PlaySfxGeneral(sfxId, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &gSfxDefaultReverb); } } @@ -2568,13 +2568,13 @@ void func_800B9D1C(Actor* actor) { if (sfxId != 0) { if (actor->audioFlags & 2) { - Audio_PlaySfxGeneral(sfxId, &actor->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); + Audio_PlaySfxGeneral(sfxId, &actor->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &gSfxDefaultReverb); } else if (actor->audioFlags & 4) { play_sound(sfxId); } else if (actor->audioFlags & 8) { func_8019F128(sfxId); } else if (actor->audioFlags & 0x10) { - func_801A0810(&D_801DB4A4, NA_SE_SY_TIMER - SFX_FLAG, (sfxId - 1)); + func_801A0810(&gSfxDefaultPos, NA_SE_SY_TIMER - SFX_FLAG, (sfxId - 1)); } else if (actor->audioFlags & 1) { Audio_PlaySfxAtPos(&actor->projectedPos, sfxId); } diff --git a/src/code/z_demo.c b/src/code/z_demo.c index 383f8928a..b02fe51a9 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -256,8 +256,7 @@ void Cutscene_Command_Misc(PlayState* play2, CutsceneContext* csCtx, CsCmdBase* } break; case 0x13: - // AudioOcarina_PlayLongScarecrowAfterCredits - func_8019D758(); + AudioOcarina_PlayLongScarecrowAfterCredits(); csCtx->frames = cmd->startFrame - 1; break; case 0x14: diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c index bb6308fb6..221305f46 100644 --- a/src/code/z_sram_NES.c +++ b/src/code/z_sram_NES.c @@ -1000,10 +1000,10 @@ void Sram_OpenSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { } if (gSaveContext.save.unk_F65) { - Lib_MemCpy(gScarecrowSpawnSongPtr, gSaveContext.save.scarecrowsSong, - sizeof(gSaveContext.save.scarecrowsSong)); + Lib_MemCpy(gScarecrowSpawnSongPtr, gSaveContext.save.scarecrowSpawnSong, + sizeof(gSaveContext.save.scarecrowSpawnSong)); - for (i = 0; i != ARRAY_COUNT(gSaveContext.save.scarecrowsSong); i++) {} + for (i = 0; i != ARRAY_COUNT(gSaveContext.save.scarecrowSpawnSong); i++) {} } fileNum = gSaveContext.fileNum; |
