mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
link rhythm
This commit is contained in:
@@ -453,6 +453,7 @@ JAUDIO_FUNC_ALIGN_32 = [
|
||||
"-inline off"
|
||||
]
|
||||
JAUDIO_USER = [
|
||||
"-d _LANGUAGE_C_PLUS_PLUS",
|
||||
"-O0",
|
||||
"-char unsigned",
|
||||
"-fp hard",
|
||||
|
||||
@@ -37,6 +37,12 @@ jaudio_NES/verysimple.c:
|
||||
.sdata: [0x80217b80, 0x80217b88]
|
||||
# jaudio_NES/game64.c: # TODO: finish
|
||||
# .rodata: [0x800a9938, 0x800a9b98]
|
||||
jaudio_NES/rhythm.c:
|
||||
.text: [0x80015a4c, 0x800165ec]
|
||||
.bss: [0x8017bdd8, 0x8017be80]
|
||||
.sdata: [0x80217bd0, 0x80217bd8]
|
||||
.sbss: [0x802183a0, 0x802183b0]
|
||||
.sdata2: [0x80218d60, 0x80218d78]
|
||||
jaudio_NES/aictrl.c:
|
||||
.text: [0x80017e80, 0x80018640]
|
||||
.rodata: [0x800aa500, 0x800aa518]
|
||||
|
||||
@@ -3503,6 +3503,7 @@ global:
|
||||
0x80217bac: write_pointer
|
||||
0x80217bb0: buffer_remain
|
||||
0x80217bb4: _STOP
|
||||
0x80217bc0: sou_now_bgm_handle
|
||||
0x80217bc4: SOU_ONGEN_AREA1
|
||||
0x80217bc8: SOU_ONGEN_AREA2
|
||||
0x80217bcc: sou_md_bgm_boost_pasent
|
||||
|
||||
@@ -633,6 +633,7 @@ JAUDIO_FUNC_ALIGN_32_TUS = [
|
||||
]
|
||||
|
||||
JAUDIO_USER_TUS = [
|
||||
"rhythm.c",
|
||||
"verysimple.c"
|
||||
]
|
||||
|
||||
|
||||
@@ -169,6 +169,38 @@ typedef struct envp_ {
|
||||
/* 0x1C */ envdat* pEnvData;
|
||||
} envp;
|
||||
|
||||
/* sizeof(group) == 0x160 */
|
||||
typedef struct group_ {
|
||||
struct flags_ {
|
||||
/* 0x000 */ u32 flag0 : 1;
|
||||
} flags;
|
||||
|
||||
/* 0x004 */ u8 state;
|
||||
/* 0x005 */ u8 unk4;
|
||||
/* 0x006 */ u8 unk5;
|
||||
/* 0x007 */ u16 tempo;
|
||||
/* 0x00C */ u8 unkC[0xD4];
|
||||
/* 0x0E0 */ int unkE0;
|
||||
/* 0x0E4 */ u8 E4[0x77];
|
||||
/* 0x15B */ s8 unk15B;
|
||||
/* 0x15C */ s8 unk15C;
|
||||
} group;
|
||||
|
||||
/* sizeof(AudioGlobals) == 0x92b0 */
|
||||
typedef struct AudioGlobals {
|
||||
/* 0x0000 */ u8 unk0[0x3788];
|
||||
/* 0x3788 */ group groups[5];
|
||||
/* 0x3E68 */ u8 unk3E68[0x5448];
|
||||
} AudioGlobals;
|
||||
|
||||
/* sizeof(sub) >= 0xCD */
|
||||
typedef struct sub_ {
|
||||
/* 0x00 */ s8 unk0[0xCB];
|
||||
/* 0xCB */ s8 unkCB;
|
||||
/* 0xCD */ s8 unkCC;
|
||||
} sub;
|
||||
|
||||
|
||||
typedef union SOUNDID_ {
|
||||
struct {
|
||||
u8 wave_id;
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
#define AUDIOWORK_H
|
||||
|
||||
#include "types.h"
|
||||
#include "jaudio_NES/audiostruct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern AudioGlobals AG;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -61,6 +61,8 @@ extern void Na_RestartPrepare();
|
||||
extern u8 Na_CheckRestartReady();
|
||||
extern void Na_Restart();
|
||||
|
||||
extern u8 sou_now_bgm_handle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void Na_RhythmStart(u32, s8, s8);
|
||||
extern void Na_RhythmStop(u32);
|
||||
extern void Na_RhythmInit();
|
||||
extern s8 Na_GetRhythmSubTrack(u32 idx);
|
||||
extern void Na_RhythmStart(u32 idx, s8 arg1, s8 arg2);
|
||||
extern void Na_RhythmStop(u32 idx);
|
||||
extern void Na_RhythmAllStop();
|
||||
extern f32 Na_GetRhythmAnimCounter(u32);
|
||||
extern s8 Na_GetRhythmDelay(u32);
|
||||
extern void Na_GetRhythmInfo(TempoBeat_c* rhythm);
|
||||
extern void Na_SetRhythmInfo(TempoBeat_c* rhythm);
|
||||
extern f32 Na_GetRhythmAnimCounter(u32 idx);
|
||||
extern s8 Na_GetRhythmDelay(u32 idx);
|
||||
extern void Na_GetRhythmInfo(TempoBeat_c* tempo);
|
||||
extern void Na_SetRhythmInfo(TempoBeat_c* tempo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -3,7 +3,23 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "jaudio_NES/audiostruct.h"
|
||||
#include "PR/mbi.h"
|
||||
|
||||
|
||||
#define NA_MAKE_COMMAND(a0, a1, a2, a3) \
|
||||
(u32)((((a0)&0xFF) << 24) | (((a1)&0xFF) << 16) | (((a2)&0xFF) << 8) | (((a3)&0xFF) << 0))
|
||||
|
||||
extern s32 CreateAudioTask(Acmd* cmds, s16* pSamples, u32 nSamples, s32 param_4);
|
||||
|
||||
extern void Nap_SetU16(u32 command , u16 value);
|
||||
extern void Nap_SetU8(u32 command, u8 value);
|
||||
extern void Nap_SetS8(u32 command, s8 value);
|
||||
extern void Nap_SetF32(u32 command, f32 value);
|
||||
extern void Nap_SetS32(u32 command, s32 value);
|
||||
|
||||
extern s8 Nap_ReadSubPort(s32, s32, s32);
|
||||
extern s8 Nap_ReadGrpPort(s32, s32);
|
||||
|
||||
extern s32 Nap_GetRandom();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
#include "jaudio_NES/rhythm.h"
|
||||
#include "jaudio_NES/sub_sys.h"
|
||||
#include "jaudio_NES/game64.h"
|
||||
#include "jaudio_NES/audiowork.h"
|
||||
|
||||
typedef struct NA_RHYTHM_BUFFER {
|
||||
/* 0x0 */ u8 state;
|
||||
/* 0x1 */ s8 current_subtrack;
|
||||
/* 0x2 */ u8 unk2[0x2];
|
||||
/* 0x4 */ u32 current_buffer_id;
|
||||
/* 0x8 */ s8 unk8;
|
||||
/* 0x9 */ s8 unk9;
|
||||
/* 0xA */ u8 unkA[0x2];
|
||||
} NA_RHYTHM_BUFFER;
|
||||
|
||||
typedef enum RythmBuffer_State {
|
||||
NA_RHYTHM_BUFFER_STOPPED,
|
||||
NA_RHYTHM_BUFFER_ALLOC,
|
||||
NA_RHYTHM_BUFFER_STARTED,
|
||||
} RythmBuffer_State;
|
||||
|
||||
|
||||
static s16 rhythm_beat_type = -1;
|
||||
|
||||
static NA_RHYTHM_BUFFER rhythm_buffer[14];
|
||||
|
||||
static s8 Na_GetRhythmSeNum(s8 num, sub* sub);
|
||||
static s8 Na_RhythmGrpProcess(s8 arg0, group* group);
|
||||
|
||||
extern void Na_RhythmInit() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 14; i++) {
|
||||
rhythm_buffer[i].state = NA_RHYTHM_BUFFER_STOPPED;
|
||||
rhythm_buffer[i].current_subtrack = i;
|
||||
}
|
||||
|
||||
Nap_SetS32(NA_MAKE_COMMAND(228, 0, 0, 0), (s32)Na_GetRhythmSeNum);
|
||||
Nap_SetS32(NA_MAKE_COMMAND(228, 0, 0, 1), (s32)Na_RhythmGrpProcess);
|
||||
}
|
||||
|
||||
static NA_RHYTHM_BUFFER* rhythm_buffer_alloc() {
|
||||
int i;
|
||||
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
|
||||
for (i = 0; i < 14; i++) {
|
||||
buf = &rhythm_buffer[i];
|
||||
|
||||
if (buf->state == NA_RHYTHM_BUFFER_STOPPED) {
|
||||
buf->state = NA_RHYTHM_BUFFER_ALLOC;
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static NA_RHYTHM_BUFFER* get_rhythm_buffer(u32 idx) {
|
||||
int i;
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
|
||||
for (i = 0; i < 14; i++) {
|
||||
buf = &rhythm_buffer[i];
|
||||
|
||||
if (buf->state != NA_RHYTHM_BUFFER_STOPPED && idx == buf->current_buffer_id) {
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern s8 Na_GetRhythmSubTrack(u32 idx) {
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
|
||||
buf = get_rhythm_buffer(idx);
|
||||
if (buf == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
return buf->current_subtrack;
|
||||
}
|
||||
|
||||
static void rhythm_start(NA_RHYTHM_BUFFER* buffer) {
|
||||
if (buffer != nullptr) {
|
||||
Nap_SetS8(NA_MAKE_COMMAND(6, 2, buffer->current_subtrack, 0), 0);
|
||||
Nap_SetS8(NA_MAKE_COMMAND(6, 2, buffer->current_subtrack, 3), buffer->unk8);
|
||||
Nap_SetS8(NA_MAKE_COMMAND(6, 2, buffer->current_subtrack, 7), buffer->unk9);
|
||||
buffer->state = NA_RHYTHM_BUFFER_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
static void rhythm_stop(NA_RHYTHM_BUFFER* buffer) {
|
||||
if (buffer != nullptr) {
|
||||
if (buffer->state == NA_RHYTHM_BUFFER_STARTED) {
|
||||
Nap_SetS8(NA_MAKE_COMMAND(6, 2, buffer->current_subtrack, 0), 1);
|
||||
}
|
||||
|
||||
buffer->state = NA_RHYTHM_BUFFER_STOPPED;
|
||||
}
|
||||
}
|
||||
|
||||
extern void Na_RhythmStart(u32 idx, s8 arg1, s8 arg2) {
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
|
||||
buf = get_rhythm_buffer(idx);
|
||||
if (buf == nullptr) {
|
||||
buf = rhythm_buffer_alloc();
|
||||
}
|
||||
if (buf != nullptr) {
|
||||
buf->current_buffer_id = idx;
|
||||
buf->unk8 = arg1;
|
||||
buf->unk9 = arg2;
|
||||
rhythm_start(buf);
|
||||
}
|
||||
}
|
||||
|
||||
extern void Na_RhythmStop(u32 idx) {
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
|
||||
buf = get_rhythm_buffer(idx);
|
||||
if (buf != nullptr) {
|
||||
rhythm_stop(buf);
|
||||
}
|
||||
}
|
||||
|
||||
extern void Na_RhythmAllStop() {
|
||||
int i;
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
|
||||
for (i = 0; i < 14; i++) {
|
||||
buf = &rhythm_buffer[i];
|
||||
|
||||
if (buf->state != NA_RHYTHM_BUFFER_STOPPED) {
|
||||
rhythm_stop(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static s16 Na_GetRhythmBeatType(void) {
|
||||
if (AG.groups[sou_now_bgm_handle].flags.flag0 != 0) {
|
||||
rhythm_beat_type = Nap_ReadGrpPort(sou_now_bgm_handle, 1);
|
||||
}
|
||||
return rhythm_beat_type;
|
||||
}
|
||||
|
||||
extern f32 Na_GetRhythmAnimCounter(u32 idx) {
|
||||
f32 f31 = 0.0f;
|
||||
NA_RHYTHM_BUFFER* buf = get_rhythm_buffer(idx);
|
||||
s16 r30;
|
||||
s16 r29;
|
||||
int r28;
|
||||
s16 r27;
|
||||
|
||||
if (buf == nullptr) {
|
||||
return -2.0f;
|
||||
}
|
||||
|
||||
if (Nap_ReadSubPort(2, buf->current_subtrack, 1) == 0) {
|
||||
if (Nap_ReadSubPort(2, buf->current_subtrack, 6) <= 1) {
|
||||
return -1.0f;
|
||||
}
|
||||
return -2.0f;
|
||||
}
|
||||
|
||||
r30 = Nap_ReadSubPort(2, buf->current_subtrack, 4);
|
||||
r29 = Nap_ReadSubPort(2, buf->current_subtrack, 5);
|
||||
r27 = Nap_ReadGrpPort(2, 3);
|
||||
if (r30 == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (Na_GetRhythmBeatType() == 0) {
|
||||
if (Nap_ReadGrpPort(2, 2) % 2 != 0) {
|
||||
r28 = 32;
|
||||
} else {
|
||||
r28 = 16;
|
||||
}
|
||||
} else {
|
||||
r28 = 24;
|
||||
}
|
||||
|
||||
r30 = (r29 - r30) * r28;
|
||||
r30 += r27;
|
||||
r29 *= r28;
|
||||
f31 = (f32)r30 / (f32)r29;
|
||||
return f31;
|
||||
}
|
||||
|
||||
extern s8 Na_GetRhythmDelay(u32 idx) {
|
||||
NA_RHYTHM_BUFFER* buf;
|
||||
s8 delay = 0;
|
||||
|
||||
buf = get_rhythm_buffer(idx);
|
||||
if (buf == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
delay = Nap_ReadSubPort(2, buf->current_subtrack, 7);
|
||||
|
||||
return delay;
|
||||
}
|
||||
|
||||
static s8 Na_GetRhythmSeNum(s8 num, sub* sub) {
|
||||
u32 rand;
|
||||
|
||||
if (num == 0) {
|
||||
num = 16 - sub->unkCC;
|
||||
if (num == 16) {
|
||||
num = 0;
|
||||
}
|
||||
} else {
|
||||
rand = Nap_GetRandom();
|
||||
switch (sub->unkCB) {
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x5A:
|
||||
num = rand & 7;
|
||||
break;
|
||||
case 0xC:
|
||||
case 0xD:
|
||||
case 0xE:
|
||||
case 0x17:
|
||||
case 0x18:
|
||||
case 0x19:
|
||||
case 0x1A:
|
||||
case 0x1B:
|
||||
case 0x1C:
|
||||
case 0x1D:
|
||||
case 0x1E:
|
||||
case 0x1F:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
case 0x2A:
|
||||
case 0x2B:
|
||||
case 0x2C:
|
||||
case 0x2D:
|
||||
case 0x2E:
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
case 0x3E:
|
||||
case 0x3F:
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x4C:
|
||||
case 0x4D:
|
||||
case 0x4E:
|
||||
case 0x4F:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5E:
|
||||
case 0x5F:
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6A:
|
||||
case 0x6B:
|
||||
case 0x6C:
|
||||
case 0x6D:
|
||||
case 0x6E:
|
||||
case 0x6F:
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x78:
|
||||
case 0x79:
|
||||
case 0x7A:
|
||||
case 0x7B:
|
||||
case 0x7C:
|
||||
num = (rand % 6);
|
||||
break;
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
num = (rand % 5);
|
||||
break;
|
||||
case 0x3C:
|
||||
case 0x3D:
|
||||
case 0x5D:
|
||||
num = rand & 3;
|
||||
break;
|
||||
case 0x5:
|
||||
case 0xF:
|
||||
case 0x2F:
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4A:
|
||||
case 0x4B:
|
||||
num = (rand % 3);
|
||||
break;
|
||||
default:
|
||||
num = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
extern void Na_GetRhythmInfo(TempoBeat_c* tempo) {
|
||||
if (tempo != nullptr) {
|
||||
tempo->tempo = (AG.groups[2].tempo / 48);
|
||||
tempo->beat = Na_GetRhythmBeatType();
|
||||
}
|
||||
}
|
||||
|
||||
extern void Na_SetRhythmInfo(TempoBeat_c* tempo) {
|
||||
(tempo != nullptr);
|
||||
if ((tempo == nullptr) || (tempo->tempo == 0)) {
|
||||
Nap_SetS32(NA_MAKE_COMMAND(71, 2, 0, 0), 120);
|
||||
rhythm_beat_type = -1;
|
||||
} else {
|
||||
Nap_SetS32(NA_MAKE_COMMAND(71, 2, 0, 0), tempo->tempo);
|
||||
rhythm_beat_type = tempo->beat;
|
||||
}
|
||||
}
|
||||
|
||||
static void tempo_adjust(group* group) {
|
||||
int tempo = (AG.groups[2].tempo / 48);
|
||||
int newTempo;
|
||||
if (AG.groups[sou_now_bgm_handle].flags.flag0 != 0) {
|
||||
newTempo = (AG.groups[sou_now_bgm_handle].tempo / 48);
|
||||
|
||||
if (tempo > newTempo) {
|
||||
tempo--;
|
||||
} else if (tempo < newTempo) {
|
||||
tempo++;
|
||||
}
|
||||
}
|
||||
group->tempo = tempo * 48;
|
||||
}
|
||||
|
||||
static s8 Na_RhythmGrpProcess(s8 arg0, group* group) {
|
||||
int r29;
|
||||
int r27;
|
||||
int r30;
|
||||
int r31;
|
||||
(void)arg0;
|
||||
int ret = 1;
|
||||
r29 = 24;
|
||||
static int pre_beat_type = -1;
|
||||
static u8 init;
|
||||
static int pre_frame_per_step = -1;
|
||||
|
||||
{ static u8 init; }
|
||||
|
||||
tempo_adjust(group);
|
||||
if (Na_GetRhythmBeatType() == 0) {
|
||||
if (Nap_ReadGrpPort(2, 2) % 2 != 0) {
|
||||
r29 = 32;
|
||||
} else {
|
||||
r29 = 16;
|
||||
}
|
||||
} else {
|
||||
r29 = 24;
|
||||
}
|
||||
|
||||
r31 = Nap_ReadGrpPort(2, 3);
|
||||
if (Nap_ReadGrpPort(2, 2) % 2 != 0) {
|
||||
r27 = r31;
|
||||
} else if (Na_GetRhythmBeatType() == 0) {
|
||||
r27 = r31 + 32;
|
||||
} else {
|
||||
r27 = r31 + 24;
|
||||
}
|
||||
|
||||
if (pre_beat_type != rhythm_beat_type) {
|
||||
if (pre_frame_per_step > 0) {
|
||||
r31 = (r31 * (r29 / (f32)pre_frame_per_step));
|
||||
}
|
||||
pre_beat_type = rhythm_beat_type;
|
||||
}
|
||||
pre_frame_per_step = r29;
|
||||
|
||||
if (AG.groups[sou_now_bgm_handle].flags.flag0 != 0) {
|
||||
int r25 = Nap_ReadGrpPort(sou_now_bgm_handle, 0);
|
||||
r30 = r25 - r27;
|
||||
} else {
|
||||
r30 = 0;
|
||||
}
|
||||
|
||||
if (r30 > 24) {
|
||||
r30 -= 48;
|
||||
}
|
||||
if (r30 < -24) {
|
||||
r30 += 48;
|
||||
}
|
||||
|
||||
if (r30 > 1 || r30 < -1) {
|
||||
if (AG.groups[2].unkE0 % 2 != 0) {
|
||||
r31++;
|
||||
}
|
||||
} else {
|
||||
r31++;
|
||||
}
|
||||
|
||||
if (r31 >= r29) {
|
||||
r31 -= r29;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
group->unk15B = r31;
|
||||
group->unk15C = (s8)((s32)(r31 * 0x64) / r29);
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user