diff --git a/lib/NitroSDK/asm/fx_atanidx.s b/lib/NitroSDK/asm/fx_atanidx.s new file mode 100644 index 00000000..ecc23456 --- /dev/null +++ b/lib/NitroSDK/asm/fx_atanidx.s @@ -0,0 +1,133 @@ + .include "asm/macros.inc" + .include "include/fx_vec.inc" + + .text + + arm_func_start FX_Atan2Idx +FX_Atan2Idx: ; 0x02075EC8 + stmdb sp!, {r4, lr} + cmp r0, #0 + ble _02075F5C + cmp r1, #0 + ble _02075F14 + cmp r1, r0 + ble _02075EF4 + mov r2, r0 + mov r4, #0 + mov r0, #1 + b _0207600C +_02075EF4: + bge _02075F0C + mov r2, r1 + mov r1, r0 + mov r4, #0x4000 + mov r0, #0 + b _0207600C +_02075F0C: + mov r0, #0x2000 + ldmia sp!, {r4, pc} +_02075F14: + bge _02075F54 + rsb r1, r1, #0 + cmp r1, r0 + bge _02075F38 + mov r2, r1 + mov r1, r0 + mov r4, #0x4000 + mov r0, #1 + b _0207600C +_02075F38: + ble _02075F4C + mov r2, r0 + mov r4, #0x8000 + mov r0, #0 + b _0207600C +_02075F4C: + mov r0, #0x6000 + ldmia sp!, {r4, pc} +_02075F54: + mov r0, #0x4000 + ldmia sp!, {r4, pc} +_02075F5C: + bge _02075FFC + cmp r1, #0 + rsb r0, r0, #0 + bge _02075FB0 + rsb r1, r1, #0 + cmp r1, r0 + ble _02075F8C + mov r4, #0x8000 + mov r2, r0 + rsb r4, r4, #0 + mov r0, #1 + b _0207600C +_02075F8C: + bge _02075FA8 + mov r4, #0x4000 + mov r2, r1 + mov r1, r0 + rsb r4, r4, #0 + mov r0, #0 + b _0207600C +_02075FA8: + mov r0, #0xa000 + ldmia sp!, {r4, pc} +_02075FB0: + cmp r1, #0 + ble _02075FF4 + cmp r1, r0 + bge _02075FD8 + mov r4, #0x4000 + mov r2, r1 + mov r1, r0 + rsb r4, r4, #0 + mov r0, #1 + b _0207600C +_02075FD8: + ble _02075FEC + mov r4, #0 + mov r2, r0 + mov r0, r4 + b _0207600C +_02075FEC: + mov r0, #0xe000 + ldmia sp!, {r4, pc} +_02075FF4: + mov r0, #0xc000 + ldmia sp!, {r4, pc} +_02075FFC: + cmp r1, #0 + movge r0, #0 + movlt r0, #0x8000 + ldmia sp!, {r4, pc} +_0207600C: + cmp r1, #0 + moveq r0, #0 + ldmeqia sp!, {r4, pc} + cmp r0, #0 + mov r0, r2 + beq _02076048 + bl FX_Div + mov r1, r0, asr #5 + ldr r0, _0207606C ; =FX_AtanIdxTable_ + mov r1, r1, lsl #1 + ldrsh r0, [r0, r1] + add r0, r4, r0 + mov r0, r0, lsl #0x10 + mov r0, r0, lsr #0x10 + ldmia sp!, {r4, pc} +_02076048: + bl FX_Div + mov r1, r0, asr #5 + ldr r0, _0207606C ; =FX_AtanIdxTable_ + mov r1, r1, lsl #1 + ldrsh r0, [r0, r1] + sub r0, r4, r0 + mov r0, r0, lsl #0x10 + mov r0, r0, lsr #0x10 + ldmia sp!, {r4, pc} + .align 2, 0 +_0207606C: .word FX_AtanIdxTable_ + arm_func_end FX_Atan2Idx + + diff --git a/lib/NitroSDK/asm/fx_fx.s b/lib/NitroSDK/asm/fx_fx.s new file mode 100644 index 00000000..4e31020a --- /dev/null +++ b/lib/NitroSDK/asm/fx_fx.s @@ -0,0 +1,9 @@ + .include "asm/macros.inc" + + .text + + arm_func_start FX_Init +FX_Init: ; 0x02076070 + bx lr + arm_func_end FX_Init + diff --git a/lib/NitroSDK/asm/fx_vec.s b/lib/NitroSDK/asm/fx_vec.s index 0de9e03c..1ed88384 100644 --- a/lib/NitroSDK/asm/fx_vec.s +++ b/lib/NitroSDK/asm/fx_vec.s @@ -173,134 +173,3 @@ _02075EC0: .word 0x040002B0 _02075EC4: .word 0x040002B4 arm_func_end VEC_Distance - arm_func_start FX_Atan2Idx -FX_Atan2Idx: ; 0x02075EC8 - stmdb sp!, {r4, lr} - cmp r0, #0 - ble _02075F5C - cmp r1, #0 - ble _02075F14 - cmp r1, r0 - ble _02075EF4 - mov r2, r0 - mov r4, #0 - mov r0, #1 - b _0207600C -_02075EF4: - bge _02075F0C - mov r2, r1 - mov r1, r0 - mov r4, #0x4000 - mov r0, #0 - b _0207600C -_02075F0C: - mov r0, #0x2000 - ldmia sp!, {r4, pc} -_02075F14: - bge _02075F54 - rsb r1, r1, #0 - cmp r1, r0 - bge _02075F38 - mov r2, r1 - mov r1, r0 - mov r4, #0x4000 - mov r0, #1 - b _0207600C -_02075F38: - ble _02075F4C - mov r2, r0 - mov r4, #0x8000 - mov r0, #0 - b _0207600C -_02075F4C: - mov r0, #0x6000 - ldmia sp!, {r4, pc} -_02075F54: - mov r0, #0x4000 - ldmia sp!, {r4, pc} -_02075F5C: - bge _02075FFC - cmp r1, #0 - rsb r0, r0, #0 - bge _02075FB0 - rsb r1, r1, #0 - cmp r1, r0 - ble _02075F8C - mov r4, #0x8000 - mov r2, r0 - rsb r4, r4, #0 - mov r0, #1 - b _0207600C -_02075F8C: - bge _02075FA8 - mov r4, #0x4000 - mov r2, r1 - mov r1, r0 - rsb r4, r4, #0 - mov r0, #0 - b _0207600C -_02075FA8: - mov r0, #0xa000 - ldmia sp!, {r4, pc} -_02075FB0: - cmp r1, #0 - ble _02075FF4 - cmp r1, r0 - bge _02075FD8 - mov r4, #0x4000 - mov r2, r1 - mov r1, r0 - rsb r4, r4, #0 - mov r0, #1 - b _0207600C -_02075FD8: - ble _02075FEC - mov r4, #0 - mov r2, r0 - mov r0, r4 - b _0207600C -_02075FEC: - mov r0, #0xe000 - ldmia sp!, {r4, pc} -_02075FF4: - mov r0, #0xc000 - ldmia sp!, {r4, pc} -_02075FFC: - cmp r1, #0 - movge r0, #0 - movlt r0, #0x8000 - ldmia sp!, {r4, pc} -_0207600C: - cmp r1, #0 - moveq r0, #0 - ldmeqia sp!, {r4, pc} - cmp r0, #0 - mov r0, r2 - beq _02076048 - bl FX_Div - mov r1, r0, asr #5 - ldr r0, _0207606C ; =FX_AtanIdxTable_ - mov r1, r1, lsl #1 - ldrsh r0, [r0, r1] - add r0, r4, r0 - mov r0, r0, lsl #0x10 - mov r0, r0, lsr #0x10 - ldmia sp!, {r4, pc} -_02076048: - bl FX_Div - mov r1, r0, asr #5 - ldr r0, _0207606C ; =FX_AtanIdxTable_ - mov r1, r1, lsl #1 - ldrsh r0, [r0, r1] - sub r0, r4, r0 - mov r0, r0, lsl #0x10 - mov r0, r0, lsr #0x10 - ldmia sp!, {r4, pc} - .align 2, 0 -_0207606C: .word FX_AtanIdxTable_ - arm_func_end FX_Atan2Idx - - arm_func_start FX_Init -FX_Init: ; 0x02076070 - bx lr - arm_func_end FX_Init diff --git a/lib/NitroSDK/asm/snd_bank.s b/lib/NitroSDK/asm/snd_bank.s deleted file mode 100644 index 66153334..00000000 --- a/lib/NitroSDK/asm/snd_bank.s +++ /dev/null @@ -1,316 +0,0 @@ - .include "asm/macros.inc" - .include "include/nitro.inc" - - .text - - arm_func_start Snd_AssignWaveArc -Snd_AssignWaveArc: ; 0x0207D5B0 - stmdb sp!, {r4, r5, r6, lr} - mov r6, r0 - mov r5, r1 - mov r4, r2 - bl Sndi_LockMutex - add r3, r6, r5, lsl #3 - ldr r2, [r3, #0x18] - cmp r2, #0 - beq _0207D640 - cmp r4, r2 - bne _0207D5E4 - bl Sndi_UnlockMutex - ldmia sp!, {r4, r5, r6, pc} -_0207D5E4: - add r1, r6, #0x18 - ldr r0, [r2, #0x18] - add ip, r1, r5, lsl #3 - cmp ip, r0 - bne _0207D610 - ldr r0, [r3, #0x1c] - mov r1, #0x3c - str r0, [r2, #0x18] - ldr r0, [r3, #0x18] - bl DC_StoreRange - b _0207D640 -_0207D610: - cmp r0, #0 - beq _0207D62C -_0207D618: - ldr r1, [r0, #4] - cmp ip, r1 - movne r0, r1 - cmpne r1, #0 - bne _0207D618 -_0207D62C: - add r1, r6, r5, lsl #3 - ldr r2, [r1, #0x1c] - mov r1, #8 - str r2, [r0, #4] - bl DC_StoreRange -_0207D640: - add r0, r6, #0x18 - ldr r1, [r4, #0x18] - add r0, r0, r5, lsl #3 - str r0, [r4, #0x18] - add r0, r6, r5, lsl #3 - str r1, [r0, #0x1c] - str r4, [r0, #0x18] - bl Sndi_UnlockMutex - mov r0, r6 - mov r1, #0x3c - bl DC_StoreRange - mov r0, r4 - mov r1, #0x3c - bl DC_StoreRange - ldmia sp!, {r4, r5, r6, pc} - arm_func_end Snd_AssignWaveArc - - arm_func_start Snd_DestroyBank -Snd_DestroyBank: ; 0x0207D67C - stmdb sp!, {r4, r5, r6, r7, r8, lr} - mov r7, r0 - bl Sndi_LockMutex - add r5, r7, #0x18 - mov r6, #0 - mov r8, #8 - mov r4, #0x3c -_0207D698: - add r1, r7, r6, lsl #3 - ldr r0, [r1, #0x18] - cmp r0, #0 - beq _0207D6FC - ldr r3, [r0, #0x18] - cmp r5, r3 - bne _0207D6C8 - ldr r2, [r1, #0x1c] - mov r1, r4 - str r2, [r0, #0x18] - bl DC_StoreRange - b _0207D6FC -_0207D6C8: - cmp r3, #0 - beq _0207D6E4 -_0207D6D0: - ldr r0, [r3, #4] - cmp r5, r0 - movne r3, r0 - cmpne r0, #0 - bne _0207D6D0 -_0207D6E4: - add r0, r7, r6, lsl #3 - ldr r2, [r0, #0x1c] - mov r0, r3 - mov r1, r8 - str r2, [r3, #4] - bl DC_StoreRange -_0207D6FC: - add r6, r6, #1 - cmp r6, #4 - add r5, r5, #8 - blt _0207D698 - bl Sndi_UnlockMutex - ldmia sp!, {r4, r5, r6, r7, r8, pc} - arm_func_end Snd_DestroyBank - - arm_func_start Snd_DestroyWaveArc -Snd_DestroyWaveArc: ; 0x0207D714 - stmdb sp!, {r4, r5, r6, lr} - mov r4, r0 - bl Sndi_LockMutex - ldr r0, [r4, #0x18] - cmp r0, #0 - beq _0207D754 - mov r5, #0 - mov r4, #8 -_0207D734: - ldr r6, [r0, #4] - mov r1, r4 - str r5, [r0] - str r5, [r0, #4] - bl DC_StoreRange - mov r0, r6 - cmp r6, #0 - bne _0207D734 -_0207D754: - bl Sndi_UnlockMutex - ldmia sp!, {r4, r5, r6, pc} - arm_func_end Snd_DestroyWaveArc - - arm_func_start Snd_GetFirstInstDataPos -Snd_GetFirstInstDataPos: ; 0x0207D75C - sub sp, sp, #8 - mov r1, #0 - str r1, [r0] - str r1, [sp] - str r1, [sp, #4] - str r1, [r0, #4] - add sp, sp, #8 - bx lr - arm_func_end Snd_GetFirstInstDataPos - - arm_func_start Snd_GetNextInstData -Snd_GetNextInstData: ; 0x0207D77C - stmdb sp!, {r3, r4, r5, lr} - ldr r4, [r2] - ldr r3, [r0, #0x38] - cmp r4, r3 - bhs _0207D924 - mov ip, #0 -_0207D794: - add r3, r0, r4, lsl #2 - ldr r4, [r3, #0x3c] - and r3, r4, #0xff - strb r4, [r1] - cmp r3, #0x10 - mov r4, r4, lsr #8 - bgt _0207D7DC - cmp r3, #0x10 - bge _0207D828 - cmp r3, #5 - addls pc, pc, r3, lsl #2 - b _0207D908 -_0207D7C4: ; jump table - b _0207D908 ; case 0 - b _0207D7E8 ; case 1 - b _0207D7E8 ; case 2 - b _0207D7E8 ; case 3 - b _0207D7E8 ; case 4 - b _0207D7E8 ; case 5 -_0207D7DC: - cmp r3, #0x11 - beq _0207D89C - b _0207D908 -_0207D7E8: - add r5, r0, r4 - ldrh r4, [r0, r4] - ldrh r3, [r5, #2] - mov r0, #1 - strh r4, [r1, #2] - strh r3, [r1, #4] - ldrh r4, [r5, #4] - ldrh r3, [r5, #6] - strh r4, [r1, #6] - strh r3, [r1, #8] - ldrh r3, [r5, #8] - strh r3, [r1, #0xa] - ldr r1, [r2] - add r1, r1, #1 - str r1, [r2] - ldmia sp!, {r3, r4, r5, pc} -_0207D828: - add r5, r0, r4 - b _0207D87C -_0207D830: - mov r0, #0xc - mla ip, lr, r0, r5 - ldrh r4, [ip, #2] - ldrh r3, [ip, #4] - mov r0, #1 - strh r4, [r1] - strh r3, [r1, #2] - ldrh r4, [ip, #6] - ldrh r3, [ip, #8] - strh r4, [r1, #4] - strh r3, [r1, #6] - ldrh r4, [ip, #0xa] - ldrh r3, [ip, #0xc] - strh r4, [r1, #8] - strh r3, [r1, #0xa] - ldr r1, [r2, #4] - add r1, r1, #1 - str r1, [r2, #4] - ldmia sp!, {r3, r4, r5, pc} -_0207D87C: - ldrb r4, [r5, #1] - ldrb r3, [r5] - ldr lr, [r2, #4] - sub r3, r4, r3 - add r3, r3, #1 - cmp lr, r3 - blo _0207D830 - b _0207D908 -_0207D89C: - add r4, r0, r4 - b _0207D8FC -_0207D8A4: - ldrb lr, [r4, r3] - cmp lr, #0 - beq _0207D908 - mov r0, #0xc - mla lr, r3, r0, r4 - ldrh ip, [lr, #8] - ldrh r3, [lr, #0xa] - mov r0, #1 - strh ip, [r1] - strh r3, [r1, #2] - ldrh ip, [lr, #0xc] - ldrh r3, [lr, #0xe] - strh ip, [r1, #4] - strh r3, [r1, #6] - ldrh ip, [lr, #0x10] - ldrh r3, [lr, #0x12] - strh ip, [r1, #8] - strh r3, [r1, #0xa] - ldr r1, [r2, #4] - add r1, r1, #1 - str r1, [r2, #4] - ldmia sp!, {r3, r4, r5, pc} -_0207D8FC: - ldr r3, [r2, #4] - cmp r3, #8 - blo _0207D8A4 -_0207D908: - ldr r3, [r2] - add r3, r3, #1 - stmia r2, {r3, ip} - ldr r4, [r2] - ldr r3, [r0, #0x38] - cmp r4, r3 - blo _0207D794 -_0207D924: - mov r0, #0 - ldmia sp!, {r3, r4, r5, pc} - arm_func_end Snd_GetNextInstData - - arm_func_start Snd_GetWaveDataCount -Snd_GetWaveDataCount: ; 0x0207D92C - ldr r0, [r0, #0x38] - bx lr - arm_func_end Snd_GetWaveDataCount - - arm_func_start Snd_SetWaveDataAddress -Snd_SetWaveDataAddress: ; 0x0207D934 - stmdb sp!, {r4, r5, r6, lr} - mov r6, r0 - mov r5, r1 - mov r4, r2 - bl Sndi_LockMutex - add r0, r6, #0x3c - add r2, r6, r5, lsl #2 - add r0, r0, r5, lsl #2 - mov r1, #4 - str r4, [r2, #0x3c] - bl DC_StoreRange - bl Sndi_UnlockMutex - ldmia sp!, {r4, r5, r6, pc} - arm_func_end Snd_SetWaveDataAddress - - arm_func_start Snd_GetWaveDataAddress -Snd_GetWaveDataAddress: ; 0x0207D968 - stmdb sp!, {r3, r4, r5, lr} - mov r5, r0 - mov r4, r1 - bl Sndi_LockMutex - add r0, r5, r4, lsl #2 - ldr r4, [r0, #0x3c] - cmp r4, #0 - beq _0207D994 - cmp r4, #0x2000000 - addlo r4, r5, r4 - b _0207D998 -_0207D994: - mov r4, #0 -_0207D998: - bl Sndi_UnlockMutex - mov r0, r4 - ldmia sp!, {r3, r4, r5, pc} - arm_func_end Snd_GetWaveDataAddress - diff --git a/lib/NitroSDK/src/snd/snd_bank.c b/lib/NitroSDK/src/snd/snd_bank.c new file mode 100644 index 00000000..215fe1f9 --- /dev/null +++ b/lib/NitroSDK/src/snd/snd_bank.c @@ -0,0 +1,502 @@ +#include + +static u8 MI_ReadByte (const void * address) +{ + return *(u8 *)address; +} + +#ifdef _MSC_VER + #pragma warning(disable : 4018) + #pragma warning(disable : 4311) + #pragma warning(disable : 4312) +#endif + +static const SNDWaveData * GetWaveData(const SNDBankData * bank, int waveArcNo, int waveIndex); + +void Snd_AssignWaveArc (SNDBankData * bank, int index, SNDWaveArc * waveArc) +{ + SNDWaveArcLink * next; + SNDWaveArcLink * prev; + + SDK_NULL_ASSERT(bank); + SDK_NULL_ASSERT(waveArc); +#ifdef SDK_ARM9 + SDK_ASSERTMSG(((u32)bank & 0x1f) == 0, "bank address must be aligned 32 bytes boundary."); + SDK_ASSERTMSG(((u32)waveArc & 0x1f) == 0, "waveArc address must be aligned 32 bytes boundary."); +#endif + SDK_MINMAX_ASSERT(index, 0, SND_BANK_TO_WAVEARC_MAX - 1); + + Sndi_LockMutex(); + + if (bank->waveArcLink[index].waveArc != NULL) { + if (waveArc == bank->waveArcLink[index].waveArc) { + Sndi_UnlockMutex(); + return; + } + + if (&bank->waveArcLink[index] == bank->waveArcLink[index].waveArc->topLink) { + bank->waveArcLink[index].waveArc->topLink = bank->waveArcLink[index].next; + +#ifdef SDK_ARM9 + DC_StoreRange(bank->waveArcLink[index].waveArc, sizeof(SNDWaveArc)); +#endif + } else { + prev = bank->waveArcLink[index].waveArc->topLink; + while (prev != NULL) { + if (&bank->waveArcLink[index] == prev->next) + break; + prev = prev->next; + } + SDK_NULL_ASSERT(prev); + prev->next = bank->waveArcLink[index].next; + +#ifdef SDK_ARM9 + DC_StoreRange(prev, sizeof(SNDWaveArcLink)); +#endif + } + } + + next = waveArc->topLink; + waveArc->topLink = &bank->waveArcLink[index]; + bank->waveArcLink[index].next = next; + bank->waveArcLink[index].waveArc = waveArc; + + Sndi_UnlockMutex(); + +#ifdef SDK_ARM9 + DC_StoreRange(bank, sizeof(SNDBankData)); + DC_StoreRange(waveArc, sizeof(SNDWaveArc)); +#endif +} + +void Snd_DestroyBank (SNDBankData * bank) +{ + SNDWaveArc * waveArc; + SNDWaveArcLink * prev; + int i; + + SDK_NULL_ASSERT(bank); +#ifdef SDK_ARM9 + SDK_ASSERTMSG(((u32)bank & 0x1f) == 0, "bank address must be aligned 32 bytes boundary."); +#endif + + Sndi_LockMutex(); + + for (i = 0; i < SND_BANK_TO_WAVEARC_MAX; i++) { + waveArc = bank->waveArcLink[i].waveArc; + if (waveArc == NULL) + continue; + + if (&bank->waveArcLink[i] == waveArc->topLink) { + waveArc->topLink = bank->waveArcLink[i].next; + +#ifdef SDK_ARM9 + DC_StoreRange(waveArc, sizeof(SNDWaveArc)); +#endif + } else { + prev = waveArc->topLink; + while (prev != NULL) { + if (&bank->waveArcLink[i] == prev->next) + break; + prev = prev->next; + } + SDK_NULL_ASSERT(prev); + prev->next = bank->waveArcLink[i].next; + +#ifdef SDK_ARM9 + DC_StoreRange(prev, sizeof(SNDWaveArcLink)); +#endif + } + } + + Sndi_UnlockMutex(); +} + +void Snd_DestroyWaveArc (SNDWaveArc * waveArc) +{ + SNDWaveArcLink * link; + SNDWaveArcLink * next; + + SDK_NULL_ASSERT(waveArc); +#ifdef SDK_ARM9 + SDK_ASSERTMSG(((u32)waveArc & 0x1f) == 0, "waveArc address must be aligned 32 bytes boundary."); +#endif + + Sndi_LockMutex(); + + link = waveArc->topLink; + while (link != NULL) { + next = link->next; + + link->waveArc = NULL; + link->next = NULL; + +#ifdef SDK_ARM9 + DC_StoreRange(link, sizeof(SNDWaveArcLink)); +#endif + link = next; + } + + Sndi_UnlockMutex(); +} + +// BOOL Snd_ReadInstData (const SNDBankData * bank, int prgNo, int key, SNDInstData * inst) +// { +// u32 instOffset; +// +// SDK_NULL_ASSERT(bank); +// SDK_NULL_ASSERT(inst); +// +// if (prgNo < 0) +// return FALSE; +// +// #ifdef SDK_FROM_TOOL +// if (bank->fileHeader.signature[0] == 'S' && +// bank->fileHeader.signature[1] == 'B' && +// bank->fileHeader.signature[2] == 'C' && bank->fileHeader.signature[3] == 'B') { +// const SNDBankDataCallback * bankcb = (const SNDBankDataCallback *)bank; +// return bankcb->readInstDataFunc(bankcb, prgNo, key, inst); +// } +// #endif +// +// Sndi_LockMutex(); +// +// if (prgNo >= bank->instCount) { +// Sndi_UnlockMutex(); +// return FALSE; +// } +// +// instOffset = bank->instOffset[prgNo]; +// inst->type = (u8)(instOffset & 0xff); +// instOffset >>= 8; +// +// switch (inst->type) { +// case SND_INST_PCM: +// case SND_INST_PSG: +// case SND_INST_NOISE: +// case SND_INST_DIRECTPCM: +// case SND_INST_NULL: +// { +// const SNDInstParam * param = (const SNDInstParam *)((u8 *)bank + instOffset); +// +// inst->param = *param; +// break; +// } +// case SND_INST_DRUM_SET: +// { +// const SNDDrumSet * drumSet = (const SNDDrumSet *)((u8 *)bank + instOffset); +// u8 min = MI_ReadByte(&drumSet->min); +// u8 max = MI_ReadByte(&drumSet->max); +// +// if (key < min || key > max) { +// Sndi_UnlockMutex(); +// return FALSE; +// } +// +// *inst = drumSet->instOffset[key - min]; +// break; +// } +// case SND_INST_KEY_SPLIT: +// { +// int index = 0; +// const SNDKeySplit * keySplit = (const SNDKeySplit *)((u8 *)bank + instOffset); +// +// while (key > MI_ReadByte(&keySplit->key[index])) { +// index++; +// if (index >= SND_INST_KEYSPLIT_MAX) { +// Sndi_UnlockMutex(); +// return FALSE; +// } +// } +// +// *inst = keySplit->instOffset[index]; +// break; +// } +// case SND_INST_INVALID: +// default: +// Sndi_UnlockMutex(); +// return FALSE; +// } +// +// Sndi_UnlockMutex(); +// return TRUE; +// } + +// BOOL Snd_WriteInstData (SNDBankData * bank, int prgNo, int key, const struct SNDInstData * inst) +// { +// u32 instOffset; +// u8 type; +// +// SDK_NULL_ASSERT(bank); +// SDK_NULL_ASSERT(inst); +// +// if (prgNo < 0) +// return FALSE; +// +// Sndi_LockMutex(); +// +// if (prgNo >= bank->instCount) { +// Sndi_UnlockMutex(); +// return FALSE; +// } +// +// instOffset = bank->instOffset[prgNo]; +// type = (u8)(instOffset & 0xff); +// instOffset >>= 8; +// +// switch (type) { +// case SND_INST_PCM: +// case SND_INST_PSG: +// case SND_INST_NOISE: +// case SND_INST_DIRECTPCM: +// case SND_INST_NULL: +// { +// SNDInstParam * param = (SNDInstParam *)((u8 *)bank + instOffset); +// +// bank->instOffset[prgNo] = (instOffset << 8) | inst->type; +// *param = inst->param; +// break; +// } +// case SND_INST_DRUM_SET: +// { +// SNDDrumSet * drumSet = (SNDDrumSet *)((u8 *)bank + instOffset); +// u8 min = MI_ReadByte(&drumSet->min); +// u8 max = MI_ReadByte(&drumSet->max); +// +// if (key < min || key > max) { +// Sndi_UnlockMutex(); +// return FALSE; +// } +// +// drumSet->instOffset[key - min] = *inst; +// break; +// } +// case SND_INST_KEY_SPLIT: +// { +// int index = 0; +// SNDKeySplit * keySplit = (SNDKeySplit *)((u8 *)bank + instOffset); +// +// while (key > MI_ReadByte(&keySplit->key[index])) { +// index++; +// if (index >= SND_INST_KEYSPLIT_MAX) { +// Sndi_UnlockMutex(); +// return FALSE; +// } +// } +// +// keySplit->instOffset[index] = *inst; +// break; +// } +// case SND_INST_INVALID: +// default: +// Sndi_UnlockMutex(); +// return FALSE; +// } +// +// Sndi_UnlockMutex(); +// +// #ifdef SDK_ARM9 +// DC_StoreRange(bank, bank->fileHeader.fileSize); +// #endif +// +// return TRUE; +// } + +SNDInstPos Snd_GetFirstInstDataPos (const SNDBankData * bank) +{ + SNDInstPos pos; + + SDK_NULL_ASSERT(bank); + + (void)bank; + + pos.prgNo = 0; + pos.index = 0; + + return pos; +} + +BOOL Snd_GetNextInstData (const SNDBankData * bank, SNDInstData * inst, SNDInstPos * pos) +{ + SDK_NULL_ASSERT(bank); + SDK_NULL_ASSERT(inst); + SDK_NULL_ASSERT(pos); + + for (; pos->prgNo < bank->instCount; pos->prgNo++, pos->index = 0) { + u32 instOffset = bank->instOffset[pos->prgNo]; + inst->type = (u8)(instOffset & 0xff); + instOffset >>= 8; + + switch (inst->type) { + case SND_INST_PCM: + case SND_INST_PSG: + case SND_INST_NOISE: + case SND_INST_DIRECTPCM: + case SND_INST_NULL: + { + const SNDInstParam * param = (const SNDInstParam *)((u8 *)bank + instOffset); + inst->param = *param; + pos->prgNo++; + return TRUE; + } + case SND_INST_DRUM_SET: + { + const SNDDrumSet * drumSet = (const SNDDrumSet *)((u8 *)bank + instOffset); + for (; pos->index < drumSet->max - drumSet->min + 1; pos->index++) { + *inst = drumSet->instOffset[pos->index]; + pos->index++; + return TRUE; + } + break; + } + case SND_INST_KEY_SPLIT: + { + const SNDKeySplit * keySplit = (const SNDKeySplit *)((u8 *)bank + instOffset); + for (; pos->index < SND_INST_KEYSPLIT_MAX; pos->index++) { + if (keySplit->key[pos->index] == 0) + break; + *inst = keySplit->instOffset[pos->index]; + pos->index++; + return TRUE; + } + break; + } + default: + break; + } + } + + return FALSE; +} + +u32 Snd_GetWaveDataCount (const struct SNDWaveArc * waveArc) +{ + SDK_NULL_ASSERT(waveArc); + return waveArc->waveCount; +} + +void Snd_SetWaveDataAddress (SNDWaveArc * waveArc, int index, const SNDWaveData * address) +{ + SDK_NULL_ASSERT(waveArc); + SDK_MINMAX_ASSERT(index, 0, waveArc->waveCount); + SDK_ASSERT(address == NULL || address >= (void *)HW_MAIN_MEM); + + Sndi_LockMutex(); + + waveArc->waveOffset[index] = (u32)address; + +#ifdef SDK_ARM9 + DC_StoreRange(&waveArc->waveOffset[index], sizeof(u32)); +#endif + + Sndi_UnlockMutex(); +} + +const SNDWaveData * Snd_GetWaveDataAddress (const SNDWaveArc * waveArc, int index) +{ + const SNDWaveData * wave; + u32 offset; + + SDK_NULL_ASSERT(waveArc); + SDK_MINMAX_ASSERT(index, 0, waveArc->waveCount); + + Sndi_LockMutex(); + + offset = waveArc->waveOffset[index]; + + if (offset != 0) { + if (offset < HW_MAIN_MEM) + wave = (const SNDWaveData *)((u8 *)waveArc + offset); + else + wave = (const SNDWaveData *)offset; + } else { + wave = NULL; + } + + Sndi_UnlockMutex(); + + return wave; +} + +#ifdef SDK_ARM7 + +BOOL Snd_NoteOn (SNDExChannel * ch_p, int key, int velocity, s32 length, const SNDBankData * bank, const SNDInstData * inst) +{ + const SNDWaveData * wave_data; + int release; + BOOL result; + + SDK_NULL_ASSERT(ch_p); + SDK_MINMAX_ASSERT(key, 0, 127); + SDK_MINMAX_ASSERT(velocity, 0, 127); + SDK_NULL_ASSERT(inst); + + release = inst->param.release; + if (inst->param.release == SND_BANK_DISABLE_RELEASE) { + length = -1; + release = 0; + } + + switch (inst->type) { + case SND_INST_PCM: + case SND_INST_DIRECTPCM: + if (inst->type == SND_INST_PCM) { + wave_data = GetWaveData(bank, inst->param.wave[1], inst->param.wave[0]); + } else { + wave_data = (const SNDWaveData *)(inst->param.wave[1] << 16 | inst->param.wave[0]); + } + + if (wave_data != NULL) { + result = Snd_StartExChannelPcm(ch_p, &wave_data->param, wave_data->samples, length); + } else { + result = FALSE; + } + break; + case SND_INST_PSG: + result = Snd_StartExChannelPsg(ch_p, (SNDDuty)inst->param.wave[0], length); + break; + case SND_INST_NOISE: + result = Snd_StartExChannelNoise(ch_p, length); + break; + default: + result = FALSE; + break; + } + + if (!result) + return FALSE; + + ch_p->key = (u8)key; + ch_p->original_key = inst->param.original_key; + ch_p->velocity = (u8)velocity; + + Snd_SetExChannelAttack(ch_p, inst->param.attack); + Snd_SetExChannelDecay(ch_p, inst->param.decay); + Snd_SetExChannelSustain(ch_p, inst->param.sustain); + Snd_SetExChannelRelease(ch_p, release); + + ch_p->init_pan = (s8)(inst->param.pan - 64); + + return TRUE; +} + +#endif + +#ifdef SDK_ARM7 + static const SNDWaveData * GetWaveData (const SNDBankData * bank, int waveArcNo, int waveIndex) + { + const SNDWaveArc * arc; + + SDK_MINMAX_ASSERT(waveArcNo, 0, SND_BANK_TO_WAVEARC_MAX - 1); + + arc = bank->waveArcLink[waveArcNo].waveArc; + + if (arc == NULL) + return NULL; + + if (waveIndex >= arc->waveCount) + return NULL; + + return Snd_GetWaveDataAddress(arc, waveIndex); + } +#endif diff --git a/lib/include/nitro/snd.h b/lib/include/nitro/snd.h index c9b41fa0..0ff406f7 100644 --- a/lib/include/nitro/snd.h +++ b/lib/include/nitro/snd.h @@ -3,5 +3,6 @@ #include #include +#include #endif //NITRO_SND_H_ diff --git a/lib/include/nitro/snd/common/bank.h b/lib/include/nitro/snd/common/bank.h new file mode 100644 index 00000000..e9e87705 --- /dev/null +++ b/lib/include/nitro/snd/common/bank.h @@ -0,0 +1,130 @@ +#ifndef NITRO_SND_COMMON_BANK_H_ +#define NITRO_SND_COMMON_BANK_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SND_INST_KEYSPLIT_MAX 8 +#define SND_BANK_TO_WAVEARC_MAX 4 +#define SND_BANK_DISABLE_RELEASE 255 + +struct SNDWaveArc; +struct SNDExChannel; + +typedef enum SNDInstType { + SND_INST_INVALID = 0, + SND_INST_PCM = 0x01, + SND_INST_PSG, + SND_INST_NOISE, + SND_INST_DIRECTPCM, + SND_INST_NULL, + SND_INST_DRUM_SET = 0x10, + SND_INST_KEY_SPLIT +} SNDInstType; + +#ifdef _MSC_VER + #pragma warning( disable : 4200 ) +#endif + +typedef struct SNDWaveArcLink { + struct SNDWaveArc * waveArc; + struct SNDWaveArcLink * next; +} SNDWaveArcLink; + +typedef struct SNDWaveArc { + struct SNDBinaryFileHeader fileHeader; + struct SNDBinaryBlockHeader blockHeader; + struct SNDWaveArcLink * topLink; + u32 reserved[7]; + u32 waveCount; + u32 waveOffset[0]; +} SNDWaveArc; + +typedef struct SNDWaveData { + struct SNDWaveParam param; + u8 samples[0]; +} SNDWaveData; + +typedef struct SNDBankData { + struct SNDBinaryFileHeader fileHeader; + struct SNDBinaryBlockHeader blockHeader; + struct SNDWaveArcLink waveArcLink[SND_BANK_TO_WAVEARC_MAX]; + u32 instCount; + u32 instOffset[0]; +} SNDBankData; + +typedef struct SNDInstParam { + u16 wave[2]; + u8 original_key; + u8 attack; + u8 decay; + u8 sustain; + u8 release; + u8 pan; +} SNDInstParam; + +typedef struct SNDInstData { + u8 type; + u8 padding_; + struct SNDInstParam param; +} SNDInstData; + +typedef struct SNDKeySplit { + u8 key[SND_INST_KEYSPLIT_MAX]; + struct SNDInstData instOffset[0]; +} SNDKeySplit; + +typedef struct SNDDrumSet { + u8 min; + u8 max; + struct SNDInstData instOffset[0]; +} SNDDrumSet; + +typedef struct SNDInstPos { + u32 prgNo; + u32 index; +} SNDInstPos; + +#if defined(SDK_WIN32) || defined(SDK_FROM_TOOL) + struct SNDBankDataCallback; + typedef BOOL (__stdcall * SNDReadInstDataFunc)(const struct SNDBankDataCallback * bank, int prgNo, int key, struct SNDInstData * inst); + + typedef struct SNDBankDataCallback { + struct SNDBinaryFileHeader fileHeader; + struct SNDBinaryBlockHeader blockHeader; + void * arg; + SNDReadInstDataFunc readInstDataFunc; + } SNDBankDataCallback; +#endif + +#ifdef _MSC_VER + #pragma warning(default : 4200) +#endif + +void Snd_AssignWaveArc(struct SNDBankData * bank, int index, struct SNDWaveArc * waveArc); +void Snd_DestroyBank(struct SNDBankData * bank); +void Snd_DestroyWaveArc(struct SNDWaveArc * waveArc); + +BOOL Snd_ReadInstData(const struct SNDBankData * bank, int prgNo, int key, struct SNDInstData * inst); +BOOL Snd_WriteInstData(struct SNDBankData * bank, int prgNo, int key, const struct SNDInstData * inst); + +struct SNDInstPos Snd_GetFirstInstDataPos(const struct SNDBankData * bank); +BOOL Snd_GetNextInstData(const struct SNDBankData * bank, struct SNDInstData * inst, struct SNDInstPos * pos); + +u32 Snd_GetWaveDataCount(const struct SNDWaveArc * waveArc); +void Snd_SetWaveDataAddress(struct SNDWaveArc * waveArc, int index, const SNDWaveData * address); +const SNDWaveData * Snd_GetWaveDataAddress(const struct SNDWaveArc * waveArc, int index); + +#ifdef SDK_ARM7 + BOOL Snd_NoteOn(struct SNDExChannel * ch_p, int key, int velocity, s32 length, const struct SNDBankData * bank, const struct SNDInstData * inst); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/include/nitro/snd/common/channel.h b/lib/include/nitro/snd/common/channel.h index ff210049..903daae9 100644 --- a/lib/include/nitro/snd/common/channel.h +++ b/lib/include/nitro/snd/common/channel.h @@ -144,7 +144,7 @@ typedef enum { #ifdef SDK_ARM7 #if !(defined(SDK_WIN32) || defined(SDK_FROM_TOOL)) - static inline void SND_StartChannel (int chNo) + static inline void Snd_StartChannel (int chNo) { SDK_MINMAX_ASSERT(chNo, SND_CHANNEL_MIN, SND_CHANNEL_MAX); @@ -152,34 +152,34 @@ typedef enum { |= REG_SND_SOUND0CNT_8_E_MASK; } #else - void SND_StartChannel(int chNo); + void Snd_StartChannel(int chNo); #endif #endif #ifdef SDK_ARM7 - void SND_SetupChannelPcm(int chNo, + void Snd_SetupChannelPcm(int chNo, const void * dataaddr, SNDWaveFormat format, SNDChannelLoop loop, int loopStart, int loopLen, int volume, SNDChannelDataShift shift, int timer, int pan); - void SND_SetupChannelPsg(int chNo, + void Snd_SetupChannelPsg(int chNo, SNDDuty duty, int volume, SNDChannelDataShift shift, int timer, int pan); - void SND_SetupChannelNoise(int chNo, int volume, SNDChannelDataShift shift, int timer, int pan); - void SND_StopChannel(int chNo, s32 flags); - void SND_SetChannelVolume(int chNo, int volume, SNDChannelDataShift shift); - void SND_SetChannelTimer(int chNo, int timer); - void SND_SetChannelPan(int chNo, int pan); - BOOL SND_IsChannelActive(int chNo); - void SND_SetMasterPan(int pan); - u32 SND_GetChannelControl(int chNo); + void Snd_SetupChannelNoise(int chNo, int volume, SNDChannelDataShift shift, int timer, int pan); + void Snd_StopChannel(int chNo, s32 flags); + void Snd_SetChannelVolume(int chNo, int volume, SNDChannelDataShift shift); + void Snd_SetChannelTimer(int chNo, int timer); + void Snd_SetChannelPan(int chNo, int pan); + BOOL Snd_IsChannelActive(int chNo); + void Snd_SetMasterPan(int pan); + u32 Snd_GetChannelControl(int chNo); #endif #ifdef SDK_ARM7 - void SNDi_SetSurroundDecay(int decay); + void Sndi_SetSurroundDecay(int decay); #endif #ifdef __cplusplus diff --git a/lib/include/nitro/snd/common/data.h b/lib/include/nitro/snd/common/data.h new file mode 100644 index 00000000..3c731cad --- /dev/null +++ b/lib/include/nitro/snd/common/data.h @@ -0,0 +1,28 @@ +#ifndef NITRO_SND_COMMON_DATA_H_ +#define NITRO_SND_COMMON_DATA_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SNDBinaryFileHeader { + char signature[4]; + u16 byteOrder; + u16 version; + u32 fileSize; + u16 headerSize; + u16 dataBlocks; +} SNDBinaryFileHeader; + +typedef struct SNDBinaryBlockHeader { + u32 kind; + u32 size; +} SNDBinaryBlockHeader; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/include/nitro/snd/common/exchannel.h b/lib/include/nitro/snd/common/exchannel.h new file mode 100644 index 00000000..34c57d66 --- /dev/null +++ b/lib/include/nitro/snd/common/exchannel.h @@ -0,0 +1,175 @@ +#ifndef NITRO_SND_COMMON_EX_CHANNEL_H_ +#define NITRO_SND_COMMON_EX_CHANNEL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SND_EX_CHANNEL_PRIO_HIGHEST 255 +#define SND_EX_CHANNEL_PRIO_LOWEST 1 + +#define SND_EX_CHANNEL_RELEASE_PRIO 1 +#define SND_EX_CHANNEL_STOP_PRIO 0 + +#define SND_EX_CHANNEL_USER_PAN_MIN -128 +#define SND_EX_CHANNEL_USER_PAN_MAX 127 + +#define SND_EX_CHANNEL_ENV_DECAY_SHIFT 7 + +#define SND_EX_CHANNEL_UPDATE_START (0x01 << 0) +#define SND_EX_CHANNEL_UPDATE_STOP (0x01 << 1) +#define SND_EX_CHANNEL_UPDATE_TIMER (0x01 << 2) +#define SND_EX_CHANNEL_UPDATE_VOLUME (0x01 << 3) +#define SND_EX_CHANNEL_UPDATE_PAN (0x01 << 4) + +#define SND_LOCK_IMPLIED_ALLOC_CHANNEL (1 << 0) + +struct SNDExChannel; + +typedef enum SNDExChannelType { + SND_EX_CHANNEL_PCM, + SND_EX_CHANNEL_PSG, + SND_EX_CHANNEL_NOISE +} SNDExChannelType; + +typedef enum SNDExChannelCallbackStatus { + SND_EX_CHANNEL_CALLBACK_DROP, + SND_EX_CHANNEL_CALLBACK_FINISH +} SNDExChannelCallbackStatus; + +typedef enum SNDEnvStatus { + SND_ENV_ATTACK, + SND_ENV_DECAY, + SND_ENV_SUSTAIN, + SND_ENV_RELEASE +} SNDEnvStatus; + +typedef enum SNDLfoTarget { + SND_LFO_PITCH, + SND_LFO_VOLUME, + SND_LFO_PAN +} SNDLfoTarget; + +typedef void (*SNDExChannelCallback) (struct SNDExChannel * ch_p, SNDExChannelCallbackStatus status, void * userData); + +#if !(defined(SDK_WIN32) || defined(SDK_FROM_TOOL)) + typedef struct SNDWaveParam { + u8 format; + u8 loopflag; + u16 rate; + u16 timer; + u16 loopstart; + u32 looplen; + } SNDWaveParam; +#else + typedef struct SNDWaveParam { + u8 format; + u8 loopflag; + u16 rate; + u16 timer; + u32 loopstart; + u32 looplen; + } SNDWaveParam; +#endif + +typedef struct SNDLfoParam { + u8 target; + u8 speed; + u8 depth; + u8 range; + u16 delay; +} SNDLfoParam; + +typedef struct SNDLfo { + struct SNDLfoParam param; + u16 delay_counter; + u16 counter; +} SNDLfo; + +typedef struct SNDExChannel { + u8 myNo; + u8 type; + u8 env_status; + u8 active_flag : 1; + u8 start_flag : 1; + u8 auto_sweep : 1; + u8 sync_flag : 5; + u8 pan_range; + u8 original_key; + s16 user_decay2; + u8 key; + u8 velocity; + s8 init_pan; + s8 user_pan; + s16 user_decay; + s16 user_pitch; + s32 env_decay; + s32 sweep_counter; + s32 sweep_length; + u8 attack; + u8 sustain; + u16 decay; + u16 release; + u8 prio; + u8 pan; + u16 volume; + u16 timer; + struct SNDLfo lfo; + s16 sweep_pitch; + s32 length; + + struct SNDWaveParam wave; + union { + const void * data; + SNDDuty duty; + }; + + SNDExChannelCallback callback; + void * callback_data; + struct SNDExChannel * nextLink; +} SNDExChannel; + +#ifdef SDK_ARM7 + void Snd_ExChannelInit(void); + void Snd_ExChannelMain(BOOL doPeriodicProc); + void Snd_UpdateExChannel(void); + + struct SNDExChannel * Snd_AllocExChannel(u32 chBitMask, + int prio, + BOOL strongRequest, + SNDExChannelCallback callback, void * callbackData); + + void Snd_FreeExChannel(struct SNDExChannel * ch_p); + BOOL Snd_StartExChannelPcm(SNDExChannel * ch_p, const struct SNDWaveParam * wave, const void * data, s32 length); + BOOL Snd_StartExChannelPsg(struct SNDExChannel * ch_p, SNDDuty duty, s32 length); + BOOL Snd_StartExChannelNoise(struct SNDExChannel * ch_p, s32 length); + void Snd_ReleaseExChannel(struct SNDExChannel * ch_p); + BOOL Snd_IsExChannelActive(struct SNDExChannel * ch_p); + void Snd_InvalidateWave(const void * start, const void * end); + + s32 Snd_UpdateExChannelEnvelope(SNDExChannel * ch_p, BOOL doPeriodicProc); + + void Snd_SetExChannelAttack(struct SNDExChannel * ch_p, int attack); + void Snd_SetExChannelDecay(struct SNDExChannel * ch_p, int decay); + void Snd_SetExChannelSustain(struct SNDExChannel * ch_p, int sustain); + void Snd_SetExChannelRelease(struct SNDExChannel * ch_p, int release); + + void Snd_InitLfoParam(SNDLfoParam * lfo); + void Snd_StartLfo(SNDLfo * lfo); + void Snd_UpdateLfo(SNDLfo * lfo); + s32 Snd_GetLfoValue(SNDLfo * lfo); + + void Snd_LockChannel(u32 chBitMask, u32 flags); + void Snd_UnlockChannel(u32 chBitMask, u32 flags); + void Snd_StopUnlockedChannel(u32 chBitMask, u32 flags); + u32 Snd_GetLockedChannel(u32 flags); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/main.lsf b/main.lsf index 8f75b3c6..a8615d99 100644 --- a/main.lsf +++ b/main.lsf @@ -227,6 +227,8 @@ Static main Object lib/NitroSDK/asm/mtx.o Object lib/NitroSDK/asm/fx_cp.o Object lib/NitroSDK/asm/fx_vec.o + Object lib/NitroSDK/asm/fx_atanidx.o + Object lib/NitroSDK/asm/fx_fx.o Object lib/NitroSDK/asm/gx.o Object lib/NitroSDK/asm/gxstate.o Object lib/NitroSDK/asm/gx_vramcnt.o @@ -276,7 +278,7 @@ Static main Object lib/NitroSDK/asm/snd_alarm.o Object lib/NitroSDK/asm/snd_work.o Object lib/NitroSDK/src/snd/snd_util.o - Object lib/NitroSDK/asm/snd_bank.o + Object lib/NitroSDK/src/snd/snd_bank.o Object lib/NitroSDK/src/pxi_init.o Object lib/NitroSDK/asm/pxi_fifo.o Object lib/NitroSDK/asm/fs_command.o