synthmacros, snd3d progress

Former-commit-id: a31a2f914b4c714e790dd12b310341ccc3f6c640
This commit is contained in:
Phillip Stephens 2023-10-19 10:10:36 -07:00
parent 41589cec2a
commit 4cbeb40e28
5 changed files with 278 additions and 124 deletions

View File

@ -483,100 +483,105 @@ extern VS vs;
#pragma push
#pragma pack(4)
typedef struct SYNTH_VOICE {
SYNTH_QUEUE lowPrecisionJob;
SYNTH_QUEUE zeroOffsetJob; // offset 0xC, size 0xC
SYNTH_QUEUE eventJob; // offset 0x18, size 0xC
u64 lastLowCallTime;
u64 lastZeroCallTime;
MSTEP* addr;
MSTEP* curAddr;
struct SYNTH_VOICE* nextMacActive;
struct SYNTH_VOICE* prevMacActive;
struct SYNTH_VOICE* nextTimeQueueMacro;
struct SYNTH_VOICE* prevTimeQueueMacro;
MAC_STATE macState;
MSTEP* trapEventAddr[3];
MSTEP* trapEventCurAddr[3];
u8 trapEventAny;
CALLSTACK callStack[4];
u8 callStackEntryNum;
u8 callStackIndex;
u64 macStartTime;
u64 wait;
u64 waitTime;
u8 timeUsedByInput;
u16 loop;
s32 local_vars[16];
u32 child;
u32 parent;
u32 id;
VID_LIST* vidList;
VID_LIST* vidMasterList;
u16 allocId;
u16 macroId;
u8 keyGroup;
u32 lastVID;
u8 prio;
u16 ageSpeed;
u32 age;
u64 cFlags;
u8 block;
u8 fxFlag;
u8 vGroup;
u8 studio;
u8 track;
u8 midi;
u8 midiSet;
u8 section;
u32 sInfo;
u32 playFrq;
u16 curNote;
s8 curDetune;
u8 orgNote;
u8 lastNote;
u8 portType;
u16 portLastCtrlState;
u32 portDuration;
u32 portCurPitch;
u32 portTime; // offset 0x13C, size 0x4
u8 vibKeyRange; // offset 0x140, size 0x1
u8 vibCentRange; // offset 0x141, size 0x1
u32 vibPeriod; // offset 0x144, size 0x4
u32 vibCurTime; // offset 0x148, size 0x4
s32 vibCurOffset; // offset 0x14C, size 0x4
s16 vibModAddScale; // offset 0x150, size 0x2
u32 volume; // offset 0x154, size 0x4
u32 orgVolume; // offset 0x158, size 0x4
f32 lastVolFaderScale; // offset 0x15C, size 0x4
u32 lastPan; // offset 0x160, size 0x4
u32 lastSPan; // offset 0x164, size 0x4
f32 treCurScale; // offset 0x168, size 0x4
u16 treScale; // offset 0x16C, size 0x2
u16 treModAddScale; // offset 0x16E, size 0x2
u32 panning[2]; // offset 0x170, size 0x8
s32 panDelta[2]; // offset 0x178, size 0x8
u32 panTarget[2]; // offset 0x180, size 0x8
u32 panTime[2]; // offset 0x188, size 0x8
u8 revVolScale; // offset 0x190, size 0x1
u8 revVolOffset; // offset 0x191, size 0x1
u8 volTable; // offset 0x192, size 0x1
u8 itdMode; // offset 0x193, size 0x1
s32 envDelta; // offset 0x194, size 0x4
u32 envTarget; // offset 0x198, size 0x4
u32 envCurrent; // offset 0x19C, size 0x4
u32 sweepOff[2]; // offset 0x1A0, size 0x8
s32 sweepAdd[2]; // offset 0x1A8, size 0x8
s32 sweepCnt[2]; // offset 0x1B0, size 0x8
u8 sweepNum[2]; // offset 0x1B8, size 0x2
SYNTH_LFO lfo[2]; // offset 0x1BC, size 0x18
u8 lfoUsedByInput[2]; // offset 0x1D4, size 0x2
u8 pbLowerKeyRange; // offset 0x1D6, size 0x1
u8 pbUpperKeyRange; // offset 0x1D7, size 0x1
u16 pbLast; // offset 0x1D8, size 0x2
ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28
s16 pitchADSRRange; // offset 0x204, size 0x2
u16 curPitch; // offset 0x206, size 0x2
// total size: 0x404
SYNTH_QUEUE lowPrecisionJob; // offset 0x0, size 0xC
SYNTH_QUEUE zeroOffsetJob; // offset 0xC, size 0xC
SYNTH_QUEUE eventJob; // offset 0x18, size 0xC
u64 lastLowCallTime; // offset 0x24, size 0x8
u64 lastZeroCallTime; // offset 0x2C, size 0x8
MSTEP* addr; // offset 0x34, size 0x4
MSTEP* curAddr; // offset 0x38, size 0x4
struct SYNTH_VOICE* nextMacActive; // offset 0x3C, size 0x4
struct SYNTH_VOICE* prevMacActive; // offset 0x40, size 0x4
struct SYNTH_VOICE* nextTimeQueueMacro; // offset 0x44, size 0x4
struct SYNTH_VOICE* prevTimeQueueMacro; // offset 0x48, size 0x4
MAC_STATE macState; // offset 0x4C, size 0x4
MSTEP* trapEventAddr[3]; // offset 0x50, size 0xC
MSTEP* trapEventCurAddr[3]; // offset 0x5C, size 0xC
u8 trapEventAny; // offset 0x68, size 0x1
CALLSTACK callStack[4]; // offset 0x6C, size 0x20
u8 callStackEntryNum; // offset 0x8C, size 0x1
u8 callStackIndex; // offset 0x8D, size 0x1
u64 macStartTime; // offset 0x90, size 0x8
u64 wait; // offset 0x98, size 0x8
u64 waitTime; // offset 0xA0, size 0x8
u8 timeUsedByInput; // offset 0xA8, size 0x1
u16 loop; // offset 0xAA, size 0x2
s32 local_vars[16]; // offset 0xAC, size 0x40
u32 child; // offset 0xEC, size 0x4
u32 parent; // offset 0xF0, size 0x4
u32 id; // offset 0xF4, size 0x4
VID_LIST* vidList; // offset 0xF8, size 0x4
VID_LIST* vidMasterList; // offset 0xFC, size 0x4
u16 allocId; // offset 0x100, size 0x2
u16 macroId; // offset 0x102, size 0x2
u8 keyGroup; // offset 0x104, size 0x1
u32 lastVID; // offset 0x108, size 0x4
u8 prio; // offset 0x10C, size 0x1
u16 ageSpeed; // offset 0x10E, size 0x2
u32 age; // offset 0x110, size 0x4
u64 cFlags; // offset 0x114, size 0x8
u8 block; // offset 0x11C, size 0x1
u8 fxFlag; // offset 0x11D, size 0x1
u8 vGroup; // offset 0x11E, size 0x1
u8 studio; // offset 0x11F, size 0x1
u8 track; // offset 0x120, size 0x1
u8 midi; // offset 0x121, size 0x1
u8 midiSet; // offset 0x122, size 0x1
u8 section; // offset 0x123, size 0x1
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 0)
void* sAddr;
#endif
u32 sInfo; // offset 0x124, size 0x4
u32 playFrq; // offset 0x128, size 0x4
u16 curNote; // offset 0x12C, size 0x2
s8 curDetune; // offset 0x12E, size 0x1
u8 orgNote; // offset 0x12F, size 0x1
u8 lastNote; // offset 0x130, size 0x1
u8 portType; // offset 0x131, size 0x1
u16 portLastCtrlState; // offset 0x132, size 0x2
u32 portDuration; // offset 0x134, size 0x4
u32 portCurPitch; // offset 0x138, size 0x4
u32 portTime; // offset 0x13C, size 0x4
u8 vibKeyRange; // offset 0x140, size 0x1
u8 vibCentRange; // offset 0x141, size 0x1
u32 vibPeriod; // offset 0x144, size 0x4
u32 vibCurTime; // offset 0x148, size 0x4
s32 vibCurOffset; // offset 0x14C, size 0x4
s16 vibModAddScale; // offset 0x150, size 0x2
u32 volume; // offset 0x154, size 0x4
u32 orgVolume; // offset 0x158, size 0x4
float lastVolFaderScale; // offset 0x15C, size 0x4
u32 lastPan; // offset 0x160, size 0x4
u32 lastSPan; // offset 0x164, size 0x4
float treCurScale; // offset 0x168, size 0x4
u16 treScale; // offset 0x16C, size 0x2
u16 treModAddScale; // offset 0x16E, size 0x2
u32 panning[2]; // offset 0x170, size 0x8
s32 panDelta[2]; // offset 0x178, size 0x8
u32 panTarget[2]; // offset 0x180, size 0x8
u32 panTime[2]; // offset 0x188, size 0x8
u8 revVolScale; // offset 0x190, size 0x1
u8 revVolOffset; // offset 0x191, size 0x1
u8 volTable; // offset 0x192, size 0x1
u8 itdMode; // offset 0x193, size 0x1
s32 envDelta; // offset 0x194, size 0x4
u32 envTarget; // offset 0x198, size 0x4
u32 envCurrent; // offset 0x19C, size 0x4
u32 sweepOff[2]; // offset 0x1A0, size 0x8
s32 sweepAdd[2]; // offset 0x1A8, size 0x8
s32 sweepCnt[2]; // offset 0x1B0, size 0x8
u8 sweepNum[2]; // offset 0x1B8, size 0x2
SYNTH_LFO lfo[2]; // offset 0x1BC, size 0x18
u8 lfoUsedByInput[2]; // offset 0x1D4, size 0x2
u8 pbLowerKeyRange; // offset 0x1D6, size 0x1
u8 pbUpperKeyRange; // offset 0x1D7, size 0x1
u16 pbLast; // offset 0x1D8, size 0x2
ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28
s16 pitchADSRRange; // offset 0x204, size 0x2
u16 curPitch; // offset 0x206, size 0x2
struct setup {
// total size: 0x9
u8 vol; // offset 0x0, size 0x1
u8 pan; // offset 0x1, size 0x1
u8 midi; // offset 0x2, size 0x1
@ -1054,7 +1059,7 @@ u16 inpGetExCtrl(SYNTH_VOICE* svoice, u8 ctrl);
u16 inpGetMidiCtrl(u8 ctrl, u8 channel, u8 set);
void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key);
u16 inpGetModulation(SYNTH_VOICE* svoice);
void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset);
void inpResetMidiCtrl(u8 ch, u8 set, u32 coldReset) ;
void inpResetChannelDefaults(u8 midi, u8 midiSet);
u16 inpGetPitchBend(SYNTH_VOICE* svoice);
u16 inpGetDoppler(SYNTH_VOICE* svoice);
@ -1070,6 +1075,7 @@ u16 inpGetPostAuxB(SYNTH_VOICE* svoice);
u16 inpGetPedal(SYNTH_VOICE* svoice);
u16 inpGetAuxA(u8 studio, u8 index, u8 midi, u8 midiSet);
u16 inpGetAuxB(u8 studio, u8 index, u8 midi, u8 midiSet);
void inpInit(SYNTH_VOICE* svoice);
/* TODO: Figure out what `unk` is */
void hwSetSRCType(u32 v, u8 salSRCType);

