diff options
| author | engineer124 <47598039+engineer124@users.noreply.github.com> | 2022-03-28 01:52:43 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-27 11:52:43 -0300 |
| commit | 02cb97161609e1c9aa53e2bbdc29e8b6f4f46c47 (patch) | |
| tree | 4f607197c6244d5f652cb88a772bd9298bcf530a /src/code | |
| parent | 928acac500e8b7df19998003b466b4dc8371dc01 (diff) | |
En_Gakufu OK and Documented + Related Audio Functions (#662)
* Gakufu OK, copy progress from audio WIP
* Extraction
* import wip in prep for audio data import
* Add in `code_8019AF00.c` functions
* Finish docs
* Spacing
* Add enum
* Many PR suggestions
* Another enum
* PR Suggestions
* Fix bss
* Move comment higher
* Fix bss
Co-authored-by: angie <angheloalf95@gmail.com>
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/audio/code_80192BE0.c | 2 | ||||
| -rw-r--r-- | src/code/audio/code_8019AF00.c | 182 |
2 files changed, 162 insertions, 22 deletions
diff --git a/src/code/audio/code_80192BE0.c b/src/code/audio/code_80192BE0.c index d088db607..20b4239da 100644 --- a/src/code/audio/code_80192BE0.c +++ b/src/code/audio/code_80192BE0.c @@ -76,6 +76,6 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80194568.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80194668.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_NextRandom.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_InitMesgQueues.s") diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c index 0006122c2..2e7cc91e1 100644 --- a/src/code/audio/code_8019AF00.c +++ b/src/code/audio/code_8019AF00.c @@ -45,7 +45,7 @@ typedef enum { /* 0xD */ SFX_CHANNEL_OCARINA, // SfxOcarinaBank /* 0xE */ SFX_CHANNEL_VOICE0, // SfxVoiceBank /* 0xF */ SFX_CHANNEL_VOICE1 -} SfxChannelIdx; // playerIdx = 2 +} SfxChannelIndex; // playerIndex = 2 // Global IO ports for sequences, 8 global ports per seqPlayer typedef enum { @@ -66,6 +66,7 @@ typedef struct { /* 0xC */ s32 remainingFrames; } FreqLerp; // size = 0x10 +s32 AudioOcarina_MemoryGameGenerateNotes(void); s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume); void func_801A3238(s8 playerIndex, u16 seqId, u8 fadeTimer, s8 arg3, u8 arg4); @@ -107,7 +108,7 @@ u8 sIsFinalHoursOrSoaring; u8 sObjSoundFanfareSeqId; u8 sObjSoundFanfareRequested; Vec3f sObjSoundFanfarePos; -u8 sObjSoundPlayerIdx; +u8 sObjSoundPlayerIndex; Vec3f sObjSoundPos; s16 sObjSoundFlags; f32 sObjSoundMinDist; @@ -122,7 +123,7 @@ u8 sSpatialSeqFlags; u8 D_801FD432; u8 sSpatialSubBgmFadeTimer; u8 D_801FD434; -u8 sSpatialSeqPlayerIdx; +u8 sSpatialSeqPlayerIndex; u8 sSpatialSeqFadeTimer; u16 D_801FD438; @@ -139,8 +140,8 @@ s32 sOcaInputBtnPress; u8 sOcarinaResetDelay; u8 sOcarinaResetUnused; u8 sOcarinaHasStartedSong; -u8 sFirstOcarinaSongIdx; -u8 sLastOcarinaSongIdx; +u8 sFirstOcarinaSongIndex; +u8 sLastOcarinaSongIndex; u32 sOcarinaAvailSongs; u8 sOcarinaStaffPlayingPos; u16 sMusicStaffPos[OCARINA_SONG_MAX]; @@ -987,11 +988,11 @@ u8 sIsOcarinaInputEnabled = false; s8 sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF; u8 sCurOcarinaPitch = OCARINA_PITCH_NONE; u8 sPrevOcarinaPitch = 0; -u8 sCurOcarinaButtonIdx = 0; +u8 sCurOcarinaButtonIndex = 0; u8 sMusicStaffPrevPitch = 0; f32 sCurOcarinaBendFreq = 1.0f; f32 sDefaultOcarinaVolume = 0.68503935f; -s8 sCurOcarinaBendIdx = 0; +s8 sCurOcarinaBendIndex = 0; s8 sCurOcarinaVolume = 0x57; s8 sCurOcarinaVibrato = 0; u8 sPlaybackState = 0; @@ -1017,7 +1018,7 @@ u8 sCurOcarinaSong[8] = { u8 sOcarinaSongAppendPos = 0; u8 sOcarinaSongStartingPos = 0; -u8 sButtonToNoteMap[5] = { +u8 sButtonToPitchMap[5] = { OCARINA_PITCH_D4, // OCARINA_BTN_A OCARINA_PITCH_F4, // OCARINA_BTN_C_DOWN OCARINA_PITCH_A4, // OCARINA_BTN_C_RIGHT @@ -1025,7 +1026,7 @@ u8 sButtonToNoteMap[5] = { OCARINA_PITCH_D5, // OCARINA_BTN_C_UP }; -u8 sOcaMemoryGameAppendPos = 0; +u8 sOcarinaMemoryGameAppendPos = 0; u8 sOcaMemoryGameEndPos = 0; u8 sOcaMemoryGameNumNotes[] = { 5, 6, 8 }; OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { @@ -1446,9 +1447,9 @@ u32 sOcarinaRecordTaskStart = 0; u8 sRecordOcarinaPitch = 0; u8 sRecordOcarinaVolume = 0; u8 sRecordOcarinaVibrato = 0; -s8 sRecordOcarinaBendIdx = 0; -u8 sRecordOcarinaButtonIdx = 0; -u8 sPlayedOcarinaSongIdxPlusOne = 0; +s8 sRecordOcarinaBendIndex = 0; +u8 sRecordOcarinaButtonIndex = 0; +u8 sPlayedOcarinaSongIndexPlusOne = 0; u8 sMusicStaffNumNotesPerTest = 0; u8 D_801D8530 = false; u32 D_801D8534 = 0; @@ -1463,7 +1464,7 @@ OcarinaNote* gScarecrowLongSongPtr = sScarecrowsLongSongNotes; u8* gScarecrowSpawnSongPtr = (u8*)&sOcarinaSongNotes[OCARINA_SONG_SCARECROW]; OcarinaNote* sTerminaWallSongPtr = sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL]; -u8 sNoteToButtonMap[16] = { +u8 sPitchToButtonMap[16] = { OCARINA_BTN_A, // OCARINA_PITCH_C4 OCARINA_BTN_A, // OCARINA_PITCH_DFLAT4 OCARINA_BTN_A, // OCARINA_PITCH_D4 @@ -1852,6 +1853,7 @@ 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 @@ -1889,7 +1891,8 @@ const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B02C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B074.s") +void AudioOcarina_MapSongFromNotesToButtons(u8 noteSongIndex, u8 buttonSongIndex, u8 numButtons); +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_MapSongFromNotesToButtons.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B144.s") @@ -1901,7 +1904,7 @@ const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B4B8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B544.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_StartDefault.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B568.s") @@ -1927,7 +1930,7 @@ const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C2E4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C300.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_SetInstrumentId.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C398.s") @@ -1956,17 +1959,154 @@ const char sAudioOcarinaUnusedText7[] = "check is over!!! %d %d %d\n"; #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF78.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF9C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_GetPlaybackStaff.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CFA8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D134.s") +/** + * Tests to see if the notes from songIndex contain identical notes + * within its song to any of the reserved songIndex from 0 up to maxSongIndex + */ +s32 AudioOcarina_TerminaWallValidateNotes(u8 songIndex, u8 maxSongIndex) { + u8 curSongIndex; + u8 j; + u8 k; + + // loop through all possible songs up to maxSongIndex + for (curSongIndex = 0; curSongIndex < maxSongIndex; curSongIndex++) { + // check to see if the song is reserved or not + if (sIsOcarinaSongReserved[curSongIndex]) { + // starting index to test the song + for (j = 0; j < (9 - gOcarinaSongButtons[curSongIndex].numButtons); j++) { + // loop through each note in the song + for (k = 0; (k < gOcarinaSongButtons[curSongIndex].numButtons) && ((k + j) < 8) && + (gOcarinaSongButtons[curSongIndex].buttonIndex[k] == + gOcarinaSongButtons[songIndex].buttonIndex[(k + j)]); + k++) { + continue; + } + + if (k == gOcarinaSongButtons[curSongIndex].numButtons) { + // failure: songIndex is identical to curSongIndex. + return -1; + } + } + } + } + + // success: notes are accepted and used + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D26C.s") +/** + * Generates the notes displayed on the Termina Field wall of musical notes + * Song generation loop alternates between 8 random notes and a random song from Ocarina of Time (OoT). + * Will check to see that the notes are valid by ensuring no playable song is within the selected notes + * All OoT songs are valid, so the outer loop will run a maxiumum of two times. + * i.e. if random notes fails, then the next set of notes will be from a valid OoT song + */ +void AudioOcarina_TerminaWallGenerateNotes(void) { + OcarinaNote* ocarinaNote; + u8 randButtonIndex; + u8 i; + u8 j; + + do { + i = 0; + if (sOcarinaWallCounter++ % 2) { + j = 0; + + for (; i < 8; i++) { + randButtonIndex = Audio_NextRandom() % ARRAY_COUNT(sButtonToPitchMap); + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = sButtonToPitchMap[randButtonIndex]; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 19; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 80; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].bend = 0; + j++; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 3; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 0; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].bend = 0; + j++; + } + + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j - 2].length = 90; + 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); + } else { + j = Audio_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes); + ocarinaNote = sOoTOcarinaSongNotes[j]; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D488.s") + for (; ocarinaNote[i].length != 0; i++) { + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i] = ocarinaNote[i]; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D4F8.s") + 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]); + } + } while (AudioOcarina_TerminaWallValidateNotes(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL) != 0); +} + +/** + * Unused remnant of OoT + */ +void AudioOcarina_MemoryGameSetNumNotes(u8 minigameRound) { + u8 i; + + if (minigameRound > 2) { + minigameRound = 2; + } + + sOcarinaMemoryGameAppendPos = 0; + sOcaMemoryGameEndPos = sOcaMemoryGameNumNotes[minigameRound]; + + for (i = 0; i < 3; i++) { + AudioOcarina_MemoryGameGenerateNotes(); + } +} + +/** + * 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; + + if (sOcarinaMemoryGameAppendPos == sOcaMemoryGameEndPos) { + return true; + } + + randButtonIndex = Audio_NextRandom(); + randPitch = sButtonToPitchMap[randButtonIndex % ARRAY_COUNT(sButtonToPitchMap)]; + + if (sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos - 1].pitch == randPitch) { + randPitch = sButtonToPitchMap[(randButtonIndex + 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; + + 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; + if (1) {} + return false; +} +#undef OCARINA_SONG_MEMORYGAME #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D600.s") |
