summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorpetrie911 <pmontag@PHYS-S129.iowa.uiowa.edu>2022-08-19 12:11:26 -0500
committerpetrie911 <pmontag@PHYS-S129.iowa.uiowa.edu>2022-08-19 12:11:26 -0500
commitcbd30f22104552a1151a26b78def355bed5d9efc (patch)
tree0c8d4ab3272b2647bb8abfd313114a266a1a09e5 /src/code
parentec3aa5c3e7cfe3cbd8b27e3fee73da774533ce60 (diff)
parentbb96e47f8df9fa42e2120b7acda90432bacfde39 (diff)
merge master
Diffstat (limited to 'src/code')
-rw-r--r--src/code/audio/audio_load.c4
-rw-r--r--src/code/audio/audio_playback.c6
-rw-r--r--src/code/audio/audio_seqplayer.c2
-rw-r--r--src/code/audio/audio_sfx_params.c8
-rw-r--r--src/code/audio/code_80192BE0.c10
-rw-r--r--src/code/audio/code_8019AF00.c675
-rw-r--r--src/code/audio/code_801A5BD0.c950
-rw-r--r--src/code/audio/code_801A7B10.c2
-rw-r--r--src/code/audioMgr.c2
-rw-r--r--src/code/code_8012EC80.c2
-rw-r--r--src/code/code_80172BC0.c2
-rw-r--r--src/code/z_actor.c30
-rw-r--r--src/code/z_camera.c418
-rw-r--r--src/code/z_demo.c119
-rw-r--r--src/code/z_effect_soft_sprite.c4
-rw-r--r--src/code/z_effect_soft_sprite_old_init.c2
-rw-r--r--src/code/z_en_hy_code.c14
-rw-r--r--src/code/z_message.c67
-rw-r--r--src/code/z_play.c14
-rw-r--r--src/code/z_player_lib.c6
-rw-r--r--src/code/z_scene.c16
-rw-r--r--src/code/z_scene_table.c42
-rw-r--r--src/code/z_skelanime.c20
-rw-r--r--src/code/z_snap.c2
-rw-r--r--src/code/z_sound_source.c4
-rw-r--r--src/code/z_sram_NES.c30
-rw-r--r--src/code/z_sub_s.c32
27 files changed, 2118 insertions, 365 deletions
diff --git a/src/code/audio/audio_load.c b/src/code/audio/audio_load.c
index b4997a94e..9ebdd1d85 100644
--- a/src/code/audio/audio_load.c
+++ b/src/code/audio/audio_load.c
@@ -1208,7 +1208,7 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
gAudioContext.refreshRate = 60;
}
- Audio_InitMesgQueues();
+ AudioThread_InitMesgQueues();
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) {
gAudioContext.aiBufLengths[i] = 0xA0;
@@ -1217,7 +1217,7 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
gAudioContext.totalTaskCount = 0;
gAudioContext.rspTaskIndex = 0;
gAudioContext.curAiBuffferIndex = 0;
- gAudioContext.soundMode = AUDIO_MODE_STEREO;
+ gAudioContext.soundMode = SOUNDMODE_STEREO;
gAudioContext.curTask = NULL;
gAudioContext.rspTask[0].task.t.dataSize = 0;
gAudioContext.rspTask[1].task.t.dataSize = 0;
diff --git a/src/code/audio/audio_playback.c b/src/code/audio/audio_playback.c
index c7789bd36..e7f5153ac 100644
--- a/src/code/audio/audio_playback.c
+++ b/src/code/audio/audio_playback.c
@@ -34,7 +34,7 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
sub->bitField0.stereoStrongLeft = false;
sub->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects;
sub->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects;
- if (stereoHeadsetEffects && gAudioContext.soundMode == AUDIO_MODE_HEADSET) {
+ if (stereoHeadsetEffects && gAudioContext.soundMode == SOUNDMODE_HEADSET) {
smallPanIndex = pan >> 1;
if (smallPanIndex > 0x3F) {
smallPanIndex = 0x3F;
@@ -46,7 +46,7 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
volLeft = gHeadsetPanVolume[pan];
volRight = gHeadsetPanVolume[0x7F - pan];
- } else if (stereoHeadsetEffects && gAudioContext.soundMode == AUDIO_MODE_STEREO) {
+ } else if (stereoHeadsetEffects && gAudioContext.soundMode == SOUNDMODE_STEREO) {
strongLeft = strongRight = false;
sub->headsetPanRight = 0;
sub->headsetPanLeft = 0;
@@ -80,7 +80,7 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
break;
}
- } else if (gAudioContext.soundMode == AUDIO_MODE_MONO) {
+ } else if (gAudioContext.soundMode == SOUNDMODE_MONO) {
sub->bitField0.stereoHeadsetEffects = false;
sub->bitField0.usesHeadsetPanEffects = false;
volLeft = 0.707f; // approx 1/sqrt(2)
diff --git a/src/code/audio/audio_seqplayer.c b/src/code/audio/audio_seqplayer.c
index d504f9f3a..ebcc9a8d1 100644
--- a/src/code/audio/audio_seqplayer.c
+++ b/src/code/audio/audio_seqplayer.c
@@ -1633,7 +1633,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break;
case 0xA8: // channel: random range large (only cmd that differs from OoT)
- rand = Audio_NextRandom();
+ rand = AudioThread_NextRandom();
channel->unk_22 = (cmdArgs[0] == 0) ? (rand & 0xFFFF) : (rand % cmdArgs[0]);
channel->unk_22 += cmdArgs[1];
temp2 = (channel->unk_22 / 0x100) + 0x80;
diff --git a/src/code/audio/audio_sfx_params.c b/src/code/audio/audio_sfx_params.c
index 94a8f26bc..0066328b1 100644
--- a/src/code/audio/audio_sfx_params.c
+++ b/src/code/audio/audio_sfx_params.c
@@ -1,9 +1,9 @@
#include "global.h"
-#define DEFINE_SFX(_0, importance, distParam, randParam, flags2, flags1) \
- { importance, flags2, \
- ((((distParam) << SFX_PARAM_01_SHIFT) & SFX_PARAM_01_MASK) | \
- (((randParam) << SFX_PARAM_67_SHIFT) & SFX_PARAM_67_MASK) | (flags1)) },
+#define DEFINE_SFX(_0, importance, distParam, randParam, flags2, flags1) \
+ { importance, flags2, \
+ ((((distParam) << SFX_PARAM_DIST_RANGE_SHIFT) & SFX_PARAM_DIST_RANGE_MASK) | \
+ (((randParam) << SFX_PARAM_RAND_FREQ_RAISE_SHIFT) & SFX_PARAM_RAND_FREQ_RAISE_MASK) | (flags1)) },
SfxParams sEnemyBankParams[] = {
#include "tables/sfx/enemybank_table.h"
diff --git a/src/code/audio/code_80192BE0.c b/src/code/audio/code_80192BE0.c
index 20b4239da..e69f678ff 100644
--- a/src/code/audio/code_80192BE0.c
+++ b/src/code/audio/code_80192BE0.c
@@ -16,13 +16,13 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80193858.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_8019387C.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_QueueCmdS32.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_QueueCmdS8.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_QueueCmdS8.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_801938D0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80193900.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_ScheduleProcessCmds.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80193990.s")
@@ -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/Audio_NextRandom.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_NextRandom.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_InitMesgQueues.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_InitMesgQueues.s")
diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c
index 65c3a6de8..b896facbc 100644
--- a/src/code/audio/code_8019AF00.c
+++ b/src/code/audio/code_8019AF00.c
@@ -18,15 +18,15 @@ typedef struct {
} SfxSettings; // size = 0x9
typedef struct {
- /* 0x0 */ f32 vol;
+ /* 0x0 */ f32 volume;
/* 0x4 */ f32 freqScale;
/* 0x8 */ s8 reverb;
/* 0x9 */ s8 panSigned;
/* 0xA */ s8 stereoBits;
/* 0xB */ u8 filter;
- /* 0xC */ u8 unk_0C;
- /* 0xD */ u8 unk_0D;
-} SfxPlayerState; // size = 0xE
+ /* 0xC */ u8 combFilterGain;
+ /* 0xD */ u8 zVolume;
+} SfxChannelState; // size = 0xE
typedef enum {
/* 0x0 */ SFX_CHANNEL_PLAYER0, // SfxPlayerBank
@@ -91,7 +91,7 @@ f32* sSfxVolumeCur;
f32 sSfxVolumeTarget;
f32 sSfxVolumeRate;
u16 sSceneSeqId1;
-SfxPlayerState sSfxChannelState[16];
+SfxChannelState sSfxChannelState[16];
// Sequence bss
u8 D_801FD3A8;
@@ -154,7 +154,8 @@ OcarinaNote sScarecrowsLongSongSecondNote;
u16 sCustomSequencePc;
// Sfx Data
-u8 D_801D6600[] = {
+// If the Sfx Bank has more than 255 values (max value of u8)
+u8 gIsLargeSfxBank[] = {
true, false, true, true, false, false, true,
};
u8 D_801D6608[] = {
@@ -192,7 +193,7 @@ u8 sEnterGanonsTowerTimer = 0;
u16 sSfxVolumeDuration = 0;
// System Data
-s8 sAudioFileSelectSetting = AUDIO_FS_STEREO;
+s8 sSoundMode = SOUNDMODE_STEREO;
s8 sAudioIsWindowOpen = false;
s8 sAudioCutsceneFlag = false;
s8 sSpecReverb = 0;
@@ -2495,7 +2496,7 @@ void AudioOcarina_PlayControllerInput(u8 isOcarinaSfxSuppressedWhenCancelled) {
// 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);
+ AudioThread_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;
@@ -2507,15 +2508,16 @@ void AudioOcarina_PlayControllerInput(u8 isOcarinaSfxSuppressedWhenCancelled) {
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);
+ AudioThread_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);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, sCurOcarinaPitch);
+ AudioSfx_PlaySfx(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);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
}
}
}
@@ -2540,10 +2542,10 @@ void AudioOcarina_ResetAndMute(void) {
sOcarinaInputButtonStart = 0xFFFF;
AudioOcarina_PlayControllerInput(false);
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
if (gAudioSpecId != 12) {
- Audio_SetSfxBanksMute(0);
+ AudioSfx_MuteBanks(0);
}
sPlaybackState = 0;
@@ -2553,7 +2555,7 @@ void AudioOcarina_ResetAndMute(void) {
sOcarinaFlags = 0;
// return to full volume for both bgm players after ocarina is finished
- Audio_ClearFlagForBgmVolumeLow(SFX_CHANNEL_OCARINA);
+ AudioSfx_RestoreBgmVolume(SFX_CHANNEL_OCARINA);
// return to full volume for all sfx channels except system & ocarina banks
Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x7F);
}
@@ -2602,7 +2604,7 @@ u32 AudioOcarina_SetInstrument(u8 ocarinaInstrumentId) {
// 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);
+ AudioSfx_LowerBgmVolume(SFX_CHANNEL_OCARINA);
}
}
}
@@ -2612,7 +2614,7 @@ void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, u8 playbackState) {
if (songIndexPlusOne == 0) {
sPlaybackState = 0;
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
return;
}
@@ -2700,7 +2702,7 @@ void AudioOcarina_PlaybackSong(void) {
sPlaybackStaffPos = 0;
sPlaybackPitch = OCARINA_PITCH_NONE;
} else {
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
}
return;
} else {
@@ -2716,7 +2718,7 @@ void AudioOcarina_PlaybackSong(void) {
// 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);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sNotePlaybackVibrato);
// Update bend
if (sNotePlaybackBend != sPlaybackSong[sPlaybackNotePos].bend) {
@@ -2746,14 +2748,14 @@ void AudioOcarina_PlaybackSong(void) {
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);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7,
+ sOcarinaInstrumentId - 1);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5,
+ sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH);
+ AudioSfx_PlaySfx(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend,
+ &sRelativeNotePlaybackVolume, &gSfxDefaultReverb);
} else {
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
}
}
sPlaybackNotePos++;
@@ -3073,7 +3075,7 @@ void AudioOcarina_TerminaWallGenerateNotes(void) {
j = 0;
for (; i < 8; i++) {
- randomButtonIndex = Audio_NextRandom() % ARRAY_COUNT(sButtonToPitchMap);
+ randomButtonIndex = AudioThread_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;
@@ -3094,7 +3096,7 @@ void AudioOcarina_TerminaWallGenerateNotes(void) {
sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].length = 0;
AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, 8);
} else {
- j = Audio_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes);
+ j = AudioThread_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes);
ocarinaNote = sOoTOcarinaSongNotes[j];
for (; ocarinaNote[i].length != 0; i++) {
@@ -3140,7 +3142,7 @@ s32 AudioOcarina_MemoryGameNextNote(void) {
return true;
}
- randomButtonIndex = Audio_NextRandom();
+ randomButtonIndex = AudioThread_NextRandom();
randomPitch = sButtonToPitchMap[randomButtonIndex % ARRAY_COUNT(sButtonToPitchMap)];
if (sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos - 1].pitch == randomPitch) {
@@ -3234,7 +3236,7 @@ void AudioOcarina_PlayLongScarecrowAfterCredits(void) {
break;
case 1:
- Audio_SetSfxBanksMute(0);
+ AudioSfx_MuteBanks(0);
AudioOcarina_SetInstrument(sScarecrowAfterCreditsIntrumentId);
AudioOcarina_SetPlaybackSong(OCARINA_SONG_SCARECROW_LONG + 1, 1);
sScarecrowAfterCreditsIntrumentId++;
@@ -3475,20 +3477,6 @@ void AudioOcarina_ResetStaffs(void) {
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")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E000.s")
@@ -3503,23 +3491,447 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E110.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E14C.s")
+f32 AudioSfx_ComputeVolume(u8 bankId, u8 entryIndex) {
+ SfxBankEntry* bankEntry = &gSfxBanks[bankId][entryIndex];
+ f32 minDist;
+ f32 phi_f14;
+ f32 baseDist;
+ f32 phi_f12;
+ f32 volume; // Also acts as intermediate volumeSquared
+ s32 pad[3];
+
+ if (bankEntry->sfxParams & SFX_FLAG_VOLUME_NO_DIST) {
+ return 1.0f;
+ }
+
+ if (bankEntry->dist > 10000.0f) {
+ volume = 0.0f;
+ } else {
+ if (bankEntry->sfxParams & SFX_PARAM_DIST_RANGE_MASK_UPPER) {
+ phi_f12 = 0.35f;
+ phi_f14 = 0.65f;
+ } else {
+ phi_f12 = 0.81f;
+ phi_f14 = 0.19f;
+ }
+
+ switch (bankEntry->sfxParams & SFX_PARAM_DIST_RANGE_MASK) {
+ case 0:
+ baseDist = 500.0f;
+ break;
+
+ case 1:
+ baseDist = 666.6667f;
+ break;
+
+ case 2:
+ baseDist = 952.381f;
+ break;
+
+ case 3:
+ baseDist = 3846.154f;
+ break;
+
+ case 4:
+ baseDist = 1000.0f;
+ break;
+
+ case 5:
+ baseDist = 666.6667f;
+ break;
+
+ case 6:
+ baseDist = 500.0f;
+ break;
+
+ case 7:
+ baseDist = 400.0f;
+ break;
+ }
+
+ minDist = baseDist / 5.0f;
+
+ if (bankEntry->dist < minDist) {
+ volume = 1.0f;
+ } else if (bankEntry->dist < baseDist) {
+ volume =
+ ((((baseDist - minDist) - (bankEntry->dist - minDist)) / (baseDist - minDist)) * phi_f14) + phi_f12;
+ } else {
+ volume = (1.0f - ((bankEntry->dist - baseDist) / (10000.0f - baseDist))) * phi_f12;
+ }
+
+ volume = SQ(volume);
+ }
+
+ return volume;
+}
+
+s8 AudioSfx_ComputeReverb(u8 bankId, u8 entryIndex, u8 channelIndex) {
+ s8 distAdd = 0;
+ s32 scriptAdd = 0;
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ s32 reverb;
+
+ if (!(entry->sfxParams & SFX_FLAG_REVERB_NO_DIST)) {
+ if (entry->dist < 2500.0f) {
+ distAdd = *entry->posZ > 0.0f ? (entry->dist / 2500.0f) * 70.0f : (entry->dist / 2500.0f) * 91.0f;
+ } else {
+ distAdd = 70;
+ }
+ }
+
+ if (IS_SEQUENCE_CHANNEL_VALID(gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex])) {
+ scriptAdd = gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[1];
+ if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[1] < 0) {
+ scriptAdd = 0;
+ }
+ }
+
+ reverb = (*entry->reverbAdd & 0x7F) + distAdd;
+
+ if (entry->state != SFX_STATE_READY) {
+ reverb += scriptAdd;
+ }
+
+ if ((bankId != BANK_OCARINA) || (SFX_INDEX(entry->sfxId) >= 2)) {
+ reverb += sAudioEnvReverb + (sAudioCodeReverb & 0x3F) + sSpecReverb;
+ }
+
+ if (reverb > 0x7F) {
+ reverb = 0x7F;
+ }
+
+ return reverb;
+}
+
+s8 AudioSfx_ComputePanSigned(f32 x, f32 z, u8 token) {
+ f32 absX = ABS_ALT(x);
+ f32 absZ = ABS_ALT(z);
+ f32 pan;
+
+ if (absX > 8000.0f) {
+ absX = 8000.0f;
+ }
+
+ if (absZ > 8000.0f) {
+ absZ = 8000.0f;
+ }
+
+ if ((x == 0.0f) && (z == 0.0f)) {
+ pan = 0.5f;
+ } else if (absZ <= absX) {
+ pan = (16000.0f - absX) / (4.5f * (16000.0f - absZ));
+ if (x >= 0.0f) {
+ pan = 1.0f - pan;
+ }
+ } else {
+ pan = (x / (3.6f * absZ)) + 0.5f;
+ }
+
+ if ((absZ < 50.0f) && (absX < 50.0f)) {
+ pan = ((pan - 0.5f) * SQ(absX / 50.0f)) + 0.5f;
+ }
+
+ return (pan * 127.0f) + 0.5f;
+}
+
+f32 AudioSfx_ComputeFreqScale(u8 bankId, u8 entryIndex) {
+ s32 applyRandScaling = false;
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ f32 dist;
+ f32 freq = 1.0f;
+
+ if (entry->sfxParams & SFX_PARAM_RAND_FREQ_LOWER) {
+ freq = 1.0f - ((gAudioContext.audioRandom & 0xF) / 192.0f);
+ }
+
+ switch (bankId) {
+ case BANK_VOICE:
+ if (((entry->sfxId & 0xFF) < 0x40) && (sAudioBaseFilter2 != 0)) {
+ applyRandScaling = true;
+ } else if (((entry->sfxId & 0xFF) >= 0x40) && (sAudioExtraFilter2 != 0)) {
+ applyRandScaling = true;
+ }
+ break;
+
+ case BANK_PLAYER:
+ case BANK_ITEM:
+ if (sAudioBaseFilter2 != 0) {
+ applyRandScaling = true;
+ }
+ break;
+
+ case BANK_ENV:
+ case BANK_ENEMY:
+ if (((*entry->reverbAdd & 0x80) != 0) | (sAudioExtraFilter2 != 0)) {
+ applyRandScaling = true;
+ }
+ break;
+
+ case BANK_SYSTEM:
+ case BANK_OCARINA:
+ break;
+
+ default:
+ break;
+ }
+
+ if ((applyRandScaling == true) && !(entry->sfxParams & SFX_PARAM_RAND_FREQ_SCALE)) {
+ freq *= 1.0293 - ((gAudioContext.audioRandom & 0xF) / 144.0f);
+ }
+
+ dist = entry->dist;
+ if (!(entry->sfxParams & SFX_FLAG_VOLUME_NO_DIST) && !(entry->sfxParams & SFX_FLAG_FREQ_NO_DIST)) {
+ if (dist >= 10000.0f) {
+ freq += 0.2f;
+ } else {
+ freq += (0.2f * (dist / 10000.0f));
+ }
+ }
+
+ if ((entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) != (0 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT)) {
+ freq += (entry->randFreq / 192.0f);
+ }
+
+ return freq;
+}
+
+u8 AudioSfx_ComputeSurroundSoundFilter(f32 behindScreenZ, SfxBankEntry* entry, s8 panSigned) {
+ u8 lowPassCutoff;
+ u8 highPassCutoff;
+ u16* sfxParams;
+ f32 distParam;
+ f32 dist;
+
+ // Remnant of OoT
+ if (*entry->posZ < behindScreenZ) {
+ lowPassCutoff = 0;
+ } else {
+ lowPassCutoff = 0;
+ }
+
+ sfxParams = &entry->sfxParams;
+
+ if (*sfxParams & SFX_FLAG_SURROUND_LOWPASS_FILTER) {
+ lowPassCutoff = 0xF;
+ }
+
+ switch ((*sfxParams & SFX_PARAM_DIST_RANGE_MASK)) {
+ case 0:
+ distParam = 15.0f;
+ break;
+
+ case 1:
+ distParam = 12.0f;
+ break;
+
+ case 2:
+ distParam = 9.0f;
+ break;
+
+ case 3:
+ distParam = 6.0f;
+ break;
+
+ case 4:
+ distParam = 18.0f;
+ break;
+
+ case 5:
+ distParam = 21.0f;
+ break;
+
+ case 6:
+ distParam = 24.0f;
+ break;
+
+ case 7:
+ distParam = 27.0f;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!(entry->sfxFlags & SFX_FLAG2_SURROUND_NO_HIGHPASS_FILTER)) {
+ if (entry->dist > 1923.077f) {
+ dist = 1923.077f;
+ } else {
+ dist = entry->dist;
+ }
+
+ highPassCutoff = (distParam * dist) / (2 * 1923.077f);
+ } else {
+ highPassCutoff = 0;
+ }
+
+ return (lowPassCutoff << 4) + highPassCutoff;
+}
+
+s8 AudioSfx_ComputeCombFilter(f32 posY, u16 sfxParams) {
+ s8 combFilterGain;
+
+ if (posY < 0.0f) {
+ if (posY < -625.0f) {
+ combFilterGain = -32;
+ } else {
+ combFilterGain = (s8)(((625.0f + posY) / 625.0f) * 31.0f) + 0xE0;
+ }
+ } else if (posY > 1250.0f) {
+ combFilterGain = 127;
+ } else {
+ combFilterGain = (posY / 1250.0f) * 126.0f;
+ }
+
+ return combFilterGain | 1;
+}
+
+void AudioSfx_SetProperties(u8 bankId, u8 entryIndex, u8 channelIndex) {
+ static s8 sZVolumes[] = {
+ 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 volume = 1.0f;
+ s8 volumeS8;
+ s8 reverb = 0;
+ f32 freqScale = 1.0f;
+ s8 panSigned = 0x40;
+ u8 pad;
+ u8 filter = 0;
+ s8 combFilterGain = 0;
+ s8 zVolume = -1;
+ f32 behindScreenZ;
+ u8 baseFilter = 0;
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ s32 pad2;
+
+ switch (bankId) {
+ case BANK_PLAYER:
+ case BANK_ITEM:
+ case BANK_ENV:
+ case BANK_ENEMY:
+ case BANK_VOICE:
+ if (sSoundMode == SOUNDMODE_SURROUND) {
+ combFilterGain = AudioSfx_ComputeCombFilter(*entry->posY, entry->sfxParams);
+ }
+ // fallthrough
+ case BANK_OCARINA:
+ entry->dist = sqrtf(entry->dist * 10.0f);
+ volume = AudioSfx_ComputeVolume(bankId, entryIndex) * *entry->volume;
+ reverb = AudioSfx_ComputeReverb(bankId, entryIndex, channelIndex);
+ panSigned = AudioSfx_ComputePanSigned(*entry->posX, *entry->posZ, entry->token);
+ freqScale = AudioSfx_ComputeFreqScale(bankId, entryIndex) * *entry->freqScale;
+
+ if (sSoundMode == SOUNDMODE_SURROUND) {
+ if (*entry->posZ >= 0.0f) {
+ if (*entry->posZ < 200.0f) {
+ zVolume = 32.0f - ((*entry->posZ / 300.0f) * 32.0f);
+ } else {
+ zVolume = 0;
+ }
+ } else if (*entry->posZ < 0.0f) {
+ if (*entry->posZ > -300.0f) {
+ zVolume = 32.0f - ((*entry->posZ / 300.0f) * 95.0f);
+ } else {
+ zVolume = 127;
+ }
+ }
+ zVolume = sZVolumes[zVolume];
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E324.s")
+ if (sAudioBaseFilter != 0) {
+ if ((bankId == BANK_PLAYER) || (bankId == BANK_ITEM) ||
+ ((bankId == BANK_VOICE) && (((entry->sfxId & 0xFF) < 0x40) || ((entry->sfxId & 0xFF) >= 0x80)))) {
+ baseFilter = sAudioBaseFilter;
+ if (sAudioExtraFilter) {
+ reverb >>= 2;
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E4B0.s")
+ if (((*entry->reverbAdd & 0x80) | baseFilter | sAudioExtraFilter |
+ (entry->sfxFlags & SFX_FLAG2_APPLY_LOWPASS_FILTER)) != 0) {
+ filter = ((((*entry->reverbAdd & 0x80) >> 2) | baseFilter | sAudioExtraFilter |
+ ((entry->sfxFlags & SFX_FLAG2_APPLY_LOWPASS_FILTER) >> 2)) *
+ 2);
+ filter &= 0xFF;
+ } else if ((sSoundMode == SOUNDMODE_SURROUND) && !(entry->sfxParams & SFX_FLAG_VOLUME_NO_DIST)) {
+ filter = AudioSfx_ComputeSurroundSoundFilter(behindScreenZ, entry, panSigned);
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E634.s")
+ case BANK_SYSTEM:
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E864.s")
+ if (sSfxChannelState[channelIndex].volume != volume) {
+ volumeS8 = (u8)(volume * 127.0f);
+ sSfxChannelState[channelIndex].volume = volume;
+ } else {
+ volumeS8 = -1;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EA40.s")
+ //! FAKE:
+ if (1) {}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EB2C.s")
+ // CHAN_UPD_SCRIPT_IO (slot 2, sets volume)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | (channelIndex << 8) | 2, volumeS8);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F024.s")
+ if (sSfxChannelState[channelIndex].reverb != reverb) {
+ sSfxChannelState[channelIndex].reverb = reverb;
+ }
+ if (sSfxChannelState[channelIndex].freqScale != freqScale) {
+ sSfxChannelState[channelIndex].freqScale = freqScale;
+ }
+ if (sSfxChannelState[channelIndex].stereoBits != 0) {
+ sSfxChannelState[channelIndex].stereoBits = 0;
+ }
+ if (sSfxChannelState[channelIndex].filter != filter) {
+ sSfxChannelState[channelIndex].filter = filter;
+ }
+ if (sSfxChannelState[channelIndex].combFilterGain != combFilterGain) {
+ sSfxChannelState[channelIndex].combFilterGain = combFilterGain;
+ }
+ if (sSfxChannelState[channelIndex].zVolume != zVolume) {
+ sSfxChannelState[channelIndex].zVolume = zVolume;
+ }
+ if (sSfxChannelState[channelIndex].panSigned != panSigned) {
+ sSfxChannelState[channelIndex].panSigned = panSigned;
+ }
+}
+
+u32 AudioSfx_SetFreqAndStereoBits(u8 seqScriptValIn, SequenceChannel* channel) {
+ channel->stereo.asByte = sSfxChannelState[seqScriptValIn].stereoBits;
+ channel->freqScale = sSfxChannelState[seqScriptValIn].freqScale;
+ channel->changes.s.freqScale = true;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F05C.s")
+ return seqScriptValIn;
+}
+
+void AudioSfx_ResetSfxChannelState(void) {
+ SfxChannelState* state;
+ u8 i;
+
+ for (i = 0; i < ARRAY_COUNT(sSfxChannelState); i++) {
+ state = &sSfxChannelState[i];
+ state->volume = 1.0f;
+ state->freqScale = 1.0f;
+ state->reverb = 0;
+ state->panSigned = 0x40;
+ state->stereoBits = 0;
+ state->filter = 0xFF;
+ state->combFilterGain = 0xFF;
+ state->zVolume = 0xFF;
+ }
+
+ sSfxChannelState[SFX_CHANNEL_OCARINA].combFilterGain = 0;
+ sPrevSeqMode = SEQ_MODE_DEFAULT;
+ sAudioCodeReverb = 0;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/play_sound.s")
@@ -3533,9 +3945,75 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F230.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F258.s")
+SfxSettings* AudioSfx_AddSfxSetting(Vec3f* pos) {
+ SfxSettings* sfxSettings;
+ u8 i = 0;
+ u8 sfxSettingIndex = 0xFF;
+
+ for (; i < ARRAY_COUNT(sSfxSettings); i++) {
+ sfxSettings = &sSfxSettings[i];
+
+ if ((sfxSettings->pos == NULL) && (sfxSettingIndex == 0xFF)) {
+ sfxSettingIndex = i;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F300.s")
+ if (sfxSettings->pos == pos) {
+ return sfxSettings;
+ }
+ }
+
+ if (sfxSettingIndex != 0xFF) {
+ sSfxSettingsFlags |= 1 << sfxSettingIndex;
+ sfxSettings = &sSfxSettings[sfxSettingIndex];
+ sfxSettings->pos = pos;
+ return sfxSettings;
+ }
+
+ return NULL;
+}
+
+void AudioSfx_ProcessSfxSettings(void) {
+ SfxBankEntry* entry;
+ u8 sfxSettingsFlags;
+ u8 sfxSettingIndex = 0;
+ u8 bankId;
+ u8 entryIndex;
+ s32 found;
+
+ if (sSfxSettingsFlags != 0) {
+ sfxSettingsFlags = sSfxSettingsFlags;
+
+ while (sfxSettingsFlags != 0) {
+ bankId = BANK_ENV;
+ if ((sfxSettingsFlags & (1 << sfxSettingIndex))) {
+
+ found = false;
+ while ((bankId <= BANK_ENEMY) && !found) {
+ entryIndex = gSfxBanks[bankId]->next;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ entryIndex = 0xFF;
+ if (entry->posX == &sSfxSettings[sfxSettingIndex].pos->x) {
+ found = true;
+ } else {
+ entryIndex = entry->next;
+ }
+ }
+ bankId++;
+ }
+
+ if (!found) {
+ sSfxSettingsFlags ^= (1 << sfxSettingIndex);
+ sSfxSettings[sfxSettingIndex].pos = NULL;
+ }
+
+ sfxSettingsFlags ^= (1 << sfxSettingIndex);
+ }
+ sfxSettingIndex++;
+ }
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F420.s")
@@ -3543,7 +4021,17 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F540.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F570.s")
+void AudioSfx_LowerSfxSettingsReverb(Vec3f* pos, s8 isReverbLowered) {
+ SfxSettings* sfxSettings = AudioSfx_AddSfxSetting(pos);
+
+ if (sfxSettings != NULL) {
+ if (isReverbLowered) {
+ sfxSettings->reverbAdd = -0x80;
+ } else {
+ sfxSettings->reverbAdd = 0;
+ }
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F5AC.s")
@@ -3585,15 +4073,15 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
* Used for EnRiverSound
*/
void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) {
- if (!Audio_IsSfxPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) {
+ if (!AudioSfx_IsPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) {
sRiverFreqScaleLerp.value = freqScale;
} else if (freqScale != sRiverFreqScaleLerp.value) {
sRiverFreqScaleLerp.target = freqScale;
sRiverFreqScaleLerp.remainingFrames = 40;
sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40;
}
- Audio_PlaySfxGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &D_801DB4B0,
- &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
}
/**
@@ -3601,15 +4089,15 @@ void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) {
* Used for Zora's River Waterfall
*/
void Audio_PlaySfxForWaterfall(Vec3f* pos, f32 freqScale) {
- if (!Audio_IsSfxPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) {
+ if (!AudioSfx_IsPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) {
sWaterfallFreqScaleLerp.value = freqScale;
} else if (freqScale != sWaterfallFreqScaleLerp.value) {
sWaterfallFreqScaleLerp.target = freqScale;
sWaterfallFreqScaleLerp.remainingFrames = 40;
sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40;
}
- Audio_PlaySfxGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value,
- &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value,
+ &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb);
}
/**
@@ -3626,6 +4114,9 @@ void Audio_StepFreqLerp(FreqLerp* lerp) {
}
}
+f32 sBigBellsVolume[8] = {
+ 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f,
+};
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0124.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0184.s")
@@ -3652,7 +4143,7 @@ void Audio_SetGanonsTowerBgmVolumeLevel(u8 ganonsTowerLevel) {
for (channelIndex = 0; channelIndex < 16; channelIndex++) {
// CHAN_UPD_PAN_UNSIGNED
- Audio_QueueCmdS8(((u8)(u32)channelIndex << 8) | 0x7000000, pan);
+ AudioThread_QueueCmdS8(((u8)(u32)channelIndex << 8) | 0x7000000, pan);
}
// Lowest room in Ganon's Tower (Entrance Room)
@@ -3710,9 +4201,9 @@ s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume) {
}
// CHAN_UPD_REVERB
- Audio_QueueCmdS8(_SHIFTL(5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) |
- _SHIFTL(channelIndex, 8, 8),
- (u8)reverb);
+ AudioThread_QueueCmdS8(_SHIFTL(5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) |
+ _SHIFTL(channelIndex, 8, 8),
+ (u8)reverb);
}
}
}
@@ -3768,7 +4259,29 @@ void Audio_UpdateRiverSoundVolumes(void) {
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05F0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0654.s")
+void AudioSfx_SetChannelIO(Vec3f* pos, u16 sfxId, u8 ioData) {
+ u8 channelIndex = 0;
+ u8 bankId = SFX_BANK_SHIFT(sfxId);
+ u8 entryIndex;
+ u8 i;
+
+ for (i = 0; i < bankId; i++) {
+ channelIndex += gChannelsPerBank[gSfxChannelLayout][i];
+ }
+
+ for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
+ entryIndex = gActiveSfx[bankId][i].entryIndex;
+
+ if (entryIndex != 0xFF) {
+ if ((sfxId == gSfxBanks[bankId][entryIndex].sfxId) && (&pos->x == gSfxBanks[bankId][entryIndex].posX)) {
+ AudioThread_QueueCmdS8(_SHIFTL(6, 24, 8) | _SHIFTL(SEQ_PLAYER_SFX, 16, 8) |
+ _SHIFTL(channelIndex, 8, 8) | _SHIFTL(6, 0, 8),
+ ioData);
+ }
+ }
+ channelIndex++;
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0810.s")
@@ -3814,7 +4327,7 @@ void func_801A09D4(Vec3f* pos, f32 xzDistToPlayer) {
if (channelIndex != 9) {
Audio_QueueSeqCmd(((u32)(6) << 28) | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(2) << 16) |
((u32)(channelIndex) << 8) | ((u8)(127.0f * volumeRel)));
- Audio_QueueCmdS8(0x03000000 | ((u8)((u32)channelIndex) << 8), pan);
+ AudioThread_QueueCmdS8(0x03000000 | ((u8)((u32)channelIndex) << 8), pan);
}
}
}
@@ -3837,6 +4350,7 @@ void Audio_ClearSariaBgmAtPos(Vec3f* pos) {
}
}
+u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB };
void Audio_SplitBgmChannels(s8 volumeSplit);
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SplitBgmChannels.s")
@@ -4043,6 +4557,7 @@ void Audio_ClearSariaBgm2(void) {
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A46F8.s")
+f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4748.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A479C.s")
@@ -4053,11 +4568,27 @@ void Audio_ClearSariaBgm2(void) {
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4A28.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4B80.s")
+u32 Audio_SetNatureAmbienceRandomBend(u8 seqScriptValIn, SequenceChannel* channel);
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetNatureAmbienceRandomBend.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C30.s")
+void Audio_Init(void) {
+ AudioLoad_Init(NULL, 0);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C54.s")
+void AudioSfx_Init(u16 fadeTimer) {
+ u8 channelIndex;
+
+ AudioThread_ScheduleProcessCmds();
+ Audio_StartSequence(SEQ_PLAYER_SFX, NA_BGM_GENERAL_SFX, 0x70, fadeTimer);
+
+ for (channelIndex = 0; channelIndex < ARRAY_COUNT(sSfxChannelState); channelIndex++) {
+ AudioThread_QueueCmdS32(0x10 << 24 | SEQ_PLAYER_SFX << 16 | ((u8)(u32)channelIndex << 8),
+ &sSfxChannelState[channelIndex]);
+ }
+
+ AudioThread_QueueCmdS32(0xE4000000, AudioSfx_SetFreqAndStereoBits);
+ AudioThread_QueueCmdS32(0xE4000001, Audio_SetNatureAmbienceRandomBend);
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D00.s")
diff --git a/src/code/audio/code_801A5BD0.c b/src/code/audio/code_801A5BD0.c
index 38e4ff187..4cf1147bf 100644
--- a/src/code/audio/code_801A5BD0.c
+++ b/src/code/audio/code_801A5BD0.c
@@ -1,45 +1,951 @@
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_SetSfxBanksMute.s")
+typedef struct {
+ /* 0x00 */ u16 sfxId;
+ /* 0x02 */ u8 token;
+ /* 0x04 */ s8* reverbAdd;
+ /* 0x08 */ Vec3f* pos;
+ /* 0x0C */ f32* freqScale;
+ /* 0x10 */ f32* volume;
+} SfxRequest; // size = 0x14
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_SetFlagForBgmVolumeLow.s")
+typedef struct {
+ /* 0x0 */ f32 value;
+ /* 0x4 */ f32 target;
+ /* 0x8 */ f32 step;
+ /* 0xC */ u16 remainingFrames;
+} SfxBankLerp; // size = 0x10
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_ClearFlagForBgmVolumeLow.s")
+typedef enum {
+ /* 0 */ SFX_RM_REQ_BY_BANK,
+ /* 1 */ SFX_RM_REQ_BY_POS_AND_BANK,
+ /* 2 */ SFX_RM_REQ_BY_POS,
+ /* 3 */ SFX_RM_REQ_BY_POS_AND_ID,
+ /* 4 */ SFX_RM_REQ_BY_TOKEN_AND_ID,
+ /* 5 */ SFX_RM_REQ_BY_ID
+} SfxRemoveRequest;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_PlaySfxGeneral.s")
+SfxBankEntry sSfxPlayerBank[9];
+SfxBankEntry sSfxItemBank[12];
+SfxBankEntry sSfxEnvironmentBank[32];
+SfxBankEntry sSfxEnemyBank[20];
+SfxBankEntry sSfxSystemBank[8];
+SfxBankEntry sSfxOcarinaBank[3];
+SfxBankEntry sSfxVoiceBank[5];
+SfxRequest sSfxRequests[0x100];
+u8 sSfxBankListEnd[7];
+u8 sSfxBankFreeListStart[7];
+u8 sSfxBankUnused[7];
+ActiveSfx gActiveSfx[7][3];
+u8 sCurSfxPlayerChannelIndex;
+u8 gSfxBankMuted[7];
+SfxBankLerp sSfxBankLerp[7];
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5DDC.s")
+// sSfxRequests ring buffer endpoints. read index <= write index, wrapping around mod 256.
+u8 sSfxRequestWriteIndex = 0;
+u8 sSfxRequestReadIndex = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5F7C.s")
+/**
+ * Array of pointers to arrays of SfxBankEntry of sizes: 9, 12, 32, 20, 8, 3, 5
+ *
+ * 0 : Player Bank size 9
+ * 1 : Item Bank size 12
+ * 2 : Environment Bank size 32
+ * 3 : Enemy Bank size 20
+ * 4 : System Bank size 8
+ * 5 : Ocarina Bank size 3
+ * 6 : Voice Bank size 5
+ */
+SfxBankEntry* gSfxBanks[7] = {
+ sSfxPlayerBank, sSfxItemBank, sSfxEnvironmentBank, sSfxEnemyBank, sSfxSystemBank, sSfxOcarinaBank, sSfxVoiceBank,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A6430.s")
+u8 sSfxBankSizes[ARRAY_COUNT(gSfxBanks)] = {
+ ARRAY_COUNT(sSfxPlayerBank), ARRAY_COUNT(sSfxItemBank), ARRAY_COUNT(sSfxEnvironmentBank),
+ ARRAY_COUNT(sSfxEnemyBank), ARRAY_COUNT(sSfxSystemBank), ARRAY_COUNT(sSfxOcarinaBank),
+ ARRAY_COUNT(sSfxVoiceBank),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A65C8.s")
+u8 gSfxChannelLayout = 0;
+u16 sSfxChannelLowVolumeFlag = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A6D0C.s")
+// The center of the screen in projected coordinates.
+// Gives the impression that the sfx has no specific location
+Vec3f gSfxDefaultPos = { 0.0f, 0.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7084.s")
+// Reused as either frequency or volume multiplicative scaling factor
+// Does not alter or change frequency or volume
+f32 gSfxDefaultFreqAndVolScale = 1.0f;
+s32 D_801DB4B4 = 0; // unused
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7168.s")
+// Adds no reverb to the existing reverb
+s8 gSfxDefaultReverb = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7284.s")
+void AudioSfx_MuteBanks(u16 muteMask) {
+ u8 bankId;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_StopSfxByPos.s")
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ if (muteMask & 1) {
+ gSfxBankMuted[bankId] = true;
+ } else {
+ gSfxBankMuted[bankId] = false;
+ }
+ muteMask = muteMask >> 1;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7328.s")
+/**
+ * Lowers volumes of both bgm players so that sfx can be more pronounced.
+ * Each sfx channel stores its own bit to lower the volume.
+ * Only a single channel needs to request this to lower the volume.
+ */
+void AudioSfx_LowerBgmVolume(u8 channelIndex) {
+ sSfxChannelLowVolumeFlag |= (1 << channelIndex);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7484.s")
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 2, 0x40, 0xF);
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 2, 0x40, 0xF);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_StopSfxById.s")
+/**
+ * Clears the flag for the specific channel to lower volume.
+ * If all flags are cleared, then both bgm players return to full volume
+ */
+void AudioSfx_RestoreBgmVolume(u8 channelIndex) {
+ sSfxChannelLowVolumeFlag &= ((1 << channelIndex) ^ 0xFFFF);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7720.s")
+ if (sSfxChannelLowVolumeFlag == 0) {
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 2, 0x7F, 0xF);
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 2, 0x7F, 0xF);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7794.s")
+/**
+ * The main function to request a sfx. All sfx requests begin here.
+ */
+void AudioSfx_PlaySfx(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* volume, s8* reverbAdd) {
+ u8 i;
+ SfxRequest* reqWrite;
+ SfxRequest* reqRead;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7828.s")
+ if (!gSfxBankMuted[SFX_BANK_SHIFT(sfxId)]) {
+ reqWrite = &sSfxRequests[sSfxRequestWriteIndex];
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A787C.s")
+ for (i = sSfxRequestReadIndex; sSfxRequestWriteIndex != i; i++) {
+ reqRead = &sSfxRequests[i];
+ if ((reqRead->pos == pos) && (reqRead->sfxId == sfxId)) {
+ return;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_IsSfxPlaying.s")
+ reqWrite->sfxId = sfxId;
+ reqWrite->pos = pos;
+ reqWrite->token = token;
+ reqWrite->freqScale = freqScale;
+ reqWrite->volume = volume;
+ reqWrite->reverbAdd = reverbAdd;
+ sSfxRequestWriteIndex++;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A794C.s")
+void AudioSfx_RemoveMatchingRequests(u8 aspect, SfxBankEntry* entry) {
+ SfxRequest* req;
+ s32 remove;
+ u8 i = sSfxRequestReadIndex;
+
+ for (; i != sSfxRequestWriteIndex; i++) {
+ remove = false;
+ req = &sSfxRequests[i];
+
+ switch (aspect) {
+ case SFX_RM_REQ_BY_BANK:
+ if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(entry->sfxId)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_POS_AND_BANK:
+ if ((SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(entry->sfxId)) && (&req->pos->x == entry->posX)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_POS:
+ if (&req->pos->x == entry->posX) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_POS_AND_ID:
+ if ((&req->pos->x == entry->posX) && (req->sfxId == entry->sfxId)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_TOKEN_AND_ID:
+ if ((req->token == entry->token) && (req->sfxId == entry->sfxId)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_ID:
+ if (req->sfxId == entry->sfxId) {
+ remove = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (remove) {
+ req->sfxId = 0;
+ }
+ }
+}
+
+void AudioSfx_ProcessRequest(void) {
+ u16 sfxId;
+ u8 channelCount;
+ u8 index;
+ SfxRequest* req = &sSfxRequests[sSfxRequestReadIndex];
+ SfxBankEntry* entry;
+ SfxParams* sfxParams;
+ s32 bankId;
+ u8 evictImportance;
+ u8 evictIndex = 0x80;
+
+ if (req->sfxId == 0) {
+ return;
+ }
+
+ bankId = SFX_BANK(req->sfxId);
+ channelCount = 0;
+ index = gSfxBanks[bankId][0].next;
+
+ // Compare the sfx request to all sfx bank entries
+ while ((index != 0xFF) && (index != 0)) {
+
+ // If an existing sfx from the same source exists in the bank, then we should either:
+ // renew if it is the same sfx, check if any sfx channels are available for that bank,
+ // interrupt that sfx and replace it with the new sfx request, or drop the new sfx request.
+ if (gSfxBanks[bankId][index].posX == &req->pos->x) {
+
+ // If the new sfx has equal importance to the existing sfx,
+ // drop the request if the existing sfx has the "SFX_FLAG_BLOCK_EQUAL_IMPORTANCE" flag.
+ // Otherwise, keep processing the new sfx request
+ if ((gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].params &
+ SFX_FLAG_BLOCK_EQUAL_IMPORTANCE) &&
+ (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance ==
+ gSfxBanks[bankId][index].sfxImportance)) {
+ // Drop the new request
+ return;
+ }
+
+ if (gSfxBanks[bankId][index].sfxId == req->sfxId) {
+ // The new sfx is the same as the existing sfx
+ // Set channelCount to max value to reprocess the sfx
+ channelCount = gUsedChannelsPerBank[gSfxChannelLayout][bankId];
+ } else {
+ // Determine which sfx to evict based on importance if there are no more channels available
+ if (channelCount == 0) {
+ // If this is the first sfx at the same source, than store the existing sfx info into evict temps
+ evictIndex = index;
+ sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF;
+ evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance;
+ } else if (gSfxBanks[bankId][index].sfxImportance < evictImportance) {
+ // If a different existing sfx is at the same source, than update the evict temps if the next
+ // existing src has lower importance than the previous existing source
+ evictIndex = index;
+ sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF;
+ evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance;
+ }
+
+ channelCount++;
+
+ // There are no channels available, evict the lowest importance
+ if (channelCount == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) {
+ if (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance >= evictImportance) {
+ index = evictIndex;
+ } else {
+ index = 0;
+ }
+ }
+ }
+
+ // Process this sfx by refreshing or replacing and existing sfx
+ if (channelCount == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) {
+ sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)];
+
+ // Interrupt existing sfx and play the new sfx instead.
+ if ((req->sfxId & SFX_FLAG_MASK) || (sfxParams->flags & SFX_FLAG2_FORCE_RESET) ||
+ (index == evictIndex)) {
+
+ // Restore bgm if the sfx about to be replaced has the right flag
+ if ((gSfxBanks[bankId][index].sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) &&
+ (gSfxBanks[bankId][index].state != SFX_STATE_QUEUED)) {
+ AudioSfx_RestoreBgmVolume(gSfxBanks[bankId][index].channelIndex);
+ }
+
+ gSfxBanks[bankId][index].token = req->token;
+ gSfxBanks[bankId][index].sfxId = req->sfxId;
+ gSfxBanks[bankId][index].state = SFX_STATE_QUEUED;
+ gSfxBanks[bankId][index].freshness = 2;
+ gSfxBanks[bankId][index].freqScale = req->freqScale;
+ gSfxBanks[bankId][index].volume = req->volume;
+ gSfxBanks[bankId][index].reverbAdd = req->reverbAdd;
+ gSfxBanks[bankId][index].sfxParams = sfxParams->params;
+ gSfxBanks[bankId][index].sfxFlags = sfxParams->flags;
+ gSfxBanks[bankId][index].sfxImportance = sfxParams->importance;
+ } else if (gSfxBanks[bankId][index].state == SFX_STATE_PLAYING_ONE_FRAME) {
+ // The new sfx is "one-frame" and equals the existing sfx,
+ // continue playing the "one-frame" sfx by setting "SFX_STATE_PLAYING".
+ // This will avoid triggering deletion and get "SFX_STATE_REFRESH"
+ // The state will be set back to "SFX_STATE_PLAYING_ONE_FRAME" at the end of the cycle
+ gSfxBanks[bankId][index].state = SFX_STATE_PLAYING;
+ }
+ // Terminate loop, function is finished (nothing more is processed)
+ index = 0;
+ }
+ }
+
+ if (index != 0) {
+ index = gSfxBanks[bankId][index].next;
+ }
+ }
+
+ if ((gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next != 0xFF) && (index != 0)) {
+ // Allocate from free list
+ index = sSfxBankFreeListStart[bankId];
+
+ entry = &gSfxBanks[bankId][index];
+ entry->posX = &req->pos->x;
+ entry->posY = &req->pos->y;
+ entry->posZ = &req->pos->z;
+ entry->token = req->token;
+ entry->freqScale = req->freqScale;
+ entry->volume = req->volume;
+ entry->reverbAdd = req->reverbAdd;
+
+ sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)];
+
+ entry->sfxParams = sfxParams->params;
+ entry->sfxFlags = sfxParams->flags;
+ entry->sfxImportance = sfxParams->importance;
+ entry->sfxId = req->sfxId;
+ entry->state = SFX_STATE_QUEUED;
+ entry->freshness = 2;
+ entry->prev = sSfxBankListEnd[bankId];
+
+ gSfxBanks[bankId][sSfxBankListEnd[bankId]].next = sSfxBankFreeListStart[bankId];
+ sSfxBankListEnd[bankId] = sSfxBankFreeListStart[bankId];
+ sSfxBankFreeListStart[bankId] = gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next;
+ gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = 0xFF;
+
+ entry->next = 0xFF;
+ }
+}
+
+void AudioSfx_RemoveBankEntry(u8 bankId, u8 entryIndex) {
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ u8 i;
+
+ if (entry->sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) {
+ AudioSfx_RestoreBgmVolume(entry->channelIndex);
+ }
+
+ if (entryIndex == sSfxBankListEnd[bankId]) {
+ sSfxBankListEnd[bankId] = entry->prev;
+ } else {
+ gSfxBanks[bankId][entry->next].prev = entry->prev;
+ }
+
+ gSfxBanks[bankId][entry->prev].next = entry->next;
+ entry->next = sSfxBankFreeListStart[bankId];
+ entry->prev = 0xFF;
+ gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = entryIndex;
+ sSfxBankFreeListStart[bankId] = entryIndex;
+ entry->state = SFX_STATE_EMPTY;
+
+ for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
+ if (gActiveSfx[bankId][i].entryIndex == entryIndex) {
+ gActiveSfx[bankId][i].entryIndex = 0xFF;
+ i = gChannelsPerBank[gSfxChannelLayout][bankId];
+ }
+ }
+}
+
+void AudioSfx_ChooseActiveSfx(u8 bankId) {
+ u8 numChosenSfx = 0;
+ u8 numChannels;
+ u8 entryIndex;
+ u8 i;
+ u8 j;
+ u8 k;
+ u8 sfxImportance;
+ u8 needNewSfx;
+ u8 chosenEntryIndex;
+ s32 pad;
+ SfxBankEntry* entry;
+ ActiveSfx chosenSfx[MAX_CHANNELS_PER_BANK];
+ ActiveSfx* activeSfx;
+ f32 entryPosY;
+ f32 entryPosX;
+
+ for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) {
+ chosenSfx[i].priority = 0x7FFFFFFF;
+ chosenSfx[i].entryIndex = 0xFF;
+ }
+
+ entryIndex = gSfxBanks[bankId][0].next;
+ k = 0;
+
+ // Delete stale sfx and prioritize remaining sfx into the gActiveSfx arrays
+ while (entryIndex != 0xFF) {
+
+ // Update the freshness for an "all-frame" sfx if it is still queued
+ if ((gSfxBanks[bankId][entryIndex].state == SFX_STATE_QUEUED) &&
+ (gSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_MASK)) {
+ gSfxBanks[bankId][entryIndex].freshness--;
+
+ // If a "one-frame" sfx is still in "SFX_STATE_PLAYING_ONE_FRAME", then remove the sfx
+ } else if (!(gSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_MASK) &&
+ (gSfxBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_ONE_FRAME)) {
+ // CHAN_UPD_SCRIPT_IO (ioPort 0, force stop sfx in seq 0)
+ AudioThread_QueueCmdS8(
+ (0x6 << 24) | (SEQ_PLAYER_SFX << 16) | (gSfxBanks[bankId][entryIndex].channelIndex << 8), 0);
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ }
+
+ // If a "all-frame" sfx goes 2 frames in the "queued" state
+ // (because it is too low priority), then remove the sfx
+ if (gSfxBanks[bankId][entryIndex].freshness == 0) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ } else if (gSfxBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) {
+ // process the entry
+ entry = &gSfxBanks[bankId][entryIndex];
+
+ // Recompute distSq each frame since the sound's position may have changed
+ // (later converted into dist)
+ if (&gSfxDefaultPos.x == entry[0].posX) {
+ entry->dist = 0.0f;
+ } else {
+ entryPosY = *entry->posY * 1;
+ entryPosX = *entry->posX * 0.5f;
+ entry->dist = (SQ(entryPosX) + SQ(entryPosY) + SQ(*entry->posZ)) / 10.0f;
+ }
+
+ // Recompute priority, possibly based on sfx position relative to the camera.
+ // (Note that the priority is the opposite of importance; lower is more preserved)
+ sfxImportance = entry->sfxImportance;
+
+ if (entry->sfxParams & SFX_FLAG_PRIORITY_NO_DIST) {
+ // Priority is independent of distance
+ entry->priority = SQ(0xFF - sfxImportance) * SQ(76);
+ } else {
+ // Priority value increases with distance (more likely to eject)
+ if (entry->dist > 0x7FFFFFD0) {
+ // max distance
+ entry->dist = 0x70000008;
+ }
+
+ entry->priority = (u32)entry->dist + (SQ(0xFF - sfxImportance) * SQ(76));
+ if (*entry->posZ < 0.0f) {
+ entry->priority += (s32)(-*entry->posZ * 6.0f);
+ }
+ }
+
+ // Sfx is too far away, do not consider for chosen sfx
+ if (entry->dist > SQ(1e5f)) {
+
+ // If too far away and also playing, stop playing
+ if (entry->state == SFX_STATE_PLAYING) {
+ // CHAN_UPD_SCRIPT_IO (ioPort 0, force stop sfx in seq 0)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | (entry->channelIndex << 8), 0);
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ entryIndex = k;
+ }
+ }
+ } else {
+ // Loop through all channels allocated to a specific bank
+ // Choose which sfx from gSfxBanks to play
+ // This includes all sfx requests and sfx already playing
+ // Sort all current sfx entries in gSfxBanks by priority
+ // This is where the "active" sfx are chosen
+ numChannels = gChannelsPerBank[gSfxChannelLayout][bankId];
+
+ for (i = 0; i < numChannels; i++) {
+ // Sort all sfx entries by priority
+ if (chosenSfx[i].priority >= entry->priority) {
+ // Update the number of sfx to attampt to play
+ if (numChosenSfx < gChannelsPerBank[gSfxChannelLayout][bankId]) {
+ numChosenSfx++;
+ }
+
+ for (j = numChannels - 1; j > i; j--) {
+ chosenSfx[j].priority = chosenSfx[j - 1].priority;
+ chosenSfx[j].entryIndex = chosenSfx[j - 1].entryIndex;
+ }
+
+ chosenSfx[i].priority = entry->priority;
+ chosenSfx[i].entryIndex = entryIndex;
+ i = numChannels; // make this the last pass through the loop, here equivalent to "break"
+ }
+ }
+ }
+
+ k = entryIndex;
+ }
+
+ entryIndex = gSfxBanks[bankId][k].next;
+ }
+
+ // If a sfx is chosen, update its state
+ for (i = 0; i < numChosenSfx; i++) {
+ entry = &gSfxBanks[bankId][chosenSfx[i].entryIndex];
+
+ if (entry->state == SFX_STATE_QUEUED) {
+ // sfx is a new entry
+ entry->state = SFX_STATE_READY;
+ } else if (entry->state == SFX_STATE_PLAYING) {
+ // sfx is already playing
+ entry->state = SFX_STATE_PLAYING_REFRESH;
+ }
+ }
+
+ // Apply the chosenSfx to the activeSfx in each channel
+ numChannels = gChannelsPerBank[gSfxChannelLayout][bankId];
+ for (i = 0; i < numChannels; i++) {
+ needNewSfx = false;
+ activeSfx = &gActiveSfx[bankId][i];
+
+ // Check if a sfx is already in the channel
+ if (activeSfx->entryIndex == 0xFF) {
+ // No sfx playing in the channel
+ // Available for use
+ needNewSfx = true;
+ } else {
+ // The channel is already playing a sfx
+ // Get the entry of the sfx playing
+ entry = &gSfxBanks[bankId][activeSfx[0].entryIndex];
+
+ // Check the state of the sfx playing
+ if (entry->state == SFX_STATE_PLAYING) {
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ // For "all-frames" sfx, remove the entry
+ AudioSfx_RemoveBankEntry(bankId, activeSfx->entryIndex);
+ } else {
+ // For "one-frame" sfx, reset the state to queued
+ entry->state = SFX_STATE_QUEUED;
+ entry->freshness = 0x80;
+ }
+ needNewSfx = true;
+ } else if (entry->state == SFX_STATE_EMPTY) {
+ // The sfx already in the channel is empty
+ // Can replace the sfx
+ activeSfx->entryIndex = 0xFF;
+ needNewSfx = true;
+ } else {
+ // Sfx is already playing as it should, nothing to do.
+ for (j = 0; j < numChannels; j++) {
+ if (activeSfx->entryIndex == chosenSfx[j].entryIndex) {
+ chosenSfx[j].entryIndex = 0xFF;
+ j = numChannels;
+ }
+ }
+
+ numChosenSfx--;
+ }
+ }
+
+ // enter the new sfx into the activeSfx
+ if (needNewSfx == true) {
+ for (j = 0; j < numChannels; j++) {
+ chosenEntryIndex = chosenSfx[j].entryIndex;
+ if ((chosenEntryIndex != 0xFF) &&
+ (gSfxBanks[bankId][chosenEntryIndex].state != SFX_STATE_PLAYING_REFRESH)) {
+ for (k = 0; k < numChannels; k++) {
+ if (chosenEntryIndex == gActiveSfx[bankId][k].entryIndex) {
+ needNewSfx = false;
+ k = numChannels; // "break; i.e. force for-loop to end"
+ }
+ }
+
+ if (needNewSfx == true) {
+ activeSfx->entryIndex = chosenEntryIndex;
+ chosenSfx[j].entryIndex = 0xFF;
+ j = numChannels + 1;
+ numChosenSfx--;
+ }
+ }
+ }
+ if (j == numChannels) {
+ // nothing found
+ activeSfx->entryIndex = 0xFF;
+ }
+ }
+ }
+}
+
+void AudioSfx_PlayActiveSfx(u8 bankId) {
+ u8 entryIndex;
+ SequenceChannel* channel;
+ SfxBankEntry* entry;
+ u8 i;
+ u8 ioPort5Data;
+
+ for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
+ entryIndex = gActiveSfx[bankId][i].entryIndex;
+ // If entry is not empty
+ if (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ channel = gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIndex];
+
+ if (entry->state == SFX_STATE_READY) {
+ // Initialize a sfx (new sfx request)
+ entry->channelIndex = sCurSfxPlayerChannelIndex;
+ if (entry->sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) {
+ AudioSfx_LowerBgmVolume(sCurSfxPlayerChannelIndex);
+ }
+
+ // Add noise that will offset the frequency of the sfx
+ if ((entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) != (0 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT)) {
+ switch (entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) {
+ case (1 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT):
+ entry->randFreq = AudioThread_NextRandom() & 0xF;
+ break;
+
+ case (2 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT):
+ entry->randFreq = AudioThread_NextRandom() & 0x1F;
+ break;
+
+ case (3 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT):
+ entry->randFreq = AudioThread_NextRandom() & 0x3F;
+ break;
+
+ default:
+ entry->randFreq = 0;
+ break;
+ }
+ }
+
+ // Calculate all the properties of sfx
+ AudioSfx_SetProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
+
+ // CHAN_UPD_SCRIPT_IO (ioPort 0, enable the sfx to play in seq 0)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((sCurSfxPlayerChannelIndex & 0xFF) << 8),
+ 1);
+
+ // CHAN_UPD_SCRIPT_IO (ioPort 4, write the lower bits sfx index to seq 0 so it can find the right code
+ // to execute)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) |
+ ((sCurSfxPlayerChannelIndex & 0xFF) << 8) | 4,
+ entry->sfxId & 0xFF);
+
+ // If the sfx bank has more than 255 entries (greater than a u8 can store),
+ // then store the Id in upper and lower bits
+ if (gIsLargeSfxBank[bankId]) {
+ // Store upper bits
+ ioPort5Data = ((u8)((entry->sfxId & 0x300) >> 7) + (u8)((entry->sfxId & 0xFF) >> 7));
+ } else {
+ ioPort5Data = 0;
+ }
+
+ if ((entry->sfxParams & SFX_FLAG_8) && (entry->freshness == 0x80)) {
+ ioPort5Data += 0x80;
+ }
+
+ if (D_801D6608[bankId]) {
+ // CHAN_UPD_SCRIPT_IO (ioPort 5, write the upper bits sfx index and a flag to seq 0, for banks with
+ // > 0xFF entries)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) |
+ ((sCurSfxPlayerChannelIndex & 0xFF) << 8) | 5,
+ ioPort5Data);
+ }
+
+ // Update playing state
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ // "all-frames" sfx
+ entry->state = SFX_STATE_PLAYING;
+ } else {
+ // "one-frame" sfx
+ entry->state = SFX_STATE_PLAYING_ONE_FRAME;
+ }
+ } else if ((u8)channel->soundScriptIO[1] == 0xFF) {
+ // Signal from seq 0 that the sfx is finished playing. Remove entry
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ } else if (entry->state == SFX_STATE_PLAYING_REFRESH) {
+ // Sfx is playing but a refresh is requested
+ AudioSfx_SetProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
+
+ // Update playing state
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ // "all-frames" sfx
+ entry->state = SFX_STATE_PLAYING;
+ } else {
+ // "one-frame" sfx
+ entry->state = SFX_STATE_PLAYING_ONE_FRAME;
+ }
+ }
+ }
+
+ sCurSfxPlayerChannelIndex++;
+ }
+}
+
+void AudioSfx_StopByBank(u8 bankId) {
+ SfxBankEntry* entry;
+ s32 pad;
+ SfxBankEntry entryToRemove;
+ u8 entryIndex = gSfxBanks[bankId][0].next;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ }
+ entryIndex = gSfxBanks[bankId][0].next;
+ }
+
+ entryToRemove.sfxId = bankId << 12;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_BANK, &entryToRemove);
+}
+
+void AudioSfx_StopByPosAndBankImpl(u8 bankId, Vec3f* pos) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[bankId][0].next;
+ u8 prevEntryIndex = 0;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ if (entry->posX == &pos->x) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ }
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ entryIndex = gSfxBanks[bankId][prevEntryIndex].next;
+ }
+}
+
+void AudioSfx_StopByPosAndBank(u8 bankId, Vec3f* pos) {
+ SfxBankEntry entryToRemove;
+
+ AudioSfx_StopByPosAndBankImpl(bankId, pos);
+ entryToRemove.sfxId = bankId << 12;
+ entryToRemove.posX = &pos->x;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS_AND_BANK, &entryToRemove);
+}
+
+void AudioSfx_StopByPos(Vec3f* pos) {
+ u8 bankId;
+ SfxBankEntry entryToRemove;
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ AudioSfx_StopByPosAndBankImpl(bankId, pos);
+ }
+
+ entryToRemove.posX = &pos->x;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS, &entryToRemove);
+}
+
+void AudioSfx_StopByPosAndId(Vec3f* pos, u16 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+ u8 prevEntryIndex = 0;
+ SfxBankEntry entryToRemove;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if ((entry->posX == &pos->x) && (entry->sfxId == sfxId)) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex);
+ }
+ entryIndex = 0xFF;
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ if (entryIndex != 0xFF) {
+ entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
+ }
+ }
+
+ entryToRemove.posX = &pos->x;
+ entryToRemove.sfxId = sfxId;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS_AND_ID, &entryToRemove);
+}
+
+void AudioSfx_StopByTokenAndId(u8 token, u16 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+ u8 prevEntryIndex = 0;
+ SfxBankEntry entryToRemove;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if ((entry->token == token) && (entry->sfxId == sfxId)) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex);
+ }
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ if (entryIndex != 0xFF) {
+ entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
+ }
+ }
+
+ entryToRemove.token = token;
+ entryToRemove.sfxId = sfxId;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_TOKEN_AND_ID, &entryToRemove);
+}
+
+void AudioSfx_StopById(u32 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+ u8 prevEntryIndex = 0;
+ SfxBankEntry entryToRemove;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if (entry->sfxId == sfxId) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex);
+ }
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
+ }
+
+ entryToRemove.sfxId = sfxId;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_ID, &entryToRemove);
+}
+
+void AudioSfx_ProcessRequests(void) {
+ if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].enabled) {
+ while (sSfxRequestWriteIndex != sSfxRequestReadIndex) {
+ AudioSfx_ProcessRequest();
+ sSfxRequestReadIndex++;
+ }
+ }
+}
+
+/**
+ * Unused
+ */
+void AudioSfx_SetBankLerp(u8 bankId, u8 target, u16 delay) {
+ if (delay == 0) {
+ delay++;
+ }
+
+ sSfxBankLerp[bankId].target = target / 127.0f;
+ sSfxBankLerp[bankId].remainingFrames = delay;
+ sSfxBankLerp[bankId].step = ((sSfxBankLerp[bankId].value - sSfxBankLerp[bankId].target) / delay);
+}
+
+/**
+ * Unused
+ */
+void AudioSfx_StepBankLerp(u8 bankId) {
+ if (sSfxBankLerp[bankId].remainingFrames != 0) {
+ sSfxBankLerp[bankId].remainingFrames--;
+
+ if (sSfxBankLerp[bankId].remainingFrames != 0) {
+ sSfxBankLerp[bankId].value -= sSfxBankLerp[bankId].step;
+ } else {
+ sSfxBankLerp[bankId].value = sSfxBankLerp[bankId].target;
+ }
+ }
+}
+
+void AudioSfx_ProcessActiveSfx(void) {
+ u8 bankId;
+
+ if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].enabled) {
+ sCurSfxPlayerChannelIndex = 0;
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ AudioSfx_ChooseActiveSfx(bankId);
+ AudioSfx_PlayActiveSfx(bankId);
+ AudioSfx_StepBankLerp(bankId);
+ }
+ }
+}
+
+u8 AudioSfx_IsPlaying(u32 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if (entry->sfxId == sfxId) {
+ return true;
+ }
+ entryIndex = entry->next;
+ }
+
+ return false;
+}
+
+void AudioSfx_Reset(void) {
+ u8 bankId;
+ u8 i;
+ u8 entryIndex;
+
+ sSfxRequestWriteIndex = 0;
+ sSfxRequestReadIndex = 0;
+ sSfxChannelLowVolumeFlag = 0;
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ sSfxBankListEnd[bankId] = 0;
+ sSfxBankFreeListStart[bankId] = 1;
+ sSfxBankUnused[bankId] = 0;
+ gSfxBankMuted[bankId] = false;
+ sSfxBankLerp[bankId].value = 1.0f;
+ sSfxBankLerp[bankId].remainingFrames = 0;
+ }
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) {
+ gActiveSfx[bankId][i].entryIndex = 0xFF;
+ }
+ }
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ gSfxBanks[bankId][0].prev = 0xFF;
+ gSfxBanks[bankId][0].next = 0xFF;
+
+ for (i = 1; i < sSfxBankSizes[bankId] - 1; i++) {
+ gSfxBanks[bankId][i].prev = i - 1;
+ gSfxBanks[bankId][i].next = i + 1;
+ }
+
+ gSfxBanks[bankId][i].prev = i - 1;
+ gSfxBanks[bankId][i].next = 0xFF;
+ }
+}
diff --git a/src/code/audio/code_801A7B10.c b/src/code/audio/code_801A7B10.c
index 6d3faaeab..f2f37a013 100644
--- a/src/code/audio/code_801A7B10.c
+++ b/src/code/audio/code_801A7B10.c
@@ -1,6 +1,6 @@
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A7B10.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_StartSequence.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A7D04.s")
diff --git a/src/code/audioMgr.c b/src/code/audioMgr.c
index ee6014137..ce21bda37 100644
--- a/src/code/audioMgr.c
+++ b/src/code/audioMgr.c
@@ -78,7 +78,7 @@ void AudioMgr_ThreadEntry(void* arg) {
s16* msg = NULL;
s32 exit;
- func_801A4C30();
+ Audio_Init();
AudioLoad_SetDmaHandler(DmaMgr_DmaHandler);
func_801A4D00();
osSendMesg(&audioMgr->lockMsgQ, NULL, OS_MESG_BLOCK);
diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c
index 5649ae80c..ee2070610 100644
--- a/src/code/code_8012EC80.c
+++ b/src/code/code_8012EC80.c
@@ -189,7 +189,7 @@ void* gItemIcons[] = {
0x08059000, // ITEM_WALLET_DEFAULT
0x0805A000, // ITEM_WALLET_ADULT
0x0805B000, // ITEM_WALLET_GIANT
- 0x0805C000, // ITEM_FISHING_POLE
+ 0x0805C000, // ITEM_FISHING_ROD
0x0805D000, // ITEM_REMAINS_ODOLWA
0x0805E000, // ITEM_REMAINS_GOHT
0x0805F000, // ITEM_REMAINS_GYORG
diff --git a/src/code/code_80172BC0.c b/src/code/code_80172BC0.c
index 2ea9e6c67..94b55d4df 100644
--- a/src/code/code_80172BC0.c
+++ b/src/code/code_80172BC0.c
@@ -9,7 +9,7 @@ void AudioMgr_StopAllSfxExceptSystem(void) {
for (bankIdPtr = sSfxBankIds; bankIdPtr < (sSfxBankIds + ARRAY_COUNT(sSfxBankIds)); bankIdPtr++) {
if (*bankIdPtr != BANK_SYSTEM) {
- func_801A7084(*bankIdPtr);
+ AudioSfx_StopByBank(*bankIdPtr);
}
}
}
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 34e5fe4a2..1875d6669 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -1850,10 +1850,10 @@ s32 Actor_ProcessTalkRequest(Actor* actor, GameState* gameState) {
// Actor_PickUpExchange? Seems to be called with exchangeItemId -1 if the same actor used Actor_PickUp
// This function is also used to toggle the "Speak" action on the A button
-s32 func_800B8500(Actor* actor, PlayState* play, f32 xzRange, f32 yRange, s32 exchangeItemId) {
+s32 func_800B8500(Actor* actor, PlayState* play, f32 xzRange, f32 yRange, PlayerActionParam exchangeItemId) {
Player* player = GET_PLAYER(play);
- if ((player->actor.flags & ACTOR_FLAG_100) || ((exchangeItemId > EXCH_ITEM_NONE) && Player_InCsMode(play)) ||
+ if ((player->actor.flags & ACTOR_FLAG_100) || ((exchangeItemId > PLAYER_AP_NONE) && Player_InCsMode(play)) ||
(!actor->isTargeted &&
((fabsf(actor->playerHeightRel) > fabsf(yRange)) || ((actor->xzDistToPlayer > player->targetActorDistance)) ||
(xzRange < actor->xzDistToPlayer)))) {
@@ -1868,12 +1868,12 @@ s32 func_800B8500(Actor* actor, PlayState* play, f32 xzRange, f32 yRange, s32 ex
return true;
}
-s32 func_800B85E0(Actor* actor, PlayState* play, f32 radius, s32 exchangeItemId) {
+s32 func_800B85E0(Actor* actor, PlayState* play, f32 radius, PlayerActionParam exchangeItemId) {
return func_800B8500(actor, play, radius, radius, exchangeItemId);
}
s32 func_800B8614(Actor* actor, PlayState* play, f32 radius) {
- return func_800B85E0(actor, play, radius, EXCH_ITEM_NONE);
+ return func_800B85E0(actor, play, radius, PLAYER_AP_NONE);
}
s32 func_800B863C(Actor* actor, PlayState* play) {
@@ -2127,7 +2127,8 @@ 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, &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(sfxId, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
}
@@ -2567,7 +2568,8 @@ void func_800B9D1C(Actor* actor) {
if (sfxId != 0) {
if (actor->audioFlags & 2) {
- Audio_PlaySfxGeneral(sfxId, &actor->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(sfxId, &actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
} else if (actor->audioFlags & 4) {
play_sound(sfxId);
} else if (actor->audioFlags & 8) {
@@ -3338,7 +3340,7 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, PlayState* play) {
actorCtx->targetContext.bgmEnemy = NULL;
}
- Audio_StopSfxByPos(&actor->projectedPos);
+ AudioSfx_StopByPos(&actor->projectedPos);
Actor_Destroy(actor, play);
newHead = Actor_RemoveFromCategory(play, actorCtx, actor);
@@ -4291,18 +4293,18 @@ s16 func_800BDB6C(Actor* actor, PlayState* play, s16 arg2, f32 arg3) {
return arg2;
}
-void Actor_ChangeAnimationByInfo(SkelAnime* skelAnime, AnimationInfo* animation, s32 index) {
+void Actor_ChangeAnimationByInfo(SkelAnime* skelAnime, AnimationInfo* animationInfo, s32 animIndex) {
f32 frameCount;
- animation += index;
- if (animation->frameCount > 0.0f) {
- frameCount = animation->frameCount;
+ animationInfo += animIndex;
+ if (animationInfo->frameCount > 0.0f) {
+ frameCount = animationInfo->frameCount;
} else {
- frameCount = Animation_GetLastFrame(&animation->animation->common);
+ frameCount = Animation_GetLastFrame(&animationInfo->animation->common);
}
- Animation_Change(skelAnime, animation->animation, animation->playSpeed, animation->startFrame, frameCount,
- animation->mode, animation->morphFrames);
+ Animation_Change(skelAnime, animationInfo->animation, animationInfo->playSpeed, animationInfo->startFrame,
+ frameCount, animationInfo->mode, animationInfo->morphFrames);
}
// Unused
diff --git a/src/code/z_camera.c b/src/code/z_camera.c
index 20420d6ef..027b78a4a 100644
--- a/src/code/z_camera.c
+++ b/src/code/z_camera.c
@@ -1,42 +1,243 @@
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_fabsf.s")
+/**
+ * Returns the absolute value for floats
+ */
+f32 Camera_fabsf(f32 f) {
+ return ABS(f);
+}
+
+/**
+ * Returns the magnitude for 3D float vectors
+ */
+f32 Camera_Vec3fMagnitude(Vec3f* vec) {
+ return sqrtf(SQ(vec->x) + SQ(vec->y) + SQ(vec->z));
+}
+
+/**
+ * Interpolates along the curve shown below
+ * returns value y ranging from 0.0f to 1.0f for -xMax <= x <= xMax
+ * returns 1.0f otherwise
+ *
+ * y = 1.0f ________ _________
+ * __ __
+ * _ _
+ * y axis _ _
+ * ___ ___
+ * _____
+ * y = 0.0f | | |
+ * -xMax 0 xMax
+ *
+ * x axis
+ */
+f32 Camera_QuadraticAttenuation(f32 xRange, f32 x) {
+ f32 y;
+ f32 absX;
+ f32 percent40 = 0.4f;
+ f32 percent60;
+ f32 xQuadratic;
+ f32 xMaxQuadratic; // Normalizing constant
+
+ absX = Camera_fabsf(x);
+
+ if (absX > xRange) {
+ // fixed value outside xMax range
+ y = 1.0f;
+ } else {
+ // inside xMax range
+ percent60 = 1.0f - percent40;
+
+ if (absX < (xRange * percent60)) {
+ // quadratic curve in the inner 60% of xMax range: +concavity (upward curve)
+ xQuadratic = SQ(x) * (1.0f - percent40);
+ xMaxQuadratic = SQ(xRange * percent60);
+
+ y = xQuadratic / xMaxQuadratic;
+ } else {
+ // quadratic curve in the outer 40% of xMax range: -concavity (flattening curve)
+ xQuadratic = SQ(xRange - absX) * percent40;
+ xMaxQuadratic = SQ(0.4f * xRange);
+
+ y = 1.0f - (xQuadratic / xMaxQuadratic);
+ }
+ }
+ return y;
+}
+
+/*
+ * Performs linear interpoloation between `cur` and `target`. If `cur` is within
+ * `minDiff` units, the result is rounded up to `target`
+ */
+f32 Camera_LerpCeilF(f32 target, f32 cur, f32 stepScale, f32 minDiff) {
+ f32 diff = target - cur;
+ f32 step = diff * stepScale;
+
+ return (Camera_fabsf(diff) >= minDiff) ? cur + step : target;
+}
+
+/*
+ * Performs linear interpoloation between `cur` and `target`. If `cur` is within
+ * `minDiff` units, the result is rounded up to `target`
+ */
+s16 Camera_LerpCeilS(s16 target, s16 cur, f32 stepScale, s16 minDiff) {
+ s16 diff = target - cur;
+ s16 step = diff * stepScale + 0.5f;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_LengthVec3f.s")
+ return (ABS(diff) >= minDiff) ? cur + step : target;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB270.s")
+/*
+ * Performs linear interpoloation between `cur` and `target`. If `cur` is within
+ * `minDiff` units, the result is rounded down to `cur`
+ */
+s16 Camera_LerpFloorS(s16 target, s16 cur, f32 stepScale, s16 minDiff) {
+ s16 diff = target - cur;
+ s16 step = diff * stepScale + 0.5f;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Lerpf.s")
+ return (ABS(diff) >= minDiff) ? cur + step : cur;
+}
+
+/*
+ * Performs linear interpoloation between `cur` and `target`. If `cur` is within
+ * `minDiff` units, the result is rounded up to `target`. Output is written to `cur`
+ */
+void Camera_LerpCeilVec3f(Vec3f* target, Vec3f* cur, f32 xzStepScale, f32 yStepScale, f32 minDiff) {
+ cur->x = Camera_LerpCeilF(target->x, cur->x, xzStepScale, minDiff);
+ cur->y = Camera_LerpCeilF(target->y, cur->y, yStepScale, minDiff);
+ cur->z = Camera_LerpCeilF(target->z, cur->z, xzStepScale, minDiff);
+}
+
+void Camera_SetUpdateRatesFastPitch(Camera* camera) {
+ camera->yawUpdateRateInv = 100.0f;
+ camera->pitchUpdateRateInv = 16.0f;
+ camera->rUpdateRateInv = 20.0f;
+ camera->yOffsetUpdateRate = 0.05f;
+ camera->xzOffsetUpdateRate = 0.05f;
+ camera->fovUpdateRate = 0.05f;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Lerps.s")
+void Camera_SetUpdateRatesFastYaw(Camera* camera) {
+ camera->rUpdateRateInv = 50.0f;
+ camera->pitchUpdateRateInv = 100.0f;
+ camera->yawUpdateRateInv = 50.0f;
+ camera->yOffsetUpdateRate = 0.01f;
+ camera->xzOffsetUpdateRate = 0.1f;
+ camera->fovUpdateRate = 0.01f;
+ if (camera->speedRatio > 1.0f) {
+ camera->speedRatio = 1.0f;
+ }
+}
+
+void Camera_SetUpdateRatesSlow(Camera* camera) {
+ camera->rUpdateRateInv = 1800.0f;
+ camera->yawUpdateRateInv = 1800.0f;
+ camera->pitchUpdateRateInv = 1800.0f;
+ camera->yOffsetUpdateRate = 0.01;
+ camera->xzOffsetUpdateRate = 0.01;
+ camera->fovUpdateRate = 0.01;
+}
+
+/**
+ * Converts a 3D s16 vector into a 3D f32 vector
+ */
+Vec3f* Camera_Vec3sToVec3f(Vec3f* dest, Vec3s* src) {
+ Vec3f copy;
+
+ copy.x = src->x;
+ copy.y = src->y;
+ copy.z = src->z;
+
+ *dest = copy;
+ return dest;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB42C.s")
+/**
+ * Returns the difference between two angles and scales the difference up
+ */
+s16 Camera_AngleDiffAndScale(s16 angle1, s16 angle2, f32 scale) {
+ return BINANG_SUB(angle1, angle2) * scale;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_LerpVec3f.s")
+/**
+ * Calculates the current offset between the camera's at-coordinates and the centered actor's coordinates
+ */
+void Camera_UpdateAtActorOffset(Camera* camera, Vec3f* actorOffset) {
+ camera->atActorOffset.x = camera->at.x - actorOffset->x;
+ camera->atActorOffset.y = camera->at.y - actorOffset->y;
+ camera->atActorOffset.z = camera->at.z - actorOffset->z;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB544.s")
+f32 Camera_GetFocalActorHeight(Camera* camera) {
+ PosRot actorFocus;
+ Actor* focalActor = camera->focalActor;
+ f32 focalHeight;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB584.s")
+ if (focalActor == &GET_PLAYER(camera->play)->actor) {
+ focalHeight = Player_GetHeight((Player*)focalActor);
+ } else {
+ Actor_GetFocus(&actorFocus, focalActor);
+ focalHeight = actorFocus.pos.y - camera->focalActorPosRot.pos.y;
+ if (focalHeight == 0.0f) {
+ focalHeight = 10.0f;
+ }
+ }
+ return focalHeight;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB5DC.s")
+f32 Camera_GetRunSpeedLimit(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+ f32 runSpeedLimit;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB60C.s")
+ if (focalActor == &GET_PLAYER(camera->play)->actor) {
+ runSpeedLimit = Player_GetRunSpeedLimit((Player*)focalActor);
+ } else {
+ runSpeedLimit = 10.0f;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB674.s")
+ return runSpeedLimit;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB6C8.s")
+s32 func_800CB7CC(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB700.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags3 & PLAYER_STATE3_10;
+ } else {
+ return 0;
+ }
+}
+s32 Camera_IsMountedOnHorse(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB780.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags1 & PLAYER_STATE1_800000;
+ } else {
+ return 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB7CC.s")
+s32 Camera_IsDekuHovering(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB7F8.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags3 & PLAYER_STATE3_2000;
+ } else {
+ return 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB828.s")
+/**
+ * When walking in a cutscene? Used during Postman's minigame.
+ */
+s32 func_800CB854(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB854.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags1 & PLAYER_STATE1_20;
+ } else {
+ return 0;
+ }
+}
s32 Camera_IsSwimming(Camera* camera) {
Actor* focalActor = camera->focalActor;
@@ -55,31 +256,184 @@ s32 Camera_IsSwimming(Camera* camera) {
}
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB8C8.s")
+s32 Camera_IsDiving(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags2 & PLAYER_STATE2_800;
+ } else {
+ return 0;
+ }
+}
+
+s32 Camera_IsPlayerFormZora(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->transformation == PLAYER_FORM_ZORA;
+ } else {
+ return false;
+ }
+}
+
+s32 func_800CB924(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags3 & PLAYER_STATE3_1000;
+ } else {
+ return 0;
+ }
+}
+
+s32 func_800CB950(Camera* camera) {
+ Player* player;
+ s32 phi_v0;
+ s32 ret;
+ f32 yDiff;
+
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ yDiff = Camera_fabsf(camera->focalActorPosRot.pos.y - camera->playerFloorHeight);
+
+ phi_v0 = false;
+ if (yDiff < 11.0f) {
+ phi_v0 = true;
+ }
+
+ ret = phi_v0;
+
+ if (!ret) {
+
+ ret = false;
+
+ if (camera->focalActor->gravity > -0.1f) {
+ ret = true;
+ }
+
+ player = (Player*)camera->focalActor;
+ if (!ret) {
+ // Using zora fins
+ ret = player->stateFlags1 & PLAYER_STATE1_200000;
+ ret = !!ret;
+ }
+ }
+ return ret;
+ } else {
+ return true;
+ }
+}
+
+s32 Camera_IsClimbingLedge(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+
+ if (focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags1 & PLAYER_STATE1_4;
+ } else {
+ return 0;
+ }
+}
+
+s32 Camera_IsChargingSwordOrDekuFlowerDive(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+ s32 ret;
+
+ if (focalActor == &GET_PLAYER(camera->play)->actor) {
+ // Charging Sword
+ ret = !!(((Player*)focalActor)->stateFlags1 & PLAYER_STATE1_1000);
+ if (!ret) {
+ // Deku Flower Dive
+ ret = !!(((Player*)focalActor)->stateFlags3 & PLAYER_STATE3_100);
+ }
+ return ret;
+ } else {
+ return false;
+ }
+}
+
+s32 func_800CBA7C(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
+
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags2 & PLAYER_STATE2_800000;
+ } else {
+ return 0;
+ }
+}
+
+s32 func_800CBAAC(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB8F4.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->meleeWeaponState;
+ } else {
+ return 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB924.s")
+s32 Camera_GetFocalActorPos(Vec3f* dst, Camera* camera) {
+ PosRot focalPosRot;
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CB950.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ *dst = ((Player*)focalActor)->bodyPartsPos[0];
+ return dst;
+ } else {
+ Actor_GetWorldPosShapeRot(&focalPosRot, camera->focalActor);
+ *dst = focalPosRot.pos;
+ return dst;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBA08.s")
+s32 Camera_IsUnderwaterAsZora(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBA34.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->currentBoots == PLAYER_BOOTS_ZORA_UNDERWATER;
+ } else {
+ return 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBA7C.s")
+/**
+ * Evaluate if player is in one of two sword animations
+ */
+s32 func_800CBB88(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBAAC.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ if ((((Player*)focalActor)->meleeWeaponState != 0) &&
+ (((Player*)focalActor)->meleeWeaponAnimation == PLAYER_MWA_GORON_PUNCH_BUTT)) {
+ return 3;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBAD4.s")
+ if ((((Player*)focalActor)->stateFlags2 & PLAYER_STATE2_20000) ||
+ ((((Player*)focalActor)->meleeWeaponState != 0) &&
+ (((Player*)focalActor)->meleeWeaponAnimation == PLAYER_MWA_ZORA_PUNCH_KICK))) {
+ return 1;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBB58.s")
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBB88.s")
+s32 Camera_IsUsingZoraFins(Camera* camera) {
+ Actor* focalActor = camera->focalActor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBC00.s")
+ if (camera->focalActor == &GET_PLAYER(camera->play)->actor) {
+ return ((Player*)focalActor)->stateFlags1 & PLAYER_STATE1_200000;
+ } else {
+ return 0;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBC30.s")
+s32 func_800CBC30(Camera* camera, f32 waterYMax, f32 waterYMin) {
+ if ((camera->playerFloorHeight != camera->waterYPos) && (camera->waterYPos < waterYMax) &&
+ (camera->waterYPos > waterYMin)) {
+ return true;
+ } else {
+ return false;
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800CBC84.s")
diff --git a/src/code/z_demo.c b/src/code/z_demo.c
index b02fe51a9..8923669a7 100644
--- a/src/code/z_demo.c
+++ b/src/code/z_demo.c
@@ -290,7 +290,7 @@ void Cutscene_Command_Misc(PlayState* play2, CutsceneContext* csCtx, CsCmdBase*
break;
case 0x1B:
if (isStartFrame) {
- play->nextEntranceIndex = 0x1C00;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 0);
gSaveContext.nextCutsceneIndex = 0xFFF8;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
@@ -488,6 +488,7 @@ void func_800EADB0(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
}
}
#else
+void func_800EADB0(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EADB0.s")
#endif
@@ -569,7 +570,7 @@ void Cutscene_TerminatorImpl(PlayState* play, CutsceneContext* csCtx, CsCmdBase*
gSaveContext.save.cutscene = 0;
if (cmd->base == 1) {
- play->nextEntranceIndex = play->csCtx.sceneCsList[play->csCtx.currentCsIndex].nextEntranceIndex;
+ play->nextEntrance = play->csCtx.sceneCsList[play->csCtx.currentCsIndex].nextEntrance;
gSaveContext.nextCutsceneIndex = 0;
play->transitionTrigger = TRANS_TRIGGER_START;
if (gSaveContext.gameMode != 1) {
@@ -582,11 +583,11 @@ void Cutscene_TerminatorImpl(PlayState* play, CutsceneContext* csCtx, CsCmdBase*
play->transitionType = TRANS_TYPE_04;
}
- if ((play->nextEntranceIndex & 0xF) > 0) {
- gSaveContext.nextCutsceneIndex = (play->nextEntranceIndex & 0xF) + 0xFFEF;
+ if ((play->nextEntrance & 0xF) > 0) {
+ gSaveContext.nextCutsceneIndex = (play->nextEntrance & 0xF) + 0xFFEF;
}
- play->nextEntranceIndex &= ~0xF;
+ play->nextEntrance &= ~0xF;
}
}
@@ -603,11 +604,11 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
switch (D_801F4DE2) {
case 0x1F:
if (gSaveContext.save.weekEventReg[20] & 2) {
- play->nextEntranceIndex = 0x3010;
+ play->nextEntrance = ENTRANCE(WOODFALL_TEMPLE, 1);
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
} else {
- play->nextEntranceIndex = 0x8600;
+ play->nextEntrance = ENTRANCE(WOODFALL, 0);
gSaveContext.nextCutsceneIndex = 0xFFF0;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
@@ -616,11 +617,11 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
case 0x44:
if (gSaveContext.save.weekEventReg[33] & 0x80) {
- play->nextEntranceIndex = 0xAE70;
+ play->nextEntrance = ENTRANCE(MOUNTAIN_VILLAGE_SPRING, 7);
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
} else {
- play->nextEntranceIndex = 0xAE00;
+ play->nextEntrance = ENTRANCE(MOUNTAIN_VILLAGE_SPRING, 0);
gSaveContext.nextCutsceneIndex = 0xFFF0;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
@@ -629,7 +630,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
case 0x5F:
gSaveContext.save.weekEventReg[55] |= 0x80;
- play->nextEntranceIndex = 0x6A80;
+ play->nextEntrance = ENTRANCE(ZORA_CAPE, 8);
gSaveContext.nextCutsceneIndex = 0xFFF0;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
@@ -637,7 +638,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
case 0x36:
gSaveContext.save.weekEventReg[52] |= 0x20;
- play->nextEntranceIndex = 0x2000;
+ play->nextEntrance = ENTRANCE(IKANA_CANYON, 0);
gSaveContext.nextCutsceneIndex = 0xFFF1;
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_03;
@@ -658,12 +659,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 2:
if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) {
- // Milk bar
- play->nextEntranceIndex = 0x2400;
+ play->nextEntrance = ENTRANCE(MILK_BAR, 0);
gSaveContext.nextCutsceneIndex = 0xFFF0;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C00;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 0);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -671,12 +670,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 3:
if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) {
- // Fairy's fountain
- play->nextEntranceIndex = 0x4600;
+ play->nextEntrance = ENTRANCE(FAIRY_FOUNTAIN, 0);
gSaveContext.nextCutsceneIndex = 0xFFF0;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C10;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 1);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -684,12 +681,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 4:
if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) {
- // Romani ranch
- play->nextEntranceIndex = 0x6400;
+ play->nextEntrance = ENTRANCE(ROMANI_RANCH, 0);
gSaveContext.nextCutsceneIndex = 0xFFF1;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C20;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 2);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -697,12 +692,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 5:
if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) {
- // West clock town
- play->nextEntranceIndex = 0xD400;
+ play->nextEntrance = ENTRANCE(WEST_CLOCK_TOWN, 0);
gSaveContext.nextCutsceneIndex = 0xFFF0;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C30;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 3);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -710,12 +703,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 6:
if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) {
- // Milk bar
- play->nextEntranceIndex = 0x2400;
+ play->nextEntrance = ENTRANCE(MILK_BAR, 0);
gSaveContext.nextCutsceneIndex = 0xFFF1;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C50;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 5);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -723,32 +714,27 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 7:
if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) {
- // Milk bar
- play->nextEntranceIndex = 0x2400;
+ play->nextEntrance = ENTRANCE(MILK_BAR, 0);
gSaveContext.nextCutsceneIndex = 0xFFF3;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C60;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 6);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
break;
case 8:
- // Ikana canyon
- play->nextEntranceIndex = 0x2000;
+ play->nextEntrance = ENTRANCE(IKANA_CANYON, 0);
gSaveContext.nextCutsceneIndex = 0xFFF3;
play->transitionTrigger = TRANS_TRIGGER_START;
break;
case 9:
if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) {
- // Termina field
- play->nextEntranceIndex = 0x5400;
+ play->nextEntrance = ENTRANCE(TERMINA_FIELD, 0);
gSaveContext.nextCutsceneIndex = 0xFFF8;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C70;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 7);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -756,12 +742,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 10:
if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) {
- // Cucco shack
- play->nextEntranceIndex = 0x7E00;
+ play->nextEntrance = ENTRANCE(CUCCO_SHACK, 0);
gSaveContext.nextCutsceneIndex = 0xFFF0;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C40;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 4);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -769,12 +753,10 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt
case 11:
if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) {
- // Termina field
- play->nextEntranceIndex = 0x5410;
+ play->nextEntrance = ENTRANCE(TERMINA_FIELD, 1);
gSaveContext.nextCutsceneIndex = 0xFFF8;
} else {
- // SPOT00
- play->nextEntranceIndex = 0x1C80;
+ play->nextEntrance = ENTRANCE(CUTSCENE, 8);
gSaveContext.nextCutsceneIndex = 0xFFF9;
}
play->transitionTrigger = TRANS_TRIGGER_START;
@@ -1130,8 +1112,6 @@ void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index) {
}
}
-#ifdef NON_MATCHING
-// Some stack issues, and a few instructions in the "wrong" places
/**
* Loops over the cutscene data itself (`cutscenePtr`), applying the effects of each command instantaneously (for most
* commands).
@@ -1160,14 +1140,13 @@ void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index) {
*/
void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutscenePtr) {
s32 i;
- s16 phi_s0;
- s32 totalEntries;
s32 j;
- u32 cmdType; // sp5C
s32 pad;
- s32 cmdEntries; // sp58
- s32 cutsceneEndFrame; // sp50
- s16 phi_s0_23;
+ s32 totalEntries;
+ u32 cmdType;
+ s32 cmdEntries;
+ s32 pad2;
+ s32 cutsceneEndFrame;
CsCmdBase* cmd;
// Read the command list count and the ending frame for this cutscene
@@ -1196,14 +1175,14 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc
// Check special cases of command types. This are generic ActorActions
// Ranges: [0x64, 0x96), 0xC9, [0x1C2, 0x258)
if (((cmdType >= 100) && (cmdType < 150)) || (cmdType == 201) || ((cmdType >= 450) && (cmdType < 600))) {
- for (phi_s0 = 0; phi_s0 < ARRAY_COUNT(D_801F4DC8); phi_s0++) {
- if ((u16)cmdType == D_801F4DC8[phi_s0]) {
- func_800ECD7C(csCtx, &cutscenePtr, phi_s0);
+ for (j = 0; j < ARRAY_COUNT(D_801F4DC8); j = (s16)(j + 1)) {
+ if (D_801F4DC8[j] == (u16)cmdType) {
+ func_800ECD7C(csCtx, &cutscenePtr, j);
cmdType = -2;
break;
- } else if (D_801F4DC8[phi_s0] == 0) {
- D_801F4DC8[phi_s0] = cmdType;
- func_800ECD7C(csCtx, &cutscenePtr, phi_s0);
+ } else if (D_801F4DC8[j] == 0) {
+ D_801F4DC8[j] = cmdType;
+ func_800ECD7C(csCtx, &cutscenePtr, j);
cmdType = -2;
break;
}
@@ -1333,15 +1312,15 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc
cutscenePtr += sizeof(s32);
for (j = 0; j < cmdEntries; j++) {
cmd = (CsCmdBase*)cutscenePtr;
- if ((csCtx->frames >= cmd->startFrame) && (csCtx->frames < cmd->endFrame)) {
- csCtx->playerAction = (CsCmdActorAction*)cutscenePtr;
+ if ((cmd->startFrame <= csCtx->frames) && (csCtx->frames < cmd->endFrame)) {
+ csCtx->playerAction = (CsCmdActorAction*)cmd;
}
cutscenePtr += sizeof(CsCmdActorAction);
}
break;
case CS_CMD_CAMERA:
- cutscenePtr = &cutscenePtr[Cutscene_Command_Camera(play, cutscenePtr)];
+ cutscenePtr += Cutscene_Command_Camera(play, cutscenePtr);
break;
case CS_CMD_TERMINATOR:
@@ -1368,7 +1347,7 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc
for (j = 0; j < cmdEntries; j++) {
cmd = (CsCmdBase*)cutscenePtr;
if (cmd->base != 0xFFFF) {
- Cutscene_Command_Textbox(play, csCtx, (CsCmdTextbox*)cutscenePtr);
+ Cutscene_Command_Textbox(play, csCtx, (CsCmdTextbox*)cmd);
}
cutscenePtr += sizeof(CsCmdTextbox);
}
@@ -1414,10 +1393,6 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc
}
}
}
-#else
-void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutscenePtr);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_ProcessCommands.s")
-#endif
/* End of command handling section */
@@ -1528,7 +1503,7 @@ void func_800EDBE0(PlayState* play) {
if ((gSaveContext.respawnFlag == 0) || (gSaveContext.respawnFlag == -2)) {
sp24 = play->loadedScene;
if ((sp24->titleTextId != 0) && gSaveContext.showTitleCard) {
- if ((Entrance_GetTransitionFlags(((void)0, gSaveContext.save.entranceIndex) +
+ if ((Entrance_GetTransitionFlags(((void)0, gSaveContext.save.entrance) +
((void)0, gSaveContext.sceneSetupIndex)) &
0x4000) != 0) {
func_80151A68(play, sp24->titleTextId);
diff --git a/src/code/z_effect_soft_sprite.c b/src/code/z_effect_soft_sprite.c
index 87f1958bd..ea8a546d6 100644
--- a/src/code/z_effect_soft_sprite.c
+++ b/src/code/z_effect_soft_sprite.c
@@ -59,11 +59,11 @@ EffectSs* EffectSS_GetTable() {
void EffectSS_Delete(EffectSs* effectSs) {
if (effectSs->flags & 2) {
- Audio_StopSfxByPos(&effectSs->pos);
+ AudioSfx_StopByPos(&effectSs->pos);
}
if (effectSs->flags & 4) {
- Audio_StopSfxByPos(&effectSs->vec);
+ AudioSfx_StopByPos(&effectSs->vec);
}
EffectSS_ResetEntry(effectSs);
diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c
index b28e50364..5258c2ecf 100644
--- a/src/code/z_effect_soft_sprite_old_init.c
+++ b/src/code/z_effect_soft_sprite_old_init.c
@@ -978,7 +978,7 @@ void EffectSsDeadDd_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* a
initParams.envColor.r = env->r;
initParams.envColor.g = env->g;
initParams.envColor.b = env->b;
- initParams.type = 0;
+ initParams.type = DEADDD_TYPE_0;
initParams.alphaStep = alphaStep;
initParams.life = life;
diff --git a/src/code/z_en_hy_code.c b/src/code/z_en_hy_code.c
index 6549ed9e1..5e32e5c95 100644
--- a/src/code/z_en_hy_code.c
+++ b/src/code/z_en_hy_code.c
@@ -11,7 +11,7 @@
#include "objects/object_boj/object_boj.h"
#include "objects/object_os_anime/object_os_anime.h"
-static AnimationInfoS sAnimations[] = {
+static AnimationInfoS sAnimationInfo[] = {
{ &gMamamuYanUnusedIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_boj_Anim_001494, 1.0f, 0, -1, ANIMMODE_LOOP, 0 },
{ &object_boj_Anim_001494, 1.0f, 0, -1, ANIMMODE_LOOP, -8 },
@@ -45,15 +45,15 @@ s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex) {
s16 frameCount;
s32 isChanged = false;
- if (animIndex >= ENHY_ANIMATION_AOB_0 && animIndex < ENHY_ANIMATION_MAX) {
+ if (animIndex >= ENHY_ANIM_AOB_0 && animIndex < ENHY_ANIM_MAX) {
isChanged = true;
- frameCount = sAnimations[animIndex].frameCount;
+ frameCount = sAnimationInfo[animIndex].frameCount;
if (frameCount < 0) {
- frameCount = Animation_GetLastFrame(&sAnimations[animIndex].animation->common);
+ frameCount = Animation_GetLastFrame(&sAnimationInfo[animIndex].animation->common);
}
- Animation_Change(skelAnime, sAnimations[animIndex].animation, sAnimations[animIndex].playSpeed,
- sAnimations[animIndex].startFrame, frameCount, sAnimations[animIndex].mode,
- sAnimations[animIndex].morphFrames);
+ Animation_Change(skelAnime, sAnimationInfo[animIndex].animation, sAnimationInfo[animIndex].playSpeed,
+ sAnimationInfo[animIndex].startFrame, frameCount, sAnimationInfo[animIndex].mode,
+ sAnimationInfo[animIndex].morphFrames);
}
return isChanged;
}
diff --git a/src/code/z_message.c b/src/code/z_message.c
index 14fe241c4..16e1203d7 100644
--- a/src/code/z_message.c
+++ b/src/code/z_message.c
@@ -254,62 +254,39 @@ void func_8014CCB4(PlayState* play, s16* decodedBufPos, s32* offset, f32* arg3)
#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D304.s")
-#ifdef NON_EQUIVALENT
-extern u16* D_801D0188;
-extern s16* D_801D0250;
+extern u16 D_801D0188[][9];
+extern s16 D_801D0250[];
void func_8014D62C(PlayState* play, s32* arg1, f32* arg2, s16* arg3) {
- f32 sp3C;
- s16 temp_s0;
- s16 temp_s1;
- s16 temp_s1_2;
+ MessageContext* msgCtx = &play->msgCtx;
+ PauseContext* pauseCtx = &play->pauseCtx;
s16 temp_s6;
- s32 temp_s2;
- s32 temp_s2_2;
- u16* temp_v0;
+ s16 temp_s1 = *arg3;
+ s32 temp_s2 = *arg1;
+ f32 sp3C = *arg2;
s16 phi_v0;
s16 phi_s0;
- s16 phi_s1;
- s32 phi_s2;
- s16 phi_s1_2;
- s32 phi_s2_2;
-
- temp_s1 = *arg3;
- temp_s2 = *arg1;
- sp3C = *arg2;
+
if ((func_8010A0A4(play) != 0) || (play->sceneNum == 0x4F)) {
phi_v0 = 0xA;
} else {
- phi_v0 = play->pauseCtx.unk_238[PAUSE_WORLD_MAP];
+ phi_v0 = pauseCtx->unk_238[PAUSE_WORLD_MAP];
}
- temp_s6 = *(&D_801D0250 + (phi_v0 * 2));
- phi_s0 = 0;
- phi_s1_2 = temp_s1;
- phi_s2_2 = temp_s2;
- if ((s32)temp_s6 > 0) {
- phi_s1 = temp_s1;
- phi_s2 = temp_s2;
- do {
- temp_v0 = (phi_v0 * 0x12) + &D_801D0188 + (phi_s0 * 2);
- (play + 0x4908 + (phi_s1 * 2))->decodedBuffer = (u16)*temp_v0;
- Font_LoadChar(play, *temp_v0, phi_s2);
- temp_s0 = phi_s0 + 1;
- temp_s1_2 = phi_s1 + 1;
- temp_s2_2 = phi_s2 + 0x80;
- phi_s0 = temp_s0;
- phi_s1 = temp_s1_2;
- phi_s2 = temp_s2_2;
- phi_s1_2 = temp_s1_2;
- phi_s2_2 = temp_s2_2;
- } while ((s32)temp_s0 < (s32)temp_s6);
+
+ temp_s6 = D_801D0250[phi_v0];
+
+ for (phi_s0 = 0; phi_s0 < temp_s6; phi_s0++, temp_s1++, temp_s2 += 0x80) {
+ msgCtx->decodedBuffer.wchar[temp_s1] = D_801D0188[phi_v0][phi_s0];
+ Font_LoadChar(play, D_801D0188[phi_v0][phi_s0], temp_s2);
}
- *arg3 = phi_s1_2 - 1;
- *arg1 = phi_s2_2;
- *arg2 = sp3C + ((f32)(temp_s6 - 1) * (16.0f * play->msgCtx.unk12098));
+
+ temp_s1--;
+ sp3C += (temp_s6 - 1) * (16.0f * msgCtx->unk12098);
+
+ *arg3 = temp_s1;
+ *arg1 = temp_s2;
+ *arg2 = sp3C;
}
-#else
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D62C.s")
-#endif
#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D7B4.s")
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 014fb6279..c24a45b51 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -357,11 +357,11 @@ void Play_SaveCycleSceneFlags(GameState* thisx) {
cycleSceneFlags->clearedRoom = this->actorCtx.flags.clearedRoom;
}
-void Play_SetRespawnData(GameState* thisx, s32 respawnMode, u16 entranceIndex, s32 roomIndex, s32 playerParams,
- Vec3f* pos, s16 yaw) {
+void Play_SetRespawnData(GameState* thisx, s32 respawnMode, u16 entrance, s32 roomIndex, s32 playerParams, Vec3f* pos,
+ s16 yaw) {
PlayState* this = (PlayState*)thisx;
- gSaveContext.respawn[respawnMode].entranceIndex = Entrance_CreateIndex(entranceIndex >> 9, 0, entranceIndex & 0xF);
+ gSaveContext.respawn[respawnMode].entrance = Entrance_Create(entrance >> 9, 0, entrance & 0xF);
gSaveContext.respawn[respawnMode].roomIndex = roomIndex;
gSaveContext.respawn[respawnMode].pos = *pos;
gSaveContext.respawn[respawnMode].yaw = yaw;
@@ -376,7 +376,7 @@ void Play_SetupRespawnPoint(GameState* thisx, s32 respawnMode, s32 playerParams)
Player* player = GET_PLAYER(this);
if (this->sceneNum != SCENE_KAKUSIANA) { // Grottos
- Play_SetRespawnData(&this->state, respawnMode, (u16)((void)0, gSaveContext.save.entranceIndex),
+ Play_SetRespawnData(&this->state, respawnMode, (u16)((void)0, gSaveContext.save.entrance),
this->roomCtx.currRoom.num, playerParams, &player->actor.world.pos,
player->actor.shape.rot.y);
}
@@ -385,7 +385,7 @@ void Play_SetupRespawnPoint(GameState* thisx, s32 respawnMode, s32 playerParams)
// Override respawn data in Sakon's Hideout
void func_80169ECC(PlayState* this) {
if (this->sceneNum == SCENE_SECOM) {
- this->nextEntranceIndex = 0x2060;
+ this->nextEntrance = ENTRANCE(IKANA_CANYON, 6);
gSaveContext.respawnFlag = -7;
}
}
@@ -398,7 +398,7 @@ void func_80169EFC(GameState* thisx) {
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwitchFlags = this->actorCtx.flags.switches[2];
gSaveContext.respawn[RESPAWN_MODE_DOWN].unk_18 = this->actorCtx.flags.collectible[1];
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = this->actorCtx.flags.collectible[2];
- this->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex;
+ this->nextEntrance = gSaveContext.respawn[RESPAWN_MODE_DOWN].entrance;
gSaveContext.respawnFlag = 1;
func_80169ECC(this);
this->transitionTrigger = TRANS_TRIGGER_START;
@@ -410,7 +410,7 @@ void func_80169EFC(GameState* thisx) {
void func_80169F78(GameState* thisx) {
PlayState* this = (PlayState*)thisx;
- this->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_TOP].entranceIndex;
+ this->nextEntrance = gSaveContext.respawn[RESPAWN_MODE_TOP].entrance;
gSaveContext.respawnFlag = -1;
func_80169ECC(this);
this->transitionTrigger = TRANS_TRIGGER_START;
diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c
index 100cb3f8a..1566077f1 100644
--- a/src/code/z_player_lib.c
+++ b/src/code/z_player_lib.c
@@ -774,11 +774,11 @@ s32 func_801240DC(Player* player) {
}
s32 func_80124110(Player* player, s32 actionParam) {
- s32 temp_v0 = actionParam - PLAYER_AP_FISHING_POLE;
+ s32 temp_v0 = actionParam - PLAYER_AP_FISHING_ROD;
if (player->transformation != PLAYER_FORM_GORON) {
- if (((actionParam - PLAYER_AP_FISHING_POLE) > (PLAYER_AP_FISHING_POLE - PLAYER_AP_FISHING_POLE)) &&
- ((actionParam - PLAYER_AP_FISHING_POLE) < (PLAYER_AP_SWORD_GREAT_FAIRY - PLAYER_AP_FISHING_POLE))) {
+ if (((actionParam - PLAYER_AP_FISHING_ROD) > (PLAYER_AP_FISHING_ROD - PLAYER_AP_FISHING_ROD)) &&
+ ((actionParam - PLAYER_AP_FISHING_ROD) < (PLAYER_AP_SWORD_GREAT_FAIRY - PLAYER_AP_FISHING_ROD))) {
return temp_v0;
}
}
diff --git a/src/code/z_scene.c b/src/code/z_scene.c
index cf40d6049..da05eac2b 100644
--- a/src/code/z_scene.c
+++ b/src/code/z_scene.c
@@ -454,7 +454,7 @@ void Scene_HeaderCmdAltHeaderList(PlayState* play, SceneCmd* cmd) {
SceneCmd** altHeaderList;
SceneCmd* altHeader;
- if (gSaveContext.sceneSetupIndex) {
+ if (gSaveContext.sceneSetupIndex != 0) {
altHeaderList = Lib_SegmentedToVirtual(cmd->altHeaders.segment);
altHeader = altHeaderList[gSaveContext.sceneSetupIndex - 1];
@@ -527,7 +527,7 @@ void Scene_HeaderCmdAnimatedMaterials(PlayState* play, SceneCmd* cmd) {
* Sets the exit fade from the next entrance index.
*/
void Scene_SetExitFade(PlayState* play) {
- play->transitionType = Entrance_GetTransitionFlags(play->nextEntranceIndex) & 0x7F;
+ play->transitionType = Entrance_GetTransitionFlags(play->nextEntrance) & 0x7F;
}
/**
@@ -587,15 +587,15 @@ s32 Scene_ProcessHeader(PlayState* play, SceneCmd* header) {
}
/**
- * Creates an entrance index from the scene index, spawn index, and scene setup.
+ * Creates an entrance from the scene, spawn, and lyaer.
*/
-u16 Entrance_CreateIndex(s32 sceneIndex, s32 spawnIndex, s32 sceneSetup) {
- return (((sceneIndex << 9) | (spawnIndex << 4)) | sceneSetup) & 0xFFFF;
+u16 Entrance_Create(s32 scene, s32 spawn, s32 layer) {
+ return (scene << 9) | (spawn << 4) | layer;
}
/**
- * Creates an entrance index from the current entrance index with the given spawn index.
+ * Creates an layer 0 entranace from the current entrance and the given spawn.
*/
-u16 Entrance_CreateIndexFromSpawn(s32 spawnIndex) {
- return Entrance_CreateIndex(gSaveContext.save.entranceIndex >> 9, spawnIndex, 0);
+u16 Entrance_CreateFromSpawn(s32 spawn) {
+ return Entrance_Create(gSaveContext.save.entrance >> 9, spawn, 0);
}
diff --git a/src/code/z_scene_table.c b/src/code/z_scene_table.c
index daf85190a..108689978 100644
--- a/src/code/z_scene_table.c
+++ b/src/code/z_scene_table.c
@@ -486,22 +486,22 @@ static EntranceTableEntry* sTreasureChestShopEntranceTable[] = {
sTreasureChestShopEntrance1,
};
-static EntranceTableEntry sStoneTowerTempleReversedEntrance0[] = {
+static EntranceTableEntry sStoneTowerTempleInvertedEntrance0[] = {
{ 0xE8, 0x00, 0xC102 },
};
-static EntranceTableEntry sStoneTowerTempleReversedEntrance1[] = {
+static EntranceTableEntry sStoneTowerTempleInvertedEntrance1[] = {
{ 0xE8, 0x01, 0x8102 },
};
-static EntranceTableEntry sStoneTowerTempleReversedEntrance2[] = {
+static EntranceTableEntry sStoneTowerTempleInvertedEntrance2[] = {
{ 0xE8, 0x02, 0x8102 },
};
-static EntranceTableEntry* sStoneTowerTempleReversedEntranceTable[] = {
- sStoneTowerTempleReversedEntrance0,
- sStoneTowerTempleReversedEntrance1,
- sStoneTowerTempleReversedEntrance2,
+static EntranceTableEntry* sStoneTowerTempleInvertedEntranceTable[] = {
+ sStoneTowerTempleInvertedEntrance0,
+ sStoneTowerTempleInvertedEntrance1,
+ sStoneTowerTempleInvertedEntrance2,
};
static EntranceTableEntry sClockTowerRooftopEntrance0[] = {
@@ -2678,7 +2678,7 @@ static SceneEntranceTableEntry sSceneEntranceTable[] = {
/* 0x12 */ SCENE_ENTRANCE(sMilkBarEntranceTable, "Z2_MILK_BAR"),
/* 0x13 */ SCENE_ENTRANCE(sStoneTowerTempleEntranceTable, "Z2_INISIE_N"),
/* 0x14 */ SCENE_ENTRANCE(sTreasureChestShopEntranceTable, "Z2_TAKARAYA"),
- /* 0x15 */ SCENE_ENTRANCE(sStoneTowerTempleReversedEntranceTable, "Z2_INISIE_R"),
+ /* 0x15 */ SCENE_ENTRANCE(sStoneTowerTempleInvertedEntranceTable, "Z2_INISIE_R"),
/* 0x16 */ SCENE_ENTRANCE(sClockTowerRooftopEntranceTable, "Z2_OKUJOU"),
/* 0x17 */ SCENE_ENTRANCE(sOpeningDungeonEntranceTable, "Z2_OPENINGDAN"),
/* 0x18 */ SCENE_ENTRANCE(sWoodfallTempleEntranceTable, "Z2_MITURIN"),
@@ -2772,19 +2772,19 @@ static SceneEntranceTableEntry sSceneEntranceTable[] = {
/**
* Returns a pointer to an entrance table from a given entrance index.
*/
-EntranceTableEntry* Entrance_GetTableEntry(u16 entranceIndex) {
- u32 entranceIndex2 = entranceIndex;
- EntranceTableEntry** tableEntryP = sSceneEntranceTable[entranceIndex2 >> 9].table;
- EntranceTableEntry* tableEntry = tableEntryP[(entranceIndex2 >> 4) & 0x1F];
+EntranceTableEntry* Entrance_GetTableEntry(u16 entrance) {
+ u32 entranceIndex = entrance;
+ EntranceTableEntry** tableEntryP = sSceneEntranceTable[entranceIndex >> 9].table;
+ EntranceTableEntry* tableEntry = tableEntryP[(entranceIndex >> 4) & 0x1F];
- return &tableEntry[entranceIndex2 & 0xF];
+ return &tableEntry[entranceIndex & 0xF];
}
/**
* Returns the scene index from a given entrance index.
*/
-s32 Entrance_GetSceneNum(u16 entranceIndex) {
- EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entranceIndex);
+s32 Entrance_GetSceneNum(u16 entrance) {
+ EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entrance);
return tableEntry->sceneNum;
}
@@ -2792,8 +2792,8 @@ s32 Entrance_GetSceneNum(u16 entranceIndex) {
/**
* Returns the absolute value scene index (since for some reason some of them are negative) from a given entrance index.
*/
-s32 Entrance_GetSceneNumAbsolute(u16 entranceIndex) {
- EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entranceIndex);
+s32 Entrance_GetSceneNumAbsolute(u16 entrance) {
+ EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entrance);
return ABS_ALT(tableEntry->sceneNum);
}
@@ -2801,8 +2801,8 @@ s32 Entrance_GetSceneNumAbsolute(u16 entranceIndex) {
/**
* Returns the spawn index from a given entrance index.
*/
-s32 Entrance_GetSpawnNum(u16 entranceIndex) {
- EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entranceIndex);
+s32 Entrance_GetSpawnNum(u16 entrance) {
+ EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entrance);
return tableEntry->spawnNum;
}
@@ -2810,8 +2810,8 @@ s32 Entrance_GetSpawnNum(u16 entranceIndex) {
/**
* Returns the transition effect flags from a given entrance index.
*/
-s32 Entrance_GetTransitionFlags(u16 entranceIndex) {
- EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entranceIndex);
+s32 Entrance_GetTransitionFlags(u16 entrance) {
+ EntranceTableEntry* tableEntry = Entrance_GetTableEntry(entrance);
return tableEntry->flags;
}
diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c
index a22357624..8321a309e 100644
--- a/src/code/z_skelanime.c
+++ b/src/code/z_skelanime.c
@@ -924,30 +924,30 @@ s16 Animation_GetLastFrame2(LegacyAnimationHeader* animation) {
}
/**
- * Linearly interpolates the start and tactoret frame tables with the given weight, putting the result in dst
+ * Linearly interpolates the start and target frame tables with the given weight, putting the result in dst
*/
-void SkelAnime_InterpFrameTable(s32 limbCount, Vec3s* dst, Vec3s* start, Vec3s* tactoret, f32 weight) {
+void SkelAnime_InterpFrameTable(s32 limbCount, Vec3s* dst, Vec3s* start, Vec3s* target, f32 weight) {
s32 i;
s16 diff;
s16 base;
if (weight < 1.0f) {
- for (i = 0; i < limbCount; i++, dst++, start++, tactoret++) {
+ for (i = 0; i < limbCount; i++, dst++, start++, target++) {
base = start->x;
- diff = tactoret->x - base;
+ diff = target->x - base;
dst->x = (s16)(diff * weight) + base;
base = start->y;
- diff = tactoret->y - base;
+ diff = target->y - base;
dst->y = (s16)(diff * weight) + base;
base = start->z;
- diff = tactoret->z - base;
+ diff = target->z - base;
dst->z = (s16)(diff * weight) + base;
}
} else {
- for (i = 0; i < limbCount; i++, dst++, tactoret++) {
- dst->x = tactoret->x;
- dst->y = tactoret->y;
- dst->z = tactoret->z;
+ for (i = 0; i < limbCount; i++, dst++, target++) {
+ dst->x = target->x;
+ dst->y = target->y;
+ dst->z = target->z;
}
}
}
diff --git a/src/code/z_snap.c b/src/code/z_snap.c
index 246309749..7a234ca22 100644
--- a/src/code/z_snap.c
+++ b/src/code/z_snap.c
@@ -49,7 +49,7 @@ s32 Snap_RecordPictographedActors(PlayState* play) {
// Actors which may be pictographed anywhere
switch (actor->id) {
case ACTOR_EN_KAKASI:
- if (GET_KAKASI_ABOVE_GROUND(actor) == 1) {
+ if (KAKASI_GET_ABOVE_GROUND(actor) == 1) {
seen |= PICTO_SEEN_ANYWHERE;
break; //! @bug break is inside conditional, meaning it falls through if it is false
}
diff --git a/src/code/z_sound_source.c b/src/code/z_sound_source.c
index 2cdc3ab3a..15ebd018a 100644
--- a/src/code/z_sound_source.c
+++ b/src/code/z_sound_source.c
@@ -16,7 +16,7 @@ void SoundSource_UpdateAll(PlayState* play) {
for (i = 0; i < ARRAY_COUNT(play->soundSources); i++) {
if (source->countdown != 0) {
if (DECR(source->countdown) == 0) {
- Audio_StopSfxByPos(&source->projectedPos);
+ AudioSfx_StopByPos(&source->projectedPos);
} else {
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &source->worldPos, &source->projectedPos);
if (source->playSfxEachFrame) {
@@ -54,7 +54,7 @@ void SoundSource_Add(PlayState* play, Vec3f* worldPos, u32 duration, u16 sfxId,
// If no sound source is available, replace the sound source with the smallest remaining countdown
if (i >= ARRAY_COUNT(play->soundSources)) {
source = backupSource;
- Audio_StopSfxByPos(&source->projectedPos);
+ AudioSfx_StopByPos(&source->projectedPos);
}
source->worldPos = *worldPos;
diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c
index 221305f46..5f92d13e5 100644
--- a/src/code/z_sram_NES.c
+++ b/src/code/z_sram_NES.c
@@ -501,7 +501,7 @@ u16 Sram_CalcChecksum(void* data, size_t count) {
// Resets `Save` substruct
void Sram_ResetSave(void) {
- gSaveContext.save.entranceIndex = 0x1C00;
+ gSaveContext.save.entrance = ENTRANCE(CUTSCENE, 0);
gSaveContext.save.equippedMask = 0;
gSaveContext.save.isFirstCycle = false;
gSaveContext.save.unk_06 = 0;
@@ -845,7 +845,7 @@ void Sram_InitDebugSave(void) {
gSaveContext.save.horseData.pos.z = -1285;
gSaveContext.save.horseData.yaw = -0x7554;
- gSaveContext.save.entranceIndex = 0x1C00;
+ gSaveContext.save.entrance = ENTRANCE(CUTSCENE, 0);
gSaveContext.save.isFirstCycle = true;
//
@@ -910,7 +910,13 @@ void func_80144A94(SramContext* sramCtx) {
gSaveContext.jinxTimer = 0;
}
-u16 D_801C6A58[] = { 0x68B0, 0x6A60, 0xB230, 0x9A80, 0xD890, 0x3E40, 0x8640, 0x84A0, 0x2040, 0xAA30 };
+u16 D_801C6A58[] = {
+ ENTRANCE(GREAT_BAY_COAST, 11), ENTRANCE(ZORA_CAPE, 6),
+ ENTRANCE(SNOWHEAD, 3), ENTRANCE(MOUNTAIN_VILLAGE_WINTER, 8),
+ ENTRANCE(SOUTH_CLOCK_TOWN, 9), ENTRANCE(MILK_ROAD, 4),
+ ENTRANCE(WOODFALL, 4), ENTRANCE(SOUTHERN_SWAMP_POISONED, 10),
+ ENTRANCE(IKANA_CANYON, 4), ENTRANCE(STONE_TOWER, 3),
+};
void Sram_OpenSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
s32 i;
@@ -973,22 +979,24 @@ void Sram_OpenSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
}
if (gSaveContext.save.isFirstCycle) {
- gSaveContext.save.entranceIndex = 0xD800;
+ gSaveContext.save.entrance = ENTRANCE(SOUTH_CLOCK_TOWN, 0);
gSaveContext.save.day = 0;
gSaveContext.save.time = 0x3FFF;
} else {
- gSaveContext.save.entranceIndex = 0x1C00;
+ gSaveContext.save.entrance = ENTRANCE(CUTSCENE, 0);
gSaveContext.nextCutsceneIndex = 0;
gSaveContext.save.playerForm = PLAYER_FORM_HUMAN;
}
} else {
- gSaveContext.save.entranceIndex = D_801C6A58[(void)0, gSaveContext.save.owlSaveLocation];
- if ((gSaveContext.save.entranceIndex == 0x84A0) && (gSaveContext.save.weekEventReg[20] & 2)) {
+ gSaveContext.save.entrance = D_801C6A58[(void)0, gSaveContext.save.owlSaveLocation];
+ if ((gSaveContext.save.entrance == ENTRANCE(SOUTHERN_SWAMP_POISONED, 10)) &&
+ (gSaveContext.save.weekEventReg[20] & 2)) {
// Unconfirmed weekEventReg: "Woodfall Temple Prison Entrance raised / Water cleansed"
- gSaveContext.save.entranceIndex = 0xCA0;
- } else if ((gSaveContext.save.entranceIndex == 0x9A80) && (gSaveContext.save.weekEventReg[33] & 0x80)) {
+ gSaveContext.save.entrance = ENTRANCE(SOUTHERN_SWAMP_CLEARED, 10);
+ } else if ((gSaveContext.save.entrance == ENTRANCE(MOUNTAIN_VILLAGE_WINTER, 8)) &&
+ (gSaveContext.save.weekEventReg[33] & 0x80)) {
// Unconfirmed weekEventReg: "Mountain Village Unfrozen"
- gSaveContext.save.entranceIndex = 0xAE80;
+ gSaveContext.save.entrance = ENTRANCE(MOUNTAIN_VILLAGE_SPRING, 8);
}
for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) {
@@ -1513,7 +1521,7 @@ void func_80146DF8(SramContext* sramCtx) {
}
void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
- if (gSaveContext.save.entranceIndex) {} // Required to match
+ if (gSaveContext.save.entrance) {} // Required to match
func_801A3D98(gSaveContext.options.audioSetting);
}
diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c
index afc7f7168..efc6774a7 100644
--- a/src/code/z_sub_s.c
+++ b/src/code/z_sub_s.c
@@ -531,24 +531,24 @@ Actor* SubS_FindNearestActor(Actor* actor, PlayState* play, u8 actorCategory, s1
return closestActor;
}
-s32 SubS_ChangeAnimationByInfoS(SkelAnime* skelAnime, AnimationInfoS* animations, s32 index) {
+s32 SubS_ChangeAnimationByInfoS(SkelAnime* skelAnime, AnimationInfoS* animationInfo, s32 animIndex) {
s32 endFrame;
s32 startFrame;
- animations += index;
- endFrame = animations->frameCount;
- if (animations->frameCount < 0) {
- endFrame = Animation_GetLastFrame(&animations->animation->common);
+ animationInfo += animIndex;
+ endFrame = animationInfo->frameCount;
+ if (animationInfo->frameCount < 0) {
+ endFrame = Animation_GetLastFrame(&animationInfo->animation->common);
}
- startFrame = animations->startFrame;
+ startFrame = animationInfo->startFrame;
if (startFrame >= endFrame || startFrame < 0) {
return false;
}
- if (animations->playSpeed < 0.0f) {
+ if (animationInfo->playSpeed < 0.0f) {
SWAP(s32, endFrame, startFrame);
}
- Animation_Change(skelAnime, animations->animation, animations->playSpeed, startFrame, endFrame, animations->mode,
- animations->morphFrames);
+ Animation_Change(skelAnime, animationInfo->animation, animationInfo->playSpeed, startFrame, endFrame,
+ animationInfo->mode, animationInfo->morphFrames);
return true;
}
@@ -1357,21 +1357,21 @@ s32 SubS_ActorPathing_SetNextPoint(PlayState* play, ActorPathing* actorPath) {
return reupdate;
}
-void SubS_ChangeAnimationBySpeedInfo(SkelAnime* skelAnime, AnimationSpeedInfo* animations, s32 nextIndex,
- s32* curIndex) {
- AnimationSpeedInfo* animation = &animations[nextIndex];
+void SubS_ChangeAnimationBySpeedInfo(SkelAnime* skelAnime, AnimationSpeedInfo* animationInfo, s32 nextAnimIndex,
+ s32* curAnimIndex) {
+ AnimationSpeedInfo* animation = &animationInfo[nextAnimIndex];
f32 startFrame = skelAnime->curFrame;
f32 endFrame;
f32 morphFrames;
- if ((*curIndex < 0) || (nextIndex == *curIndex)) {
+ if ((*curAnimIndex < 0) || (nextAnimIndex == *curAnimIndex)) {
morphFrames = 0.0f;
- if (*curIndex < 0) {
+ if (*curAnimIndex < 0) {
startFrame = 0.0f;
}
} else {
morphFrames = animation->morphFrames;
- if (nextIndex != *curIndex) {
+ if (nextAnimIndex != *curAnimIndex) {
startFrame = 0.0f;
}
}
@@ -1383,7 +1383,7 @@ void SubS_ChangeAnimationBySpeedInfo(SkelAnime* skelAnime, AnimationSpeedInfo* a
}
Animation_Change(skelAnime, animation->animation, animation->playSpeed, startFrame, endFrame, animation->mode,
morphFrames);
- *curIndex = nextIndex;
+ *curAnimIndex = nextAnimIndex;
}
s32 SubS_StartActorCutscene(Actor* actor, s16 nextCutscene, s16 curCutscene, s32 type) {