diff --git a/build.py b/build.py index 7372644..e6e95ed 100644 --- a/build.py +++ b/build.py @@ -181,6 +181,7 @@ def build_35(): 'src/snd/ssinit_h.c', 'src/snd/ssplay.c', 'src/snd/ssquit.c', + 'src/snd/ssstart.c', 'src/snd/sstable.c', 'src/snd/sstick.c', 'src/snd/ssvol.c', diff --git a/src/snd/libsnd_i.h b/src/snd/libsnd_i.h index 4cd6cef..ba6fa6d 100644 --- a/src/snd/libsnd_i.h +++ b/src/snd/libsnd_i.h @@ -27,7 +27,7 @@ extern u8 D_80032F02; void EnterCriticalSection(void); void VSyncCallback(void (*func)()); void ExitCriticalSection(void); -void InterruptCallback(s32, s32); +void* InterruptCallback(u8, void (*)()); void ResetCallback(); void SpuInit(); void _SsInit(); @@ -225,17 +225,17 @@ extern s16 D_80032F0C; s32 GetVideoMode(); extern s32 VBLANK_MINUS; - struct SndSeqTickEnv { s32 unk0; s32 unk4; - u32 unk8; - u32 unk12; + void (*unk8)(); + void (*unk12)(); u8 unk16; u8 unk17; u8 unk18; + u8 unk19; + u32 unk20; }; - extern struct SndSeqTickEnv _snd_seq_tick_env; s32 SpuVmSeqKeyOff(s32); diff --git a/src/snd/ssstart.c b/src/snd/ssstart.c new file mode 100644 index 0000000..aa37654 --- /dev/null +++ b/src/snd/ssstart.c @@ -0,0 +1,121 @@ +#include "libsnd_i.h" + +struct SndSeqTickEnv _snd_seq_tick_env = { + 0x3c, /* 0x0000000080032ef0 */ + 0x1, /* 0x0000000080032ef4 */ + SsSeqCalledTbyT, /* 0x0000000080032ef8 */ + 0, /* 0x0000000080032efc */ + 0, /* 0x0000000080032f00 */ + 0, /* 0x0000000080032f01 */ + 0xff, /* 0x0000000080032f02 */ + 0, /* 0x0000000080032f03 */ + 0 /* 0x0000000080032f04 */ +}; + +void _SsSeqCalledTbyT_1per2(); +void _SsTrapIntrVSync(); + +static void _SsStart(s32 arg0) { + u16 rcnt_target; + s32 wait; + unsigned short var_v0_2; + u32 rcnt_spec; + u8 temp_a0; + void (*callback_func)(); + s32 temp; + s32 temp2; + s32 temp3; + wait = 999; + do { + wait -= 1; + } while (wait >= 0); + _snd_seq_tick_env.unk16 = 0; + _snd_seq_tick_env.unk18 = 6; + _snd_seq_tick_env.unk17 = 0; + _snd_seq_tick_env.unk12 = 0; + rcnt_spec = 0xF2000002; + switch (_snd_seq_tick_env.unk0) { + case 0: + _snd_seq_tick_env.unk18 = 0xFF; + return; + + case 5: + _snd_seq_tick_env.unk18 = 0; + if (arg0 == 0) { + _snd_seq_tick_env.unk16 = 1; + } else { + rcnt_spec = 0xF2000003; + rcnt_target = 1; + } + break; + + case 3: + rcnt_target = 0x89D0U; + break; + + case 2: + rcnt_target = 0x44E8; + break; + + default: + if (_snd_seq_tick_env.unk4 == 0) { + if (_snd_seq_tick_env.unk0 < 0x46) { + var_v0_2 = 0x204CC0 / _snd_seq_tick_env.unk0; + _snd_seq_tick_env.unk17++; + } else { + var_v0_2 = 0x409980 / _snd_seq_tick_env.unk0; + } + rcnt_target = var_v0_2; + } else { + return; + } + break; + } + + temp2 = _snd_seq_tick_env.unk16; + if (temp2 != 0) { + EnterCriticalSection(); + VSyncCallback(_snd_seq_tick_env.unk8); + } else { + EnterCriticalSection(); + ResetRCnt(rcnt_spec); + SetRCnt(rcnt_spec, rcnt_target & 0xFFFF, 0x1000); + temp_a0 = _snd_seq_tick_env.unk18; + if (temp_a0 == 0) { + temp3 = InterruptCallback(0U, 0); + callback_func = _SsTrapIntrVSync; + temp_a0 = _snd_seq_tick_env.unk18; + _snd_seq_tick_env.unk12 = temp3; + } else { + callback_func = _SsSeqCalledTbyT_1per2; + if (_snd_seq_tick_env.unk17 == 0) { + callback_func = _snd_seq_tick_env.unk8; + } + } + InterruptCallback(temp_a0, callback_func); + } + ExitCriticalSection(); + return; +} + +void SsStart(void) { _SsStart(1); } + +void SsStart2(void) { _SsStart(0); } + +static void _SsTrapIntrVSync(void) { + if (_snd_seq_tick_env.unk12 != NULL) { + _snd_seq_tick_env.unk12(); + } + _snd_seq_tick_env.unk8(); +} + +static inline s32 get20() { return _snd_seq_tick_env.unk20; } + +static void _SsSeqCalledTbyT_1per2(void) { + if (get20() == 0) { + _snd_seq_tick_env.unk20 = 1; + return; + } + _snd_seq_tick_env.unk20 = 0; + _snd_seq_tick_env.unk8(); +} \ No newline at end of file