From cc324e62127249b63a8a0433f32e009235183b8f Mon Sep 17 00:00:00 2001 From: mrshigure Date: Mon, 25 Dec 2023 11:26:49 -0800 Subject: [PATCH] Matched game/armem and game/perf --- include/game/armem.h | 21 +++ include/game/data.h | 4 +- include/game/memory.h | 1 + include/game/perf.h | 12 ++ src/game/armem.c | 377 ++++++++++++++++++++++++++++++++++++++++++ src/game/perf.c | 153 +++++++++++++++++ src/game/window.c | 9 +- 7 files changed, 569 insertions(+), 8 deletions(-) create mode 100644 include/game/armem.h create mode 100644 include/game/perf.h create mode 100644 src/game/armem.c create mode 100644 src/game/perf.c diff --git a/include/game/armem.h b/include/game/armem.h new file mode 100644 index 00000000..06ca3762 --- /dev/null +++ b/include/game/armem.h @@ -0,0 +1,21 @@ +#ifndef _GAME_ARMEM_H +#define _GAME_ARMEM_H + +#include "common.h" +#include "game/memory.h" + +void HuARInit(void); +void *HuARMalloc(u32 arg0); +void HuARFree(void *arg0); +void HuAMemDump(void); +void *HuAR_DVDtoARAM(u32 arg0); +void HuAR_MRAMtoARAM(s32 arg0); +void *HuAR_MRAMtoARAM2(void *arg0); +void HuAR_ARAMtoMRAM(void *dst); +void *HuAR_ARAMtoMRAMNum(void *dst, s32 num); +BOOL HuARDMACheck(void); +void *HuARDirCheck(u32 dir); +void HuARDirFree(u32 arg0); +void *HuAR_ARAMtoMRAMFileRead(u32 arg0, u32 arg1, HeapID arg2); + +#endif diff --git a/include/game/data.h b/include/game/data.h index e59ede63..123c50de 100644 --- a/include/game/data.h +++ b/include/game/data.h @@ -63,9 +63,9 @@ void *HuDataReadNumHeapShortForce(s32 data_id, s32 num, HeapID heap); void HuDecodeData(void *src, void *dst, u32 size, int decode_type); -void *HuARDirCheck(s32 dir); +void *HuARDirCheck(u32 dir); void HuAR_ARAMtoMRAM(void *dst); -void HuAR_ARAMtoMRAMNum(void *dst, s32 num); +void *HuAR_ARAMtoMRAMNum(void *dst, s32 num); BOOL HuARDMACheck(); diff --git a/include/game/memory.h b/include/game/memory.h index 52269a8e..95728bde 100644 --- a/include/game/memory.h +++ b/include/game/memory.h @@ -34,6 +34,7 @@ void HuMemMemoryFree(void *ptr, u32 retaddr); void HuMemMemoryFreeNum(void *heap_ptr, u32 num, u32 retaddr); s32 HuMemUsedMemorySizeGet(void *heap_ptr); s32 HuMemUsedMemoryBlockGet(void *heap_ptr); +s32 HuMemMemorySizeGet(void *ptr); s32 HuMemMemoryAllocSizeGet(s32 size); void HuMemHeapDump(void *heap_ptr, s16 status); diff --git a/include/game/perf.h b/include/game/perf.h new file mode 100644 index 00000000..6061a5dd --- /dev/null +++ b/include/game/perf.h @@ -0,0 +1,12 @@ +#ifndef _GAME_PERF_H +#define _GAME_PERF_H + +#include "common.h" + +void HuPerfInit(void); +s32 HuPerfCreate(char *arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4); +void HuPerfZero(void); +void HuPerfBegin(s32 arg0); +void HuPerfEnd(s32 arg0); + +#endif diff --git a/src/game/armem.c b/src/game/armem.c new file mode 100644 index 00000000..dd989cdc --- /dev/null +++ b/src/game/armem.c @@ -0,0 +1,377 @@ +#include "game/armem.h" +#include "game/data.h" + +typedef struct some_armem_struct0 { + /* 0x00 */ u8 unk00; + /* 0x01 */ char unk01[1]; + /* 0x02 */ u16 unk02; + /* 0x04 */ void *unk04; + /* 0x08 */ u32 unk08; + /* 0x0C */ struct some_armem_struct0 *unk0C; +} SomeArmemStruct0; // Size 0x10 + +typedef struct { + /* 0x00 */ ARQRequest unk00; + /* 0x20 */ s32 unk20; + /* 0x24 */ void *unk24; +} SomeArmemStruct1; // Size 0x28 + +static void ArqCallBack(u32 pointerToARQRequest); +static void ArqCallBackAM(u32 pointerToARQRequest); +static void ArqCallBackAMFileRead(u32 pointerToARQRequest); + +static s32 ATTRIBUTE_ALIGN(32) preLoadBuf[16]; +static SomeArmemStruct1 ARQueBuf[16]; +static ARQRequest arqReq; +static SomeArmemStruct0 ARInfo[64]; + +static s32 ARBase; +static s32 arqCnt; +static s16 arqIdx; + +void HuARInit(void) { + s32 temp_r30; + s16 i; + + if (!ARCheckInit()) { + ARInit(NULL, 0); + ARQInit(); + } + for (i = 0; i < 64; i++) { + ARInfo[i].unk04 = 0; + } + temp_r30 = ARGetSize() - 0x808000; + ARBase = 0x808000; + ARInfo[0].unk04 = (void*) ARBase; + ARInfo[0].unk08 = temp_r30; + ARInfo[0].unk00 = 0; + ARInfo[0].unk0C = &ARInfo[1]; + ARInfo[0].unk02 = 0xFFFF; + ARInfo[1].unk04 = (void*) -1; + ARInfo[1].unk08 = 0; + ARInfo[1].unk00 = 1; + ARInfo[1].unk0C = 0; + ARInfo[1].unk02 = 0xFFFF; + arqCnt = 0; +} + +void *HuARMalloc(u32 arg0) { + SomeArmemStruct0 *var_r27; + SomeArmemStruct0 *var_r30; + SomeArmemStruct0 *var_r31; + s16 i; + + arg0 = (arg0 + 0x1F) & ~0x1F; + var_r31 = var_r27 = ARInfo; + while (var_r31->unk0C != 0) { + if (var_r31->unk00 == 0 && var_r31->unk08 >= arg0) { + break; + } + var_r27 = var_r31; + var_r31 = var_r31->unk0C; + } + if (var_r31->unk0C == 0) { + OSReport("Can't ARAM Allocated %x\n", arg0); + HuAMemDump(); + return 0; + } + var_r31->unk00 = 1; + if (var_r31->unk08 == arg0 && var_r27 != var_r31) { + var_r31->unk02 = 0xFFFF; + } else { + var_r30 = &ARInfo[1]; + for (i = 0; i < 63; i++, var_r30++) { + if (var_r30->unk04 == 0) { + break; + } + } + if (i == 63) { + OSReport("Can't ARAM Allocated %x\n", arg0); + return 0; + } + var_r30->unk0C = var_r31->unk0C; + var_r31->unk0C = var_r30; + var_r30->unk08 = var_r31->unk08 - arg0; + var_r30->unk04 = (u8*) var_r31->unk04 + arg0; + var_r31->unk08 = arg0; + var_r31->unk02 = var_r30->unk02 = 0xFFFF; + var_r30->unk00 = 0; + } + return var_r31->unk04; +} + +void HuARFree(void *arg0) { + SomeArmemStruct0 *var_r30; + SomeArmemStruct0 *temp_r29; + SomeArmemStruct0 *var_r31; + + var_r31 = var_r30 = ARInfo; + while (var_r31->unk0C != 0) { + if (var_r31->unk04 == arg0) { + break; + } + var_r30 = var_r31; + var_r31 = var_r31->unk0C; + } + if (var_r31->unk00 != 0) { + if (var_r31->unk0C == 0 && var_r31->unk04 != arg0) { + OSReport("Can't ARAM Free %x\n", arg0); + return; + } + temp_r29 = var_r31->unk0C; + if (temp_r29->unk0C != 0 && temp_r29->unk00 == 0) { + if (var_r31->unk04 > temp_r29->unk04) { + var_r31->unk04 = temp_r29->unk04; + } + var_r31->unk08 += temp_r29->unk08; + var_r31->unk0C = temp_r29->unk0C; + temp_r29->unk04 = 0; + } + if (var_r30 != var_r31 && var_r30->unk0C != 0 && var_r30->unk00 == 0) { + if (var_r30->unk04 > var_r31->unk04) { + var_r30->unk04 = var_r31->unk04; + } + var_r30->unk08 += var_r31->unk08; + var_r30->unk0C = var_r31->unk0C; + var_r31->unk04 = 0; + } + var_r31->unk00 = 0; + var_r31->unk02 = 0xFFFF; + } +} + +static char lbl_80130705[] = "Can't Find ARAM %x\n"; + +static inline SomeArmemStruct0 *ArmemInlineFunc1(void *arg0) { + SomeArmemStruct0 *temp_var1; + SomeArmemStruct0 *temp_var2; + + temp_var1 = temp_var2 = ARInfo; + while (temp_var1->unk0C != 0) { + if (temp_var1->unk04 == arg0) { + break; + } + temp_var2 = temp_var1; + temp_var1 = temp_var1->unk0C; + } + if (temp_var1->unk0C == 0 && temp_var1->unk04 != arg0) { + OSReport(lbl_80130705, arg0); + return NULL; + } else { + return temp_var1; + } +} + +static inline u32 ArmemInlineFunc2(void *arg0) { + SomeArmemStruct0 *temp_var1; + SomeArmemStruct0 *temp_var2; + + temp_var1 = temp_var2 = ARInfo; + while (temp_var1->unk0C != 0) { + if (temp_var1->unk04 == arg0) { + break; + } + temp_var2 = temp_var1; + temp_var1 = temp_var1->unk0C; + } + if (temp_var1->unk0C == 0 && temp_var1->unk04 != arg0) { + OSReport(lbl_80130705, arg0); + return 0; + } else { + return temp_var1->unk08; + } +} + +void HuAMemDump(void) { + SomeArmemStruct0 *var_r31; + + OSReport("ARAM DUMP ======================\n"); + OSReport("AMemPtr Stat Length\n"); + for (var_r31 = ARInfo; var_r31->unk0C != 0; var_r31 = var_r31->unk0C) { + OSReport("%08x:%04x,%08x,%08x\n", var_r31->unk04, var_r31->unk00, var_r31->unk08, var_r31->unk02); + } + OSReport("%08x:%04x,%08x\n", var_r31->unk04, var_r31->unk00, var_r31->unk08); + OSReport("================================\n"); +} + +void *HuAR_DVDtoARAM(u32 arg0) { + DataReadStat *temp_r28; + SomeArmemStruct0 *var_r27; + void *temp_r3; + + temp_r3 = HuARDirCheck(arg0); + if (temp_r3 != 0) { + return temp_r3; + } + temp_r28 = HuDataDirRead(arg0); + DirDataSize = (DirDataSize + 0x1F) & ~0x1F; + temp_r3 = HuARMalloc(DirDataSize); + if (temp_r3 == 0) { + return 0; + } + var_r27 = ArmemInlineFunc1(temp_r3); + var_r27->unk02 = (arg0 >> 16); + arqCnt++; + ARQPostRequest(&arqReq, 0x1234, 0, 0, (u32) temp_r28->dir, (u32) temp_r3, DirDataSize, ArqCallBack); + OSReport("ARAM Trans %x\n", temp_r3); + while (HuARDMACheck()); + HuDataDirClose(arg0); + return temp_r3; +} + +static void ArqCallBack(u32 pointerToARQRequest) { + arqCnt--; + (void)pointerToARQRequest; // required to match (return?) +} + +void HuAR_MRAMtoARAM(s32 arg0) { + HuAR_MRAMtoARAM2(HuDataGetDirPtr(arg0)); +} + +void *HuAR_MRAMtoARAM2(void *arg0) { + SomeArmemStruct0 *var_r27; + DataReadStat *temp_r3_3; + u32 temp_r28; + void *temp_r3; + + temp_r3_3 = HuDataGetStatus(arg0); + temp_r3 = HuARDirCheck(temp_r3_3->dir_id << 16); + if (temp_r3 != 0) { + return temp_r3; + } + temp_r28 = HuMemMemorySizeGet(arg0); + temp_r28 = (temp_r28 + 0x1F) & ~0x1F; + temp_r3 = HuARMalloc(temp_r28); + if (temp_r3 == 0) { + return 0; + } + var_r27 = ArmemInlineFunc1(temp_r3); + var_r27->unk02 = temp_r3_3->dir_id; + arqCnt++; + ARQPostRequest(&arqReq, 0x1234, 0, 0, (u32) arg0, (u32) temp_r3, temp_r28, ArqCallBack); + return temp_r3; +} + +void HuAR_ARAMtoMRAM(void *dst) { + HuAR_ARAMtoMRAMNum(dst, 0); +} + +void *HuAR_ARAMtoMRAMNum(void *dst, s32 num) { + SomeArmemStruct0 *var_r25; + s32 var_r26; + void *temp_r3; + + var_r25 = ArmemInlineFunc1(dst); + if (HuDataReadChk(var_r25->unk02 << 16) >= 0) { + return; + } + var_r26 = ArmemInlineFunc2(dst); + temp_r3 = HuMemDirectMallocNum(HEAP_DVD, var_r26, num); + if (temp_r3 == 0) { + return 0; + } + DCFlushRangeNoSync(temp_r3, var_r26); + ARQueBuf[arqIdx].unk20 = (var_r25->unk02 << 16); + ARQueBuf[arqIdx].unk24 = temp_r3; + arqCnt++; + PPCSync(); + ARQPostRequest(&ARQueBuf[arqIdx].unk00, 0x1234, 1, 0, (u32) dst, (u32) temp_r3, var_r26, ArqCallBackAM); + arqIdx++; + arqIdx &= 0xF; + return temp_r3; +} + +static void ArqCallBackAM(u32 pointerToARQRequest) { + SomeArmemStruct1 *sp8 = (SomeArmemStruct1*) pointerToARQRequest; + + arqCnt--; + HuDataDirSet(sp8->unk24, sp8->unk20); +} + +BOOL HuARDMACheck(void) { + return arqCnt; +} + +void *HuARDirCheck(u32 dir) { + SomeArmemStruct0 *var_r31; + + var_r31 = ARInfo; + dir >>= 16; + while (var_r31->unk0C != 0) { + if (var_r31->unk00 == 1 && var_r31->unk02 == dir) { + return var_r31->unk04; + } + var_r31 = var_r31->unk0C; + } + + return 0; +} + +void HuARDirFree(u32 arg0) { + SomeArmemStruct0 *var_r31; + + var_r31 = ARInfo; + arg0 >>= 16; + while (var_r31->unk0C != 0) { + if (var_r31->unk02 == arg0) { + HuARFree(var_r31->unk04); + break; + } + var_r31 = var_r31->unk0C; + } +} + +void *HuAR_ARAMtoMRAMFileRead(u32 arg0, u32 arg1, HeapID arg2) { + s32 *temp_r29; + void *temp_r3; + void *temp_r3_2; + void *var_r20; + s32 temp_r24; + s32 var_r22; + u8 *var_r17; + + if ((var_r17 = HuARDirCheck(arg0)) == 0) { + OSReport("Error: data none on ARAM %0x\n", arg0); + HuAMemDump(); + return 0; + } + DCInvalidateRange(&preLoadBuf, sizeof(preLoadBuf)); + var_r20 = var_r17 + ((u32) (((u16) arg0 + 1) * 4) & 0xFFFFFFFE0); + arqCnt++; + ARQPostRequest(&ARQueBuf[arqIdx].unk00, 0x1234, 1, 0, (u32) var_r20, (u32) &preLoadBuf, sizeof(preLoadBuf), ArqCallBackAMFileRead); + arqIdx++; + arqIdx &= 0xF; + while (HuARDMACheck()); + temp_r29 = &preLoadBuf[(arg0 + 1) & 7]; + temp_r24 = temp_r29[0]; + var_r20 = var_r17 + (temp_r24 & 0xFFFFFFFE0); + if (temp_r29[1] - temp_r24 < 0) { + var_r22 = (ArmemInlineFunc2(var_r17) - temp_r24 + 0x3F) & 0xFFFFFFFE0; + } else { + var_r22 = (temp_r29[1] - temp_r24 + 0x3F) & 0xFFFFFFFE0; + } + temp_r3_2 = HuMemDirectMalloc(HEAP_DVD, var_r22); + if (temp_r3_2 == 0) { + return 0; + } + DCFlushRangeNoSync(temp_r3_2, var_r22); + arqCnt++; + PPCSync(); + ARQPostRequest(&ARQueBuf[arqIdx].unk00, 0x1234, 1, 0, (u32) var_r20, (u32) temp_r3_2, (u32) var_r22, ArqCallBackAMFileRead); + arqIdx++; + arqIdx &= 0xF; + while (HuARDMACheck()); + temp_r29 = (s32*) ((u8*) temp_r3_2 + (temp_r24 & 0x1F)); + temp_r3 = HuMemDirectMallocNum(arg2, (temp_r29[0] + 1) & ~1, arg1); + if (temp_r3 == 0) { + return 0; + } + HuDecodeData(&temp_r29[2], temp_r3, temp_r29[0], temp_r29[1]); + HuMemDirectFree(temp_r3_2); + return temp_r3; +} + +static void ArqCallBackAMFileRead(u32 pointerToARQRequest) { + arqCnt--; + (void)pointerToARQRequest; // required to match (return?) +} diff --git a/src/game/perf.c b/src/game/perf.c new file mode 100644 index 00000000..a10efa7a --- /dev/null +++ b/src/game/perf.c @@ -0,0 +1,153 @@ +#include "game/perf.h" + +typedef struct { + /* 0x00 */ u8 unk00; + /* 0x01 */ u8 unk01; + /* 0x02 */ u8 unk02; + /* 0x03 */ u8 unk03; + /* 0x04 */ char unk04[4]; + /* 0x08 */ s64 unk08; + /* 0x10 */ s64 unk10; + /* 0x18 */ s32 unk18; + /* 0x1C */ char unk1C[0x34]; + /* 0x50 */ s16 unk50; + /* 0x52 */ char unk52[6]; +} UnknownPerfStruct; // Size 0x58 + +static void DSCallbackFunc(u16 arg0); + +void OSInitStopwatch(void*, char*); +void OSStartStopwatch(void*); +u64 OSCheckStopwatch(void*); +void OSResetStopwatch(void*); +void OSStopStopwatch(void*); +void GXSetDrawSync(s32); +void GXSetDrawSyncCallback(void*); +void GXReadGPMetric(s32*, s32*); +void GXReadMemMetric(s32*, s32*, s32*, s32*, s32*, s32*, s32*, s32*, s32*, s32*); +void GXReadPixMetric(s32*, s32*, s32*, s32*, s32*, s32*); +void GXReadVCacheMetric(s32*, s32*, s32*); +void GXClearGPMetric(void); +void GXClearMemMetric(void); +void GXClearPixMetric(void); +void GXClearVCacheMetric(void); + +static u8 Ssw[56]; +static UnknownPerfStruct perf[10]; + +static s32 met0; +static s32 met1; +static s32 vcheck; +static s32 vmiss; +static s32 vstall; +static s32 cp_req; +static s32 tc_req; +static s32 cpu_rd_req; +static s32 cpu_wr_req; +static s32 dsp_req; +static s32 io_req; +static s32 vi_req; +static s32 pe_req; +static s32 rf_req; +static s32 fi_req; +static s32 top_pixels_in; +static s32 top_pixels_out; +static s32 bot_pixels_in; +static s32 bot_pixels_out; +static s32 clr_pixels_in; +static s32 total_copy_clks; +static s16 tokenEndF; +static u8 metf; + +void HuPerfInit(void) { + s32 i; + + for (i = 0; i < 10; i++) { + perf[i].unk50 = 0; + } + HuPerfCreate("CPU", 0, 0xFF, 0, 0xFF); + HuPerfCreate("DRAW", 0xFF, 0, 0, 0xFF); + GXSetDrawSyncCallback(DSCallbackFunc); + total_copy_clks = 0; +} + +s32 HuPerfCreate(char *arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4) { + UnknownPerfStruct *temp_r3; + s32 i; + + for (i = 0; i < 10; i++) { + if (perf[i].unk50 == 0) { + break; + } + } + if (i == 10) { + return -1; + } + OSInitStopwatch(&perf[i].unk18, arg0); + perf[i].unk08 = 0; + perf[i].unk50 = 1; + perf[i].unk00 = arg1; + perf[i].unk01 = arg2; + perf[i].unk02 = arg3; + perf[i].unk03 = arg4; + return i; +} + +void HuPerfZero(void) { + OSStopStopwatch(&Ssw); + OSResetStopwatch(&Ssw); + OSStartStopwatch(&Ssw); +} + +void HuPerfBegin(s32 arg0) { + UnknownPerfStruct *temp_r5; + + if (arg0 == 1) { + GXSetDrawSync(0xFF00); + return; + } + OSStartStopwatch(&perf[arg0].unk18); + perf[arg0].unk10 = OSCheckStopwatch(&Ssw); +} + +void HuPerfEnd(s32 arg0) { + UnknownPerfStruct *temp_r5; + + if (arg0 == 1) { + GXSetDrawSync(0xFF01); + return; + } + perf[arg0].unk08 = OSCheckStopwatch(&perf[arg0].unk18); + OSStopStopwatch(&perf[arg0].unk18); + OSResetStopwatch(&perf[arg0].unk18); +} + +static void DSCallbackFunc(u16 arg0) { + switch (arg0) { + case 0xFF00: + OSStartStopwatch(&perf[1].unk18); + perf[1].unk10 = OSCheckStopwatch(&Ssw); + tokenEndF = 0; + if (metf == 1) { + GXClearGPMetric(); + GXClearVCacheMetric(); + GXClearMemMetric(); + GXClearPixMetric(); + } + break; + case 0xFF01: + if (tokenEndF == 0) { + tokenEndF = 1; + perf[1].unk08 = OSCheckStopwatch(&perf[1].unk18); + OSStopStopwatch(&perf[1].unk18); + OSResetStopwatch(&perf[1].unk18); + if (metf == 1) { + GXReadGPMetric(&met0, &met1); + GXReadVCacheMetric(&vcheck, &vmiss, &vstall); + GXReadMemMetric(&cp_req, &tc_req, &cpu_rd_req, &cpu_wr_req, &dsp_req, &io_req, &vi_req, &pe_req, &rf_req, &fi_req); + GXReadPixMetric(&top_pixels_in, &top_pixels_out, &bot_pixels_in, &bot_pixels_out, &clr_pixels_in, &total_copy_clks); + } + } + break; + } +} diff --git a/src/game/window.c b/src/game/window.c index ee65b823..bf925243 100644 --- a/src/game/window.c +++ b/src/game/window.c @@ -7,6 +7,8 @@ #include "game/memory.h" #include "game/process.h" #include "game/pad.h" +#include "game/armem.h" +#include "game/audio.h" #include "math.h" #include "stdarg.h" @@ -39,11 +41,6 @@ static void HuWinChoice(WindowData *window); static void GetMesMaxSizeSub(u32 mess); static s32 GetMesMaxSizeSub2(WindowData *window, u8 *mess_data); -void *HuAR_DVDtoARAM(s32); -void *HuAR_ARAMtoMRAMFileRead(s32, s32, s32); -s32 HuAudFXPlay(s32); -void HuAR_ARAMtoMRAM(void*); - void mtxTransCat(Mtx, float, float, float); void *MessData_MesPtrGet(void*, u32); WindowData ATTRIBUTE_ALIGN(32) winData[32]; @@ -289,7 +286,7 @@ s16 HuWinCreate(float x, float y, s16 w, s16 h, s16 frame) { } HuSprGrpCenterSet(group, w / 2, h / 2); HuSprGrpPosSet(group, window->pos_x, window->pos_y); - frame_data = HuAR_ARAMtoMRAMFileRead(frameFileTbl[frame], MEMORY_DEFAULT_NUM, 2); + frame_data = HuAR_ARAMtoMRAMFileRead(frameFileTbl[frame], MEMORY_DEFAULT_NUM, HEAP_DATA); window->frame = HuSprAnimRead(frame_data); sprite = window->sprite_id[0] = HuSprCreate(window->frame, winPrio, 0); HuSprGrpMemberSet(group, 0, sprite);