diff --git a/asm/Kyoto/Graphics/CColor.s b/asm/Kyoto/Graphics/CColor.s index 81564b02..07d2fe42 100644 --- a/asm/Kyoto/Graphics/CColor.s +++ b/asm/Kyoto/Graphics/CColor.s @@ -7,69 +7,69 @@ lbl_ctor: .section .sbss, "wa" .balign 8 -.global lbl_805A9568 -lbl_805A9568: +.global sBlackColor__6CColor +sBlackColor__6CColor: .skip 0x4 -.global lbl_805A956C -lbl_805A956C: +.global sWhiteColor__6CColor +sWhiteColor__6CColor: .skip 0x4 -.global lbl_805A9570 -lbl_805A9570: +.global sGreyColor__6CColor +sGreyColor__6CColor: .skip 0x4 -.global lbl_805A9574 -lbl_805A9574: +.global sRedColor__6CColor +sRedColor__6CColor: .skip 0x4 -.global lbl_805A9578 -lbl_805A9578: +.global sGreenColor__6CColor +sGreenColor__6CColor: .skip 0x4 -.global lbl_805A957C -lbl_805A957C: +.global sBlueColor__6CColor +sBlueColor__6CColor: .skip 0x4 -.global lbl_805A9580 -lbl_805A9580: +.global sYellowColor__6CColor +sYellowColor__6CColor: .skip 0x4 -.global lbl_805A9584 -lbl_805A9584: +.global sPurpleColor__6CColor +sPurpleColor__6CColor: .skip 0x4 -.global lbl_805A9588 -lbl_805A9588: +.global sOrangeColor__6CColor +sOrangeColor__6CColor: .skip 0x8 .section .text, "ax" .global Orange__6CColorFv Orange__6CColorFv: -/* 80349F84 00346EE4 38 6D A9 C8 */ addi r3, r13, lbl_805A9588@sda21 +/* 80349F84 00346EE4 38 6D A9 C8 */ addi r3, r13, sOrangeColor__6CColor@sda21 /* 80349F88 00346EE8 4E 80 00 20 */ blr .global Yellow__6CColorFv Yellow__6CColorFv: -/* 80349F8C 00346EEC 38 6D A9 C0 */ addi r3, r13, lbl_805A9580@sda21 +/* 80349F8C 00346EEC 38 6D A9 C0 */ addi r3, r13, sYellowColor__6CColor@sda21 /* 80349F90 00346EF0 4E 80 00 20 */ blr .global Blue__6CColorFv Blue__6CColorFv: -/* 80349F94 00346EF4 38 6D A9 BC */ addi r3, r13, lbl_805A957C@sda21 +/* 80349F94 00346EF4 38 6D A9 BC */ addi r3, r13, sBlueColor__6CColor@sda21 /* 80349F98 00346EF8 4E 80 00 20 */ blr .global Red__6CColorFv Red__6CColorFv: -/* 80349F9C 00346EFC 38 6D A9 B4 */ addi r3, r13, lbl_805A9574@sda21 +/* 80349F9C 00346EFC 38 6D A9 B4 */ addi r3, r13, sRedColor__6CColor@sda21 /* 80349FA0 00346F00 4E 80 00 20 */ blr .global Grey__6CColorFv Grey__6CColorFv: -/* 80349FA4 00346F04 38 6D A9 B0 */ addi r3, r13, lbl_805A9570@sda21 +/* 80349FA4 00346F04 38 6D A9 B0 */ addi r3, r13, sGreyColor__6CColor@sda21 /* 80349FA8 00346F08 4E 80 00 20 */ blr .global White__6CColorFv White__6CColorFv: -/* 80349FAC 00346F0C 38 6D A9 AC */ addi r3, r13, lbl_805A956C@sda21 +/* 80349FAC 00346F0C 38 6D A9 AC */ addi r3, r13, sWhiteColor__6CColor@sda21 /* 80349FB0 00346F10 4E 80 00 20 */ blr .global Black__6CColorFv Black__6CColorFv: -/* 80349FB4 00346F14 38 6D A9 A8 */ addi r3, r13, lbl_805A9568@sda21 +/* 80349FB4 00346F14 38 6D A9 A8 */ addi r3, r13, sBlackColor__6CColor@sda21 /* 80349FB8 00346F18 4E 80 00 20 */ blr .global __sinit_CColor_cpp @@ -90,13 +90,13 @@ __sinit_CColor_cpp: /* 80349FF0 00346F50 38 03 00 FF */ addi r0, r3, 0xFF7000FF@l /* 80349FF4 00346F54 39 40 00 FF */ li r10, 0xff /* 80349FF8 00346F58 38 60 FF FF */ li r3, -1 -/* 80349FFC 00346F5C 91 4D A9 A8 */ stw r10, lbl_805A9568@sda21(r13) -/* 8034A000 00346F60 90 6D A9 AC */ stw r3, lbl_805A956C@sda21(r13) -/* 8034A004 00346F64 91 2D A9 B0 */ stw r9, lbl_805A9570@sda21(r13) -/* 8034A008 00346F68 91 0D A9 B4 */ stw r8, lbl_805A9574@sda21(r13) -/* 8034A00C 00346F6C 90 ED A9 B8 */ stw r7, lbl_805A9578@sda21(r13) -/* 8034A010 00346F70 90 CD A9 BC */ stw r6, lbl_805A957C@sda21(r13) -/* 8034A014 00346F74 90 AD A9 C0 */ stw r5, lbl_805A9580@sda21(r13) -/* 8034A018 00346F78 90 8D A9 C4 */ stw r4, lbl_805A9584@sda21(r13) -/* 8034A01C 00346F7C 90 0D A9 C8 */ stw r0, lbl_805A9588@sda21(r13) +/* 80349FFC 00346F5C 91 4D A9 A8 */ stw r10, sBlackColor__6CColor@sda21(r13) +/* 8034A000 00346F60 90 6D A9 AC */ stw r3, sWhiteColor__6CColor@sda21(r13) +/* 8034A004 00346F64 91 2D A9 B0 */ stw r9, sGreyColor__6CColor@sda21(r13) +/* 8034A008 00346F68 91 0D A9 B4 */ stw r8, sRedColor__6CColor@sda21(r13) +/* 8034A00C 00346F6C 90 ED A9 B8 */ stw r7, sGreenColor__6CColor@sda21(r13) +/* 8034A010 00346F70 90 CD A9 BC */ stw r6, sBlueColor__6CColor@sda21(r13) +/* 8034A014 00346F74 90 AD A9 C0 */ stw r5, sYellowColor__6CColor@sda21(r13) +/* 8034A018 00346F78 90 8D A9 C4 */ stw r4, sPurpleColor__6CColor@sda21(r13) +/* 8034A01C 00346F7C 90 0D A9 C8 */ stw r0, sOrangeColor__6CColor@sda21(r13) /* 8034A020 00346F80 4E 80 00 20 */ blr diff --git a/asm/musyx/snd_synthapi.s b/asm/musyx/snd_synthapi.s index 86f34e0c..3db71a7f 100644 --- a/asm/musyx/snd_synthapi.s +++ b/asm/musyx/snd_synthapi.s @@ -330,7 +330,7 @@ lbl_8039C5E4: /* 8039C608 00399568 4B FF 87 29 */ bl seqGetPrivateId /* 8039C60C 0039956C 3C A0 80 55 */ lis r5, synthAuxBCallback@ha /* 8039C610 00399570 3C 80 80 55 */ lis r4, synthAuxBUser@ha -/* 8039C614 00399574 38 CD AE 4C */ addi r6, r13, synthAuxBMidiSet@sda21 +/* 8039C614 00399574 38 CD AE 4C */ addi r6, r13, synthAuxBMIDISet@sda21 /* 8039C618 00399578 57 00 10 3A */ slwi r0, r24, 2 /* 8039C61C 0039957C 38 A5 0A 84 */ addi r5, r5, synthAuxBCallback@l /* 8039C620 00399580 38 84 0A 64 */ addi r4, r4, synthAuxBUser@l diff --git a/asm/musyx/synth.s b/asm/musyx/synth.s index e60417a0..7ae7f6df 100644 --- a/asm/musyx/synth.s +++ b/asm/musyx/synth.s @@ -120,8 +120,8 @@ sndActive: .global synthJobTableIndex synthJobTableIndex: .skip 0x3 -.global synthAuxBMidiSet -synthAuxBMidiSet: +.global synthAuxBMIDISet +synthAuxBMIDISet: .skip 0x8 .global synthAuxBMIDI synthAuxBMIDI: @@ -2582,7 +2582,7 @@ lbl_8039AEEC: /* 8039AF00 00397E60 3B 6D AE 64 */ addi r27, r13, synthAuxAMIDI@sda21 /* 8039AF04 00397E64 3B 8D AE 5C */ addi r28, r13, synthAuxAMIDISet@sda21 /* 8039AF08 00397E68 3B ED AE 54 */ addi r31, r13, synthAuxBMIDI@sda21 -/* 8039AF0C 00397E6C 3B 0D AE 4C */ addi r24, r13, synthAuxBMidiSet@sda21 +/* 8039AF0C 00397E6C 3B 0D AE 4C */ addi r24, r13, synthAuxBMIDISet@sda21 lbl_8039AF10: /* 8039AF10 00397E70 88 1B 00 00 */ lbz r0, 0(r27) /* 8039AF14 00397E74 28 00 00 FF */ cmplwi r0, 0xff diff --git a/include/musyx/musyx.h b/include/musyx/musyx.h index 6df2be59..cdc26f34 100644 --- a/include/musyx/musyx.h +++ b/include/musyx/musyx.h @@ -76,6 +76,29 @@ typedef struct SND_FMATRIX { f32 t[3]; } SND_FMATRIX; +s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize); +void sndQuit(void); + +bool sndIsInstalled(); +bool sndIsIdle(); +SND_PLAYBACKINFO* sndGetPlayBackInfo(); + +void sndSetMaxVoices(u8 music, u8 sfx); + +#define SND_USERMUSIC_VOLGROUPS 0xFA +#define SND_USERFX_VOLGROUPS 0xFB +#define SND_USERALL_VOLGROUPS 0xFC +#define SND_MUSIC_VOLGROUPS 0xFD +#define SND_FX_VOLGROUPS 0xFE +#define SND_ALL_VOLGROUPS 0xFF + +#define SND_MAX_USER_VOLGROUP 20 + +void sndVolume(u8 volume, u16 time, u8 volGroup); +void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx); +void sndOutputMode(SND_OUTPUTMODE mode); +void sndSilence(); + #define SND_AUX_NUMPARAMETERS 4 #define SND_AUX_REASON_BUFFERUPDATE 0 @@ -204,14 +227,14 @@ typedef struct SND_PARAMETER_INFO { } SND_PARAMETER_INFO; -#define sndFXStart(fid,vol,pan) sndFXStartEx(fid,vol,pan,SND_STUDIO_DEFAULT) -SND_VOICEID sndFXStartEx(SND_FXID fid,u8 vol,u8 pan,u8 studio); -SND_VOICEID sndFXStartPara(SND_FXID fid,u8 vol,u8 pan,u8 studio,u8 numPara,...); -SND_VOICEID sndFXStartParaInfo(SND_FXID fid,u8 vol,u8 pan,u8 studio,SND_PARAMETER_INFO *paraInfo); +#define sndFXStart(fid, vol, pan) sndFXStartEx(fid, vol, pan, SND_STUDIO_DEFAULT) +SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio); +SND_VOICEID sndFXStartPara(SND_FXID fid, u8 vol, u8 pan, u8 studio, u8 numPara, ...); +SND_VOICEID sndFXStartParaInfo(SND_FXID fid, u8 vol, u8 pan, u8 studio, SND_PARAMETER_INFO* paraInfo); SND_VOICEID sndFXCheck(SND_VOICEID vid); bool sndFXKeyOff(SND_VOICEID vid); -bool sndFXCtrl(SND_VOICEID vid,u8 ctrl,u8 value); -bool sndFXCtrl14(SND_VOICEID vid,u8 ctrl,u16 value); +bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value); +bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value); #ifdef __cplusplus } diff --git a/include/musyx/musyx_priv.h b/include/musyx/musyx_priv.h index e9a1e81c..4f80a999 100644 --- a/include/musyx/musyx_priv.h +++ b/include/musyx/musyx_priv.h @@ -38,6 +38,9 @@ void sndConvertMs(u32* time); void sndConvertTicks(u32* out, u32 seconds); u32 sndConvert2Ms(u32 time); +void hwDeactivateStudio(u8); +u32 hwIsActive(s32); + extern SND_HOOKS salHooks; /* Math */ @@ -46,6 +49,11 @@ float salNormalizeVector(SND_FVECTOR* vec); void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR* b); void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in); + +/* hardware */ +/* TODO: Figure out what `unk` is */ +bool hwAddInput(u8 studio, void* unk); +bool hwRemoveInput(u8 studio, void* unk); #ifdef __cplusplus } #endif diff --git a/include/musyx/synth.h b/include/musyx/synth.h new file mode 100644 index 00000000..030bebfb --- /dev/null +++ b/include/musyx/synth.h @@ -0,0 +1,50 @@ +#ifndef __SYNTH_H__ +#define __SYNTH_H__ + +#include "musyx/musyx_priv.h" +#ifndef __cplusplus +extern "C" { +#endif + +typedef struct SynthVoice { + char data1[0xf4]; + u32 _f4; + VoiceID* voiceId; + char data2[0x18]; + u32 _114[2]; + u8 _11c; + u8 _11d; + u8 _11e; + u8 studio; + char data3[0x404 - 0x120]; +} SynthVoice; + +typedef void (*SND_AUX_CALLBACK)(u8 reason, SND_AUX_INFO * info, void * user); + +extern SND_AUX_CALLBACK synthAuxACallback[8]; +extern u8 synthAuxAMIDI[8]; +extern u8 synthAuxAMIDISet[8]; +extern void* synthAuxAUser[8]; +extern SND_AUX_CALLBACK synthAuxBCallback[8]; +extern u8 synthAuxBMIDI[8]; +extern u8 synthAuxBMIDISet[8]; +extern void* synthAuxBUser[8]; + +s32 vidGetInternalId(SND_VOICEID id); +bool synthFXSetCtrl(SND_VOICEID vid, u8 ctrl, u8 value); +bool synthFXSetCtrl14(SND_VOICEID vid, u8 ctrl, u16 value); +bool synthSendKeyOff(SND_VOICEID vid); +SND_VOICEID synthFXStart(SND_FXID fid, u8 vol, u8 pan, u8 studio, u8); +void synthVolume(u8 volume, u16 time, u8 volgroup2, s32, s32); + + +/* TODO: Move this where it belongs */ +void hwSetAUXProcessingCallbacks(u8 studio, + SND_AUX_CALLBACK auxA, void * userA, + SND_AUX_CALLBACK auxB, void * userB); +#ifndef __cplusplus +} +#endif + +#endif // __SYNTH_H__ + diff --git a/src/musyx/snd_init.c b/src/musyx/snd_init.c index 61c7f4f2..13ca05cc 100644 --- a/src/musyx/snd_init.c +++ b/src/musyx/snd_init.c @@ -9,7 +9,7 @@ extern s8 sndActive; extern s8 synthIdleWaitActive; extern SynthInfo synthInfo; -inline bool DoInit(u32 rate, u32 aramSize, u8 voices, u32 flags) { +s32 DoInit(u32 rate, u32 aramSize, u8 voices, u32 flags) { dataInitStack(); dataInit(0, aramSize); seqInit(); @@ -23,17 +23,17 @@ inline bool DoInit(u32 rate, u32 aramSize, u8 voices, u32 flags) { return FALSE; } -bool sndInit(u8 voices, u8 music, u8 sfx, u8 studios, s32 flags, s32 aramSize) { +s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize) { s32 rate; s32 ret; sndActive = 0; - if (64 >= voices) { + if (voices <= 64) { synthInfo.voices = voices; } else { synthInfo.voices = 64; } - if (8 >= studios) { + if (studios <= 8) { synthInfo.studios = studios; } else { synthInfo.studios = 8; diff --git a/src/musyx/snd_synthapi.c b/src/musyx/snd_synthapi.c new file mode 100644 index 00000000..97645b33 --- /dev/null +++ b/src/musyx/snd_synthapi.c @@ -0,0 +1,140 @@ +#include "musyx/synth.h" + +bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value) { + bool ret; + + hwDisableIrq(); + ret = synthFXSetCtrl(vid, ctrl, value); + hwEnableIrq(); + return ret; +} + +bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value) { + bool ret; + + hwDisableIrq(); + ret = synthFXSetCtrl14(vid, ctrl, value); + hwEnableIrq(); + return ret; +} + +bool sndFXKeyOff(SND_VOICEID vid) { + bool ret; + + hwDisableIrq(); + ret = synthSendKeyOff(vid); + hwEnableIrq(); + return ret; +} + +SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio) { + SND_VOICEID temp_r31; + + hwDisableIrq(); + temp_r31 = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio * 2 + 1]); + hwEnableIrq(); + return temp_r31; +} + +s32 sndFXCheck(SND_VOICEID arg0) { + u32 check; + s32 ret; + check = vidGetInternalId(arg0); + + ret = -1; + if (check != -1) { + ret = arg0; + } + return ret; +} + +void sndVolume(u8 volume, u16 time, u8 volgroup) { + hwDisableIrq(); + synthVolume(volume, time, volgroup, 0, -1); + hwEnableIrq(); +} + +void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx) { + hwDisableIrq(); + if (music != 0) { + synthVolume(volume, time, 0x15, 0, -1); + } + if (fx != 0) { + synthVolume(volume, time, 0x16, 0, -1); + } + hwEnableIrq(); +} + +// sndOutputMode + +// clang-format off +void sndSetAuxProcessingCallbacks(u8 studio, + SND_AUX_CALLBACK auxA, void* userA, u8 midiA, SND_SEQID seqIDA, + SND_AUX_CALLBACK auxB, void* userB, u8 midiB, SND_SEQID seqIDB) { + // clang-format on + + hwDisableIrq(); + if (auxA != NULL) { + synthAuxAMIDI[studio] = midiA; + if (midiA != 0xFF) { + synthAuxAMIDISet[studio] = seqGetPrivateId(seqIDA); + synthAuxACallback[studio] = auxA; + synthAuxAUser[studio] = userA; + } + } else { + synthAuxACallback[studio] = NULL; + synthAuxAMIDI[studio] = 0xff; + } + + if (auxB != NULL) { + synthAuxBMIDI[studio] = midiB; + if (midiB != 0xFF) { + synthAuxBMidiSet[studio] = seqGetPrivateId(seqIDB); + synthAuxBCallback[studio] = auxB; + synthAuxBUser[studio] = userB; + } + } else { + synthAuxBCallback[studio] = NULL; + synthAuxBMIDI[studio] = 0xff; + } + + hwSetAUXProcessingCallbacks(studio, auxA, userA, auxB, userB); + hwEnableIrq(); +} + +void synthActivateStudio(u8 studio, u32 arg1, u32 arg2) { + hwDisableIrq(); + synthAuxACallback[studio] = NULL; + synthAuxBCallback[studio] = NULL; + synthAuxAMIDI[studio] = 0xFF; + synthAuxBMIDI[studio] = 0xFF; + synthITDDefault[studio * 2 + 1] = 0; + synthITDDefault[studio * 2 + 0] = 0; + hwActivateStudio(studio, arg1, arg2); + hwEnableIrq(); +} + +void synthDeactivateStudio(u8 studio) { + u32 i; + for (i = 0; i < synthInfo.voices; ++i) { + if (studio == synthVoice[i].studio) { + if (synthVoice[i]._f4 != 0xFFFFFFFF) { + voiceKillSound(synthVoice[i].voiceId->pubId); + } else if (hwIsActive(i)) { + hwOff(i); + } + } + } + hwDisableIrq(); + synthAuxACallback[studio] = 0; + synthAuxBCallback[studio] = 0; + synthAuxAMIDI[studio] = 0xFF; + synthAuxBMIDI[studio] = 0xFF; + hwEnableIrq(); + hwDeactivateStudio(studio); +} + +/* TODO: Figure out what `unk` is */ +bool synthAddStudioInput(u8 studio, void* unk) { + return hwAddInput(studio, unk); +}