View File

@ -19,6 +19,7 @@ extern synthITDInfo synthITDDefault[8];
extern u32 synthFlags;
u32 vidGetInternalId(SND_VOICEID id);
void synthKeyStateUpdate(SYNTH_VOICE* svoice);
bool synthFXSetCtrl(SND_VOICEID vid, u8 ctrl, u8 value);
bool synthFXSetCtrl14(SND_VOICEID vid, u8 ctrl, u16 value);
bool synthSendKeyOff(SND_VOICEID vid);
@ -35,6 +36,11 @@ bool synthIsFadeOutActive(u8 vGroup);
/* TODO: Move this where it belongs */
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
SND_AUX_CALLBACK auxB, void* userB);
MSTEP* dataGetMacro(u16 mid);
u32 voiceAllocate(u8 priority, u8 maxVoices, u16 allocId, u8 fxFlag);
void voiceFree(SYNTH_VOICE* svoice);
#ifdef __cplusplus
}
#endif

View File

@ -1,3 +1,4 @@
#include "musyx/musyx.h"
#include "musyx/musyx_priv.h"
#include "musyx/synth.h"
@ -11,7 +12,6 @@ static u8 snd_base_studio;
static u8 snd_max_studios;
static u8 s3dUseMaxVoices;
static void UpdateRoomDistances() {
SND_ROOM* r; // r30
SND_LISTENER* li; // r31
@ -260,17 +260,17 @@ bool sndRemoveDoor(SND_DOOR* door) {
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
SND_LISTENER* li; // r31
SND_FVECTOR d; // r1+0x44
SND_FVECTOR v; // r1+0x38
SND_FVECTOR p; // r1+0x2C
float relspeed; // r60
float distance; // r61
float new_distance; // r59
float ft; // r63
float vd; // r62
SND_FVECTOR pan; // r1+0x20
unsigned long n; // r29
}
static u8 clip127(u8 v) {
@ -289,9 +289,31 @@ static u16 clip3FFF(u32 v) {
static void SetFXParameters(SND_EMITTER* em, float vol, float xPan, float yPan, float zPan,
float doppler) {
unsigned long vid; // r30
unsigned char i; // r28
struct SND_PARAMETER* pPtr; // r31
SND_VOICEID vid; // r30
u8 i; // r28
SND_PARAMETER* pPtr; // r31
vid = em->vid;
if ((em->flags & 0x100000) != 0) {
synthFXSetCtrl(vid, 7, clip127((em->fade * vol) * 127.f));
} else {
synthFXSetCtrl(vid, 7, clip127(vol * 127.f));
}
synthFXSetCtrl(vid, 10, clip127((1.f + xPan) * 64.f));
synthFXSetCtrl(vid, 131, clip127((1.f - zPan) * 64.f));
synthFXSetCtrl14(vid, 132, clip3FFF(doppler * 8192.f));
if (em->paraInfo != NULL) {
pPtr = em->paraInfo->paraArray;
for (i = 0; i < em->paraInfo->numPara; ++pPtr, ++i) {
if (pPtr->ctrl < 0x40 || pPtr->ctrl == 0x80 || pPtr->ctrl == 0x84) {
synthFXSetCtrl14(vid, pPtr->ctrl, (pPtr->paraData).value14);
} else {
synthFXSetCtrl(vid, pPtr->ctrl, (pPtr->paraData).value7);
}
}
}
}
static void EmitterShutdown(SND_EMITTER* em) {

View File

@ -1,4 +1,6 @@
#include "musyx/musyx_priv.h"
#include "musyx/seq.h"
#include "musyx/synth.h"
static u8 DebugMacroSteps = 0;
@ -292,9 +294,37 @@ static void mcmdUntrapEvent(SYNTH_VOICE* svoice, MSTEP* cstep) {
svoice->trapEventAny = 0;
}
#pragma dont_inline on
static void mcmdLoop(SYNTH_VOICE* svoice, MSTEP* cstep) {}
#pragma dont_inline reset
static void mcmdLoop(SYNTH_VOICE* svoice, MSTEP* cstep) {
if (svoice->loop == 0) {
if ((u8)(cstep->para[0] >> 16) & 1) {
svoice->loop = sndRand() % (s32)(cstep->para[1] >> 16);
} else {
svoice->loop = (cstep->para[1] >> 16);
}
if (svoice->loop == 0xFFFF) {
goto skip;
}
++svoice->loop;
} else if (svoice->loop == 0xFFFF) {
goto skip;
}
if (--svoice->loop == 0) {
return;
}
skip:
if (((u8)(cstep->para[0] >> 8) & 1) != 0 && (svoice->cFlags & 0x10000000008) == 0x00000000008) {
svoice->loop = 0;
} else if (((u8)(cstep->para[0] >> 0x18) & 1) && (svoice->cFlags & 0x20) == 0 &&
!hwIsActive(svoice->id & 0xFF)) {
svoice->loop = 0;
} else {
svoice->curAddr = svoice->addr + ((u16)cstep->para[1]);
}
}
static void mcmdPlayMacro(SYNTH_VOICE* svoice, MSTEP* cstep) {
s32 key; // r29
@ -585,6 +615,26 @@ static void DoSetPitch(SYNTH_VOICE* svoice) {
static u16 kf[13] = {
4096, 4339, 4597, 4871, 5160, 5467, 5792, 6137, 6502, 6888, 7298, 7732, 8192,
};
frq = svoice->playFrq & 0xFFFFFF;
ofrq = svoice->sInfo & 0xFFFFFF;
if (ofrq == frq) {
svoice->curNote = svoice->sInfo >> 24;
} else if (ofrq < frq) {
f = (frq << 12) / ofrq;
for (no = 0; no < 11 && (1 << ((no + 1) & 0x3f)) < (f >> 12); ++no) {
}
f /= (1 << (no & 0x3f));
for (i = 11; f <= kf[i]; i--) {
}
svoice->curNote = (svoice->sInfo >> 24) + no * 12 + i;
svoice->curDetune = (no - kf[i]) * 100 / (kf[i + 1] - kf[i]);
}
}
#pragma dont_inline reset
@ -1494,9 +1544,9 @@ void macSampleEndNotify(SYNTH_VOICE* sv) {
if (sv->macState != MAC_STATE_YIELDED) {
return;
}
#line 3156 /* clang-format off */
/* clang-format off */
MUSY_ASSERT(sv->addr!=NULL);
/* clang-format on */
/* clang-format on */
if (!ExecuteTrap(sv, 1) && (sv->cFlags & 0x40000)) {
macMakeActive(sv);
@ -1588,9 +1638,9 @@ void macMakeActive(SYNTH_VOICE* sv) {
if (sv->macState == MAC_STATE_RUNNABLE) {
return;
}
#line 3297 /* clang-format off */
/* clang-format off */
MUSY_ASSERT(sv->addr!=NULL);
/* clang-format on */
/* clang-format on */
UnYieldMacro(sv, 0);
if (sv->nextMacActive = macActiveMacroRoot) {
macActiveMacroRoot->prevMacActive = sv;
@ -1605,9 +1655,9 @@ void macMakeInactive(SYNTH_VOICE* svoice, MAC_STATE newState) {
return;
}
#line 3333 /* clang-format off */
/* clang-format off */
MUSY_ASSERT(svoice->addr!=NULL);
/* clang-format on */
/* clang-format on */
if (svoice->macState == MAC_STATE_RUNNABLE) {
if (svoice->prevMacActive == NULL) {
macActiveMacroRoot = svoice->nextMacActive;
@ -1634,6 +1684,77 @@ u32 macStart(u16 macid, u8 priority, u8 maxVoices, u16 allocId, u8 key, u8 vol,
MSTEP* addr; // r28
SYNTH_VOICE* svoice; // r31
u16 seqPrio; // r24
if ((addr = dataGetMacro(macid))) {
if (!(key & 0x80) && (seqPrio = seqGetMIDIPriority(midiSet, midi)) != 0xFFFF) {
priority = seqPrio;
}
if ((voice = voiceAllocate(priority, maxVoices, allocId, (key & 0x80) ? 1 : 0)) != -1) {
svoice = &synthVoice[voice];
vidRemoveVoiceReferences(svoice);
macMakeInactive(svoice, MAC_STATE_STOPPED);
svoice->cFlags = (svoice->cFlags & 0x10) | 2;
if (hwIsActive(voice)) {
svoice->cFlags |= 1;
}
svoice->wait = 0;
if ((key & 0x80) != 0) {
svoice->fxFlag = 01;
key &= 0x7f;
inpResetMidiCtrl(voice, 0xff, 1);
inpResetChannelDefaults(voice, 0xff);
svoice->setup.midi = voice;
svoice->setup.midiSet = 0xff;
svoice->setup.section = 0;
} else {
svoice->fxFlag = 0;
svoice->setup.midi = midi;
svoice->setup.midiSet = midiSet;
svoice->setup.section = section;
}
svoice->macroId = macid;
svoice->allocId = allocId;
svoice->age = 0x75300000;
svoice->ageSpeed = 0x400;
svoice->addr = addr;
svoice->curAddr = addr + step;
svoice->orgNote = key;
svoice->curNote = key;
svoice->curDetune = 0;
svoice->setup.vol = vol;
svoice->setup.pan = panning;
svoice->setup.track = trackid;
svoice->callStackEntryNum = 0;
svoice->callStackIndex = 0;
svoice->child = -1;
svoice->parent = -1;
svoice->lastVID = -1;
svoice->setup.vGroup = vGroup;
svoice->setup.studio = studio;
svoice->setup.itdMode = itd != 0 ? 0 : 1;
svoice->mesgNum = svoice->mesgRead = svoice->mesgWrite = 0;
svoice->id = voice | ((macid << 16) | (key << 8));
voiceSetPriority(svoice, priority);
if ((vid = vidMakeNew(svoice, new_vid)) != -1) {
macMakeActive(svoice);
return vid;
}
if (hwIsActive(voice)) {
hwBreak(voice);
}
voiceFree(svoice);
}
}
return -1;
}
void macInit() {

View File

@ -220,12 +220,11 @@ void __win_log_refresh(struct STRUCT_WIN* handle) {
unsigned short index; // r1+0xC
#line 506
MUSY_ASSERT_MSG(handle != NULL, "OHMYGAWD\n");
n = (u32)handle->curr_output_line;
n = handle->curr_output_line;
x = handle->x1;
y = handle->y2;
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[n]);
index = n + (u16)(n + (handle->total_lines - 1)) % (u32)handle->total_lines;
DEMOPrintf(x, (y + i) % 2, 0, "%s", handle->buffer[index]);
}
}