mirror of https://github.com/PrimeDecomp/prime.git
parent
eb7ee60f79
commit
4c2d5594ba
|
@ -3,8 +3,8 @@
|
|||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/libc"
|
||||
"${workspaceFolder}/include/**",
|
||||
"${workspaceFolder}/libc/**"
|
||||
],
|
||||
"cStandard": "c99",
|
||||
"cppStandard": "c++98",
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
"osfont.h": "c",
|
||||
"arq.h": "c",
|
||||
"string.h": "c",
|
||||
"hw_regs.h": "c"
|
||||
"hw_regs.h": "c",
|
||||
"synth.h": "c"
|
||||
},
|
||||
"files.autoSave": "onFocusChange",
|
||||
"files.insertFinalNewline": true,
|
||||
|
|
|
@ -925,7 +925,7 @@ LIBS = [
|
|||
"cflags": "$cflags_musyx -DMUSY_VERSION_MAJOR=1 -DMUSY_VERSION_MINOR=5 -DMUSY_VERSION_PATCH=4",
|
||||
"host": False,
|
||||
"objects": [
|
||||
"musyx/runtime/seq",
|
||||
["musyx/runtime/seq", False],
|
||||
["musyx/runtime/synth", False],
|
||||
["musyx/runtime/seq_api", True],
|
||||
["musyx/runtime/snd_synthapi", True, {"add_to_all": False}],
|
||||
|
@ -1034,6 +1034,7 @@ LIBS = [
|
|||
{
|
||||
"lib": "gba",
|
||||
"mw_version": "1.2.5e",
|
||||
#"cflags" : "-proc gecko -Cpp_exceptions off -fp hard -nodefaults -nosyspath -i include -i libc -g -sym on -D_DEBUG=1 -enum int -use_lmw_stmw on",
|
||||
"cflags": "$cflags_base",
|
||||
"host": False,
|
||||
"objects": [
|
||||
|
@ -1043,7 +1044,7 @@ LIBS = [
|
|||
["Dolphin/GBA/GBARead", True],
|
||||
["Dolphin/GBA/GBAWrite", True],
|
||||
["Dolphin/GBA/GBAXfer", True],
|
||||
"Dolphin/GBA/GBAKey",
|
||||
["Dolphin/GBA/GBAKey", True],
|
||||
],
|
||||
},
|
||||
]
|
||||
|
|
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
|
||||
typedef void (*GBATransferCallback)(s32 chan);
|
||||
|
||||
typedef struct GBASecParams {
|
||||
typedef struct GBASecParam {
|
||||
u8 readbuf[4];
|
||||
s32 paletteColor;
|
||||
s32 paletteSpeed;
|
||||
|
@ -23,7 +23,7 @@ typedef struct GBASecParams {
|
|||
u32 keyA;
|
||||
s32 keyB;
|
||||
u8 _padding1[24];
|
||||
} GBASecParams;
|
||||
} GBASecParam;
|
||||
|
||||
typedef struct GBABootInfo {
|
||||
s32 paletteColor;
|
||||
|
@ -61,7 +61,7 @@ typedef struct GBAControl {
|
|||
GBATransferCallback proc;
|
||||
GBABootInfo bootInfo;
|
||||
DSPTaskInfo task;
|
||||
GBASecParams* param;
|
||||
GBASecParam* param;
|
||||
} GBAControl;
|
||||
|
||||
extern GBAControl __GBA[4];
|
||||
|
|
|
@ -29,12 +29,21 @@ u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h
|
|||
#define OS_CORE_CLOCK __OSCoreClock
|
||||
#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4)
|
||||
|
||||
#ifndef _DEBUG
|
||||
#define OSPhysicalToCached(paddr) ((void*)((u32)(paddr) + OS_BASE_CACHED))
|
||||
#define OSPhysicalToUncached(paddr) ((void*)((u32)(paddr) + OS_BASE_UNCACHED))
|
||||
#define OSCachedToPhysical(caddr) ((u32)((u8*)(caddr)-OS_BASE_CACHED))
|
||||
#define OSUncachedToPhysical(ucaddr) ((u32)((u8*)(ucaddr)-OS_BASE_UNCACHED))
|
||||
#define OSCachedToUncached(caddr) ((void*)((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED)))
|
||||
#define OSUncachedToCached(ucaddr) ((void*)((u8*)(ucaddr) - (OS_BASE_UNCACHED - OS_BASE_CACHED)))
|
||||
#else
|
||||
u32 OSPhysicalToCached(void* paddr);
|
||||
u32 OSPhysicalToUncached(void* paddr);
|
||||
u32 OSCachedToPhysical(void* caddr);
|
||||
u32 OSUncachedToPhysical(void* ucaddr);
|
||||
u32 OSCachedToUncached(void* caddr);
|
||||
u32 OSUncachedToCached(void* ucaddr);
|
||||
#endif
|
||||
|
||||
#define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2)
|
||||
#define OSTicksToSeconds(ticks) ((ticks) / OS_TIMER_CLOCK)
|
||||
|
|
|
@ -1,30 +1,25 @@
|
|||
#ifndef _MUSYX_ASSERT
|
||||
#define _MUSYX_ASSERT
|
||||
#include "musyx/version.h"
|
||||
|
||||
extern void OSPanic(const char* file, int line, const char* msg, ...);
|
||||
extern void OSReport(const char* msg, ...);
|
||||
|
||||
static inline unsigned __SOME_ASSERT_DERP1() {
|
||||
return 0;
|
||||
}
|
||||
static inline unsigned __SOME_ASSERT_DERP1() { return 0; }
|
||||
|
||||
static inline unsigned __SOME_ASSERT_DERP2() {
|
||||
return __SOME_ASSERT_DERP1();
|
||||
}
|
||||
static inline unsigned __SOME_ASSERT_DERP2() { return __SOME_ASSERT_DERP1(); }
|
||||
|
||||
static inline void __SOME_ASSERT_DERP() {
|
||||
__SOME_ASSERT_DERP2() != 0;
|
||||
}
|
||||
static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; }
|
||||
|
||||
#ifndef ASSERT
|
||||
#ifdef _DEBUG
|
||||
#define MUSY_ASSERT(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
OSPanic(__FILE__, __LINE__, "Failed assertion " #cond); \
|
||||
} \
|
||||
__SOME_ASSERT_DERP(); \
|
||||
} while(0)
|
||||
#define MUSY_ASSERT(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
OSPanic(__FILE__, __LINE__, "Failed assertion " #cond); \
|
||||
} \
|
||||
__SOME_ASSERT_DERP(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define MUSY_ASSERT(cond)
|
||||
#endif
|
||||
|
@ -32,12 +27,27 @@ static inline void __SOME_ASSERT_DERP() {
|
|||
|
||||
#ifndef MUSY_ASSERT_MSG
|
||||
#ifdef _DEBUG
|
||||
#define MUSY_ASSERT_MSG(cond, msg) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
OSPanic(__FILE__, __LINE__, msg); \
|
||||
} \
|
||||
} while(0)
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
|
||||
#define MUSY_ASSERT_MSG(cond, msg) \
|
||||
do { \
|
||||
s32 tmp = 1; \
|
||||
s32 tmp2; \
|
||||
if (!(cond)) { \
|
||||
OSPanic(__FILE__, __LINE__, msg); \
|
||||
tmp2 = 0; \
|
||||
if (tmp2 == 0) { \
|
||||
tmp = 0; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define MUSY_ASSERT_MSG(cond, msg) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
OSPanic(__FILE__, __LINE__, msg); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#else
|
||||
#define MUSY_ASSERT_MSG(cond, msg)
|
||||
#endif
|
||||
|
@ -51,4 +61,12 @@ static inline void __SOME_ASSERT_DERP() {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MUSY_FATAL
|
||||
#ifdef _DEBUG
|
||||
#define MUSY_FATAL(msg) OSPanic(__FILE__, __LINE__, msg)
|
||||
#else
|
||||
#define MUSY_FATAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // _MUSYX_ASSERT
|
||||
|
|
|
@ -39,6 +39,10 @@ typedef signed long bool;
|
|||
|
||||
#define SYNTH_MAX_VOICES 64
|
||||
|
||||
typedef struct SND_ADPCMSTREAM_INFO {
|
||||
s16 coefTab[8][2]; // Table of coef. pairs
|
||||
} SND_ADPCMSTREAM_INFO;
|
||||
|
||||
typedef u32 SND_SEQID;
|
||||
typedef u32 SND_VOICEID;
|
||||
typedef u32 SND_STREAMID;
|
||||
|
@ -65,6 +69,13 @@ typedef struct SND_SEQVOLDEF {
|
|||
u8 volGroup;
|
||||
} SND_SEQVOLDEF;
|
||||
|
||||
#define SND_PLAYPARA_DEFAULT 0x00000000
|
||||
#define SND_PLAYPARA_TRACKMUTE 0x00000001
|
||||
#define SND_PLAYPARA_SPEED 0x00000002
|
||||
#define SND_PLAYPARA_VOLUME 0x00000004
|
||||
#define SND_PLAYPARA_SEQVOLDEF 0x00000008
|
||||
#define SND_PLAYPARA_PAUSE 0x00000010
|
||||
|
||||
typedef struct SND_PLAYPARA {
|
||||
u32 flags;
|
||||
u32 trackMute[2];
|
||||
|
@ -310,6 +321,37 @@ bool sndAuxCallbackPrepareChorus(SND_AUX_CHORUS* ch);
|
|||
bool sndAuxCallbackShutdownChorus(SND_AUX_CHORUS* ch);
|
||||
bool sndAuxCallbackUpdateSettingsChorus(SND_AUX_CHORUS* ch);
|
||||
|
||||
#define SND_CROSSFADE_STOP 0 // Stop old song after fadedown
|
||||
#define SND_CROSSFADE_PAUSE 1 // Pause old song after fadedown
|
||||
#define SND_CROSSFADE_CONTINUE 2 // Continue previously paused song as new one
|
||||
#define SND_CROSSFADE_START 0 // Start new song (no continue)
|
||||
#define SND_CROSSFADE_SYNC 4 // Crossfade should start syncronized by sync-controller (104)
|
||||
#define SND_CROSSFADE_PAUSENEW 8 // Pause new song before even starting it
|
||||
#define SND_CROSSFADE_TRACKMUTE 16 // Use trackmute informtion
|
||||
#define SND_CROSSFADE_SPEED 32 // Use speed informtion
|
||||
#define SND_CROSSFADE_MUTE 64 // Old song continues playing & gets muted after fade down
|
||||
#define SND_CROSSFADE_MUTENEW 128 // Mute new song after starting it
|
||||
|
||||
#define SND_CROSSFADE_DEFAULT 0
|
||||
|
||||
typedef struct SND_CROSSFADE {
|
||||
SND_SEQID seqId1;
|
||||
u16 time1;
|
||||
|
||||
SND_SEQID seqId2;
|
||||
u16 time2;
|
||||
void* arr2;
|
||||
SND_GROUPID gid2;
|
||||
SND_SONGID sid2;
|
||||
u8 vol2;
|
||||
u8 studio2;
|
||||
|
||||
u32 trackMute2[2];
|
||||
u16 speed2;
|
||||
|
||||
u8 flags;
|
||||
} SND_CROSSFADE;
|
||||
|
||||
typedef struct SND_PROFILE_DATA {
|
||||
unsigned long loadStores;
|
||||
unsigned long missCycles;
|
||||
|
|
|
@ -10,10 +10,10 @@ extern "C" {
|
|||
|
||||
typedef struct SND_STUDIO_INPUT {
|
||||
// total size: 0x4
|
||||
unsigned char vol; // offset 0x0, size 0x1
|
||||
unsigned char volA; // offset 0x1, size 0x1
|
||||
unsigned char volB; // offset 0x2, size 0x1
|
||||
unsigned char srcStudio; // offset 0x3, size 0x1
|
||||
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 {
|
||||
|
@ -28,8 +28,8 @@ extern SYNTH_VOICELIST voicePrioSortVoices[64];
|
|||
|
||||
typedef struct SYNTH_ROOTLIST {
|
||||
// total size: 0x4
|
||||
unsigned short next; // offset 0x0, size 0x2
|
||||
unsigned short prev; // offset 0x2, size 0x2
|
||||
u16 next; // offset 0x0, size 0x2
|
||||
u16 prev; // offset 0x2, size 0x2
|
||||
} SYNTH_ROOTLIST;
|
||||
|
||||
extern SYNTH_ROOTLIST voicePrioSortRootList[256];
|
||||
|
@ -73,117 +73,117 @@ typedef struct ADSR_VARS {
|
|||
|
||||
typedef struct _PBMIX {
|
||||
// total size: 0x24
|
||||
unsigned short vL; // offset 0x0, size 0x2
|
||||
unsigned short vDeltaL; // offset 0x2, size 0x2
|
||||
unsigned short vR; // offset 0x4, size 0x2
|
||||
unsigned short vDeltaR; // offset 0x6, size 0x2
|
||||
unsigned short vAuxAL; // offset 0x8, size 0x2
|
||||
unsigned short vDeltaAuxAL; // offset 0xA, size 0x2
|
||||
unsigned short vAuxAR; // offset 0xC, size 0x2
|
||||
unsigned short vDeltaAuxAR; // offset 0xE, size 0x2
|
||||
unsigned short vAuxBL; // offset 0x10, size 0x2
|
||||
unsigned short vDeltaAuxBL; // offset 0x12, size 0x2
|
||||
unsigned short vAuxBR; // offset 0x14, size 0x2
|
||||
unsigned short vDeltaAuxBR; // offset 0x16, size 0x2
|
||||
unsigned short vAuxBS; // offset 0x18, size 0x2
|
||||
unsigned short vDeltaAuxBS; // offset 0x1A, size 0x2
|
||||
unsigned short vS; // offset 0x1C, size 0x2
|
||||
unsigned short vDeltaS; // offset 0x1E, size 0x2
|
||||
unsigned short vAuxAS; // offset 0x20, size 0x2
|
||||
unsigned short vDeltaAuxAS; // offset 0x22, size 0x2
|
||||
u16 vL; // offset 0x0, size 0x2
|
||||
u16 vDeltaL; // offset 0x2, size 0x2
|
||||
u16 vR; // offset 0x4, size 0x2
|
||||
u16 vDeltaR; // offset 0x6, size 0x2
|
||||
u16 vAuxAL; // offset 0x8, size 0x2
|
||||
u16 vDeltaAuxAL; // offset 0xA, size 0x2
|
||||
u16 vAuxAR; // offset 0xC, size 0x2
|
||||
u16 vDeltaAuxAR; // offset 0xE, size 0x2
|
||||
u16 vAuxBL; // offset 0x10, size 0x2
|
||||
u16 vDeltaAuxBL; // offset 0x12, size 0x2
|
||||
u16 vAuxBR; // offset 0x14, size 0x2
|
||||
u16 vDeltaAuxBR; // offset 0x16, size 0x2
|
||||
u16 vAuxBS; // offset 0x18, size 0x2
|
||||
u16 vDeltaAuxBS; // offset 0x1A, size 0x2
|
||||
u16 vS; // offset 0x1C, size 0x2
|
||||
u16 vDeltaS; // offset 0x1E, size 0x2
|
||||
u16 vAuxAS; // offset 0x20, size 0x2
|
||||
u16 vDeltaAuxAS; // offset 0x22, size 0x2
|
||||
} _PBMIX;
|
||||
|
||||
typedef struct _PBITD {
|
||||
// total size: 0xE
|
||||
unsigned short flag; // offset 0x0, size 0x2
|
||||
unsigned short bufferHi; // offset 0x2, size 0x2
|
||||
unsigned short bufferLo; // offset 0x4, size 0x2
|
||||
unsigned short shiftL; // offset 0x6, size 0x2
|
||||
unsigned short shiftR; // offset 0x8, size 0x2
|
||||
unsigned short targetShiftL; // offset 0xA, size 0x2
|
||||
unsigned short targetShiftR; // offset 0xC, size 0x2
|
||||
u16 flag; // offset 0x0, size 0x2
|
||||
u16 bufferHi; // offset 0x2, size 0x2
|
||||
u16 bufferLo; // offset 0x4, size 0x2
|
||||
u16 shiftL; // offset 0x6, size 0x2
|
||||
u16 shiftR; // offset 0x8, size 0x2
|
||||
u16 targetShiftL; // offset 0xA, size 0x2
|
||||
u16 targetShiftR; // offset 0xC, size 0x2
|
||||
} _PBITD;
|
||||
|
||||
typedef struct _PBUPDATE {
|
||||
// total size: 0xE
|
||||
unsigned short updNum[5]; // offset 0x0, size 0xA
|
||||
unsigned short dataHi; // offset 0xA, size 0x2
|
||||
unsigned short dataLo; // offset 0xC, size 0x2
|
||||
u16 updNum[5]; // offset 0x0, size 0xA
|
||||
u16 dataHi; // offset 0xA, size 0x2
|
||||
u16 dataLo; // offset 0xC, size 0x2
|
||||
} _PBUPDATE;
|
||||
|
||||
typedef struct _PBDPOP {
|
||||
// total size: 0x12
|
||||
unsigned short aL; // offset 0x0, size 0x2
|
||||
unsigned short aAuxAL; // offset 0x2, size 0x2
|
||||
unsigned short aAuxBL; // offset 0x4, size 0x2
|
||||
unsigned short aR; // offset 0x6, size 0x2
|
||||
unsigned short aAuxAR; // offset 0x8, size 0x2
|
||||
unsigned short aAuxBR; // offset 0xA, size 0x2
|
||||
unsigned short aS; // offset 0xC, size 0x2
|
||||
unsigned short aAuxAS; // offset 0xE, size 0x2
|
||||
unsigned short aAuxBS; // offset 0x10, size 0x2
|
||||
u16 aL; // offset 0x0, size 0x2
|
||||
u16 aAuxAL; // offset 0x2, size 0x2
|
||||
u16 aAuxBL; // offset 0x4, size 0x2
|
||||
u16 aR; // offset 0x6, size 0x2
|
||||
u16 aAuxAR; // offset 0x8, size 0x2
|
||||
u16 aAuxBR; // offset 0xA, size 0x2
|
||||
u16 aS; // offset 0xC, size 0x2
|
||||
u16 aAuxAS; // offset 0xE, size 0x2
|
||||
u16 aAuxBS; // offset 0x10, size 0x2
|
||||
} _PBDPOP;
|
||||
|
||||
typedef struct _PBVE {
|
||||
// total size: 0x4
|
||||
unsigned short currentVolume; // offset 0x0, size 0x2
|
||||
unsigned short currentDelta; // offset 0x2, size 0x2
|
||||
u16 currentVolume; // offset 0x0, size 0x2
|
||||
u16 currentDelta; // offset 0x2, size 0x2
|
||||
} _PBVE;
|
||||
|
||||
typedef struct _PBFIR {
|
||||
// total size: 0x6
|
||||
unsigned short numCoefs; // offset 0x0, size 0x2
|
||||
unsigned short coefsHi; // offset 0x2, size 0x2
|
||||
unsigned short coefsLo; // offset 0x4, size 0x2
|
||||
u16 numCoefs; // offset 0x0, size 0x2
|
||||
u16 coefsHi; // offset 0x2, size 0x2
|
||||
u16 coefsLo; // offset 0x4, size 0x2
|
||||
} _PBFIR;
|
||||
|
||||
typedef struct _PBADDR {
|
||||
// total size: 0x10
|
||||
unsigned short loopFlag; // offset 0x0, size 0x2
|
||||
unsigned short format; // offset 0x2, size 0x2
|
||||
unsigned short loopAddressHi; // offset 0x4, size 0x2
|
||||
unsigned short loopAddressLo; // offset 0x6, size 0x2
|
||||
unsigned short endAddressHi; // offset 0x8, size 0x2
|
||||
unsigned short endAddressLo; // offset 0xA, size 0x2
|
||||
unsigned short currentAddressHi; // offset 0xC, size 0x2
|
||||
unsigned short currentAddressLo; // offset 0xE, size 0x2
|
||||
u16 loopFlag; // offset 0x0, size 0x2
|
||||
u16 format; // offset 0x2, size 0x2
|
||||
u16 loopAddressHi; // offset 0x4, size 0x2
|
||||
u16 loopAddressLo; // offset 0x6, size 0x2
|
||||
u16 endAddressHi; // offset 0x8, size 0x2
|
||||
u16 endAddressLo; // offset 0xA, size 0x2
|
||||
u16 currentAddressHi; // offset 0xC, size 0x2
|
||||
u16 currentAddressLo; // offset 0xE, size 0x2
|
||||
} _PBADDR;
|
||||
|
||||
typedef struct _PBADPCM {
|
||||
// total size: 0x28
|
||||
unsigned short a[8][2]; // offset 0x0, size 0x20
|
||||
unsigned short gain; // offset 0x20, size 0x2
|
||||
unsigned short pred_scale; // offset 0x22, size 0x2
|
||||
unsigned short yn1; // offset 0x24, size 0x2
|
||||
unsigned short yn2; // offset 0x26, size 0x2
|
||||
u16 a[8][2]; // offset 0x0, size 0x20
|
||||
u16 gain; // offset 0x20, size 0x2
|
||||
u16 pred_scale; // offset 0x22, size 0x2
|
||||
u16 yn1; // offset 0x24, size 0x2
|
||||
u16 yn2; // offset 0x26, size 0x2
|
||||
} _PDADPCM;
|
||||
|
||||
typedef struct _PBSRC {
|
||||
// total size: 0xE
|
||||
unsigned short ratioHi; // offset 0x0, size 0x2
|
||||
unsigned short ratioLo; // offset 0x2, size 0x2
|
||||
unsigned short currentAddressFrac; // offset 0x4, size 0x2
|
||||
unsigned short last_samples[4]; // offset 0x6, size 0x8
|
||||
u16 ratioHi; // offset 0x0, size 0x2
|
||||
u16 ratioLo; // offset 0x2, size 0x2
|
||||
u16 currentAddressFrac; // offset 0x4, size 0x2
|
||||
u16 last_samples[4]; // offset 0x6, size 0x8
|
||||
} _PBSRC;
|
||||
|
||||
typedef struct _PBADPCMLOOP {
|
||||
// total size: 0x6
|
||||
unsigned short loop_pred_scale; // offset 0x0, size 0x2
|
||||
unsigned short loop_yn1; // offset 0x2, size 0x2
|
||||
unsigned short loop_yn2; // offset 0x4, size 0x2
|
||||
u16 loop_pred_scale; // offset 0x0, size 0x2
|
||||
u16 loop_yn1; // offset 0x2, size 0x2
|
||||
u16 loop_yn2; // offset 0x4, size 0x2
|
||||
} _PBADPCMLOOP;
|
||||
|
||||
typedef struct _PB {
|
||||
// total size: 0xBC
|
||||
unsigned short nextHi; // offset 0x0, size 0x2
|
||||
unsigned short nextLo; // offset 0x2, size 0x2
|
||||
unsigned short currHi; // offset 0x4, size 0x2
|
||||
unsigned short currLo; // offset 0x6, size 0x2
|
||||
unsigned short srcSelect; // offset 0x8, size 0x2
|
||||
unsigned short coefSelect; // offset 0xA, size 0x2
|
||||
unsigned short mixerCtrl; // offset 0xC, size 0x2
|
||||
unsigned short state; // offset 0xE, size 0x2
|
||||
unsigned short loopType; // offset 0x10, size 0x2
|
||||
u16 nextHi; // offset 0x0, size 0x2
|
||||
u16 nextLo; // offset 0x2, size 0x2
|
||||
u16 currHi; // offset 0x4, size 0x2
|
||||
u16 currLo; // offset 0x6, size 0x2
|
||||
u16 srcSelect; // offset 0x8, size 0x2
|
||||
u16 coefSelect; // offset 0xA, size 0x2
|
||||
u16 mixerCtrl; // offset 0xC, size 0x2
|
||||
u16 state; // offset 0xE, size 0x2
|
||||
u16 loopType; // offset 0x10, size 0x2
|
||||
struct _PBMIX mix; // offset 0x12, size 0x24
|
||||
struct _PBITD itd; // offset 0x36, size 0xE
|
||||
struct _PBUPDATE update; // offset 0x44, size 0xE
|
||||
|
@ -194,7 +194,7 @@ typedef struct _PB {
|
|||
struct _PBADPCM adpcm; // offset 0x7E, size 0x28
|
||||
struct _PBSRC src; // offset 0xA6, size 0xE
|
||||
struct _PBADPCMLOOP adpcmLoop; // offset 0xB4, size 0x6
|
||||
unsigned short streamLoopCnt; // offset 0xBA, size 0x2
|
||||
u16 streamLoopCnt; // offset 0xBA, size 0x2
|
||||
} _PB;
|
||||
|
||||
typedef struct SAMPLE_INFO {
|
||||
|
@ -211,81 +211,81 @@ typedef struct SAMPLE_INFO {
|
|||
|
||||
typedef struct GROUP_DATA {
|
||||
// total size: 0x28
|
||||
unsigned long nextOff; // offset 0x0, size 0x4
|
||||
unsigned short id; // offset 0x4, size 0x2
|
||||
unsigned short type; // offset 0x6, size 0x2
|
||||
unsigned long macroOff; // offset 0x8, size 0x4
|
||||
unsigned long sampleOff; // offset 0xC, size 0x4
|
||||
unsigned long curveOff; // offset 0x10, size 0x4
|
||||
unsigned long keymapOff; // offset 0x14, size 0x4
|
||||
unsigned long layerOff; // offset 0x18, size 0x4
|
||||
u32 nextOff; // offset 0x0, size 0x4
|
||||
u16 id; // offset 0x4, size 0x2
|
||||
u16 type; // offset 0x6, size 0x2
|
||||
u32 macroOff; // offset 0x8, size 0x4
|
||||
u32 sampleOff; // offset 0xC, size 0x4
|
||||
u32 curveOff; // offset 0x10, size 0x4
|
||||
u32 keymapOff; // offset 0x14, size 0x4
|
||||
u32 layerOff; // offset 0x18, size 0x4
|
||||
union {
|
||||
struct fx {
|
||||
// total size: 0x4
|
||||
unsigned long tableOff; // offset 0x0, size 0x4
|
||||
u32 tableOff; // offset 0x0, size 0x4
|
||||
} fx;
|
||||
struct song {
|
||||
// total size: 0xC
|
||||
unsigned long normpageOff; // offset 0x0, size 0x4
|
||||
unsigned long drumpageOff; // offset 0x4, size 0x4
|
||||
unsigned long midiSetupOff; // offset 0x8, size 0x4
|
||||
u32 normpageOff; // offset 0x0, size 0x4
|
||||
u32 drumpageOff; // offset 0x4, size 0x4
|
||||
u32 midiSetupOff; // offset 0x8, size 0x4
|
||||
} song;
|
||||
} data; // offset 0x1C, size 0xC
|
||||
} GROUP_DATA;
|
||||
|
||||
typedef struct SAMPLE_HEADER {
|
||||
// total size: 0x10
|
||||
unsigned long info; // offset 0x0, size 0x4
|
||||
unsigned long length; // offset 0x4, size 0x4
|
||||
unsigned long loopOffset; // offset 0x8, size 0x4
|
||||
unsigned long loopLength; // offset 0xC, size 0x4
|
||||
u32 info; // offset 0x0, size 0x4
|
||||
u32 length; // offset 0x4, size 0x4
|
||||
u32 loopOffset; // offset 0x8, size 0x4
|
||||
u32 loopLength; // offset 0xC, size 0x4
|
||||
} SAMPLE_HEADER;
|
||||
|
||||
typedef struct SDIR_DATA {
|
||||
// total size: 0x20
|
||||
unsigned short id; // offset 0x0, size 0x2
|
||||
unsigned short ref_cnt; // offset 0x2, size 0x2
|
||||
unsigned long offset; // offset 0x4, size 0x4
|
||||
u16 id; // offset 0x0, size 0x2
|
||||
u16 ref_cnt; // offset 0x2, size 0x2
|
||||
u32 offset; // offset 0x4, size 0x4
|
||||
void* addr; // offset 0x8, size 0x4
|
||||
struct SAMPLE_HEADER header; // offset 0xC, size 0x10
|
||||
unsigned long extraData; // offset 0x1C, size 0x4
|
||||
u32 extraData; // offset 0x1C, size 0x4
|
||||
} SDIR_DATA;
|
||||
|
||||
typedef struct SDIR_TAB {
|
||||
// total size: 0xC
|
||||
struct SDIR_DATA* data; // offset 0x0, size 0x4
|
||||
void* base; // offset 0x4, size 0x4
|
||||
unsigned short numSmp; // offset 0x8, size 0x2
|
||||
unsigned short res; // offset 0xA, size 0x2
|
||||
u16 numSmp; // offset 0x8, size 0x2
|
||||
u16 res; // offset 0xA, size 0x2
|
||||
} SDIR_TAB;
|
||||
|
||||
typedef struct DATA_TAB {
|
||||
// total size: 0x8
|
||||
void* data; // offset 0x0, size 0x4
|
||||
unsigned short id; // offset 0x4, size 0x2
|
||||
unsigned short refCount; // offset 0x6, size 0x2
|
||||
void* data; // offset 0x0, size 0x4
|
||||
u16 id; // offset 0x4, size 0x2
|
||||
u16 refCount; // offset 0x6, size 0x2
|
||||
} DATA_TAB;
|
||||
|
||||
typedef struct LAYER_TAB {
|
||||
// total size: 0xC
|
||||
void* data; // offset 0x0, size 0x4
|
||||
unsigned short id; // offset 0x4, size 0x2
|
||||
unsigned short num; // offset 0x6, size 0x2
|
||||
unsigned short refCount; // offset 0x8, size 0x2
|
||||
unsigned short reserved; // offset 0xA, size 0x2
|
||||
void* data; // offset 0x0, size 0x4
|
||||
u16 id; // offset 0x4, size 0x2
|
||||
u16 num; // offset 0x6, size 0x2
|
||||
u16 refCount; // offset 0x8, size 0x2
|
||||
u16 reserved; // offset 0xA, size 0x2
|
||||
} LAYER_TAB;
|
||||
|
||||
typedef struct MAC_MAINTAB {
|
||||
// total size: 0x4
|
||||
unsigned short num; // offset 0x0, size 0x2
|
||||
unsigned short subTabIndex; // offset 0x2, size 0x2
|
||||
u16 num; // offset 0x0, size 0x2
|
||||
u16 subTabIndex; // offset 0x2, size 0x2
|
||||
} MAC_MAINTAB;
|
||||
|
||||
typedef struct MAC_SUBTAB {
|
||||
// total size: 0x8
|
||||
void* data; // offset 0x0, size 0x4
|
||||
unsigned short id; // offset 0x4, size 0x2
|
||||
unsigned short refCount; // offset 0x6, size 0x2
|
||||
void* data; // offset 0x0, size 0x4
|
||||
u16 id; // offset 0x4, size 0x2
|
||||
u16 refCount; // offset 0x6, size 0x2
|
||||
} MAC_SUBTAB;
|
||||
|
||||
typedef struct GSTACK {
|
||||
|
@ -414,19 +414,19 @@ typedef struct SYNTH_LFO {
|
|||
|
||||
typedef struct SYNTHMasterFader {
|
||||
// total size: 0x30
|
||||
float volume; // offset 0x0, size 0x4
|
||||
float target; // offset 0x4, size 0x4
|
||||
float start; // offset 0x8, size 0x4
|
||||
float time; // offset 0xC, size 0x4
|
||||
float deltaTime; // offset 0x10, size 0x4
|
||||
float pauseVol; // offset 0x14, size 0x4
|
||||
float pauseTarget; // offset 0x18, size 0x4
|
||||
float pauseStart; // offset 0x1C, size 0x4
|
||||
float pauseTime; // offset 0x20, size 0x4
|
||||
float pauseDeltaTime; // offset 0x24, size 0x4
|
||||
unsigned long seqId; // offset 0x28, size 0x4
|
||||
unsigned char seqMode; // offset 0x2C, size 0x1
|
||||
unsigned char type; // offset 0x2D, size 0x1
|
||||
float volume; // offset 0x0, size 0x4
|
||||
float target; // offset 0x4, size 0x4
|
||||
float start; // offset 0x8, size 0x4
|
||||
float time; // offset 0xC, size 0x4
|
||||
float deltaTime; // offset 0x10, size 0x4
|
||||
float pauseVol; // offset 0x14, size 0x4
|
||||
float pauseTarget; // offset 0x18, size 0x4
|
||||
float pauseStart; // offset 0x1C, size 0x4
|
||||
float pauseTime; // offset 0x20, size 0x4
|
||||
float pauseDeltaTime; // offset 0x24, size 0x4
|
||||
u32 seqId; // offset 0x28, size 0x4
|
||||
u8 seqMode; // offset 0x2C, size 0x1
|
||||
u8 type; // offset 0x2D, size 0x1
|
||||
} SYNTHMasterFader;
|
||||
|
||||
typedef struct CTRL_SOURCE {
|
||||
|
@ -443,40 +443,40 @@ typedef struct CTRL_DEST {
|
|||
|
||||
typedef struct SND_VIRTUALSAMPLE_INFO {
|
||||
// total size: 0x14
|
||||
unsigned short smpID; // offset 0x0, size 0x2
|
||||
unsigned short instID; // offset 0x2, size 0x2
|
||||
u16 smpID; // offset 0x0, size 0x2
|
||||
u16 instID; // offset 0x2, size 0x2
|
||||
union vsData {
|
||||
struct vsUpdate {
|
||||
// total size: 0x10
|
||||
unsigned long off1; // offset 0x0, size 0x4
|
||||
unsigned long len1; // offset 0x4, size 0x4
|
||||
unsigned long off2; // offset 0x8, size 0x4
|
||||
unsigned long len2; // offset 0xC, size 0x4
|
||||
u32 off1; // offset 0x0, size 0x4
|
||||
u32 len1; // offset 0x4, size 0x4
|
||||
u32 off2; // offset 0x8, size 0x4
|
||||
u32 len2; // offset 0xC, size 0x4
|
||||
} update;
|
||||
} data;
|
||||
} SND_VIRTUALSAMPLE_INFO;
|
||||
|
||||
typedef struct VS_BUFFER {
|
||||
// total size: 0x24
|
||||
unsigned char state; // offset 0x0, size 0x1
|
||||
unsigned char hwId; // offset 0x1, size 0x1
|
||||
unsigned char smpType; // offset 0x2, size 0x1
|
||||
unsigned char voice; // offset 0x3, size 0x1
|
||||
unsigned long last; // offset 0x4, size 0x4
|
||||
unsigned long finalGoodSamples; // offset 0x8, size 0x4
|
||||
unsigned long finalLast; // offset 0xC, size 0x4
|
||||
SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14
|
||||
u8 state; // offset 0x0, size 0x1
|
||||
u8 hwId; // offset 0x1, size 0x1
|
||||
u8 smpType; // offset 0x2, size 0x1
|
||||
u8 voice; // offset 0x3, size 0x1
|
||||
u32 last; // offset 0x4, size 0x4
|
||||
u32 finalGoodSamples; // offset 0x8, size 0x4
|
||||
u32 finalLast; // offset 0xC, size 0x4
|
||||
SND_VIRTUALSAMPLE_INFO info; // offset 0x10, size 0x14
|
||||
} VS_BUFFER;
|
||||
|
||||
typedef struct _VS {
|
||||
// total size: 0x950
|
||||
unsigned char numBuffers; // offset 0x0, size 0x1
|
||||
unsigned long bufferLength; // offset 0x4, size 0x4
|
||||
u8 numBuffers; // offset 0x0, size 0x1
|
||||
u32 bufferLength; // offset 0x4, size 0x4
|
||||
VS_BUFFER streamBuffer[64]; // offset 0x8, size 0x900
|
||||
unsigned char voices[64]; // offset 0x908, size 0x40
|
||||
unsigned short nextInstID; // offset 0x948, size 0x2
|
||||
unsigned long (*callback)(unsigned char,
|
||||
struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
|
||||
u8 voices[64]; // offset 0x908, size 0x40
|
||||
u16 nextInstID; // offset 0x948, size 0x2
|
||||
u32 (*callback)(u8,
|
||||
struct SND_VIRTUALSAMPLE_INFO*); // offset 0x94C, size 0x4
|
||||
} VS;
|
||||
|
||||
extern VS vs;
|
||||
|
@ -611,46 +611,46 @@ typedef struct SYNTH_VOICE {
|
|||
|
||||
typedef struct synthITDInfo {
|
||||
// total size: 0x2
|
||||
unsigned char music; // offset 0x0, size 0x1
|
||||
unsigned char sfx; // offset 0x1, size 0x1
|
||||
u8 music; // offset 0x0, size 0x1
|
||||
u8 sfx; // offset 0x1, size 0x1
|
||||
} synthITDInfo;
|
||||
|
||||
#pragma pop
|
||||
|
||||
typedef struct LAYER {
|
||||
// total size: 0xC
|
||||
unsigned short id; // offset 0x0, size 0x2
|
||||
unsigned char keyLow; // offset 0x2, size 0x1
|
||||
unsigned char keyHigh; // offset 0x3, size 0x1
|
||||
signed char transpose; // offset 0x4, size 0x1
|
||||
unsigned char volume; // offset 0x5, size 0x1
|
||||
signed short prioOffset; // offset 0x6, size 0x2
|
||||
unsigned char panning; // offset 0x8, size 0x1
|
||||
unsigned char reserved[3]; // offset 0x9, size 0x3
|
||||
u16 id; // offset 0x0, size 0x2
|
||||
u8 keyLow; // offset 0x2, size 0x1
|
||||
u8 keyHigh; // offset 0x3, size 0x1
|
||||
s8 transpose; // offset 0x4, size 0x1
|
||||
u8 volume; // offset 0x5, size 0x1
|
||||
s16 prioOffset; // offset 0x6, size 0x2
|
||||
u8 panning; // offset 0x8, size 0x1
|
||||
u8 reserved[3]; // offset 0x9, size 0x3
|
||||
} LAYER;
|
||||
|
||||
typedef struct KEYMAP {
|
||||
// total size: 0x8
|
||||
unsigned short id; // offset 0x0, size 0x2
|
||||
signed char transpose; // offset 0x2, size 0x1
|
||||
unsigned char panning; // offset 0x3, size 0x1
|
||||
signed short prioOffset; // offset 0x4, size 0x2
|
||||
unsigned char reserved[2]; // offset 0x6, size 0x2
|
||||
u16 id; // offset 0x0, size 0x2
|
||||
s8 transpose; // offset 0x2, size 0x1
|
||||
u8 panning; // offset 0x3, size 0x1
|
||||
s16 prioOffset; // offset 0x4, size 0x2
|
||||
u8 reserved[2]; // offset 0x6, size 0x2
|
||||
} KEYMAP;
|
||||
|
||||
typedef struct MEM_DATA {
|
||||
// total size: 0x408
|
||||
unsigned long nextOff; // offset 0x0, size 0x4
|
||||
unsigned short id; // offset 0x4, size 0x2
|
||||
unsigned short reserved; // offset 0x6, size 0x2
|
||||
u32 nextOff; // offset 0x0, size 0x4
|
||||
u16 id; // offset 0x4, size 0x2
|
||||
u16 reserved; // offset 0x6, size 0x2
|
||||
union {
|
||||
struct {
|
||||
// total size: 0x10
|
||||
unsigned long num; // offset 0x0, size 0x4
|
||||
LAYER entry[1]; // offset 0x4, size 0xC
|
||||
u32 num; // offset 0x0, size 0x4
|
||||
LAYER entry[1]; // offset 0x4, size 0xC
|
||||
} layer;
|
||||
KEYMAP map[128];
|
||||
unsigned char tab[1];
|
||||
u8 tab[1];
|
||||
MSTEP cmd[1][2];
|
||||
} data; // offset 0x8, size 0x400
|
||||
} MEM_DATA;
|
||||
|
@ -694,33 +694,33 @@ typedef struct SAL_PANINFO {
|
|||
|
||||
typedef struct _SPB {
|
||||
// total size: 0x36
|
||||
unsigned short dpopLHi; // offset 0x0, size 0x2
|
||||
unsigned short dpopLLo; // offset 0x2, size 0x2
|
||||
unsigned short dpopLDelta; // offset 0x4, size 0x2
|
||||
unsigned short dpopRHi; // offset 0x6, size 0x2
|
||||
unsigned short dpopRLo; // offset 0x8, size 0x2
|
||||
unsigned short dpopRDelta; // offset 0xA, size 0x2
|
||||
unsigned short dpopSHi; // offset 0xC, size 0x2
|
||||
unsigned short dpopSLo; // offset 0xE, size 0x2
|
||||
unsigned short dpopSDelta; // offset 0x10, size 0x2
|
||||
unsigned short dpopALHi; // offset 0x12, size 0x2
|
||||
unsigned short dpopALLo; // offset 0x14, size 0x2
|
||||
unsigned short dpopALDelta; // offset 0x16, size 0x2
|
||||
unsigned short dpopARHi; // offset 0x18, size 0x2
|
||||
unsigned short dpopARLo; // offset 0x1A, size 0x2
|
||||
unsigned short dpopARDelta; // offset 0x1C, size 0x2
|
||||
unsigned short dpopASHi; // offset 0x1E, size 0x2
|
||||
unsigned short dpopASLo; // offset 0x20, size 0x2
|
||||
unsigned short dpopASDelta; // offset 0x22, size 0x2
|
||||
unsigned short dpopBLHi; // offset 0x24, size 0x2
|
||||
unsigned short dpopBLLo; // offset 0x26, size 0x2
|
||||
unsigned short dpopBLDelta; // offset 0x28, size 0x2
|
||||
unsigned short dpopBRHi; // offset 0x2A, size 0x2
|
||||
unsigned short dpopBRLo; // offset 0x2C, size 0x2
|
||||
unsigned short dpopBRDelta; // offset 0x2E, size 0x2
|
||||
unsigned short dpopBSHi; // offset 0x30, size 0x2
|
||||
unsigned short dpopBSLo; // offset 0x32, size 0x2
|
||||
unsigned short dpopBSDelta; // offset 0x34, size 0x2
|
||||
u16 dpopLHi; // offset 0x0, size 0x2
|
||||
u16 dpopLLo; // offset 0x2, size 0x2
|
||||
u16 dpopLDelta; // offset 0x4, size 0x2
|
||||
u16 dpopRHi; // offset 0x6, size 0x2
|
||||
u16 dpopRLo; // offset 0x8, size 0x2
|
||||
u16 dpopRDelta; // offset 0xA, size 0x2
|
||||
u16 dpopSHi; // offset 0xC, size 0x2
|
||||
u16 dpopSLo; // offset 0xE, size 0x2
|
||||
u16 dpopSDelta; // offset 0x10, size 0x2
|
||||
u16 dpopALHi; // offset 0x12, size 0x2
|
||||
u16 dpopALLo; // offset 0x14, size 0x2
|
||||
u16 dpopALDelta; // offset 0x16, size 0x2
|
||||
u16 dpopARHi; // offset 0x18, size 0x2
|
||||
u16 dpopARLo; // offset 0x1A, size 0x2
|
||||
u16 dpopARDelta; // offset 0x1C, size 0x2
|
||||
u16 dpopASHi; // offset 0x1E, size 0x2
|
||||
u16 dpopASLo; // offset 0x20, size 0x2
|
||||
u16 dpopASDelta; // offset 0x22, size 0x2
|
||||
u16 dpopBLHi; // offset 0x24, size 0x2
|
||||
u16 dpopBLLo; // offset 0x26, size 0x2
|
||||
u16 dpopBLDelta; // offset 0x28, size 0x2
|
||||
u16 dpopBRHi; // offset 0x2A, size 0x2
|
||||
u16 dpopBRLo; // offset 0x2C, size 0x2
|
||||
u16 dpopBRDelta; // offset 0x2E, size 0x2
|
||||
u16 dpopBSHi; // offset 0x30, size 0x2
|
||||
u16 dpopBSLo; // offset 0x32, size 0x2
|
||||
u16 dpopBSDelta; // offset 0x34, size 0x2
|
||||
} _SPB;
|
||||
|
||||
typedef struct DSPhostDPop {
|
||||
|
@ -738,10 +738,10 @@ typedef struct DSPhostDPop {
|
|||
|
||||
typedef struct DSPinput {
|
||||
// total size: 0xC
|
||||
unsigned char studio; // offset 0x0, size 0x1
|
||||
unsigned short vol; // offset 0x2, size 0x2
|
||||
unsigned short volA; // offset 0x4, size 0x2
|
||||
unsigned short volB; // offset 0x6, size 0x2
|
||||
u8 studio; // offset 0x0, size 0x1
|
||||
u16 vol; // offset 0x2, size 0x2
|
||||
u16 volA; // offset 0x4, size 0x2
|
||||
u16 volB; // offset 0x6, size 0x2
|
||||
struct SND_STUDIO_INPUT* desc; // offset 0x8, size 0x4
|
||||
} DSPinput;
|
||||
|
||||
|
@ -754,9 +754,9 @@ typedef struct DSPstudioinfo {
|
|||
long* auxB[3]; // offset 0x3C, size 0xC
|
||||
struct DSPvoice* voiceRoot; // offset 0x48, size 0x4
|
||||
struct DSPvoice* alienVoiceRoot; // offset 0x4C, size 0x4
|
||||
unsigned char state; // offset 0x50, size 0x1
|
||||
unsigned char isMaster; // offset 0x51, size 0x1
|
||||
unsigned char numInputs; // offset 0x52, size 0x1
|
||||
u8 state; // offset 0x50, size 0x1
|
||||
u8 isMaster; // offset 0x51, size 0x1
|
||||
u8 numInputs; // offset 0x52, size 0x1
|
||||
SND_STUDIO_TYPE type; // offset 0x54, size 0x4
|
||||
struct DSPinput in[7]; // offset 0x58, size 0x54
|
||||
SND_AUX_CALLBACK auxAHandler; // offset 0xAC, size 0x4
|
||||
|
@ -774,50 +774,50 @@ typedef s32 (*SND_COMPARE)(void*, void*);
|
|||
|
||||
typedef struct CHANNEL_DEFAULTS {
|
||||
// total size: 0x1
|
||||
unsigned char pbRange; // offset 0x0, size 0x1
|
||||
u8 pbRange; // offset 0x0, size 0x1
|
||||
} CHANNEL_DEFAULTS;
|
||||
typedef struct FX_TAB {
|
||||
// total size: 0xA
|
||||
unsigned short id; // offset 0x0, size 0x2
|
||||
unsigned short macro; // offset 0x2, size 0x2
|
||||
unsigned char maxVoices; // offset 0x4, size 0x1
|
||||
unsigned char priority; // offset 0x5, size 0x1
|
||||
unsigned char volume; // offset 0x6, size 0x1
|
||||
unsigned char panning; // offset 0x7, size 0x1
|
||||
unsigned char key; // offset 0x8, size 0x1
|
||||
unsigned char vGroup; // offset 0x9, size 0x1
|
||||
u16 id; // offset 0x0, size 0x2
|
||||
u16 macro; // offset 0x2, size 0x2
|
||||
u8 maxVoices; // offset 0x4, size 0x1
|
||||
u8 priority; // offset 0x5, size 0x1
|
||||
u8 volume; // offset 0x6, size 0x1
|
||||
u8 panning; // offset 0x7, size 0x1
|
||||
u8 key; // offset 0x8, size 0x1
|
||||
u8 vGroup; // offset 0x9, size 0x1
|
||||
} FX_TAB;
|
||||
|
||||
typedef struct FX_DATA {
|
||||
// total size: 0xE
|
||||
unsigned short num; // offset 0x0, size 0x2
|
||||
unsigned short reserverd; // offset 0x2, size 0x2
|
||||
struct FX_TAB fx[1]; // offset 0x4, size 0xA
|
||||
u16 num; // offset 0x0, size 0x2
|
||||
u16 reserverd; // offset 0x2, size 0x2
|
||||
struct FX_TAB fx[1]; // offset 0x4, size 0xA
|
||||
} FX_DATA;
|
||||
|
||||
typedef struct FX_GROUP {
|
||||
// total size: 0x8
|
||||
unsigned short gid; // offset 0x0, size 0x2
|
||||
unsigned short fxNum; // offset 0x2, size 0x2
|
||||
u16 gid; // offset 0x0, size 0x2
|
||||
u16 fxNum; // offset 0x2, size 0x2
|
||||
struct FX_TAB* fxTab; // offset 0x4, size 0x4
|
||||
} FX_GROUP;
|
||||
|
||||
typedef struct PAGE {
|
||||
// total size: 0x6
|
||||
unsigned short macro; // offset 0x0, size 0x2
|
||||
unsigned char prio; // offset 0x2, size 0x1
|
||||
unsigned char maxVoices; // offset 0x3, size 0x1
|
||||
unsigned char index; // offset 0x4, size 0x1
|
||||
unsigned char reserved; // offset 0x5, size 0x1
|
||||
u16 macro; // offset 0x0, size 0x2
|
||||
u8 prio; // offset 0x2, size 0x1
|
||||
u8 maxVoices; // offset 0x3, size 0x1
|
||||
u8 index; // offset 0x4, size 0x1
|
||||
u8 reserved; // offset 0x5, size 0x1
|
||||
} PAGE;
|
||||
|
||||
typedef struct MIDI_CHANNEL_SETUP {
|
||||
// total size: 0x5
|
||||
unsigned char program; // offset 0x0, size 0x1
|
||||
unsigned char volume; // offset 0x1, size 0x1
|
||||
unsigned char panning; // offset 0x2, size 0x1
|
||||
unsigned char reverb; // offset 0x3, size 0x1
|
||||
unsigned char chorus; // offset 0x4, size 0x1
|
||||
u8 program; // offset 0x0, size 0x1
|
||||
u8 volume; // offset 0x1, size 0x1
|
||||
u8 panning; // offset 0x2, size 0x1
|
||||
u8 reverb; // offset 0x3, size 0x1
|
||||
u8 chorus; // offset 0x4, size 0x1
|
||||
} MIDI_CHANNEL_SETUP;
|
||||
|
||||
typedef struct MIDISETUP {
|
||||
|
@ -832,19 +832,19 @@ typedef struct ADSR_INFO {
|
|||
union ai_data {
|
||||
struct {
|
||||
// total size: 0x14
|
||||
long atime; // offset 0x0, size 0x4
|
||||
long dtime; // offset 0x4, size 0x4
|
||||
unsigned short slevel; // offset 0x8, size 0x2
|
||||
unsigned short rtime; // offset 0xA, size 0x2
|
||||
long ascale; // offset 0xC, size 0x4
|
||||
long dscale; // offset 0x10, size 0x4
|
||||
long atime; // offset 0x0, size 0x4
|
||||
long dtime; // offset 0x4, size 0x4
|
||||
u16 slevel; // offset 0x8, size 0x2
|
||||
u16 rtime; // offset 0xA, size 0x2
|
||||
long ascale; // offset 0xC, size 0x4
|
||||
long dscale; // offset 0x10, size 0x4
|
||||
} dls;
|
||||
struct {
|
||||
// total size: 0x8
|
||||
unsigned short atime; // offset 0x0, size 0x2
|
||||
unsigned short dtime; // offset 0x2, size 0x2
|
||||
unsigned short slevel; // offset 0x4, size 0x2
|
||||
unsigned short rtime; // offset 0x6, size 0x2
|
||||
u16 atime; // offset 0x0, size 0x2
|
||||
u16 dtime; // offset 0x2, size 0x2
|
||||
u16 slevel; // offset 0x4, size 0x2
|
||||
u16 rtime; // offset 0x6, size 0x2
|
||||
} linear;
|
||||
} data; // offset 0x0, size 0x14
|
||||
} ADSR_INFO;
|
||||
|
@ -870,22 +870,25 @@ FX_TAB* dataGetFX(u16 fid);
|
|||
s32 hwInit(u32* frq, u16 numVoices, u16 numStudios, u32 flags); /* extern */
|
||||
void hwInitSamplePlayback(u32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 prio,
|
||||
u32 callbackUserValue, u32 setSRC, u8 itdMode);
|
||||
void hwSetVolume(u32 v, u8 table, float vol, u32 pan, u32 span, float auxa, float auxb);
|
||||
void hwSetPitch(u32 v, u16 speed);
|
||||
void hwEnableIrq();
|
||||
void hwDisableIrq();
|
||||
void* hwTransAddr(void* samples);
|
||||
|
||||
void seqInit(); /* extern */
|
||||
unsigned long seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song,
|
||||
SND_PLAYPARA* para, u8 studio, u16 sgid);
|
||||
unsigned long seqGetPrivateId(unsigned long seqId);
|
||||
u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PLAYPARA* para,
|
||||
u8 studio, u16 sgid);
|
||||
u32 seqGetPrivateId(u32 seqId);
|
||||
void streamInit(); /* extern */
|
||||
void vsInit(); /* extern */
|
||||
void hwExit();
|
||||
void dataExit();
|
||||
void s3dInit(s32); /* extern */
|
||||
void s3dKillEmitterByFXID(FX_TAB* fxTab, unsigned long num);
|
||||
void s3dKillEmitterByFXID(FX_TAB* fxTab, u32 num);
|
||||
void s3dExit();
|
||||
void synthInit(u32, u8); /* extern */
|
||||
void synthSetBpm(u32 pbm, u8 set, u8 section);
|
||||
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
|
||||
void synthSetMusicVolumeType(u8 vGroup, u8 type);
|
||||
|
||||
|
@ -895,7 +898,7 @@ extern u8 voiceMusicRunning;
|
|||
extern u8 voiceFxRunning;
|
||||
extern u8 voiceListInsert;
|
||||
extern u8 voiceListRoot;
|
||||
void voiceSetPriority(struct SYNTH_VOICE* svoice, unsigned char prio);
|
||||
void voiceSetPriority(struct SYNTH_VOICE* svoice, u8 prio);
|
||||
u32 voiceIsLastStarted(struct SYNTH_VOICE* svoice);
|
||||
s32 voiceKillSound(u32 voiceid);
|
||||
|
||||
|
@ -909,13 +912,19 @@ void* sndBSearch(void* key, void* base, s32 num, s32 len, SND_COMPARE cmp);
|
|||
void sndConvertMs(u32* time);
|
||||
void sndConvertTicks(u32* out, SYNTH_VOICE* svoice);
|
||||
u32 sndConvert2Ms(u32 time);
|
||||
void hwActivateStudio(unsigned char studio, unsigned long isMaster, SND_STUDIO_TYPE type);
|
||||
u32 sndStreamAllocLength(u32 num, u32 flags);
|
||||
void sndStreamFree(u32 stid);
|
||||
u32 sndStreamActivate(u32 stid);
|
||||
void sndStreamDeactivate(u32 stid);
|
||||
|
||||
void hwActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
|
||||
void hwDeactivateStudio(u8);
|
||||
void hwSetPriority(unsigned long v, unsigned long prio);
|
||||
void hwSetPriority(u32 v, u32 prio);
|
||||
u32 hwIsActive(u32);
|
||||
u32 hwGlobalActivity();
|
||||
void hwSetAUXProcessingCallbacks(unsigned char studio, SND_AUX_CALLBACK auxA, void* userA,
|
||||
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
|
||||
SND_AUX_CALLBACK auxB, void* userB);
|
||||
u8 hwInitStream(u32 len);
|
||||
s16 varGet(SYNTH_VOICE* svoice, u32 ctrl, u8 index);
|
||||
|
||||
u32 sndGetPitch(u8 key, u32 sInfo);
|
||||
|
@ -944,7 +953,7 @@ void salInitHRTFBuffer();
|
|||
void salActivateVoice(DSPvoice* dsp_vptr, u8 studio);
|
||||
void salDeactivateVoice(DSPvoice* dsp_vptr);
|
||||
void salActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type);
|
||||
void salDeactivateStudio(unsigned char studio);
|
||||
void salDeactivateStudio(u8 studio);
|
||||
void salActivateVoice(DSPvoice* dsp_vptr, u8 studio);
|
||||
void salCalcVolume(u8 voltab_index, SAL_VOLINFO* vi, float vol, u32 pan, u32 span, float auxa,
|
||||
float auxb, u32 itd, u32 dpl2);
|
||||
|
@ -959,38 +968,75 @@ extern u8 salNumVoices;
|
|||
/* Stream */
|
||||
typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2,
|
||||
void* user);
|
||||
typedef struct SND_STREAM_INFO {
|
||||
u32 x0_;
|
||||
u32 x4_;
|
||||
u32 x8_;
|
||||
u8 xc_;
|
||||
char data2[0x10 - 0xd];
|
||||
SND_STREAM_UPDATE_CALLBACK updateCb;
|
||||
char data3[0x4C - 0x14];
|
||||
SND_VOICEID voiceId;
|
||||
void* user;
|
||||
char data4[0x64 - 0x54];
|
||||
} SND_STREAM_INFO;
|
||||
typedef struct SNDADPCMinfo {
|
||||
// total size: 0x28
|
||||
u16 numCoef; // offset 0x0, size 0x2
|
||||
u8 initialPS; // offset 0x2, size 0x1
|
||||
u8 loopPS; // offset 0x3, size 0x1
|
||||
s16 loopY0; // offset 0x4, size 0x2
|
||||
s16 loopY1; // offset 0x6, size 0x2
|
||||
s16 coefTab[8][2]; // offset 0x8, size 0x20
|
||||
} SNDADPCMinfo;
|
||||
|
||||
typedef struct STREAM_INFO {
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
u32 nextStreamHandle;
|
||||
#endif
|
||||
u32 stid;
|
||||
u32 flags;
|
||||
u8 state;
|
||||
u8 type;
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
u8 hwStreamHandle;
|
||||
u8 lastPSFromBuffer;
|
||||
#endif
|
||||
SND_STREAM_UPDATE_CALLBACK updateFunction;
|
||||
s16* buffer;
|
||||
u32 size;
|
||||
u32 bytes;
|
||||
u32 last;
|
||||
SNDADPCMinfo adpcmInfo;
|
||||
volatile SND_VOICEID voice;
|
||||
u32 user;
|
||||
u32 frq;
|
||||
u8 prio;
|
||||
u8 vol;
|
||||
u8 pan;
|
||||
u8 span;
|
||||
u8 auxa;
|
||||
u8 auxb;
|
||||
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
u8 orgPan;
|
||||
u8 orgSPan;
|
||||
#endif
|
||||
|
||||
u8 studio;
|
||||
/* These were moved to near the start of the structure in later versions */
|
||||
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
|
||||
u8 hwStreamHandle;
|
||||
u32 nextStreamHandle;
|
||||
#endif
|
||||
} STREAM_INFO;
|
||||
|
||||
void streamOutputModeChanged();
|
||||
u8 inpTranslateExCtrl(unsigned char ctrl);
|
||||
u8 inpTranslateExCtrl(u8 ctrl);
|
||||
void inpSetGlobalMIDIDirtyFlag(u8 chan, u8 midiSet, s32 flag);
|
||||
void inpAddCtrl(struct CTRL_DEST* dest, unsigned char ctrl, long scale, unsigned char comb,
|
||||
unsigned long isVar);
|
||||
void inpSetExCtrl(SYNTH_VOICE* svoice, unsigned char ctrl, signed short v);
|
||||
CHANNEL_DEFAULTS* inpGetChannelDefaults(unsigned char midi, unsigned char midiSet);
|
||||
void inpAddCtrl(struct CTRL_DEST* dest, u8 ctrl, long scale, u8 comb, u32 isVar);
|
||||
void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v);
|
||||
CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet);
|
||||
extern CTRL_DEST inpAuxA[8][4];
|
||||
extern CTRL_DEST inpAuxB[8][4];
|
||||
void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key);
|
||||
u8 inpGetMidiLastNote(u8 midi, u8 midiSet);
|
||||
unsigned short inpGetExCtrl(SYNTH_VOICE* svoice, unsigned char ctrl);
|
||||
unsigned short inpGetMidiCtrl(unsigned char ctrl, unsigned char channel, unsigned char set);
|
||||
void inpSetMidiLastNote(unsigned char midi, unsigned char midiSet, unsigned char key);
|
||||
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);
|
||||
/* TODO: Figure out what `unk` is */
|
||||
void hwSetSRCType(u32 v, u8 salSRCType);
|
||||
void hwSetITDMode(u32 v, u8 mode);
|
||||
void hwSetPolyPhaseFilter(unsigned long v, unsigned char salCoefSel);
|
||||
void hwSetPolyPhaseFilter(u32 v, u8 salCoefSel);
|
||||
bool hwAddInput(u8 studio, SND_STUDIO_INPUT* in_desc);
|
||||
bool hwRemoveInput(u8 studio, SND_STUDIO_INPUT* in_desc);
|
||||
void hwChangeStudio(u32 v, u8 studio);
|
||||
|
@ -1005,19 +1051,15 @@ extern u8 dspScale2IndexTab[1024];
|
|||
|
||||
typedef void* (*ARAMUploadCallback)(u32, u32);
|
||||
|
||||
u32 aramGetStreamBufferAddress(unsigned char id, unsigned long* len);
|
||||
void aramUploadData(void* mram, unsigned long aram, unsigned long len, unsigned long highPrio,
|
||||
void (*callback)(unsigned long), unsigned long user);
|
||||
u32 aramGetStreamBufferAddress(u8 id, u32* len);
|
||||
void aramUploadData(void* mram, u32 aram, u32 len, u32 highPrio, void (*callback)(u32), u32 user);
|
||||
void aramFreeStreamBuffer(u8 id);
|
||||
void* aramStoreData(void* src, unsigned long len);
|
||||
void aramRemoveData(void* aram, unsigned long len);
|
||||
|
||||
unsigned long macStart(unsigned short macid, unsigned char priority, unsigned char maxVoices,
|
||||
unsigned short allocId, unsigned char key, unsigned char vol,
|
||||
unsigned char panning, unsigned char midi, unsigned char midiSet,
|
||||
unsigned char section, unsigned short step, unsigned short trackid,
|
||||
unsigned char new_vid, unsigned char vGroup, unsigned char studio,
|
||||
unsigned long itd);
|
||||
void* aramStoreData(void* src, u32 len);
|
||||
void aramRemoveData(void* aram, u32 len);
|
||||
u8 aramAllocateStreamBuffer(u32 len);
|
||||
u32 macStart(u16 macid, u8 priority, u8 maxVoices, u16 allocId, u8 key, u8 vol, u8 panning, u8 midi,
|
||||
u8 midiSet, u8 section, u16 step, u16 trackid, u8 new_vid, u8 vGroup, u8 studio,
|
||||
u32 itd);
|
||||
void macMakeInactive(SYNTH_VOICE* svoice, MAC_STATE);
|
||||
|
||||
void sndProfUpdateMisc(SND_PROFILE_INFO* info);
|
||||
|
|
|
@ -7,6 +7,160 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ARR {
|
||||
// total size: 0x58
|
||||
unsigned long tTab; // offset 0x0, size 0x4
|
||||
unsigned long pTab; // offset 0x4, size 0x4
|
||||
unsigned long tmTab; // offset 0x8, size 0x4
|
||||
unsigned long mTrack; // offset 0xC, size 0x4
|
||||
unsigned long info; // offset 0x10, size 0x4
|
||||
unsigned long loopPoint[16]; // offset 0x14, size 0x40
|
||||
unsigned long tsTab; // offset 0x54, size 0x4
|
||||
} ARR;
|
||||
|
||||
typedef struct TENTRY {
|
||||
// total size: 0xC
|
||||
u32 time; // offset 0x0, size 0x4
|
||||
u8 prgChange; // offset 0x4, size 0x1
|
||||
u8 velocity; // offset 0x5, size 0x1
|
||||
u8 res[2]; // offset 0x6, size 0x2
|
||||
u16 pattern; // offset 0x8, size 0x2
|
||||
s8 transpose; // offset 0xA, size 0x1
|
||||
s8 velocityAdd; // offset 0xB, size 0x1
|
||||
} TENTRY;
|
||||
|
||||
typedef struct TRACK {
|
||||
// total size: 0x8
|
||||
struct TENTRY* base; // offset 0x0, size 0x4
|
||||
struct TENTRY* addr; // offset 0x4, size 0x4
|
||||
} TRACK;
|
||||
|
||||
typedef struct NOTE {
|
||||
// total size: 0x14
|
||||
struct NOTE* next; // offset 0x0, size 0x4
|
||||
struct NOTE* prev; // offset 0x4, size 0x4
|
||||
u32 id; // offset 0x8, size 0x4
|
||||
s32 endTime; // offset 0xC, size 0x4
|
||||
u8 section; // offset 0x10, size 0x1
|
||||
u8 timeIndex; // offset 0x11, size 0x1
|
||||
u8 reserved[2]; // offset 0x12, size 0x2
|
||||
} NOTE;
|
||||
|
||||
typedef struct NOTE_DATA {
|
||||
// total size: 0x6
|
||||
u16 time; // offset 0x0, size 0x2
|
||||
u8 key; // offset 0x2, size 0x1
|
||||
u8 velocity; // offset 0x3, size 0x1
|
||||
u16 length; // offset 0x4, size 0x2
|
||||
} NOTE_DATA;
|
||||
|
||||
typedef struct PRG_STATE {
|
||||
// total size: 0x4
|
||||
u16 macId; // offset 0x0, size 0x2
|
||||
u8 priority; // offset 0x2, size 0x1
|
||||
u8 maxVoices; // offset 0x3, size 0x1
|
||||
} PRG_STATE;
|
||||
|
||||
typedef struct SEQ_STREAM {
|
||||
// total size: 0xC
|
||||
u8* nextAddr; // offset 0x0, size 0x4
|
||||
u16 value; // offset 0x4, size 0x2
|
||||
s16 nextDelta; // offset 0x6, size 0x2
|
||||
u32 nextTime; // offset 0x8, size 0x4
|
||||
} SEQ_STREAM;
|
||||
|
||||
typedef struct CPAT {
|
||||
// total size: 0x2C
|
||||
u32 lTime; // offset 0x0, size 0x4
|
||||
u32 baseTime; // offset 0x4, size 0x4
|
||||
NOTE_DATA* addr; // offset 0x8, size 0x4
|
||||
TENTRY* patternInfo; // offset 0xC, size 0x4
|
||||
SEQ_STREAM pitchBend; // offset 0x10, size 0xC
|
||||
SEQ_STREAM modulation; // offset 0x1C, size 0xC
|
||||
u8 midi; // offset 0x28, size 0x1
|
||||
} CPAT;
|
||||
|
||||
typedef struct SEQ_EVENT {
|
||||
// total size: 0x18
|
||||
struct SEQ_EVENT* next; // offset 0x0, size 0x4
|
||||
struct SEQ_EVENT* prev; // offset 0x4, size 0x4
|
||||
u32 time; // offset 0x8, size 0x4
|
||||
union evInfo {
|
||||
TENTRY* trackAddr;
|
||||
struct {
|
||||
// total size: 0x8
|
||||
NOTE_DATA* addr; // offset 0x0, size 0x4
|
||||
CPAT* base; // offset 0x4, size 0x4
|
||||
} pattern;
|
||||
} info; // offset 0xC, size 0x8
|
||||
u8 type; // offset 0x14, size 0x1
|
||||
u8 trackId; // offset 0x15, size 0x1
|
||||
} SEQ_EVENT;
|
||||
|
||||
typedef struct MTRACK_DATA {
|
||||
// total size: 0x8
|
||||
u32 time; // offset 0x0, size 0x4
|
||||
u32 bpm; // offset 0x4, size 0x4
|
||||
} MTRACK_DATA;
|
||||
|
||||
typedef struct MTRACK {
|
||||
// total size: 0x8
|
||||
MTRACK_DATA* base; // offset 0x0, size 0x4
|
||||
MTRACK_DATA* addr; // offset 0x4, size 0x4
|
||||
} MTRACK;
|
||||
|
||||
typedef struct TICKS {
|
||||
// total size: 0x8
|
||||
u32 low; // offset 0x0, size 0x4
|
||||
long high; // offset 0x4, size 0x4
|
||||
} TICKS;
|
||||
|
||||
typedef struct SEQ_SECTION {
|
||||
// total size: 0x38
|
||||
struct MTRACK mTrack; // offset 0x0, size 0x8
|
||||
u32 bpm; // offset 0x8, size 0x4
|
||||
TICKS tickDelta[2]; // offset 0xC, size 0x10
|
||||
SEQ_EVENT* globalEventRoot; // offset 0x1C, size 0x4
|
||||
TICKS time[2]; // offset 0x20, size 0x10
|
||||
u8 timeIndex; // offset 0x30, size 0x1
|
||||
u16 speed; // offset 0x32, size 0x2
|
||||
u16 loopCnt; // offset 0x34, size 0x2
|
||||
u8 loopDisable; // offset 0x36, size 0x1
|
||||
} SEQ_SECTION;
|
||||
|
||||
typedef struct SEQ_INSTANCE {
|
||||
// total size: 0x1868
|
||||
struct SEQ_INSTANCE* next; // offset 0x0, size 0x4
|
||||
struct SEQ_INSTANCE* prev; // offset 0x4, size 0x4
|
||||
u8 state; // offset 0x8, size 0x1
|
||||
u8 index; // offset 0x9, size 0x1
|
||||
u16 groupID; // offset 0xA, size 0x2
|
||||
u32 publicId; // offset 0xC, size 0x4
|
||||
PAGE* normtab; // offset 0x10, size 0x4
|
||||
u8 normTrans[128]; // offset 0x14, size 0x80
|
||||
PAGE* drumtab; // offset 0x94, size 0x4
|
||||
u8 drumTrans[128]; // offset 0x98, size 0x80
|
||||
ARR* arrbase; // offset 0x118, size 0x4
|
||||
u32 trackMute[2]; // offset 0x11C, size 0x8
|
||||
TRACK track[64]; // offset 0x124, size 0x200
|
||||
u8 trackVolGroup[64]; // offset 0x324, size 0x40
|
||||
CPAT pattern[64]; // offset 0x364, size 0xB00
|
||||
NOTE* noteUsed[2]; // offset 0xE64, size 0x8
|
||||
NOTE* noteKeyOff; // offset 0xE6C, size 0x4
|
||||
PRG_STATE prgState[16]; // offset 0xE70, size 0x40
|
||||
u8 defVGroup; // offset 0xEB0, size 0x1
|
||||
SND_CROSSFADE syncCrossInfo; // offset 0xEB4, size 0x28
|
||||
u32* syncSeqIdPtr; // offset 0xEDC, size 0x4
|
||||
u8 syncActive; // offset 0xEE0, size 0x1
|
||||
u8 defStudio; // offset 0xEE1, size 0x1
|
||||
u8 keyOffCheck; // offset 0xEE2, size 0x1
|
||||
SEQ_EVENT event[64]; // offset 0xEE4, size 0x600
|
||||
u8* trackSectionTab; // offset 0x14E4, size 0x4
|
||||
SEQ_SECTION section[16]; // offset 0x14E8, size 0x380
|
||||
} SEQ_INSTANCE;
|
||||
|
||||
extern u8 synthTrackVolume[64];
|
||||
extern SEQ_INSTANCE seqInstance[8];
|
||||
extern u16 seqMIDIPriority[8][16];
|
||||
|
||||
void sndSeqStop(s32 unk);
|
||||
|
@ -14,6 +168,7 @@ void sndSeqSpeed(s32 unk1, s32 unk2);
|
|||
void sndSeqContinue(s32 unk);
|
||||
void sndSeqMute(s32 unk1, s32 unk2, s32 unk3);
|
||||
void sndSeqVolume(s32 unk1, s32 unk2, s32 unk3, s32 unk4);
|
||||
void seqStop(unsigned long seqId);
|
||||
u16 seqGetMIDIPriority(s32 unk1, s32 unk2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -23,7 +23,8 @@ 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);
|
||||
void synthVolume(unsigned char volume, unsigned short time, unsigned char vGroup,
|
||||
unsigned char seqMode, unsigned long seqId);
|
||||
|
||||
/* TODO: Move this where it belongs */
|
||||
void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA,
|
||||
|
|
|
@ -88,6 +88,7 @@ double ldexp(double x, int exp);
|
|||
double copysign(double x, double y);
|
||||
|
||||
double floor(double x);
|
||||
float floorf(float x) { return floor(x); }
|
||||
|
||||
double fabs(double x);
|
||||
double pow(double x, double y);
|
||||
|
|
|
@ -1,17 +1,54 @@
|
|||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#include "dolphin/GBAPriv.h"
|
||||
|
||||
static GBASecParams SecParams[4];
|
||||
static GBASecParam SecParams[4];
|
||||
GBAControl __GBA[4];
|
||||
BOOL __GBAReset = FALSE;
|
||||
|
||||
static BOOL OnReset(BOOL);
|
||||
|
||||
static OSResetFunctionInfo ResetFunctionInfo = {
|
||||
OnReset,
|
||||
127
|
||||
};
|
||||
static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127};
|
||||
|
||||
void ShortCommandProc(s32 chan) {
|
||||
static void ShortCommandProc(s32 chan) {
|
||||
GBAControl* gba;
|
||||
gba = &__GBA[chan];
|
||||
|
||||
|
@ -27,6 +64,19 @@ void ShortCommandProc(s32 chan) {
|
|||
gba->status[0] = gba->input[2] & GBA_JSTAT_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
void GBAInit() {
|
||||
GBAControl* gba;
|
||||
s32 chan;
|
||||
|
@ -37,16 +87,37 @@ void GBAInit() {
|
|||
OSInitThreadQueue(&gba->threadQueue);
|
||||
gba->param = &SecParams[chan];
|
||||
|
||||
// ASSERTMSG((u32) gba->param % 32 == 0)
|
||||
ASSERT((u32) gba->param % 32 == 0);
|
||||
}
|
||||
|
||||
OSInitAlarm();
|
||||
DSPInit();
|
||||
__GBAReset = FALSE;
|
||||
|
||||
DSPInit();
|
||||
|
||||
__GBAReset = FALSE;
|
||||
OSRegisterResetFunction(&ResetFunctionInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
s32 GBAGetStatusAsync(s32 chan, u8* status, GBACallback callback) {
|
||||
GBAControl* gba;
|
||||
gba = &__GBA[chan];
|
||||
|
@ -59,43 +130,89 @@ s32 GBAGetStatusAsync(s32 chan, u8* status, GBACallback callback) {
|
|||
gba->callback = callback;
|
||||
return __GBATransfer(chan, 1, 3, ShortCommandProc);
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
*/
|
||||
s32 GBAGetStatus(s32 chan, u8* status) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
|
||||
//
|
||||
s32 ret = GBAGetStatusAsync(chan, status, __GBASyncCallback);
|
||||
return ret != GBA_READY ? ret : __GBASync(chan);
|
||||
}
|
||||
if (ret != GBA_READY) {
|
||||
|
||||
|
||||
s32 GBAResetAsync(s32 chan, u8* status, GBACallback callback) {
|
||||
GBAControl* gba;
|
||||
s32 ret;
|
||||
gba = &__GBA[chan];
|
||||
if (gba->callback != NULL) {
|
||||
ret = GBA_BUSY;
|
||||
} else {
|
||||
gba->output[0] = 0xFF;
|
||||
gba->status = status;
|
||||
gba->callback = callback;
|
||||
ret = __GBATransfer(chan, 1, 3, ShortCommandProc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return __GBASync(chan);
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
s32 GBAResetAsync(s32 chan, u8* status, GBACallback callback) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
s32 ret;
|
||||
if (gba->callback != NULL) {
|
||||
|
||||
return GBA_BUSY;
|
||||
}
|
||||
gba->output[0] = 0xFF;
|
||||
gba->status = status;
|
||||
gba->callback = callback;
|
||||
return __GBATransfer(chan, 1, 3, ShortCommandProc);
|
||||
}
|
||||
/*
|
||||
*/
|
||||
s32 GBAReset(s32 chan, u8* status) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
s32 ret;
|
||||
|
||||
ret = GBAResetAsync(chan, status, __GBASyncCallback);
|
||||
if (ret != GBA_READY) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return __GBASync(chan);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
BOOL OnReset(BOOL) {
|
||||
__GBAReset = TRUE;
|
||||
return TRUE;
|
||||
|
|
|
@ -1,14 +1,71 @@
|
|||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#include "dolphin/GBAPriv.h"
|
||||
|
||||
s32 GBAGetProcessStatus(s32 chan, u8* percentp) {
|
||||
BOOL enabled;
|
||||
s32 ret; // r29
|
||||
GBAControl * gba; // r25
|
||||
GBABootInfo * bootInfo; // r31
|
||||
u8 percent; // r30
|
||||
OSTime t; // r27
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
s32 GBAGetProcessStatus(s32 chan, u8* percentp) {
|
||||
BOOL enabled;
|
||||
s32 ret; // r29
|
||||
GBAControl* gba = &__GBA[chan]; // r25
|
||||
GBABootInfo* bootInfo; // r31
|
||||
u8 percent; // r30
|
||||
OSTime t; // r27
|
||||
|
||||
gba = &__GBA[chan];
|
||||
bootInfo = &gba->bootInfo;
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
|
@ -17,9 +74,12 @@ s32 GBAGetProcessStatus(s32 chan, u8* percentp) {
|
|||
percent = (bootInfo->curOffset * 100) / bootInfo->realLength;
|
||||
if (bootInfo->begin != 0) {
|
||||
t = OSGetTime();
|
||||
if (OSTicksToMilliseconds(t - bootInfo->begin) < (5500)) {
|
||||
percent = ((t - bootInfo->begin) * percent) / OSMillisecondsToTicks((OSTime)5500);
|
||||
}
|
||||
|
||||
if (t - bootInfo->begin < OSMillisecondsToTicks(5500)) {
|
||||
percentp = 0;
|
||||
if (percent >= 100) {
|
||||
percent = 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,9 +87,9 @@ s32 GBAGetProcessStatus(s32 chan, u8* percentp) {
|
|||
*percentp = percent;
|
||||
}
|
||||
} else if (gba->callback != NULL) {
|
||||
ret = 2;
|
||||
ret = 2;
|
||||
} else {
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
|
|
@ -17,22 +17,24 @@ static void F37(s32 chan, s32 ret);
|
|||
static void F39(s32 chan, s32 ret);
|
||||
|
||||
static u32 F72(u32 crc, u32 src, vu8* keyp) {
|
||||
int i;
|
||||
int poly;
|
||||
|
||||
int i; // r31
|
||||
int poly =
|
||||
(keyp[0x13] << 8) + ((keyp[0x15] + (keyp[0x18] - (keyp[0x18] << 4))) - keyp[0x10]); // r30
|
||||
for (i = keyp[1]; i > keyp[11]; --i) {
|
||||
if ((src ^ crc) & 1 != 0) {
|
||||
crc = (crc >> 1) ^ ((keyp[19] * 256 + keyp[21] + keyp[24] + keyp[24] * -16) - keyp[16]);
|
||||
if ((src ^ crc) & 1) {
|
||||
crc >>= 1;
|
||||
crc ^= poly;
|
||||
} else {
|
||||
crc >>= 1;
|
||||
}
|
||||
|
||||
src >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
u32 F95(u32 src, vu8* keyp) {
|
||||
return src * ((keyp[3] << keyp[0x16]) | keyp[1] | (keyp[4] << keyp[0x11]) |
|
||||
(keyp[4] << keyp[0x18])) -
|
||||
return src * ((keyp[4] << keyp[0x11]) | keyp[1] | (keyp[4] << keyp[0x18]) |
|
||||
(keyp[3] << keyp[0x16])) -
|
||||
(keyp[7] - keyp[6]);
|
||||
}
|
||||
|
||||
|
@ -52,36 +54,35 @@ static void F104(s32 chan, s32 ret) {
|
|||
s32 GBAJoyBootAsync(s32 chan, s32 paletteColor, s32 paletteSpeed, u8* programp, s32 length,
|
||||
u8* status, GBACallback callback) {
|
||||
int ret;
|
||||
GBABootInfo* bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
u8 percent;
|
||||
bootInfo = &__GBA[chan].bootInfo;
|
||||
if (chan & ~3) {
|
||||
ret = GBA_JOYBOOT_ERR_INVALID;
|
||||
return GBA_JOYBOOT_ERR_INVALID;
|
||||
} else if (length == 0 || GBA_JOYBOOT_PROGRAM_SIZE_MAX < length) {
|
||||
ret = GBA_JOYBOOT_ERR_INVALID;
|
||||
return GBA_JOYBOOT_ERR_INVALID;
|
||||
} else if (paletteSpeed < -4 || paletteSpeed > 4) {
|
||||
ret = GBA_JOYBOOT_ERR_INVALID;
|
||||
return GBA_JOYBOOT_ERR_INVALID;
|
||||
} else if (paletteColor < 0 || paletteColor > 6) {
|
||||
ret = GBA_JOYBOOT_ERR_INVALID;
|
||||
return GBA_JOYBOOT_ERR_INVALID;
|
||||
} else if (programp[0xac] * programp[0xad] * programp[0xae] * programp[0xaf] == 0) {
|
||||
ret = GBA_JOYBOOT_ERR_INVALID;
|
||||
} else {
|
||||
ret = GBAGetProcessStatus(chan, &percent);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return GBA_JOYBOOT_ERR_INVALID;
|
||||
}
|
||||
|
||||
bootInfo->paletteColor = paletteColor;
|
||||
bootInfo->paletteSpeed = paletteSpeed;
|
||||
bootInfo->programp = programp;
|
||||
bootInfo->length = length;
|
||||
bootInfo->status = status;
|
||||
bootInfo->callback = callback;
|
||||
bootInfo->curOffset = D54[8];
|
||||
ret = GBAGetStatusAsync(chan, bootInfo->status, F23);
|
||||
if (ret != GBA_READY) {
|
||||
bootInfo->callback = NULL;
|
||||
}
|
||||
ret = GBAGetProcessStatus(chan, &percent);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bootInfo->paletteColor = paletteColor;
|
||||
bootInfo->paletteSpeed = paletteSpeed;
|
||||
bootInfo->programp = programp;
|
||||
bootInfo->length = length;
|
||||
bootInfo->status = status;
|
||||
bootInfo->callback = callback;
|
||||
bootInfo->curOffset = D54[8];
|
||||
ret = GBAGetStatusAsync(chan, bootInfo->status, F23);
|
||||
if (ret != GBA_READY) {
|
||||
bootInfo->callback = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -91,7 +92,7 @@ static void F23(s32 chan, s32 ret) {
|
|||
GBABootInfo* bootInfo;
|
||||
|
||||
gba = &__GBA[chan];
|
||||
bootInfo = &gba->bootInfo;
|
||||
bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret != GBA_READY || (ret = GBAResetAsync(chan, bootInfo->status, F25)) != GBA_READY) {
|
||||
F104(chan, ret);
|
||||
|
@ -102,7 +103,7 @@ static void F23(s32 chan, s32 ret) {
|
|||
|
||||
static void F25(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == GBA_READY && *bootInfo->status != D54[37]) {
|
||||
ret = GBA_JOYBOOT_UNKNOWN_STATE;
|
||||
|
@ -117,7 +118,7 @@ static void F25(s32 chan, s32 ret) {
|
|||
|
||||
static void F27(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == GBA_READY && *bootInfo->status != D54[0]) {
|
||||
ret = GBA_JOYBOOT_UNKNOWN_STATE;
|
||||
|
@ -132,7 +133,7 @@ static void F27(s32 chan, s32 ret) {
|
|||
|
||||
static void F29(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == GBA_READY) {
|
||||
__GBAX02(chan, bootInfo->readbuf);
|
||||
|
@ -144,7 +145,7 @@ static void F29(s32 chan, s32 ret) {
|
|||
}
|
||||
void __GBAX01(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
int val200;
|
||||
|
||||
if (ret == GBA_READY) {
|
||||
|
@ -184,11 +185,9 @@ void __GBAX01(s32 chan, s32 ret) {
|
|||
}
|
||||
|
||||
static void F31(s32 chan, s32 ret) {
|
||||
GBAControl* gba;
|
||||
GBABootInfo* bootInfo;
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
u32 writeWord;
|
||||
gba = &__GBA[chan];
|
||||
bootInfo = &gba->bootInfo;
|
||||
|
||||
if (ret == GBA_READY) {
|
||||
if (bootInfo->firstXfer != FALSE) {
|
||||
|
@ -232,10 +231,11 @@ static void F31(s32 chan, s32 ret) {
|
|||
writeWord = bootInfo->crc | (bootInfo->curOffset << 16);
|
||||
}
|
||||
|
||||
if (D54[43] < bootInfo->curOffset) {
|
||||
if (bootInfo->curOffset > D54[43]) {
|
||||
bootInfo->keyA = F95(bootInfo->keyA, &D54[20]);
|
||||
writeWord ^= bootInfo->keyA ^ -(bootInfo->curOffset + D54[11] * 0x100000) ^
|
||||
((D54[18] << 8) | (D54[19] << 16) | (D54[11] << 24) | D54[11]);
|
||||
writeWord ^= bootInfo->keyA;
|
||||
writeWord ^= -(bootInfo->curOffset + D54[11] * 0x100000);
|
||||
writeWord ^= (D54[11] | (D54[11] << 24)) | (D54[19] << 16) | (D54[18] << 8);
|
||||
}
|
||||
|
||||
bootInfo->writebuf[3] = (writeWord >> D54[0]);
|
||||
|
@ -248,7 +248,13 @@ static void F31(s32 chan, s32 ret) {
|
|||
}
|
||||
|
||||
if (bootInfo->i < D54[33]) {
|
||||
bootInfo->dummyWord[bootInfo->i] = writeWord;
|
||||
bootInfo->dummyWord[3 - (1 - bootInfo->i)] = writeWord;
|
||||
bootInfo->dummyWord[5 - bootInfo->i] =
|
||||
bootInfo->dummyWord[(2 - (1 - bootInfo->i))] * bootInfo->dummyWord[4 - bootInfo->i];
|
||||
bootInfo->dummyWord[5 - (1 - bootInfo->i)] =
|
||||
bootInfo->dummyWord[((1 - bootInfo->i))] * bootInfo->dummyWord[1 - (1 - bootInfo->i)];
|
||||
bootInfo->dummyWord[7 - bootInfo->i] =
|
||||
bootInfo->dummyWord[(-(1 - bootInfo->i))] * bootInfo->dummyWord[4 - bootInfo->i];
|
||||
}
|
||||
|
||||
ret = GBAWriteAsync(chan, bootInfo->writebuf, bootInfo->status, F31);
|
||||
|
@ -266,7 +272,7 @@ exit:
|
|||
}
|
||||
static void F33(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == GBA_READY) {
|
||||
for (bootInfo->i = 33; bootInfo->i < 36; ++bootInfo->i) {
|
||||
|
@ -297,7 +303,7 @@ static void F33(s32 chan, s32 ret) {
|
|||
}
|
||||
static void F35(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == 0) {
|
||||
if (OSSecondsToTicks(10) <= OSGetTick() - bootInfo->start) {
|
||||
|
@ -322,7 +328,7 @@ static void F35(s32 chan, s32 ret) {
|
|||
|
||||
static void F37(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == GBA_READY) {
|
||||
if ((((bootInfo->readbuf[3] ^ (bootInfo->initialCode >> 24)) |
|
||||
|
@ -344,7 +350,7 @@ static void F37(s32 chan, s32 ret) {
|
|||
|
||||
static void F39(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
GBABootInfo* bootInfo = &gba->bootInfo;
|
||||
GBABootInfo* bootInfo = &__GBA[chan].bootInfo;
|
||||
|
||||
if (ret == GBA_READY) {
|
||||
*bootInfo->status = 0;
|
||||
|
@ -354,13 +360,12 @@ static void F39(s32 chan, s32 ret) {
|
|||
gba->ret = ret;
|
||||
}
|
||||
|
||||
s32 GBAJoyBoot(s32 chan, s32 paletteColor, s32 paletteSpeed, unsigned char* programp, s32 length,
|
||||
unsigned char* status) {
|
||||
s32 GBAJoyBoot(s32 chan, s32 paletteColor, s32 paletteSpeed, u8* programp, s32 length, u8* status) {
|
||||
s32 ret = GBAJoyBootAsync(chan, paletteColor, paletteSpeed, programp, length, status,
|
||||
__GBASyncCallback);
|
||||
if (ret == GBA_READY) {
|
||||
ret = __GBASync(chan);
|
||||
if (ret != GBA_READY) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return __GBASync(chan);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
#include "dolphin/GBAPriv.h"
|
||||
|
||||
static volatile u8 D35[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 33, 2, 255, 0, 33, 19, 6, 18, 3, 18, 4,
|
||||
19, 5, 0, 146, 0, 255, 0, 136, 255, 255, 0, 137, 255, 255, 0, 138, 255, 255, 0,
|
||||
139, 255, 255, 143, 0, 139, 0, 140, 0, 2, 191, 128, 126, 22, 252, 220, 209, 22, 253,
|
||||
0, 0, 22, 251, 0, 1, 2, 191, 128, 120, 36, 255, 2, 128, 171, 186, 2, 148, 0,
|
||||
41, 142, 0, 2, 191, 128, 120, 32, 255, 2, 64, 15, 255, 31, 94, 0, 155, 0, 0,
|
||||
0, 153, 0, 32, 0, 135, 0, 0, 0, 128, 0, 65, 2, 159, 128, 188, 2, 191, 0,
|
||||
140, 2, 191, 128, 126, 22, 252, 220, 209, 22, 253, 0, 3, 22, 251, 0, 1, 143, 0,
|
||||
2, 191, 128, 120, 2, 128, 205, 209, 2, 148, 0, 76, 38, 255, 2, 128, 0, 1, 2,
|
||||
149, 0, 94, 2, 128, 0, 2, 2, 149, 128, 0, 2, 159, 0, 76, 0, 33, 142, 0,
|
||||
2, 191, 128, 120, 36, 255, 2, 191, 128, 120, 36, 255, 2, 191, 128, 120, 36, 255, 2,
|
||||
191, 128, 120, 0, 197, 255, 255, 2, 64, 15, 255, 28, 158, 2, 191, 128, 120, 0, 199,
|
||||
255, 255, 2, 191, 128, 120, 0, 198, 255, 255, 2, 191, 128, 120, 0, 192, 255, 255, 2,
|
||||
191, 128, 120, 32, 255, 2, 64, 15, 255, 31, 94, 2, 191, 128, 120, 33, 255, 2, 191,
|
||||
128, 120, 35, 255, 18, 5, 18, 6, 2, 159, 128, 181, 0, 33, 129, 0, 0, 129, 0,
|
||||
16, 16, 32, 27, 62, 0, 223, 20, 86, 3, 64, 255, 208, 132, 23, 0, 128, 0, 0,
|
||||
0, 134, 0, 0, 0, 130, 0, 31, 0, 222, 21, 246, 20, 8, 0, 223, 23, 102, 3,
|
||||
64, 0, 255, 31, 95, 2, 191, 136, 229, 31, 28, 129, 30, 25, 30, 20, 120, 31, 252,
|
||||
31, 94, 2, 191, 136, 9, 2, 191, 135, 35, 0, 6, 129, 6, 0, 222, 22, 108, 20,
|
||||
4, 2, 64, 255, 0, 0, 223, 18, 49, 21, 120, 3, 64, 0, 255, 31, 95, 2, 191,
|
||||
136, 229, 31, 28, 129, 30, 25, 30, 20, 120, 31, 252, 31, 94, 2, 191, 136, 9, 2,
|
||||
191, 135, 35, 129, 0, 137, 0, 0, 209, 0, 5, 153, 0, 130, 0, 2, 149, 0, 229,
|
||||
2, 145, 0, 243, 0, 130, 0, 16, 0, 134, 0, 1, 0, 208, 23, 27, 145, 0, 125,
|
||||
0, 77, 0, 21, 1, 31, 95, 0, 223, 0, 3, 21, 4, 2, 191, 136, 9, 2, 159,
|
||||
1, 2, 0, 130, 0, 17, 0, 223, 0, 3, 21, 1, 31, 95, 0, 222, 16, 67, 2,
|
||||
64, 255, 240, 2, 191, 136, 229, 2, 159, 1, 2, 0, 130, 0, 16, 0, 134, 0, 1,
|
||||
0, 208, 18, 133, 145, 0, 77, 0, 21, 1, 0, 222, 0, 3, 20, 4, 31, 94, 2,
|
||||
191, 136, 9, 0, 131, 0, 19, 27, 126, 137, 35, 0, 131, 0, 19, 0, 223, 0, 7,
|
||||
0, 222, 17, 184, 2, 64, 255, 240, 31, 94, 2, 191, 129, 244, 241, 0, 2, 191, 132,
|
||||
88, 143, 0, 0, 130, 0, 21, 0, 222, 0, 6, 0, 218, 22, 91, 2, 191, 136, 229,
|
||||
20, 253, 20, 3, 27, 94, 27, 92, 0, 130, 0, 22, 0, 222, 23, 35, 20, 244, 0,
|
||||
218, 22, 107, 2, 191, 136, 229, 177, 0, 2, 144, 1, 46, 129, 0, 20, 253, 142, 0,
|
||||
0, 223, 20, 145, 3, 64, 208, 240, 28, 191, 0, 223, 20, 104, 0, 209, 17, 252, 21,
|
||||
124, 28, 223, 0, 209, 17, 184, 153, 0, 20, 24, 20, 120, 31, 94, 31, 254, 31, 101,
|
||||
54, 0, 20, 2, 31, 102, 55, 0, 21, 1, 76, 0, 21, 24, 153, 0, 53, 0, 76,
|
||||
0, 0, 223, 0, 18, 63, 0, 0, 255, 0, 18, 20, 112, 0, 223, 0, 17, 63, 0,
|
||||
0, 255, 0, 17, 31, 165, 21, 1, 31, 230, 241, 0, 21, 248, 245, 0, 31, 95, 31,
|
||||
125, 129, 0, 0, 222, 0, 17, 52, 0, 137, 0, 0, 223, 0, 18, 53, 0, 76, 0,
|
||||
0, 223, 0, 18, 21, 120, 76, 0, 137, 0, 31, 254, 21, 8, 59, 0, 0, 222, 0,
|
||||
17, 62, 0, 0, 223, 0, 18, 59, 0, 28, 191, 0, 218, 21, 241, 53, 0, 2, 149,
|
||||
1, 146, 0, 223, 16, 226, 21, 8, 31, 95, 0, 223, 16, 59, 121, 0, 57, 0, 48,
|
||||
128, 0, 254, 0, 34, 0, 220, 18, 41, 0, 221, 17, 248, 92, 0, 240, 0, 31, 229,
|
||||
48, 128, 2, 159, 1, 165, 0, 223, 16, 202, 21, 8, 31, 95, 0, 223, 16, 67, 117,
|
||||
0, 57, 0, 48, 128, 0, 254, 0, 34, 0, 220, 18, 89, 0, 221, 22, 254, 76, 0,
|
||||
240, 0, 31, 229, 48, 128, 0, 254, 0, 35, 0, 218, 0, 8, 0, 216, 0, 9, 0,
|
||||
155, 0, 32, 0, 153, 0, 8, 0, 135, 0, 0, 2, 191, 128, 139, 2, 223, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
static s32 F152(DSPTaskInfo* task) {
|
||||
s32 chan; // r31
|
||||
GBAControl* gba; // r29
|
||||
|
||||
for (chan = 0; chan < 4; ++chan) {
|
||||
gba = &__GBA[chan];
|
||||
if (&gba->task == task) {
|
||||
return chan;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(0 <= chan && chan < 4);
|
||||
OSPanic(__FILE__, 169, "GBA - unexpected dsp call");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void F23(void* task) {
|
||||
s32 chan; // r31
|
||||
GBAControl* gba; // r30
|
||||
chan = F152(task);
|
||||
gba = &__GBA[chan];
|
||||
DSPSendMailToDSP(0xabba0000);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
DSPSendMailToDSP((u32)gba->param);
|
||||
while (DSPCheckMailToDSP())
|
||||
;
|
||||
}
|
||||
|
||||
void F25(void* task) {
|
||||
s32 chan; // r31
|
||||
chan = F152(task);
|
||||
__GBAX01(chan, 0);
|
||||
}
|
||||
|
||||
void __GBAX02(s32 chan, u8* readbuf) {
|
||||
GBAControl* gba; // r28
|
||||
GBABootInfo* bootInfo; // r29
|
||||
GBASecParam* param; // r30
|
||||
DSPTaskInfo* task; // r31
|
||||
|
||||
gba = &__GBA[chan];
|
||||
bootInfo = &__GBA[chan].bootInfo;
|
||||
param = gba->param;
|
||||
memcpy(param, readbuf, 4);
|
||||
param->paletteColor = bootInfo->paletteColor;
|
||||
param->paletteSpeed = bootInfo->paletteSpeed;
|
||||
param->length = bootInfo->length;
|
||||
param->out = ¶m->keyA;
|
||||
DCInvalidateRange(¶m->keyA, 32);
|
||||
DCFlushRange(param, 32);
|
||||
task = &gba->task;
|
||||
task->priority = 255;
|
||||
task->iram_mmem_addr = (u16*)OSCachedToPhysical(D35);
|
||||
task->iram_length = sizeof(D35);
|
||||
task->iram_addr = 0;
|
||||
task->dsp_init_vector = 16;
|
||||
task->init_cb = F23;
|
||||
task->res_cb = NULL;
|
||||
task->done_cb = F25;
|
||||
task->req_cb = NULL;
|
||||
DSPAddTask(task);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#include "dolphin/GBAPriv.h"
|
||||
|
||||
void ReadProc(s32 chan) {
|
||||
static void ReadProc(s32 chan) {
|
||||
GBAControl* gba;
|
||||
gba = &__GBA[chan];
|
||||
|
||||
|
@ -12,26 +12,24 @@ void ReadProc(s32 chan) {
|
|||
|
||||
s32 GBAReadAsync(s32 chan, u8* dst, u8* status, GBACallback callback) {
|
||||
GBAControl* gba;
|
||||
s32 ret;
|
||||
|
||||
gba = &__GBA[chan];
|
||||
|
||||
if (gba->callback != NULL) {
|
||||
ret = 2;
|
||||
} else {
|
||||
gba->output[0] = 0x14;
|
||||
gba->ptr = dst;
|
||||
gba->status = status;
|
||||
gba->callback = callback;
|
||||
ret = __GBATransfer(chan, 1, 5, ReadProc);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
gba->output[0] = 0x14;
|
||||
gba->ptr = dst;
|
||||
gba->status = status;
|
||||
gba->callback = callback;
|
||||
|
||||
return __GBATransfer(chan, 1, 5, ReadProc);
|
||||
}
|
||||
|
||||
s32 GBARead(s32 chan, u8* dst, u8* status) {
|
||||
s32 tmp;
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
s32 ret;
|
||||
ret = GBAReadAsync(chan, dst, status, __GBASyncCallback);
|
||||
if (ret != GBA_READY) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "dolphin/GBAPriv.h"
|
||||
|
||||
void WriteProc(s32 chan) {
|
||||
static void WriteProc(s32 chan) {
|
||||
GBAControl* gba;
|
||||
gba = &__GBA[chan];
|
||||
|
||||
|
@ -12,28 +12,23 @@ void WriteProc(s32 chan) {
|
|||
}
|
||||
|
||||
s32 GBAWriteAsync(s32 chan, u8* src, u8* status, GBACallback callback) {
|
||||
GBAControl* gba;
|
||||
s32 ret;
|
||||
gba = &__GBA[chan];
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
|
||||
if (gba->callback != NULL) {
|
||||
ret = GBA_BUSY;
|
||||
} else {
|
||||
gba->output[0] = 0x15;
|
||||
memcpy(&gba->output[1], src, 4);
|
||||
gba->ptr = src;
|
||||
gba->status = status;
|
||||
gba->callback = callback;
|
||||
ret = __GBATransfer(chan, 5, 1, WriteProc);
|
||||
return GBA_BUSY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
gba->output[0] = 0x15;
|
||||
memcpy(&gba->output[1], src, 4);
|
||||
gba->ptr = src;
|
||||
gba->status = status;
|
||||
gba->callback = callback;
|
||||
return __GBATransfer(chan, 5, 1, WriteProc);
|
||||
}
|
||||
|
||||
|
||||
s32 GBAWrite(s32 chan, u8* src, u8* status) {
|
||||
s32 ret;
|
||||
s32 tmp;
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
s32 ret;
|
||||
ret = GBAWriteAsync(chan, src, status, __GBASyncCallback);
|
||||
if (ret != GBA_READY) {
|
||||
return ret;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "dolphin/GBAPriv.h"
|
||||
#include "dolphin/sipriv.h"
|
||||
|
||||
void __GBAHandler(s32 chan, u32 error, OSContext* context) {
|
||||
static void __GBAHandler(s32 chan, u32 error, OSContext* context) {
|
||||
GBAControl* gba;
|
||||
GBATransferCallback proc;
|
||||
GBACallback callback;
|
||||
|
@ -37,12 +37,15 @@ void __GBAHandler(s32 chan, u32 error, OSContext* context) {
|
|||
OSSetCurrentContext(context);
|
||||
}
|
||||
|
||||
void __GBASyncCallback(s32 chan, s32 ret) { OSWakeupThread(&__GBA[chan].threadQueue); }
|
||||
void __GBASyncCallback(s32 chan, s32 ret) {
|
||||
GBAControl* gba = &__GBA[chan];
|
||||
OSWakeupThread(&gba->threadQueue);
|
||||
}
|
||||
|
||||
s32 __GBASync(s32 chan) {
|
||||
GBAControl* gba;
|
||||
s32 enabled;
|
||||
s32 ret;
|
||||
s32 enabled;
|
||||
gba = &__GBA[chan];
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
@ -57,40 +60,42 @@ s32 __GBASync(s32 chan) {
|
|||
}
|
||||
|
||||
void TypeAndStatusCallback(s32 chan, u32 type) {
|
||||
s32 tmp;
|
||||
GBAControl* gba;
|
||||
OSContext* context;
|
||||
GBATransferCallback proc;
|
||||
GBACallback callback;
|
||||
GBATransferCallback xferCallback;
|
||||
OSContext tmpContext;
|
||||
OSContext exceptionContext;
|
||||
OSContext* context;
|
||||
|
||||
gba = &__GBA[chan];
|
||||
if (__GBAReset != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(!(type & SI_ERROR_BUSY));
|
||||
if ((type & 0xFF) != 0 || (type & 0xffff0000) != 0x40000) {
|
||||
gba->ret = GBA_NOT_READY;
|
||||
} else {
|
||||
if (SITransfer(chan, gba->output, gba->outputBytes, gba->input, gba->inputBytes, __GBAHandler, gba->delay)) {
|
||||
if (SITransfer(chan, gba->output, gba->outputBytes, gba->input, gba->inputBytes, __GBAHandler,
|
||||
gba->delay)) {
|
||||
return;
|
||||
}
|
||||
gba->ret = GBA_BUSY;
|
||||
}
|
||||
|
||||
if (gba->proc != NULL) {
|
||||
xferCallback = gba->proc;
|
||||
proc = gba->proc;
|
||||
gba->proc = NULL;
|
||||
xferCallback(chan);
|
||||
proc(chan);
|
||||
}
|
||||
|
||||
if (gba->callback != NULL) {
|
||||
context = OSGetCurrentContext();
|
||||
OSClearContext(&tmpContext);
|
||||
OSSetCurrentContext(&tmpContext);
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
callback = gba->callback;
|
||||
gba->callback = NULL;
|
||||
callback(chan, gba->ret);
|
||||
OSClearContext(&tmpContext);
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
__OSReschedule();
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ void hwFlushStream(void* base, unsigned long offset, unsigned long bytes, unsign
|
|||
}
|
||||
|
||||
void hwPrepareStreamBuffer() {}
|
||||
u32 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); }
|
||||
u8 hwInitStream(u32 len) { return aramAllocateStreamBuffer(len); }
|
||||
|
||||
void hwExitStream(u8 id) { aramFreeStreamBuffer(id); }
|
||||
|
||||
|
|
|
@ -0,0 +1,670 @@
|
|||
#include "musyx/seq.h"
|
||||
#include "musyx/synth.h"
|
||||
|
||||
static NOTE seqNote[256];
|
||||
SEQ_INSTANCE seqInstance[8];
|
||||
u16 seqMIDIPriority[8][16];
|
||||
|
||||
static SEQ_INSTANCE* cseq = NULL;
|
||||
static NOTE* noteFree = NULL;
|
||||
static u32 curSeqId = 0;
|
||||
static u8 curFadeOutState = 0;
|
||||
static u32 seq_next_id = 0;
|
||||
struct SEQ_INSTANCE* seqFreeRoot = NULL;
|
||||
struct SEQ_INSTANCE* seqActiveRoot = NULL;
|
||||
struct SEQ_INSTANCE* seqPausedRoot = NULL;
|
||||
|
||||
static void ClearNotes() {
|
||||
NOTE* ln = NULL; // r30
|
||||
s32 i; // r29
|
||||
|
||||
noteFree = &seqNote[0];
|
||||
for (i = 0; i < 256; ++i) {
|
||||
seqNote[i].prev = ln;
|
||||
if (ln != NULL) {
|
||||
ln->next = &seqNote[i];
|
||||
}
|
||||
ln = &seqNote[i];
|
||||
}
|
||||
|
||||
ln->next = NULL;
|
||||
}
|
||||
|
||||
static void ResetNotes(SEQ_INSTANCE* seq) {
|
||||
NOTE* n; // r31
|
||||
u32 i; // r30
|
||||
for (i = 0; i < 2; ++i) {
|
||||
n = seq->noteUsed[i];
|
||||
if (n != NULL) {
|
||||
for (; n->next != NULL; n = n->next) {
|
||||
}
|
||||
|
||||
if (noteFree != NULL) {
|
||||
n->next = noteFree;
|
||||
noteFree->prev = n;
|
||||
}
|
||||
|
||||
noteFree = seq->noteUsed[i];
|
||||
seq->noteUsed[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
n = seq->noteKeyOff;
|
||||
|
||||
if (n != NULL) {
|
||||
for (; n->next != NULL; n = n->next) {
|
||||
}
|
||||
|
||||
if (noteFree != NULL) {
|
||||
n->next = noteFree;
|
||||
noteFree->prev = n;
|
||||
}
|
||||
|
||||
noteFree = seq->noteKeyOff;
|
||||
seq->noteKeyOff = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void KillNotes(SEQ_INSTANCE* seq) {
|
||||
NOTE* n; // r31
|
||||
u32 i; // r30
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
for (n = seq->noteUsed[i]; n != NULL; n = n->next) {
|
||||
voiceKillSound(n->id);
|
||||
}
|
||||
}
|
||||
|
||||
for (n = seq->noteKeyOff; n != NULL; n = n->next) {
|
||||
voiceKillSound(n->id);
|
||||
}
|
||||
}
|
||||
|
||||
static NOTE* AllocateNote(u32 endTime, u8 section) {
|
||||
NOTE* n; // r31
|
||||
NOTE* nl; // r30
|
||||
NOTE* last_nl; // r29
|
||||
if ((n = noteFree) != NULL) {
|
||||
if ((noteFree = n->next) != NULL) {
|
||||
noteFree->prev = NULL;
|
||||
}
|
||||
|
||||
n->endTime = endTime;
|
||||
n->section = section;
|
||||
n->timeIndex = cseq->section[section].timeIndex;
|
||||
last_nl = NULL;
|
||||
for (nl = cseq->noteUsed[n->timeIndex]; nl != NULL; nl = nl->next) {
|
||||
if (nl->endTime > n->endTime) {
|
||||
n->next = nl;
|
||||
n->prev = last_nl;
|
||||
if (last_nl != NULL) {
|
||||
last_nl->next = n;
|
||||
} else {
|
||||
cseq->noteUsed[n->timeIndex] = n;
|
||||
}
|
||||
|
||||
nl->prev = n;
|
||||
return n;
|
||||
}
|
||||
|
||||
last_nl = nl;
|
||||
}
|
||||
n->prev = last_nl;
|
||||
|
||||
if (last_nl != NULL) {
|
||||
last_nl->next = n;
|
||||
} else {
|
||||
cseq->noteUsed[n->timeIndex] = n;
|
||||
}
|
||||
|
||||
n->next = NULL;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static void FreeNote(struct NOTE* n) {
|
||||
if (n->next != NULL) {
|
||||
n->next->prev = n->prev;
|
||||
}
|
||||
|
||||
if (n->prev != NULL) {
|
||||
n->prev->next = n->next;
|
||||
} else {
|
||||
cseq->noteUsed[n->timeIndex] = n->next;
|
||||
}
|
||||
|
||||
if ((n->next = noteFree) != NULL) {
|
||||
noteFree->prev = n;
|
||||
}
|
||||
|
||||
n->prev = NULL;
|
||||
noteFree = n;
|
||||
}
|
||||
|
||||
static u32 HandleNotes() {
|
||||
NOTE* note; // r31
|
||||
u32 i; // r30
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
note = cseq->noteUsed[i];
|
||||
if (note != NULL) {
|
||||
while (note->endTime <= cseq->section[note->section].time[i].high) {
|
||||
synthSendKeyOff(note->id);
|
||||
|
||||
if ((cseq->noteUsed[i] = note->next) != NULL) {
|
||||
cseq->noteUsed[i]->prev = NULL;
|
||||
}
|
||||
|
||||
if ((note->next = cseq->noteKeyOff) != NULL) {
|
||||
cseq->noteKeyOff->prev = note;
|
||||
}
|
||||
cseq->noteKeyOff = note;
|
||||
note = cseq->noteUsed[i];
|
||||
|
||||
if (note == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cseq->noteUsed[0] != NULL || cseq->noteUsed[1] != NULL;
|
||||
}
|
||||
|
||||
static void KeyOffNotes() {
|
||||
NOTE* note; // r31
|
||||
NOTE* nextNote; // r29
|
||||
u32 i; // r30
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
note = cseq->noteUsed[i];
|
||||
|
||||
while (note != NULL) {
|
||||
nextNote = note->next;
|
||||
synthSendKeyOff(note->id);
|
||||
if ((cseq->noteUsed[i] = note->next) != NULL) {
|
||||
cseq->noteUsed[i]->prev = NULL;
|
||||
}
|
||||
|
||||
if ((note->next = cseq->noteKeyOff) != NULL) {
|
||||
cseq->noteKeyOff->prev = note;
|
||||
}
|
||||
cseq->noteKeyOff = note;
|
||||
note = nextNote;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void seqFreeKeyOffNote(NOTE* n) {
|
||||
if (n->next != NULL) {
|
||||
n->next->prev = n->prev;
|
||||
}
|
||||
|
||||
if (n->prev != NULL) {
|
||||
n->prev->next = n->next;
|
||||
} else {
|
||||
cseq->noteKeyOff = n->next;
|
||||
}
|
||||
|
||||
if ((n->next = noteFree) != NULL) {
|
||||
noteFree->prev = n;
|
||||
}
|
||||
|
||||
n->prev = NULL;
|
||||
noteFree = n;
|
||||
}
|
||||
|
||||
static void HandleKeyOffNotes() {
|
||||
NOTE* n; // r31
|
||||
NOTE* nn; // r30
|
||||
if (!cseq->keyOffCheck) {
|
||||
n = cseq->noteKeyOff;
|
||||
while (n != NULL) {
|
||||
nn = n->next;
|
||||
if (n->id != -1 && sndFXCheck(n->id) == -1) {
|
||||
seqFreeKeyOffNote(n);
|
||||
}
|
||||
|
||||
n = nn;
|
||||
}
|
||||
}
|
||||
|
||||
cseq->keyOffCheck = (cseq->keyOffCheck + 1) % 5;
|
||||
}
|
||||
|
||||
static void InitPublicIds() { seq_next_id = 0; }
|
||||
|
||||
static u32 GetPublicId(u32 seqId) {
|
||||
u32 pub_id; // r30
|
||||
SEQ_INSTANCE* si; // r31
|
||||
si = &seqInstance[seqId];
|
||||
}
|
||||
|
||||
u32 seqGetPrivateId(u32 seqId) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
}
|
||||
|
||||
static void DoPrgChange(SEQ_INSTANCE* seq, u8 prg, u8 midi) {
|
||||
seqMIDIPriority[curSeqId][midi] = 0xFFFF;
|
||||
if (midi != 9) {
|
||||
prg = seq->normTrans[prg];
|
||||
if (prg == 0xFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
seq->prgState[midi].macId = seq->normtab[prg].macro;
|
||||
seq->prgState[midi].priority = seq->normtab[prg].prio;
|
||||
seq->prgState[midi].maxVoices = seq->normtab[prg].maxVoices;
|
||||
return;
|
||||
}
|
||||
|
||||
prg = seq->drumTrans[prg];
|
||||
if (prg == 0xFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
seq->prgState[midi].macId = seq->drumtab[prg].macro;
|
||||
seq->prgState[midi].priority = seq->drumtab[prg].prio;
|
||||
seq->prgState[midi].maxVoices = seq->drumtab[prg].maxVoices;
|
||||
}
|
||||
|
||||
static void BuildTransTab(u8* tab, PAGE* page) {
|
||||
u8 i; // r31
|
||||
|
||||
for (i = 0; i < 128; ++i) {
|
||||
tab[i] = 0xff;
|
||||
}
|
||||
|
||||
for (i = 0; page->index != 0xFF; ++i, ++page) {
|
||||
tab[page->index] = i;
|
||||
}
|
||||
}
|
||||
|
||||
u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PLAYPARA* para,
|
||||
u8 studio, u16 sgid) {
|
||||
ARR* arr; // r27
|
||||
u32* tracktab; // r24
|
||||
s32 i; // r31
|
||||
SEQ_INSTANCE* nseq; // r30
|
||||
SEQ_INSTANCE* oldCSeq; // r23
|
||||
u32 seqId; // r28
|
||||
u32 bpm; // r25
|
||||
|
||||
if ((nseq = seqFreeRoot) == NULL) {
|
||||
return -1;
|
||||
};
|
||||
if ((seqFreeRoot = seqFreeRoot->next) != NULL) {
|
||||
seqFreeRoot->prev = NULL;
|
||||
}
|
||||
|
||||
if ((nseq->next = seqActiveRoot) != NULL) {
|
||||
seqActiveRoot->prev = nseq;
|
||||
}
|
||||
nseq->prev = NULL;
|
||||
seqActiveRoot = nseq;
|
||||
nseq->state = 1;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
nseq->section[i].globalEventRoot = NULL;
|
||||
}
|
||||
|
||||
seqId = nseq->index;
|
||||
nseq->syncActive = FALSE;
|
||||
nseq->normtab = norm;
|
||||
nseq->drumtab = drum;
|
||||
nseq->arrbase = (ARR*)song;
|
||||
nseq->groupID = sgid;
|
||||
BuildTransTab(nseq->normTrans, nseq->normtab);
|
||||
BuildTransTab(nseq->drumTrans, nseq->drumtab);
|
||||
nseq->defVGroup = seqId + 23;
|
||||
for (i = 0; i < 64; ++i) {
|
||||
nseq->trackVolGroup[i] = nseq->defVGroup;
|
||||
}
|
||||
|
||||
nseq->defStudio = studio;
|
||||
if (para == NULL) {
|
||||
nseq->trackMute[0] = -1;
|
||||
nseq->trackMute[1] = -1;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
nseq->section[i].speed = 256;
|
||||
}
|
||||
|
||||
synthVolume(127, 0, nseq->defVGroup, 0, -1);
|
||||
} else {
|
||||
if (para->flags & SND_PLAYPARA_TRACKMUTE) {
|
||||
nseq->trackMute[0] = para->trackMute[0];
|
||||
nseq->trackMute[1] = para->trackMute[1];
|
||||
} else {
|
||||
nseq->trackMute[0] = -1;
|
||||
nseq->trackMute[1] = -1;
|
||||
}
|
||||
|
||||
if (para->flags & SND_PLAYPARA_SPEED) {
|
||||
for (i = 0; i < 16; ++i) {
|
||||
nseq->section[i].speed = para->speed;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; ++i) {
|
||||
nseq->section[i].speed = 256;
|
||||
}
|
||||
}
|
||||
|
||||
if (para->flags & SND_PLAYPARA_SEQVOLDEF) {
|
||||
for (i = 0; i < para->numSeqVolDef; ++i) {
|
||||
nseq->trackVolGroup[para->seqVolDef[i].track] = para->seqVolDef[i].volGroup;
|
||||
synthSetMusicVolumeType(para->seqVolDef[i].volGroup, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (para->flags & SND_PLAYPARA_VOLUME) {
|
||||
synthVolume(para->volume.target, para->volume.time, nseq->defVGroup, 0, -1);
|
||||
|
||||
for (i = 0; i < para->numFaded; ++i) {
|
||||
synthVolume(para->volume.target, para->volume.time, para->faded[i], 0, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arr = (ARR*)song;
|
||||
if (arr->info & 0x80000000) {
|
||||
nseq->trackSectionTab = (u8*)(arr->tsTab + (u32)arr);
|
||||
} else {
|
||||
nseq->trackSectionTab = NULL;
|
||||
}
|
||||
|
||||
bpm = arr->info & 0x0fffffff;
|
||||
|
||||
if (!(arr->info & 0x40000000)) {
|
||||
bpm <<= 10;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
nseq->section[i].bpm = bpm;
|
||||
synthSetBpm(bpm >> 10, seqId & 0xFF, i & 0xFF);
|
||||
|
||||
if (arr->mTrack != NULL) {
|
||||
nseq->section[i].mTrack.base = (MTRACK_DATA*)(arr->mTrack + (u32)arr);
|
||||
nseq->section[i].mTrack.addr = nseq->section[i].mTrack.base;
|
||||
} else {
|
||||
nseq->section[i].mTrack.base = NULL;
|
||||
}
|
||||
|
||||
nseq->section[i].loopDisable = FALSE;
|
||||
nseq->section[i].loopCnt = 0;
|
||||
}
|
||||
|
||||
tracktab = &arr->tTab;
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
synthTrackVolume[i] = 127;
|
||||
nseq->pattern[i].addr = NULL;
|
||||
// TODO: Finish
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void SetTickDelta(SEQ_SECTION* section, u32 deltaTime) {
|
||||
float tickDelta = (float)section->bpm * (float)deltaTime * 0.0000000244140619f;
|
||||
tickDelta *= section->speed * 0.00390625f;
|
||||
|
||||
section->tickDelta[section->timeIndex].low = fmodf(tickDelta * 65536.f, 65536.f);
|
||||
section->tickDelta[section->timeIndex].high = floorf(tickDelta);
|
||||
}
|
||||
|
||||
static void HandleMasterTrack(u8 secIndex) {
|
||||
SEQ_SECTION* section; // r31
|
||||
section = &cseq->section[secIndex];
|
||||
|
||||
if (section->mTrack.base == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (section->mTrack.addr->time != -1) {
|
||||
if (section->mTrack.addr->time > section->time[section->timeIndex].high) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cseq->arrbase->info & 0x40000000) {
|
||||
synthSetBpm((section->bpm = section->mTrack.addr->bpm) >> 10, curSeqId, secIndex);
|
||||
} else {
|
||||
synthSetBpm(section->mTrack.addr->bpm, curSeqId, secIndex);
|
||||
section->bpm = section->mTrack.addr->bpm << 10;
|
||||
}
|
||||
|
||||
++section->mTrack.addr;
|
||||
}
|
||||
}
|
||||
|
||||
static void RewindMTrack(unsigned char secIndex, unsigned long deltaTime) {
|
||||
if (cseq->section[secIndex].mTrack.base == NULL) {
|
||||
return;
|
||||
}
|
||||
cseq->section[secIndex].mTrack.addr = cseq->section[secIndex].mTrack.base;
|
||||
HandleMasterTrack(secIndex);
|
||||
SetTickDelta(cseq->section + secIndex, deltaTime);
|
||||
}
|
||||
|
||||
static void StartPause(SEQ_INSTANCE* si) {
|
||||
if (si->prev != NULL) {
|
||||
si->prev->next = si->next;
|
||||
} else {
|
||||
seqActiveRoot = si->next;
|
||||
}
|
||||
|
||||
if (si->next != NULL) {
|
||||
si->next->prev = si->prev;
|
||||
}
|
||||
|
||||
if ((si->next = seqPausedRoot) != NULL) {
|
||||
seqPausedRoot->prev = si;
|
||||
}
|
||||
|
||||
si->prev = NULL;
|
||||
seqPausedRoot = si;
|
||||
si->state = 2;
|
||||
}
|
||||
|
||||
void seqPause(u32 seqId) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
|
||||
if (seqId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
si = &seqInstance[seqId];
|
||||
if (si->state == 1) {
|
||||
StartPause(si);
|
||||
KillNotes(si);
|
||||
ResetNotes(si);
|
||||
}
|
||||
} else {
|
||||
si = &seqInstance[seqId & 0x7fffffff];
|
||||
if (si->state != 0) {
|
||||
si->syncCrossInfo.flags |= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void seqStop(unsigned long seqId) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
;
|
||||
|
||||
if ((seqId = seqGetPrivateId(seqId)) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
si = &seqInstance[seqId];
|
||||
switch (si->state) {
|
||||
case 1:
|
||||
if (si->prev != NULL) {
|
||||
si->prev->next = si->next;
|
||||
} else {
|
||||
seqActiveRoot = si->next;
|
||||
}
|
||||
|
||||
KillNotes(&seqInstance[seqId]);
|
||||
ResetNotes(&seqInstance[seqId]);
|
||||
break;
|
||||
case 2:
|
||||
if (si->prev != NULL) {
|
||||
si->prev->next = si->next;
|
||||
} else {
|
||||
seqPausedRoot = si->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (si->next != NULL) {
|
||||
si->next->prev = si->prev;
|
||||
}
|
||||
si->state = 0;
|
||||
if (seqFreeRoot != NULL) {
|
||||
seqFreeRoot->prev = si;
|
||||
}
|
||||
si->next = seqFreeRoot;
|
||||
si->prev = NULL;
|
||||
seqFreeRoot = si;
|
||||
} else {
|
||||
si = &seqInstance[seqId & 0x7fffffff];
|
||||
if (si->state != 0) {
|
||||
si->syncSeqIdPtr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void seqKillAllInstances() {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
for (si = seqActiveRoot; si != NULL; si = si->next) {
|
||||
seqStop(si->publicId);
|
||||
}
|
||||
|
||||
for (si = seqPausedRoot; si != NULL; si = si->next) {
|
||||
seqStop(si->publicId);
|
||||
}
|
||||
}
|
||||
|
||||
void seqKillInstancesByGroupID(unsigned short sgid) {
|
||||
SEQ_INSTANCE* si; // r31
|
||||
|
||||
for (si = seqActiveRoot; si != NULL; si = si->next) {
|
||||
if (si->groupID == sgid) {
|
||||
seqStop(si->publicId);
|
||||
}
|
||||
}
|
||||
for (si = seqPausedRoot; si != NULL; si = si->next) {
|
||||
if (si->groupID == sgid) {
|
||||
seqStop(si->publicId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void seqSpeed(unsigned long seqId, unsigned short speed) {
|
||||
u32 i; // r30
|
||||
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
MUSY_ASSERT_MSG(seqId != -1, "Sequencer ID is not valid.");
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
for (i = 0; i < 16; ++i) {
|
||||
seqInstance[seqId].section[i].speed = speed;
|
||||
}
|
||||
} else {
|
||||
seqId &= 0x7FFFFFFF;
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 0x20;
|
||||
seqInstance[seqId].syncCrossInfo.speed2 = speed;
|
||||
}
|
||||
}
|
||||
|
||||
void seqContinue(u32 seqId) {
|
||||
struct SEQ_INSTANCE* si; // r31
|
||||
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
MUSY_ASSERT_MSG(seqId != -1, "Sequencer ID is not valid.");
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
si = &seqInstance[seqId];
|
||||
|
||||
if (si->state == 2) {
|
||||
if (si->prev != NULL) {
|
||||
si->prev->next = si->next;
|
||||
} else {
|
||||
seqPausedRoot = si->next;
|
||||
}
|
||||
|
||||
if (si->next != NULL) {
|
||||
si->next->prev = si->prev;
|
||||
}
|
||||
|
||||
if ((si->next = seqActiveRoot) != NULL) {
|
||||
seqActiveRoot->prev = si;
|
||||
}
|
||||
|
||||
si->prev = NULL;
|
||||
seqActiveRoot = si;
|
||||
si->state = 1;
|
||||
}
|
||||
} else {
|
||||
seqInstance[seqId & 0x7FFFFFFF].syncCrossInfo.flags &= ~0x8;
|
||||
}
|
||||
}
|
||||
|
||||
void seqMute(unsigned long seqId, unsigned long mask1, unsigned long mask2) {
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
if (seqId == 0xffffffff) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
seqInstance[seqId].trackMute[0] = mask1;
|
||||
seqInstance[seqId].trackMute[1] = mask2;
|
||||
} else {
|
||||
seqId &= 0x7fffffff;
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 0x10;
|
||||
seqInstance[seqId].syncCrossInfo.trackMute2[0] = mask1;
|
||||
seqInstance[seqId].syncCrossInfo.trackMute2[1] = mask2;
|
||||
}
|
||||
}
|
||||
|
||||
void seqVolume(unsigned char volume, unsigned short time, unsigned long seqId, unsigned char mode) {
|
||||
unsigned long i; // r29
|
||||
unsigned long pub_id; // r27
|
||||
pub_id = seqId;
|
||||
seqId = seqGetPrivateId(seqId);
|
||||
|
||||
if (seqId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(seqId & 0x80000000)) {
|
||||
synthVolume(volume, time, seqInstance[seqId].defVGroup, mode, pub_id);
|
||||
for (i = 0; i < 64; ++i) {
|
||||
if (seqInstance[seqId].trackVolGroup[i] != seqInstance[seqId].defVGroup) {
|
||||
synthVolume(volume, time, seqInstance[seqId].trackVolGroup[i], 0, -1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
seqId &= 0x7fffffff;
|
||||
switch (mode & 0xf) {
|
||||
case 0:
|
||||
seqInstance[seqId].syncCrossInfo.vol2 = volume;
|
||||
break;
|
||||
case 1:
|
||||
seqInstance[seqId].syncSeqIdPtr = NULL;
|
||||
break;
|
||||
case 2:
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 8;
|
||||
seqInstance[seqId].syncCrossInfo.vol2 = volume;
|
||||
break;
|
||||
case 3:
|
||||
seqInstance[seqId].syncCrossInfo.flags |= 0x80;
|
||||
seqInstance[seqId].syncCrossInfo.vol2 = volume;
|
||||
break;
|
||||
default:
|
||||
MUSY_FATAL("Illegal sequencere fade mode detected.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,58 +1,462 @@
|
|||
#include "musyx/musyx_priv.h"
|
||||
#include "musyx/synth.h"
|
||||
#ifndef _DEBUG
|
||||
#include "dolphin/os.h"
|
||||
#endif
|
||||
|
||||
SND_STREAM_INFO streamInfo[64];
|
||||
|
||||
u32 nextPublicID = 0;
|
||||
u8 streamCallDelay = 0;
|
||||
static STREAM_INFO streamInfo[64];
|
||||
u8 streamCallCnt = 0;
|
||||
u8 streamCallDelay = 0;
|
||||
u32 nextPublicID = 0;
|
||||
|
||||
void streamInit() {
|
||||
s32 i;
|
||||
streamCallCnt = 0;
|
||||
streamCallDelay = 3;
|
||||
|
||||
for (i = 0; i < synthInfo.voices; ++i) {
|
||||
streamInfo[i].xc_ = 0;
|
||||
for (i = 0; i < synthInfo.voiceNum; ++i) {
|
||||
streamInfo[i].state = 0;
|
||||
}
|
||||
|
||||
nextPublicID = 0;
|
||||
}
|
||||
|
||||
void SetHWMix(SND_STREAM_INFO* info) {
|
||||
// hwSetVolume()
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
void SetHWMix(const STREAM_INFO* si) {
|
||||
hwSetVolume(si->voice, 0, si->vol * (1 / 127.f), (si->pan << 16), (si->span << 16),
|
||||
si->auxa * (1 / 127.f), si->auxb * (1 / 127.f));
|
||||
}
|
||||
#endif
|
||||
|
||||
void streamHandle() {}
|
||||
void streamHandle() {
|
||||
u32 i; // r25
|
||||
u32 cpos; // r30
|
||||
u32 len; // r29
|
||||
struct SAMPLE_INFO newsmp; // r1+0x8
|
||||
struct STREAM_INFO* si; // r31
|
||||
float f; // r63
|
||||
// TODO: Match this
|
||||
}
|
||||
|
||||
void streamCorrectLoops() {}
|
||||
|
||||
void streamKill(SND_STREAMID streamId) {
|
||||
SND_STREAM_INFO* stream = &streamInfo[streamId];
|
||||
|
||||
switch (stream->xc_) {
|
||||
void streamKill(u32 voice) {
|
||||
STREAM_INFO* si = &streamInfo[voice];
|
||||
switch (si->state) {
|
||||
case 1:
|
||||
case 2:
|
||||
if (stream->xc_ == 2) {
|
||||
voiceUnblock(stream->voiceId);
|
||||
if (si->state == 2) {
|
||||
voiceUnblock(si->voice);
|
||||
}
|
||||
stream->xc_ = 3;
|
||||
stream->updateCb(NULL, 0, NULL, 0, stream->user);
|
||||
si->state = 3;
|
||||
si->updateFunction(NULL, 0, NULL, 0, (void*)si->user);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
s32 GetPrivateIndex(s32 something) {
|
||||
s32 i;
|
||||
static u32 GetPrivateIndex(u32 publicID) {
|
||||
u32 i; // r31
|
||||
for (i = 0; i < 64; ++i) {
|
||||
if (streamInfo[i].xc_ != 0 && something == streamInfo[i].x4_) {
|
||||
if (streamInfo[i].state != 0 && publicID == streamInfo[i].stid) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void sndStreamARAMUpdate() {
|
||||
static u32 GeneratePublicID() {
|
||||
u32 id; // r30
|
||||
u32 i; // r31
|
||||
|
||||
do {
|
||||
if ((id = nextPublicID++) == -1) {
|
||||
id = nextPublicID;
|
||||
nextPublicID = id + 1;
|
||||
}
|
||||
for (i = 0; i < 64; ++i) {
|
||||
if (streamInfo[i].state != 0 && id == streamInfo[i].stid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (i != 64);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
u32 sndStreamCallbackFrq(u32 msTime) {
|
||||
s32 time; // r31
|
||||
time = ((msTime * 2 + 5) / 10) - 1;
|
||||
streamCallDelay = time < 0 ? 0 : time;
|
||||
return (streamCallDelay + 1) * 5;
|
||||
}
|
||||
|
||||
void sndStreamARAMUpdate(u32 stid, u32 off1, u32 len1, u32 off2, u32 len2) {
|
||||
u32 i; // r30
|
||||
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
switch (streamInfo[i].type) {
|
||||
case 0:
|
||||
off1 *= 2;
|
||||
len1 *= 2;
|
||||
off2 *= 2;
|
||||
len2 *= 2;
|
||||
break;
|
||||
case 1:
|
||||
off1 = (off1 / 14) * 8;
|
||||
len1 = ((len1 + 13) / 14) * 8;
|
||||
off2 = (off2 / 14) * 8;
|
||||
len2 = ((len2 + 13) / 14) * 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if (len1 != 0) {
|
||||
hwFlushStream(streamInfo[i].buffer, off1, len1, streamInfo[i].hwStreamHandle, 0, 0);
|
||||
}
|
||||
|
||||
if (len2 != 0) {
|
||||
hwFlushStream(streamInfo[i].buffer, off2, len2, streamInfo[i].hwStreamHandle, 0, 0);
|
||||
}
|
||||
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
if (streamInfo[i].type == 1) {
|
||||
streamInfo[i].lastPSFromBuffer = (*(u32*)OSCachedToUncached(streamInfo[i].buffer)) >> 24;
|
||||
if (streamInfo[i].voice != -1) {
|
||||
hwSetStreamLoopPS(streamInfo[i].voice, streamInfo[i].lastPSFromBuffer);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (streamInfo[i].type == 1) {
|
||||
hwSetStreamLoopPS(streamInfo[i].voice, *(u32*)OSCachedToUncached(streamInfo[i].buffer) >> 24);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
||||
static void CheckOutputMode(u8* pan, u8* span) {
|
||||
if (synthFlags & 1) {
|
||||
*pan = 64;
|
||||
*span = 0;
|
||||
} else if (!(synthFlags & 2)) {
|
||||
*span = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||
static void SetupVolumeAndPan(STREAM_INFO* si, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb) {
|
||||
si->orgPan = pan;
|
||||
si->orgSPan = span;
|
||||
CheckOutputMode(&pan, &span);
|
||||
si->vol = vol;
|
||||
si->pan = pan;
|
||||
si->span = span;
|
||||
si->auxa = auxa;
|
||||
si->auxb = auxb;
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 sndStreamAllocEx(u8 prio, void* buffer, u32 samples, u32 frq, u8 vol, u8 pan, u8 span, u8 auxa,
|
||||
u8 auxb, u8 studio, u32 flags, SND_STREAM_UPDATE_CALLBACK updateFunction,
|
||||
u32 user, SND_ADPCMSTREAM_INFO* adpcmInfo) {
|
||||
u32 stid; // r29
|
||||
u32 i; // r31
|
||||
u32 bytes; // r25
|
||||
u32 j; // r28
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
if (streamInfo[i].state == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != 64) {
|
||||
stid = GeneratePublicID();
|
||||
streamInfo[i].stid = stid;
|
||||
streamInfo[i].flags = flags;
|
||||
bytes = sndStreamAllocLength(samples, flags);
|
||||
streamInfo[i].buffer = (s16*)buffer;
|
||||
streamInfo[i].size = samples;
|
||||
streamInfo[i].bytes = bytes;
|
||||
streamInfo[i].updateFunction = updateFunction;
|
||||
streamInfo[i].voice = -1;
|
||||
if (flags & 1) {
|
||||
if (adpcmInfo != NULL) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
streamInfo[i].adpcmInfo.coefTab[j][0] = adpcmInfo->coefTab[j][0];
|
||||
streamInfo[i].adpcmInfo.coefTab[j][1] = adpcmInfo->coefTab[j][1];
|
||||
}
|
||||
streamInfo[i].adpcmInfo.numCoef = 8;
|
||||
}
|
||||
streamInfo[i].type = 1;
|
||||
} else {
|
||||
streamInfo[i].type = 0;
|
||||
}
|
||||
|
||||
streamInfo[i].frq = frq;
|
||||
streamInfo[i].studio = studio;
|
||||
streamInfo[i].prio = prio;
|
||||
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
|
||||
CheckOutputMode(&pan, &span);
|
||||
streamInfo[i].vol = vol;
|
||||
streamInfo[i].pan = pan;
|
||||
streamInfo[i].span = span;
|
||||
streamInfo[i].auxa = auxa;
|
||||
streamInfo[i].auxb = auxb;
|
||||
#else
|
||||
SetupVolumeAndPan(&streamInfo[i], vol, pan, span, auxa, auxb);
|
||||
#endif
|
||||
streamInfo[i].user = user;
|
||||
streamInfo[i].nextStreamHandle = -1;
|
||||
streamInfo[i].state = 3;
|
||||
if ((streamInfo[i].hwStreamHandle = hwInitStream(bytes)) != 0xFF) {
|
||||
if (!(flags & 0x10000) && !sndStreamActivate(stid)) {
|
||||
MUSY_DEBUG("No voice could be allocated for streaming.\n");
|
||||
stid = -1;
|
||||
}
|
||||
} else {
|
||||
MUSY_DEBUG("No ARAM memory could be allocated for streaming.\n");
|
||||
stid = -1;
|
||||
}
|
||||
if (stid == -1) {
|
||||
streamInfo[i].state = 0;
|
||||
}
|
||||
} else {
|
||||
stid = -1;
|
||||
}
|
||||
|
||||
hwEnableIrq();
|
||||
|
||||
return stid;
|
||||
}
|
||||
|
||||
u32 sndStreamAllocStereo(u8 prio, void* lBuffer, void* rBuffer, u32 samples, u32 frq, u8 vol,
|
||||
u8 pan, u8 span, u8 auxa, u8 auxb, u8 studio, u32 flags,
|
||||
SND_STREAM_UPDATE_CALLBACK updateFunction, u32 lUser, u32 rUser,
|
||||
SND_ADPCMSTREAM_INFO* adpcmInfoL, SND_ADPCMSTREAM_INFO* adpcmInfoR) {
|
||||
u32 stid[2]; // r1+0x38
|
||||
s16 rPan; // r31
|
||||
s16 lPan; // r30
|
||||
|
||||
lPan = pan - 64;
|
||||
lPan = lPan < 0 ? 0 : lPan > 127 ? 127 : lPan;
|
||||
rPan = pan + 64;
|
||||
rPan = rPan < 0 ? 0 : rPan > 127 ? 127 : rPan;
|
||||
|
||||
hwDisableIrq();
|
||||
|
||||
;
|
||||
if ((stid[0] = sndStreamAllocEx(prio, lBuffer, samples, frq, vol, lPan, span, auxa, auxb, studio,
|
||||
flags, updateFunction, lUser, adpcmInfoL)) != 0xFFFFFFFF) {
|
||||
if ((stid[1] = sndStreamAllocEx(prio, rBuffer, samples, frq, vol, rPan, span, auxa, auxb,
|
||||
studio, flags, updateFunction, rUser, adpcmInfoR)) ==
|
||||
0xFFFFFFFF) {
|
||||
sndStreamFree(stid[0]);
|
||||
hwEnableIrq();
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
streamInfo[GetPrivateIndex(stid[0])].nextStreamHandle = stid[1];
|
||||
}
|
||||
|
||||
hwEnableIrq();
|
||||
return stid[0];
|
||||
}
|
||||
u32 sndStreamAllocLength(u32 num, u32 flags) {
|
||||
if (flags & 1) {
|
||||
return (((num + 13) / 14) * 8 + 31) & ~31;
|
||||
}
|
||||
|
||||
return (num * 2 + 31) & ~31;
|
||||
}
|
||||
|
||||
void sndStreamADPCMParameter(u32 stid, SND_ADPCMSTREAM_INFO* adpcmInfo) {
|
||||
u32 j; // r31
|
||||
u32 i; // r30
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
streamInfo[i].adpcmInfo.coefTab[j][0] = adpcmInfo->coefTab[j][0];
|
||||
streamInfo[i].adpcmInfo.coefTab[j][1] = adpcmInfo->coefTab[j][1];
|
||||
}
|
||||
streamInfo[i].adpcmInfo.numCoef = 8;
|
||||
if (streamInfo[i].nextStreamHandle != 0xffffffff) {
|
||||
sndStreamADPCMParameter(streamInfo[i].nextStreamHandle, adpcmInfo);
|
||||
}
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
||||
void sndStreamMixParameter(u32 stid, u8 vol, u8 pan, u8 span, u8 fxvol) {
|
||||
u32 i; // r31
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
|
||||
if (i != -1) {
|
||||
#if MUSY_VERSION < MUSY_VERSION_CHECK(1, 5, 4)
|
||||
CheckOutputMode(&pan, &span);
|
||||
streamInfo[i].vol = vol;
|
||||
streamInfo[i].pan = pan;
|
||||
streamInfo[i].span = span;
|
||||
streamInfo[i].auxa = fxvol;
|
||||
streamInfo[i].auxb = 0;
|
||||
hwSetVolume(streamInfo[i].voice, 0, vol * (1 / 127.f), (pan << 16), (span << 16),
|
||||
fxvol * (1 / 127.f), 0.f);
|
||||
#else
|
||||
SetupVolumeAndPan(&streamInfo[i], vol, pan, span, fxvol, 0);
|
||||
SetHWMix(&streamInfo[i]);
|
||||
#endif
|
||||
|
||||
if (streamInfo[i].nextStreamHandle != -1) {
|
||||
sndStreamMixParameter(streamInfo[i].nextStreamHandle, vol, pan, span, fxvol);
|
||||
}
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
||||
void sndStreamMixParameterEx(u32 stid, u8 vol, u8 pan, u8 span, u8 auxa, u8 auxb) {
|
||||
u32 i; // r31
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
#if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3)
|
||||
streamInfo[i].vol = vol;
|
||||
streamInfo[i].pan = pan;
|
||||
streamInfo[i].span = span;
|
||||
streamInfo[i].auxa = fxvol;
|
||||
streamInfo[i].auxb = 0;
|
||||
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));
|
||||
}
|
||||
#else
|
||||
SetupVolumeAndPan(&streamInfo[i], vol, pan, span, auxa, auxb);
|
||||
if (streamInfo[i].state == 2) {
|
||||
SetHWMix(&streamInfo[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (streamInfo[i].nextStreamHandle != -1) {
|
||||
sndStreamMixParameterEx(streamInfo[i].nextStreamHandle, vol, pan, span, auxa, auxb);
|
||||
}
|
||||
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
||||
void sndStreamFrq(u32 stid, u32 frq) {
|
||||
u32 i; // r31
|
||||
u16 pitch; // r27
|
||||
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
streamInfo[i].frq = frq;
|
||||
if (streamInfo[i].state == 2) {
|
||||
pitch = (4096.f * frq) / synthInfo.mixFrq;
|
||||
hwSetPitch(streamInfo[i].voice, pitch);
|
||||
}
|
||||
|
||||
if (streamInfo[i].nextStreamHandle != -1) {
|
||||
sndStreamFrq(streamInfo[i].nextStreamHandle, frq);
|
||||
}
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
||||
void sndStreamFree(u32 stid) {
|
||||
u32 i; // r31
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
sndStreamDeactivate(stid);
|
||||
hwExitStream(streamInfo[i].hwStreamHandle);
|
||||
if (streamInfo[i].nextStreamHandle != -1) {
|
||||
sndStreamFree(streamInfo[i].nextStreamHandle);
|
||||
}
|
||||
|
||||
streamInfo[i].state = 0;
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
||||
u32 sndStreamActivate(u32 stid) {
|
||||
u32 i; // r31
|
||||
u32 ret; // r28
|
||||
|
||||
ret = 0;
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
if (streamInfo[i].state == 3) {
|
||||
if ((streamInfo[i].voice = voiceBlock(streamInfo[i].prio)) == -1) {
|
||||
MUSY_DEBUG("No voice could be allocated for streaming.\n");
|
||||
hwEnableIrq();
|
||||
return 0;
|
||||
}
|
||||
|
||||
streamInfo[i].last = 0;
|
||||
streamInfo[i].state = 1;
|
||||
} else {
|
||||
MUSY_DEBUG("Stream is already active.\n");
|
||||
}
|
||||
|
||||
if (streamInfo[i].nextStreamHandle != -1) {
|
||||
ret = sndStreamActivate(streamInfo[i].nextStreamHandle);
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
hwEnableIrq();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sndStreamDeactivate(u32 stid) {
|
||||
u32 i; // r31
|
||||
|
||||
MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized.");
|
||||
hwDisableIrq();
|
||||
i = GetPrivateIndex(stid);
|
||||
if (i != -1) {
|
||||
if (streamInfo[i].state == 1 || streamInfo[i].state == 2) {
|
||||
voiceUnblock(streamInfo[i].voice);
|
||||
streamInfo[i].state = 3;
|
||||
}
|
||||
|
||||
if (streamInfo[i].nextStreamHandle != -1) {
|
||||
sndStreamDeactivate(streamInfo[i].nextStreamHandle);
|
||||
}
|
||||
} else {
|
||||
MUSY_DEBUG("ID is invalid.\n");
|
||||
}
|
||||
|
||||
hwEnableIrq();
|
||||
}
|
||||
|
|
|
@ -618,6 +618,7 @@ static void mcmdSetADSRFromCtrl(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
|||
float sScale; // r63
|
||||
ADSR_INFO adsr; // r1+0x10
|
||||
}
|
||||
|
||||
static void mcmdSetPitchADSR(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
||||
ADSR_INFO adsr; // r1+0x10
|
||||
ADSR_INFO* adsr_ptr; // r31
|
||||
|
@ -625,6 +626,7 @@ static void mcmdSetPitchADSR(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
|||
s32 ascale; // r27
|
||||
s32 dscale; // r26
|
||||
}
|
||||
|
||||
static u32 mcmdPitchSweep(SYNTH_VOICE* svoice, MSTEP* cstep, int num) {
|
||||
s32 delta; // r31
|
||||
svoice->sweepOff[num] = 0;
|
||||
|
@ -692,7 +694,7 @@ static u32 TranslateVolume(u32 volume, u16 curve) {
|
|||
|
||||
if (vhigh < 0x7f) {
|
||||
d = vlow * (ptr[vhigh + 1] - ptr[vhigh]);
|
||||
volume = d + (ptr[vhigh] << 16);
|
||||
volume = d + ((u8)ptr[vhigh] << 16);
|
||||
} else {
|
||||
volume = ptr[vhigh] << 16;
|
||||
}
|
||||
|
@ -793,6 +795,7 @@ static void mcmdRandomKey(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
|||
s32 i2; // r27
|
||||
u8 detune; // r26
|
||||
}
|
||||
|
||||
static void mcmdSetPitchbendAfterKeyOff(SYNTH_VOICE* svoice) { svoice->cFlags |= 0x10000; }
|
||||
static void mcmdScaleReverb(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
||||
svoice->revVolScale = (u8)(cstep->para[0] >> 8);
|
||||
|
@ -1073,6 +1076,7 @@ static void mcmdGetMessage(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
|||
}
|
||||
varSet32(svoice, 0, (u8)(cstep->para[0] >> 8), mesg);
|
||||
}
|
||||
|
||||
static void mcmdGetVID(SYNTH_VOICE* svoice, MSTEP* cstep) {
|
||||
if ((u8)(cstep->para[0] >> 0x10) == 0) {
|
||||
varSet32(svoice, 0, (u8)(cstep->para[0] >> 8), svoice->vidList->vid);
|
||||
|
|
|
@ -299,9 +299,7 @@ u32 voiceAllocate(u8 priority, u8 maxVoices, u16 allocId, u8 fxFlag) {
|
|||
void voiceFree(SYNTH_VOICE* svoice) {
|
||||
u32 i; // r29
|
||||
SYNTH_VOICELIST* sfv; // r30
|
||||
#line 628
|
||||
MUSY_ASSERT(svoice->id != 0xFFFFFFFF);
|
||||
#line 256
|
||||
macMakeInactive(svoice, MAC_STATE_STOPPED);
|
||||
voiceRemovePriority(svoice);
|
||||
svoice->addr = NULL;
|
||||
|
@ -413,11 +411,11 @@ long voiceKillSound(u32 voiceid) {
|
|||
u32 next_voiceid; // r28
|
||||
u32 i; // r30
|
||||
if (sndActive != FALSE) {
|
||||
for (i = vidGetInternalId(voiceid); i != 0xFFFFFFFF; i = next_voiceid) {
|
||||
voiceid = (u8)i;
|
||||
next_voiceid = synthVoice[voiceid].child;
|
||||
if (i == synthVoice[voiceid].id) {
|
||||
voiceKill(voiceid);
|
||||
for (voiceid = vidGetInternalId(voiceid); voiceid != -1; voiceid = next_voiceid) {
|
||||
i = voiceid & 0xff;
|
||||
next_voiceid = synthVoice[i].child;
|
||||
if (voiceid == synthVoice[i].id) {
|
||||
voiceKill(i);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue