From 4b9f2b597d0667ef09ab7a9ba81d003a4ca67b14 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 21 Jun 2023 16:27:28 -0700 Subject: [PATCH] More MusyX imps Former-commit-id: bc71ab6d82de7fb9fe4254a10c02d609aaaa9654 --- asm/musyx/runtime/CheapReverb/creverb.s | 26 +- include/musyx/musyx.h | 141 ++++++++- include/musyx/musyx_priv.h | 10 +- libc/math.h | 1 + src/musyx/runtime/CheapReverb/creverb.c | 403 +++++++++++++++++++++++- src/musyx/runtime/snd3d.c | 383 ++++++++++++++++++++-- src/musyx/runtime/stream.c | 16 +- src/musyx/runtime/synthdata.c | 35 ++ src/musyx/txwin/txwin.c | 2 +- 9 files changed, 957 insertions(+), 60 deletions(-) diff --git a/asm/musyx/runtime/CheapReverb/creverb.s b/asm/musyx/runtime/CheapReverb/creverb.s index be02e390..6952556f 100644 --- a/asm/musyx/runtime/CheapReverb/creverb.s +++ b/asm/musyx/runtime/CheapReverb/creverb.s @@ -54,21 +54,21 @@ lbl_805AF3D8: # ROM: 0x3FBC78 .double 4.503601774854144E15 -.global lbl_805AF3E0 -lbl_805AF3E0: +.obj value0_3, local # ROM: 0x3FBC80 .float 0.3 +.endobj value0_3 -.global lbl_805AF3E4 -lbl_805AF3E4: +.obj value0_6, local # ROM: 0x3FBC84 .float 0.6 +.endobj value0_6 -.global lbl_805AF3E8 -lbl_805AF3E8: + +.obj i2fMagic, local # ROM: 0x3FBC88 .double 4.503601774854144E15 - +.endobj i2fMagic .section .data, "wa" @@ -383,12 +383,12 @@ HandleReverb: /* 803B5684 003B25E4 DA 41 00 78 */ stfd f18, 0x78(r1) /* 803B5688 003B25E8 DA 61 00 80 */ stfd f19, 0x80(r1) /* 803B568C 003B25EC DA 81 00 88 */ stfd f20, 0x88(r1) -/* 803B5690 003B25F0 3F E0 80 5B */ lis r31, lbl_805AF3E0@ha -/* 803B5694 003B25F4 C0 DF F3 E0 */ lfs f6, lbl_805AF3E0@l(r31) -/* 803B5698 003B25F8 3F E0 80 5B */ lis r31, lbl_805AF3E4@ha -/* 803B569C 003B25FC C1 3F F3 E4 */ lfs f9, lbl_805AF3E4@l(r31) -/* 803B56A0 003B2600 3F E0 80 5B */ lis r31, lbl_805AF3E8@ha -/* 803B56A4 003B2604 C8 BF F3 E8 */ lfd f5, lbl_805AF3E8@l(r31) +/* 803B5690 003B25F0 3F E0 80 5B */ lis r31, value0_3@ha +/* 803B5694 003B25F4 C0 DF F3 E0 */ lfs f6, value0_3@l(r31) +/* 803B5698 003B25F8 3F E0 80 5B */ lis r31, value0_6@ha +/* 803B569C 003B25FC C1 3F F3 E4 */ lfs f9, value0_6@l(r31) +/* 803B56A0 003B2600 3F E0 80 5B */ lis r31, i2fMagic@ha +/* 803B56A4 003B2604 C8 BF F3 E8 */ lfd f5, i2fMagic@l(r31) /* 803B56A8 003B2608 C0 44 00 F0 */ lfs f2, 0xf0(r4) /* 803B56AC 003B260C C1 64 01 1C */ lfs f11, 0x11c(r4) /* 803B56B0 003B2610 C1 04 01 18 */ lfs f8, 0x118(r4) diff --git a/include/musyx/musyx.h b/include/musyx/musyx.h index f2490101..dd0528bf 100644 --- a/include/musyx/musyx.h +++ b/include/musyx/musyx.h @@ -108,6 +108,133 @@ typedef struct SND_FMATRIX { f32 t[3]; } SND_FMATRIX; +typedef struct SND_PARAMETER { + u8 ctrl; + union { + u8 value7; + u16 value14; + } paraData; +} SND_PARAMETER; + +typedef struct SND_PARAMETER_INFO { + u8 numPara; + SND_PARAMETER* paraArray; + +} SND_PARAMETER_INFO; + +typedef struct SND_STUDIO_INPUT { + // total size: 0x4 + u8 vol; // offset 0x0, size 0x1 + u8 volA; // offset 0x1, size 0x1 + u8 volB; // offset 0x2, size 0x1 + u8 srcStudio; // offset 0x3, size 0x1 +} SND_STUDIO_INPUT; + +typedef struct SND_ROOM { + struct SND_ROOM* next; + struct SND_ROOM* prev; + + u32 flags; + SND_FVECTOR pos; + f32 distance; + + u8 studio; + + void (*activateReverb)(u8 studio, void* para); + void (*deActivateReverb)(u8 studio); + void* user; + + u32 curMVol; +} SND_ROOM; + +typedef struct SND_DOOR { + struct SND_DOOR* next; + struct SND_DOOR* prev; + + SND_FVECTOR pos; + + f32 open; + f32 dampen; + u8 fxVol; + + u8 destStudio; + + SND_ROOM* a; + SND_ROOM* b; + + u32 flags; + + s16 filterCoef[4]; + SND_STUDIO_INPUT input; +} SND_DOOR; + +#define SND_DOOR_A2B 0x00000000 +#define SND_DOOR_B2A 0x00000001 + +#define SND_DOOR_DEFAULT SND_DOOR_A2B + +typedef struct SND_LISTENER { + struct SND_LISTENER* next; + struct SND_LISTENER* prev; + SND_ROOM* room; + + u32 flags; + SND_FVECTOR pos; + f32 volPosOff; + SND_FVECTOR dir; + SND_FVECTOR heading; + SND_FVECTOR right; + SND_FVECTOR up; + SND_FMATRIX mat; + f32 surroundDisFront; + f32 surroundDisBack; + f32 soundSpeed; + f32 vol; +} SND_LISTENER; + +#define SND_LISTENER_DEFAULT 0x00000000 +#define SND_LISTENER_DOPPLERFX 0x00000001 + +typedef struct SND_EMITTER { + struct SND_EMITTER* next; + struct SND_EMITTER* prev; + SND_ROOM* room; + + SND_PARAMETER_INFO* paraInfo; + + u32 flags; + SND_FVECTOR pos; + SND_FVECTOR dir; + f32 maxDis; + f32 maxVol; + f32 minVol; + f32 volPush; + SND_VOICEID vid; + u32 group; + SND_FXID fxid; + + u8 studio; + + u8 maxVoices; + + u16 VolLevelCnt; + f32 fade; + +} SND_EMITTER; + +#define SND_EMITTER_DEFAULTKEY 0xFF +#define SND_EMITTER_DEFAULTVOL 0xFF + +#define SND_EMITTER_DEFAULT 0x00000000 +#define SND_EMITTER_CONTINOUS 0x00000001 +#define SND_EMITTER_CONTINUOUS 0x00000001 +#define SND_EMITTER_RESTARTABLE 0x00000002 +#define SND_EMITTER_PAUSABLE 0x00000004 +#define SND_EMITTER_DOPPLERFX 0x00000008 +#define SND_EMITTER_ITD 0x00000010 +#define SND_EMITTER_HARDSTART 0x00000020 +#define SND_EMITTER_NOSILENTSTART 0x00000040 + s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize); void sndQuit(void); @@ -254,20 +381,6 @@ bool sndAuxCallbackPrepareReverbSTD(SND_AUX_REVERBSTD* rev); bool sndAuxCallbackShutdownReverbSTD(SND_AUX_REVERBSTD* rev); bool sndAuxCallbackUpdateSettingsReverbSTD(SND_AUX_REVERBSTD* rev); -typedef struct SND_PARAMETER { - u8 ctrl; - union { - u8 value7; - u16 value14; - } paraData; -} SND_PARAMETER; - -typedef struct SND_PARAMETER_INFO { - u8 numPara; - SND_PARAMETER* paraArray; - -} 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, ...); diff --git a/include/musyx/musyx_priv.h b/include/musyx/musyx_priv.h index 45b1c6af..ef781cee 100644 --- a/include/musyx/musyx_priv.h +++ b/include/musyx/musyx_priv.h @@ -8,14 +8,6 @@ extern "C" { #endif -typedef struct SND_STUDIO_INPUT { - // total size: 0x4 - u8 vol; // offset 0x0, size 0x1 - u8 volA; // offset 0x1, size 0x1 - u8 volB; // offset 0x2, size 0x1 - u8 srcStudio; // offset 0x3, size 0x1 -} SND_STUDIO_INPUT; - typedef struct SYNTH_VOICELIST { // total size: 0x4 u8 prev; // offset 0x0, size 0x1 @@ -884,7 +876,7 @@ void streamInit(); /* extern */ void vsInit(); /* extern */ void hwExit(); void dataExit(); -void s3dInit(s32); /* extern */ +void s3dInit(u32); /* extern */ void s3dKillEmitterByFXID(FX_TAB* fxTab, u32 num); void s3dExit(); void synthInit(u32, u8); /* extern */ diff --git a/libc/math.h b/libc/math.h index 5dec523f..1141f416 100644 --- a/libc/math.h +++ b/libc/math.h @@ -92,6 +92,7 @@ float floorf(float x) { return floor(x); } double fabs(double x); double pow(double x, double y); +float powf(float __x, float __y) { return pow(__x, __y); } #ifdef __MWERKS__ #pragma cplusplus on diff --git a/src/musyx/runtime/CheapReverb/creverb.c b/src/musyx/runtime/CheapReverb/creverb.c index dd9f31f9..dd8cca5a 100644 --- a/src/musyx/runtime/CheapReverb/creverb.c +++ b/src/musyx/runtime/CheapReverb/creverb.c @@ -10,8 +10,10 @@ --------------------------------------- */ #include "musyx/musyx_priv.h" +#include +#include -static void DLsetdelay(_SND_REVSTD_DELAYLINE * dl, s32 lag) { +static void DLsetdelay(_SND_REVSTD_DELAYLINE* dl, s32 lag) { dl->outPoint = dl->inPoint - (lag * sizeof(f32)); while (dl->outPoint < 0) { dl->outPoint += dl->length; @@ -29,3 +31,402 @@ static void DLcreate(_SND_REVSTD_DELAYLINE* dl, s32 len) { } static void DLdelete(_SND_REVSTD_DELAYLINE* dl) { salFree(dl->inputs); } + +bool ReverbSTDCreate(_SND_REVSTD_WORK* rv, float coloration, float time, float mix, float damping, + float predelay) { + static u32 lens[4] = {1789, 1999, 433, 149}; + u8 i; // r31 + u8 k; // r29 + + if ((coloration < 0.f || coloration > 1.f) || (time < .01f || time > 10.f) || + (mix < 0.f || mix > 1.f) || (damping < 0.f || damping > 1.f) || + (predelay < 0.f || predelay > 0.1f)) { + return FALSE; + } + + memset(rv, 0, sizeof(_SND_REVSTD_WORK)); + for (k = 0; k < 3; ++k) { + for (i = 0; i < 2; ++i) { + DLcreate(&rv->C[i + k * 2], lens[i] + 2); + DLsetdelay(&rv->C[i + k * 2], lens[i]); + rv->combCoef[i + k * 2] = powf(10.f, (int)(lens[i] * -3) / (time * 32000.f)); + } + for (i = 0; i < 2; ++i) { + DLcreate(&rv->AP[i + k * 2], lens[i + 2] + 2); + DLsetdelay(&rv->AP[i + k * 2], lens[i + 2]); + } + rv->lpLastout[k] = 0.f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05; + } + + rv->damping = 1.f - (rv->damping * 0.8f + 0.05f); + + if (predelay != 0.f) { + rv->preDelayTime = (int)(predelay * 32000.f); + for (k = 0; k < 3; ++k) { + rv->preDelayLine[k] = salMalloc(rv->preDelayTime << 2); + memset(rv->preDelayLine[k], 0, rv->preDelayTime << 2); + rv->preDelayPtr[k] = rv->preDelayLine[k]; + } + } else { + rv->preDelayTime = 0; + for (k = 0; k < 3; ++k) { + rv->preDelayPtr[k] = NULL; + rv->preDelayLine[k] = NULL; + } + } + + return TRUE; +} + +bool ReverbSTDModify(_SND_REVSTD_WORK* rv, float coloration, float time, float mix, float damping, + float predelay) { + unsigned char i; // r31 + + if ((coloration < 0.f || coloration > 1.f) || (time < .01f || time > 10.f) || + (mix < 0.f || mix > 1.f) || (damping < 0.f || damping > 1.f) || + (predelay < 0.f || predelay > 0.1f)) { + return FALSE; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05; + } + + rv->damping = 1.f - (rv->damping * 0.8f + 0.05f); + + for (i = 0; i < 6; ++i) { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 6; ++i) { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime != 0) { + for (i = 0; i < 3; ++i) { + salFree(rv->preDelayLine[i]); + } + } + + return ReverbSTDCreate(rv, coloration, time, mix, damping, predelay); +} + +static const float value0_3 = 0.3f; +static const float value0_6 = 0.6f; +static const double i2fMagic = 4.503601774854144E15; +static asm void HandleReverb(long* sptr, struct _SND_REVSTD_WORK* rv) { +#if 1 + nofralloc + stwu r1, -0x90(r1) + stmw r17, 8(r1) + stfd f14, 0x58(r1) + stfd f15, 0x60(r1) + stfd f16, 0x68(r1) + stfd f17, 0x70(r1) + stfd f18, 0x78(r1) + stfd f19, 0x80(r1) + stfd f20, 0x88(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, 0xf0(r4) + lfs f11, 0x11c(r4) + lfs f8, 0x118(r4) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + lis r30, 0x4330 + stw r30, 0x50(r1) + li r5, 0 + +lbl_803B56C8: + slwi r31, r5, 3 + add r31, r31, r4 + lfs f19, 0xf4(r31) + lfs f20, 0xf8(r31) + slwi r31, r5, 2 + add r31, r31, r4 + lfs f7, 0x10c(r31) + lwz r27, 0x124(r31) + lwz r28, 0x130(r31) + lwz r31, 0x120(r4) + addi r22, r31, -1 + slwi r22, r22, 2 + add r22, r22, r27 + cmpwi cr7, r31, 0 + mulli r31, r5, 0x28 + addi r29, r4, 0x78 + add r29, r29, r31 + addi r30, r4, 0 + add r30, r30, r31 + lwz r21, 0(r29) + lwz r20, 4(r29) + lwz r19, 0x14(r29) + lwz r18, 0x18(r29) + lfs f15, 0x10(r29) + lfs f16, 0x24(r29) + lwz r26, 8(r29) + lwz r25, 0x1c(r29) + lwz r7, 0xc(r29) + lwz r8, 0x20(r29) + lwz r12, 0(r30) + lwz r11, 4(r30) + lwz r10, 0x14(r30) + lwz r9, 0x18(r30) + lfs f17, 0x10(r30) + lfs f18, 0x24(r30) + lwz r24, 8(r30) + lwz r23, 0x1c(r30) + lwz r17, 0xc(r30) + lwz r6, 0x20(r30) + lwz r30, 0(r3) + xoris r30, r30, 0x8000 + stw r30, 0x54(r1) + lfd f12, 0x50(r1) + fsubs f12, f12, f5 + li r31, 0x9f + mtctr r31 + +lbl_803B5780: + fmr f13, f12 + beq cr7, lbl_803B57A0 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ lbl_803B57A0 + mr r28, r27 + +lbl_803B57A0: + + fmadds f8, f19, f15, f13 + lwzu r29, 4(r3) + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ lbl_803B57EC + li r21, 0 + +lbl_803B57EC: + xoris r29, r29, 0x8000 + fmadds f9, f2, f17, f14 + bne+ cr1, lbl_803B57FC + li r20, 0 + +lbl_803B57FC: + stw r29, 0x54(r1) + bne+ cr5, lbl_803B5808 + li r19, 0 + +lbl_803B5808: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, lbl_803B581C + li r18, 0 + +lbl_803B581C: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, lbl_803B5834 + li r12, 0 + +lbl_803B5834: + bne+ cr6, lbl_803B583C + li r11, 0 + +lbl_803B583C: + fmuls f14, f14, f6 + lfd f10, 0x50(r1) + fmadds f14, f11, f7, f14 + fmadds f9, f2, f18, f14 + fmr f7, f14 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, lbl_803B5880 + li r10, 0 + +lbl_803B5880: + bne+ cr6, lbl_803B5888 + li r9, 0 + +lbl_803B5888: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, r3, r31 + bdnz lbl_803B5780 + fmr f13, f12 + beq cr7, lbl_803B58B8 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ lbl_803B58B8 + mr r28, r27 + +lbl_803B58B8: + fmadds f8, f19, f15, f13 + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ lbl_803B5900 + li r21, 0 + +lbl_803B5900: + fmadds f9, f2, f17, f14 + bne+ cr1, lbl_803B590C + li r20, 0 + +lbl_803B590C: + bne+ cr5, lbl_803B5914 + li r19, 0 + +lbl_803B5914: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, lbl_803B5928 + li r18, 0 + +lbl_803B5928: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, lbl_803B5940 + li r12, 0 + +lbl_803B5940: + bne+ cr6, lbl_803B5948 + li r11, 0 + +lbl_803B5948: + + fmuls f14, f14, f6 + fmadds f14, f11, f7, f14 + mulli r31, r5, 0x28 + fmadds f9, f2, f18, f14 + fmr f7, f14 + addi r29, r4, 0x78 + add r29, r29, r31 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + + fctiwz f14, f14 + bne+ cr5, lbl_803B5994 + li r10, 0 + +lbl_803B5994: + bne+ cr6, lbl_803B599C + li r9, 0 + +lbl_803B599C: + addi r30, r4, 0 + add r30, r30, r31 + stfiwx f14, r0, r3 + stw r21, 0(r29) + stw r20, 4(r29) + stw r19, 0x14(r29) + stw r18, 0x18(r29) + addi r3, r3, 4 + stfs f15, 0x10(r29) + stfs f16, 0x24(r29) + slwi r31, r5, 2 + add r31, r31, r4 + addi r5, r5, 1 + stw r12, 0(r30) + stw r11, 4(r30) + stw r10, 0x14(r30) + stw r9, 0x18(r30) + cmpwi r5, 3 + stfs f17, 0x10(r30) + stfs f18, 0x24(r30) + stfs f7, 0x10c(r31) + stw r28, 0x130(r31) + bne lbl_803B56C8 + lfd f14, 0x58(r1) + lfd f15, 0x60(r1) + lfd f16, 0x68(r1) + lfd f17, 0x70(r1) + lfd f18, 0x78(r1) + lfd f19, 0x80(r1) + lfd f20, 0x88(r1) + lmw r17, 8(r1) + addi r1, r1, 0x90 + + blr +#endif +} + +void ReverbSTDCallback(s32* left, s32* right, s32* surround, _SND_REVSTD_WORK* rv) { + HandleReverb(left, rv); +} + +void ReverbSTDFree(_SND_REVSTD_WORK* rv) { + u8 i; // r31 + for (i = 0; i < 6; ++i) { + DLdelete(&rv->AP[i]); + } + for (i = 0; i < 6; ++i) { + DLdelete(&rv->C[i]); + } + if (rv->preDelayTime != 0) { + for (i = 0; i < 3; ++i) { + salFree(rv->preDelayLine[i]); + } + } +} diff --git a/src/musyx/runtime/snd3d.c b/src/musyx/runtime/snd3d.c index 0ec3a0b2..7570e447 100644 --- a/src/musyx/runtime/snd3d.c +++ b/src/musyx/runtime/snd3d.c @@ -1,20 +1,371 @@ #include "musyx/musyx_priv.h" -#ifdef __cplusplus -extern "C" { -#endif +u8 s3dCallCnt; +SND_DOOR* s3dDoorRoot; +SND_EMITTER* s3dEmitterRoot; +SND_LISTENER* s3dListenerRoot; +SND_ROOM* s3dRoomRoot; +u8 s3dUseMaxVoices; +u8 snd_base_studio; +u8 snd_max_studios; +u32 snd_used_studios; -s8 s3dCallCnt; -s32 s3dDoorRoot; -s32 s3dEmitterRoot; -s32 s3dListenerRoot; -s32 s3dRoomRoot; -s8 s3dUseMaxVoices; -s8 snd_base_studio; -s8 snd_max_studios; -s32 snd_used_studios; +static void UpdateRoomDistances() { + SND_ROOM* r; // r30 + SND_LISTENER* li; // r31 + float distance; // r63 + u32 n; // r29 + SND_FVECTOR d; // r1+0x8 -void s3dInit(s32 flags) { + for (n = 0, li = s3dListenerRoot; li != NULL; li = li->next, ++n) + ; + + if (n != 0) { + for (r = s3dRoomRoot; r != NULL; r = r->next) { + if (r->studio != 0xFF) { + distance = 0.f; + for (li = s3dListenerRoot; li != NULL; li = li->next) { + d.x = r->pos.x - li->pos.x; + d.y = r->pos.y - li->pos.y; + d.z = r->pos.z - li->pos.z; + distance += d.x * d.x + d.y * d.y + d.z * d.z; + } + + r->distance = distance / n; + } + } + } +} + +static CheckRoomStatus() { + SND_LISTENER* li; // r30 + SND_EMITTER* em; // r28 + SND_ROOM* r; // r27 + SND_ROOM* max_room; // r29 + SND_ROOM* room; // r31 + SND_FVECTOR d; // r1+0x8 + float distance; // r63 + float maxDis; // r62 + u32 li_num; // r25 + u32 i; // r26 + u32 mask; // r23 + u8 has_listener; // r24 + + UpdateRoomDistances(); + + for (li_num = 0, li = s3dListenerRoot; li != NULL; li = li->next, ++li_num) + ; + + if (li_num != 0) { + for (room = s3dRoomRoot; room != NULL; room = room->next) { + if (room->studio == 0xff) { + distance = 0.f; + for (li = s3dListenerRoot; li != NULL; li = li->next) { + d.x = room->pos.x - li->pos.x; + d.y = room->pos.y - li->pos.y; + d.z = room->pos.z - li->pos.z; + distance += d.x * d.x + d.y * d.y + d.z * d.z; + } + + distance = distance / li_num; + + has_listener = FALSE; + for (li = s3dListenerRoot; li != NULL; li = li->next) { + if (li->room == room) { + has_listener = TRUE; + break; + } + } + // TODO: Finish + } + } + } +} + +bool sndAddRoom(SND_ROOM* room, SND_FVECTOR* pos, void (*activateReverb)(u8 studio, void* user), + void (*deActivateReverb)(u8 studio)) { + if (sndActive) { + hwDisableIrq(); + + if ((room->next = s3dRoomRoot) != NULL) { + room->next->prev = room; + } + + room->prev = NULL; + s3dRoomRoot = room; + room->flags = 0; + room->studio = 0xff; + room->activateReverb = activateReverb; + room->deActivateReverb = deActivateReverb; + room->pos = *pos; + + hwEnableIrq(); + return TRUE; + } + + return FALSE; +} + +bool sndRemoveRoom(SND_ROOM* room) { + if (sndActive) { + hwDisableIrq(); + if (room->prev != NULL) { + room->prev->next = room->next; + } else { + s3dRoomRoot = room->next; + } + + if (room->next != NULL) { + room->next->prev = room->prev; + } + + if (room->studio != 0xFF) { + snd_used_studios &= ~(1 << room->studio - snd_base_studio); + + if (room->deActivateReverb) { + room->deActivateReverb(room->studio); + } + + synthDeactivateStudio(room->studio); + } + + room->flags = 0; + hwEnableIrq(); + + return TRUE; + } + + return FALSE; +} + +bool sndUpdateRoom(SND_ROOM* room, SND_FVECTOR* pos) { + + if (sndActive) { + hwDisableIrq(); + room->pos = *pos; + hwEnableIrq(); + return TRUE; + } + + return FALSE; +} + +static void AddListener2Room(SND_ROOM* room) { + if (room->flags & 0x80000000) { + return; + } + + if (room->curMVol != 0) { + return; + } + + room->flags |= 0x80000000; +} + +static void RemoveListenerFromRoom(SND_ROOM* room) { + u32 n; // r30 + SND_LISTENER* li; // r31 + + for (n = 0, li = s3dListenerRoot; li != NULL; li = li->next) { + if (li->room == room) { + ++n; + } + } + + if (n == 1) { + room->flags &= ~0x80000000; + room->flags |= 0x40000000; + } +} + +static void CalcDoorParameters(SND_DOOR* door) { + float f; // r1+0xC + float v; // r63 + v = door->open; + f = (1.f - door->open) * door->dampen; + door->input.volA = door->fxVol * v; + door->input.volB = 0; + door->input.vol = v * 127.f; +} + +static void CheckDoorStatus() { + SND_DOOR* door; // r31 + + for (door = s3dDoorRoot; door != NULL; door = door->next) { + if (!(door->flags & 0x80000000)) { + if (door->a->studio != 0xFF) { + if (door->b->studio != 0xFF) { + CalcDoorParameters(door); + if (door->flags & 1) { + door->input.srcStudio = door->b->studio; + synthAddStudioInput(door->a->studio, &door->input); + } else { + door->input.srcStudio = door->a->studio; + synthAddStudioInput(door->b->studio, &door->input); + } + + door->flags |= 0x80000000; + } + } + } else if (door->a->studio == 0xFF || door->b->studio == 0xFF) { + if ((door->a->studio != 0xFF && door->a->studio == door->destStudio) || + (door->b->studio != 0xFF && door->b->studio == door->destStudio)) { + synthRemoveStudioInput(door->destStudio, &door->input); + } + + door->flags &= ~0x80000000; + } else { + CalcDoorParameters(door); + } + } +} + +bool sndAddDoor(SND_DOOR* door, SND_ROOM* a, SND_ROOM* b, SND_FVECTOR* pos, float dampen, + float open, unsigned char fxVol, s16 filterCoef[4], u32 flags) { + + hwDisableIrq(); + + if ((door->next = s3dDoorRoot) != NULL) { + door->next->prev = door; + } + + door->prev = NULL; + s3dDoorRoot = door; + door->pos = *pos; + door->open = open; + door->dampen = dampen; + door->fxVol = fxVol; + door->a = a; + door->b = b; + door->flags = flags; + hwEnableIrq(); + return 1; +} + +bool sndRemoveDoor(SND_DOOR* door) { + hwDisableIrq(); + if (door->prev != NULL) { + door->prev->next = door->next; + } else { + s3dDoorRoot = door->next; + } + if (door->next != NULL) { + door->next->prev = door->prev; + } + hwEnableIrq(); + return 1; +} + +static void CalcEmitter(struct SND_EMITTER* em, float* vol, float* doppler, float* xPan, + float* yPan, float* zPan) { + struct SND_LISTENER* li; // r31 + struct SND_FVECTOR d; // r1+0x44 + struct SND_FVECTOR v; // r1+0x38 + struct SND_FVECTOR p; // r1+0x2C + float relspeed; // r60 + float distance; // r61 + float new_distance; // r59 + float ft; // r63 + float vd; // r62 + struct SND_FVECTOR pan; // r1+0x20 + unsigned long n; // r29 +} + +static u8 clip127(u8 v) { + if (v <= 0x7f) { + return v; + } + return 0x7f; +} + +static u16 clip3FFF(u32 v) { + if (v > 0x3fff) { + return 0x3fff; + } + return v; +} + +static void SetFXParameters(struct SND_EMITTER* em, float vol, float xPan, float zPan, + float doppler) { + unsigned long vid; // r30 + unsigned char i; // r28 + struct SND_PARAMETER* pPtr; // r31 +} + +static void EmitterShutdown(SND_EMITTER* em) { + if (em->next != NULL) { + em->next->prev = em->prev; + } + + if (em->prev != NULL) { + em->prev->next = em->next; + } else { + s3dEmitterRoot = em->next; + } + + em->flags &= 0xFFFF; + if (em->vid != -1) { + synthSendKeyOff(em->vid); + } +} + +bool sndUpdateEmitter(SND_EMITTER* em, SND_FVECTOR* pos, SND_FVECTOR* dir, u8 maxVol, + SND_ROOM* room) { + u32 id; // r29 + + if (sndActive) { + hwDisableIrq(); + + em->pos = *pos; + em->dir = *dir; + em->maxVol = maxVol / 127.f; + if (em->minVol > em->maxVol) { + em->minVol = em->maxVol; + } + + if (em->room != room) { + if (em->vid != -1) { + if (room->studio != 0xFF) { + if ((id = vidGetInternalId(em->vid)) != -1) { + hwChangeStudio(id & 0xFF, room->studio); + } + } else { + synthSendKeyOff(em->vid); + em->flags |= 0x80000; + em->vid = -1; + } + } + + em->room = room; + } + hwEnableIrq(); + return TRUE; + } + + return FALSE; +} + +bool sndCheckEmitter(SND_EMITTER* em) { + if (sndActive) { + return (em->flags & 0x10000) != 0; + } + return FALSE; +} + +SND_VOICEID AddEmitter(SND_EMITTER* em_buffer, SND_FVECTOR* pos, SND_FVECTOR* dir, float maxDis, + float comp, u32 flags, u16 fxid, u32 groupid, u8 maxVol, u8 minVol, + SND_ROOM* room, SND_PARAMETER_INFO* para, u32 studio) { + SND_EMITTER* em; // r31 + float xPan; // r1+0x3C + float yPan; // r1+0x38 + float zPan; // r1+0x34 + float cvol; // r1+0x30 + float pitch; // r1+0x2C + + +} + +void s3dInit(u32 flags) { s3dEmitterRoot = 0; s3dListenerRoot = 0; s3dRoomRoot = 0; @@ -23,11 +374,7 @@ void s3dInit(s32 flags) { snd_base_studio = 1; snd_max_studios = 3; s3dCallCnt = 0; - s3dUseMaxVoices = (flags >> 1) & 1; + s3dUseMaxVoices = ((flags & 2) != 0); } void s3dExit() {} - -#ifdef __cplusplus -} -#endif diff --git a/src/musyx/runtime/stream.c b/src/musyx/runtime/stream.c index c3db672e..819d58fa 100644 --- a/src/musyx/runtime/stream.c +++ b/src/musyx/runtime/stream.c @@ -93,7 +93,7 @@ u32 sndStreamCallbackFrq(u32 msTime) { void sndStreamARAMUpdate(u32 stid, u32 off1, u32 len1, u32 off2, u32 len2) { u32 i; // r30 - +#line 0x1eb MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); @@ -168,6 +168,7 @@ u32 sndStreamAllocEx(u8 prio, void* buffer, u32 samples, u32 frq, u8 vol, u8 pan u32 i; // r31 u32 bytes; // r25 u32 j; // r28 +#line 0x234 MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); @@ -280,6 +281,7 @@ u32 sndStreamAllocLength(u32 num, u32 flags) { void sndStreamADPCMParameter(u32 stid, SND_ADPCMSTREAM_INFO* adpcmInfo) { u32 j; // r31 u32 i; // r30 +#line 0x2cb MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); @@ -300,6 +302,7 @@ void sndStreamADPCMParameter(u32 stid, SND_ADPCMSTREAM_INFO* adpcmInfo) { void sndStreamMixParameter(u32 stid, u8 vol, u8 pan, u8 span, u8 fxvol) { u32 i; // r31 +#line 0x2ec MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); @@ -330,6 +333,7 @@ void sndStreamMixParameter(u32 stid, u8 vol, u8 pan, u8 span, u8 fxvol) { void sndStreamMixParameterEx(u32 stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb) { u32 i; // r31 +#line 0x30f MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); @@ -338,8 +342,8 @@ void sndStreamMixParameterEx(u32 stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb streamInfo[i].vol = vol; streamInfo[i].pan = pan; streamInfo[i].span = span; - streamInfo[i].auxa = fxvol; - streamInfo[i].auxb = 0; + streamInfo[i].auxa = auxa; + streamInfo[i].auxb = auxb; if (streamInfo[i].state == 2) { hwSetVolume(streamInfo[i].voice, 0, vol * (1 / 127.f), (pan << 16), (span << 16), auxa * (1 / 127.f), auxb * (1 / 127.f)); @@ -358,6 +362,8 @@ void sndStreamMixParameterEx(u32 stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb } else { MUSY_DEBUG("ID is invalid.\n"); } + + hwEnableIrq(); } @@ -387,6 +393,7 @@ void sndStreamFrq(u32 stid, u32 frq) { void sndStreamFree(u32 stid) { u32 i; // r31 +#line 0x357 MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); @@ -410,6 +417,7 @@ u32 sndStreamActivate(u32 stid) { u32 ret; // r28 ret = 0; +#line 0x37a MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); @@ -441,7 +449,7 @@ u32 sndStreamActivate(u32 stid) { void sndStreamDeactivate(u32 stid) { u32 i; // r31 - +#line 0x3ab MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); i = GetPrivateIndex(stid); diff --git a/src/musyx/runtime/synthdata.c b/src/musyx/runtime/synthdata.c index 90dd00af..06698ddd 100644 --- a/src/musyx/runtime/synthdata.c +++ b/src/musyx/runtime/synthdata.c @@ -18,6 +18,41 @@ static FX_GROUP dataFXGroups[128]; u32 dataInsertKeymap(u16 cid, void* keymapdata) { long i; // r31 long j; // r29 + + hwDisableIrq(); + for (i = 0; i < dataKeymapNum && dataKeymapTab[i].id < cid; ++i); + + if (i < dataKeymapNum) { + if (cid == dataKeymapTab[i].id) { + dataKeymapTab[i].refCount++; + hwEnableIrq(); + return 0; + } + + if (256 < dataKeymapNum) { + hwEnableIrq(); + return 0; + } + + j = dataKeymapNum; + for (j = dataKeymapNum; i <= j; --j) { + dataKeymapTab[j].id = dataKeymapTab[j - 1].id; + dataKeymapTab[j].refCount = dataKeymapTab[j - 1].refCount; + dataKeymapTab[j].data = dataKeymapTab[j - 1].data; + } + } else if (256 < dataKeymapNum) { + hwEnableIrq(); + return 0; + } + + ++dataKeymapNum; + + MUSY_ASSERT_MSG(keymapdata != NULL, "Keymap data pointer is NULL"); + dataKeymapTab[i].id = cid; + dataKeymapTab[i].data = keymapdata; + dataKeymapTab[i].refCount = 1; + hwEnableIrq(); + return 1; } unsigned long dataRemoveKeymap(unsigned short sid) { diff --git a/src/musyx/txwin/txwin.c b/src/musyx/txwin/txwin.c index 739cb6d5..6f47d640 100644 --- a/src/musyx/txwin/txwin.c +++ b/src/musyx/txwin/txwin.c @@ -226,6 +226,6 @@ void __win_log_refresh(struct STRUCT_WIN* handle) { i = 0; for (i = 0; i < handle->char_height; ++i) { n = index + (u16)(n + (handle->total_lines - 1)) % (u32)handle->total_lines; - DEMOPrintf(x, (y + i) % 2, 0, "%s", handle->buffer[index]); + DEMOPrintf(x, (y + i) % 2, 0, "%s", handle->buffer[n]); } }