link rhythm

This commit is contained in:
Prakxo
2024-06-05 16:00:06 +02:00
parent c05d93542f
commit d934bd11ad
10 changed files with 509 additions and 6 deletions
+1
View File
@@ -453,6 +453,7 @@ JAUDIO_FUNC_ALIGN_32 = [
"-inline off"
]
JAUDIO_USER = [
"-d _LANGUAGE_C_PLUS_PLUS",
"-O0",
"-char unsigned",
"-fp hard",
+6
View File
@@ -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]
+1
View File
@@ -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
+1
View File
@@ -633,6 +633,7 @@ JAUDIO_FUNC_ALIGN_32_TUS = [
]
JAUDIO_USER_TUS = [
"rhythm.c",
"verysimple.c"
]
+32
View File
@@ -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;
+3
View File
@@ -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
+2
View File
@@ -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 -6
View File
@@ -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
}
+16
View File
@@ -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
+439
View File
@@ -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;
}