From efb1169e4feedcb647ef038d65757572d95cf8d2 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 22 Apr 2023 00:55:05 -0400 Subject: [PATCH] Link m_debug_hayakawa.c --- config/rel_slices.yml | 4 + include/dolphin/os.h | 23 + include/dolphin/vi.h | 3 +- include/graph.h | 16 +- include/libc64/__osMalloc.h | 2 +- include/libforest/emu64.h | 18 + include/libjsys/jsyswrapper.h | 27 + include/libu64/pad.h | 9 +- include/libu64/u64types.h | 8 + include/libultra/osContPad.h | 9 +- include/m_debug.h | 2 + include/m_debug_hayakawa.h | 5 + include/m_field_info.h | 4 + include/m_msg.h | 3 + include/m_nmibuf.h | 4 +- include/m_private.h | 6 + include/m_rcp.h | 2 + include/main.h | 20 + include/roomtype.h | 58 -- rel/graph.c | 12 +- rel/m_debug.c | 19 + rel/m_debug_hayakawa.c | 662 +++++++++++++++++++++++ rel/m_malloc.c | 6 +- rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c | 2 +- src/libc64/__osMalloc.c | 1 + 25 files changed, 837 insertions(+), 88 deletions(-) create mode 100644 include/libforest/emu64.h create mode 100644 include/main.h delete mode 100644 include/roomtype.h create mode 100644 rel/m_debug_hayakawa.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 72a16e64..f9387886 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -1,5 +1,9 @@ sys_vimgr.c: .text: [0x803703F8, 0x80370418] +m_debug_hayakawa.c: + .text: [0x803965E4, 0x803973E8] + .rodata: [0x80641D50, 0x80641D90] + .data: [0x80651328, 0x80651358] #m_malloc.c: #can't find zelda_arena # .text: [0x803BC510, 0x803BC70C] # .bss: [0x81297CA0, 0x81297CD0] diff --git a/include/dolphin/os.h b/include/dolphin/os.h index a73bf03a..fd69093f 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -40,6 +40,29 @@ extern void __OSCacheInit(); void OSResetSystem(u32, u32, u32); // goes in reset, but eh void OSInit(void); +#define OS_CONSOLE_RETAIL4 0x00000004 +#define OS_CONSOLE_RETAIL3 0x00000003 +#define OS_CONSOLE_RETAIL2 0x00000002 +#define OS_CONSOLE_RETAIL1 0x00000001 +#define OS_CONSOLE_RETAIL 0x00000000 +#define OS_CONSOLE_DEVHW4 0x10000007 +#define OS_CONSOLE_DEVHW3 0x10000006 +#define OS_CONSOLE_DEVHW2 0x10000005 +#define OS_CONSOLE_DEVHW1 0x10000004 +#define OS_CONSOLE_MINNOW 0x10000003 +#define OS_CONSOLE_ARTHUR 0x10000002 +#define OS_CONSOLE_PC_EMULATOR 0x10000001 +#define OS_CONSOLE_EMULATOR 0x10000000 +#define OS_CONSOLE_DEVELOPMENT 0x10000000 +#define OS_CONSOLE_DEVKIT 0x10000000 +#define OS_CONSOLE_TDEVKIT 0x20000000 + +#define OS_CONSOLE_DEV_MASK 0x10000000 + +u32 OSGetConsoleType(); +#define OS_CONSOLE_IS_DEV() ((OSGetConsoleType() & OS_CONSOLE_DEV_MASK) != 0) + + typedef void (*OSExceptionHandler)(u8, OSContext*); OSExceptionHandler __OSSetExceptionHandler(u8, OSExceptionHandler); diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index 16039e5e..d3a5beb5 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -8,7 +8,8 @@ extern "C" { #endif void VISetBlack(BOOL); -extern void VIWaitForRetrace(); +void VIWaitForRetrace(); +void VIConfigurePan(u16 x_origin, u16 y_origin, u16 width, u16 height); #ifdef __cplusplus }; diff --git a/include/graph.h b/include/graph.h index cc107358..43f62052 100644 --- a/include/graph.h +++ b/include/graph.h @@ -68,8 +68,8 @@ typedef struct graph_s { /* 0x02E8 */ THA_GA font_thaga; /* 0x02F8 */ THA_GA shadow_thaga; /* 0x0308 */ THA_GA light_thaga; - /* 0x0318 */ THA_GA new0_thaga; - /* 0x0328 */ THA_GA new1_thaga; + /* 0x0318 */ THA_GA bg_opaque_thaga; + /* 0x0328 */ THA_GA bg_translucent_thaga; /* 0x0338 */ int frame_counter; /* 0x033C */ u16* frameBuffer; /* 0x0340 */ u16* renderBuffer; @@ -117,8 +117,8 @@ extern void graph_dt(GRAPH* this); #define NEXT_FONT_DISP NEXT_DISP(&__graph->font_thaga) #define NEXT_SHADOW_DISP NEXT_DISP(&__graph->shadow_thaga) #define NEXT_LIGHT_DISP NEXT_DISP(&__graph->light_thaga) -#define NEXT_NEW0_DISP NEXT_DISP(&__graph->new0_thaga) -#define NEXT_NEW1_DISP NEXT_DISP(&__graph->new1_thaga) +#define NEXT_BG_OPA_DISP NEXT_DISP(&__graph->bg_opaque_thaga) +#define NEXT_BG_XLU_DISP NEXT_DISP(&__graph->bg_translucent_thaga) #define NOW_POLY_OPA_DISP (Gfx*)NOW_DISP(&__graph->polygon_opaque_thaga) #define NOW_POLY_XLU_DISP (Gfx*)NOW_DISP(&__graph->polygon_translucent_thaga) @@ -127,8 +127,8 @@ extern void graph_dt(GRAPH* this); #define NOW_FONT_DISP (Gfx*)NOW_DISP(&__graph->font_thaga) #define NOW_SHADOW_DISP (Gfx*)NOW_DISP(&__graph->shadow_thaga) #define NOW_LIGHT_DISP (Gfx*)NOW_DISP(&__graph->light_thaga) -#define NOW_NEW0_DISP (Gfx*)NOW_DISP(&__graph->new0_thaga) -#define NOW_NEW1_DISP (Gfx*)NOW_DISP(&__graph->new1_thaga) +#define NOW_BG_OPA_DISP (Gfx*)NOW_DISP(&__graph->bg_opaque_thaga) +#define NOW_BG_XLU_DISP (Gfx*)NOW_DISP(&__graph->bg_translucent_thaga) #define SET_POLY_OPA_DISP(p) SET_DISP(&__graph->polygon_opaque_thaga, p) #define SET_POLY_XLU_DISP(p) SET_DISP(&__graph->polygon_translucent_thaga, p) @@ -137,8 +137,8 @@ extern void graph_dt(GRAPH* this); #define SET_FONT_DISP(p) SET_DISP(&__graph->font_thaga, p) #define SET_SHADOW_DISP(p) SET_DISP(&__graph->shadow_thaga, p) #define SET_LIGHT_DISP(p) SET_DISP(&__graph->light_thaga, p) -#define SET_NEW0_DISP(p) SET_DISP(&__graph->new0_thaga, p) -#define SET_NEW1_DISP(p) SET_DISP(&__graph->new1_thaga, p) +#define SET_BG_OPA_DISP(p) SET_DISP(&__graph->bg_opaque_thaga, p) +#define SET_BG_XLU_DISP(p) SET_DISP(&__graph->bg_translucent_thaga, p) #define GRAPH_ALLOC(graph, size) ((void*)((graph)->polygon_opaque_thaga.tha.tail_p = (char*)((int)(graph)->polygon_opaque_thaga.tha.tail_p - (int)(size)))) #define GRAPH_ALLOC_TYPE(graph, type, num) (GRAPH_ALLOC(graph, sizeof(type) * (num))) diff --git a/include/libc64/__osMalloc.h b/include/libc64/__osMalloc.h index 8fec7734..d1d711f8 100644 --- a/include/libc64/__osMalloc.h +++ b/include/libc64/__osMalloc.h @@ -61,7 +61,7 @@ u32 __osGetMemBlockSize(Arena*, void*); void __osDisplayArena(Arena*); int __osCheckArena(Arena*); - +extern int __osMalloc_FreeBlockTest_Enable; #endif diff --git a/include/libforest/emu64.h b/include/libforest/emu64.h new file mode 100644 index 00000000..6bed0447 --- /dev/null +++ b/include/libforest/emu64.h @@ -0,0 +1,18 @@ +#ifndef EMU64_H +#define EMU64_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* These might be signed */ +extern void emu64_set_aflags(u32 idx, u32 value); +extern int emu64_get_aflags(u32 idx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libjsys/jsyswrapper.h b/include/libjsys/jsyswrapper.h index 8c0ef1a1..623e9232 100644 --- a/include/libjsys/jsyswrapper.h +++ b/include/libjsys/jsyswrapper.h @@ -9,6 +9,33 @@ extern "C" { extern void JW_BeginFrame(); extern void JW_EndFrame(); +extern void JW_JUTReport(int x, int y, int show_count, const char* fmt, ...); +extern void JW_SetLowResoMode(BOOL enable); +extern void JW_SetProgressiveMode(BOOL enable); + +extern void* JC_JFWSystem_getSystemConsole(); +extern void* JC_JFWSystem_getRootHeap(); + +extern int JC_JKRHeap_dump(void* heap); +extern s32 JC_JKRHeap_getTotalFreeSize(void* heap); + +extern int JC_JUTConsole_isVisible(void* console); +extern void JC_JUTConsole_setVisible(void* console, BOOL visible); +extern void JC_JUTConsole_clear(void* console); +extern void JC_JUTConsole_scroll(void* console, int scroll); +extern int JC_JUTConsole_getPositionX(void* console); +extern void JC_JUTConsole_setPosition(void* console, int x, int y); +extern int JC_JUTConsole_getOutput(void* console); +extern int JC_JUTConsole_getLineOffset(void* console); +extern void JC_JUTConsole_dumpToTerminal(void* console, int lines); +extern void JC_JUTConsole_setOutput(void* console, int output); + +extern void* JC_JUTDbPrint_getManager(); +extern void JC_JUTDbPrint_setVisible(void* dbprint, BOOL visible); + +extern void* JC_JUTProcBar_getManager(); +extern void JC_JUTProcBar_setVisible(void* procbar, BOOL visible); +extern void JC_JUTProcBar_setVisibleHeapBar(void* procbar, BOOL visible); #ifdef __cplusplus } diff --git a/include/libu64/pad.h b/include/libu64/pad.h index de89020c..fb83a7ff 100644 --- a/include/libu64/pad.h +++ b/include/libu64/pad.h @@ -8,11 +8,12 @@ extern "C" { #endif +/* sizeof(pad_t) == 0x18 */ typedef struct { - OSContPad now; - OSContPad last; - OSContPad on; - OSContPad off; + /* 0x00 */ OSContPad now; + /* 0x06 */ OSContPad last; + /* 0x0C */ OSContPad on; + /* 0x12 */ OSContPad off; } pad_t; #ifdef __cplusplus diff --git a/include/libu64/u64types.h b/include/libu64/u64types.h index 9cfe459c..a7aa5a10 100644 --- a/include/libu64/u64types.h +++ b/include/libu64/u64types.h @@ -3,6 +3,10 @@ #include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { u32 r:8; u32 g:8; @@ -15,4 +19,8 @@ typedef union { rgba8888_t c; } rgba8888; +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/libultra/osContPad.h b/include/libultra/osContPad.h index 367e5fa5..7192659b 100644 --- a/include/libultra/osContPad.h +++ b/include/libultra/osContPad.h @@ -17,11 +17,12 @@ typedef struct { u8 errno; } OSContStatus; +/* sizeof(OSContPad) == 6 */ typedef struct { - u16 button; - s8 stick_x; - s8 stick_y; - u8 errno; + /* 0x00 */ u16 button; + /* 0x02 */ s8 stick_x; + /* 0x03 */ s8 stick_y; + /* 0x04 */ u8 errno; } OSContPad; #ifdef __cplusplus diff --git a/include/m_debug.h b/include/m_debug.h index 15a4d272..4efa5cde 100644 --- a/include/m_debug.h +++ b/include/m_debug.h @@ -55,6 +55,8 @@ typedef enum { #define DEBUG_REG_SIZE 16 #define DEBUG_REG_GROUP 6 +#define DEBUG_REG_COUNT (DEBUG_REG_SIZE * DEBUG_REG_GROUP * DEBUG_REG_MAX) + typedef struct debug_mode_s { u8 mode; u8 type; diff --git a/include/m_debug_hayakawa.h b/include/m_debug_hayakawa.h index 3c5a3594..faffbe75 100644 --- a/include/m_debug_hayakawa.h +++ b/include/m_debug_hayakawa.h @@ -11,6 +11,11 @@ extern "C" { extern void debug_hayakawa_draw(GRAPH* graph); extern void debug_hayakawa_move(pad_t* pad); +extern int hreg_init_check(const int n); + +#define HREG_STATE_IDX 80 +#define HREG_STATE_ARGS_START 81 +#define HREG_STATE_ARGS_COUNT 14 #ifdef __cplusplus } diff --git a/include/m_field_info.h b/include/m_field_info.h index f9c8bfcb..6698a26d 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -2,6 +2,7 @@ #define M_FIELD_INFO_H #include "types.h" +#include "libu64/gfxprint.h" #ifdef __cplusplus @@ -21,6 +22,9 @@ enum { extern int mFI_GetClimate(); +extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint); +extern void mFI_PrintFgAttr(gfxprint_t* gfxprint); + #ifdef __cplusplus } #endif diff --git a/include/m_msg.h b/include/m_msg.h index d036e5d5..7c99cb28 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -2,6 +2,7 @@ #define M_MSG_H #include "types.h" +#include "libu64/gfxprint.h" #ifdef __cplusplus extern "C" { @@ -16,6 +17,8 @@ extern M_MSG_WINDOW* mMsg_Get_base_window_p(); extern void mMsg_Set_free_str(M_MSG_WINDOW* msg, int free_str_no, u8* str, size_t str_size); +extern void mMsg_debug_draw(gfxprint_t* gfxprint); + #ifdef __cplusplus } #endif diff --git a/include/m_nmibuf.h b/include/m_nmibuf.h index aaa207a0..2c6d9e44 100644 --- a/include/m_nmibuf.h +++ b/include/m_nmibuf.h @@ -10,6 +10,8 @@ extern "C" { #define APPNMI_FLAGS_IDX 15 +#define APPNMI_GETVAL() (osAppNMIBuffer[APPNMI_FLAGS_IDX]) + #define APPNMI_SET(v) (osAppNMIBuffer[APPNMI_FLAGS_IDX] |= v) #define APPNMI_CLR(v) (osAppNMIBuffer[APPNMI_FLAGS_IDX] &= ~v) #define APPNMI_GET(v) (osAppNMIBuffer[APPNMI_FLAGS_IDX] & v) @@ -54,8 +56,6 @@ extern "C" { #define APPNMI_HOTRESET_GET() (osAppNMIBuffer[APPNMI_FLAGS_IDX] & 0x200) #define APPNMI_HOTRESET_FLP() (osAppNMIBuffer[APPNMI_FLAGS_IDX] ^= 0x200) -#define APPNMI_ - #ifdef __cplusplus } #endif diff --git a/include/m_private.h b/include/m_private.h index 8836f1b4..43adda4c 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -2,6 +2,7 @@ #define M_PRIVATE_H #include "types.h" +#include "libu64/gfxprint.h" #ifdef __cplusplus extern "C" { @@ -9,6 +10,11 @@ extern "C" { #define PLAYER_NUM 4 +extern s16 mPr_GetGoodsPower(); +extern s16 mPr_GetMoneyPower(); + +extern void mPr_PrintMapInfo_debug(gfxprint_t* gfxprint); + #ifdef __cplusplus } #endif diff --git a/include/m_rcp.h b/include/m_rcp.h index 3cd41a26..f9064b82 100644 --- a/include/m_rcp.h +++ b/include/m_rcp.h @@ -9,6 +9,8 @@ extern "C" { #endif extern Gfx* gfx_gSPTextureRectangle1(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lry, int tile, int s, int t, int dsdx, int dtdy); +extern Gfx* gfx_gDPFillRectangle1(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lry); +extern Gfx* gfx_gDPFillRectangleF(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lry); #ifdef __cplusplus } diff --git a/include/main.h b/include/main.h new file mode 100644 index 00000000..cd0e7b5a --- /dev/null +++ b/include/main.h @@ -0,0 +1,20 @@ +#ifndef MAIN_H +#define MAIN_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 + +extern int ScreenWidth; +extern int ScreenHeight; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/roomtype.h b/include/roomtype.h deleted file mode 100644 index dd1e535a..00000000 --- a/include/roomtype.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef ROOM_TYPE_H -#define ROOM_TYPE_H - -#include "types.h" - -enum { - FG_ITEM0_TYPE, - FG_FTR0_TYPE, - FG_ITEM1_TYPE, - FG_FTR1_TYPE, - FG_NXGT0_TYPE, - FG_STRUCTURE_TYPE, - FG_PAD6_TYPE, - FG_PAD7_TYPE, - FG_ITEM2_TYPE, - FG_ACTOR_TYPE, - FG_PROPS_TYPE, - FG_PAD11_TYPE, - FG_PAD12_TYPE, - FG_SP_NPC_TYPE, - FG_NPC_TYPE, - FG_DONT_TYPE, - FG_TYPE_NUM -}; - -// TEMPORARY. Should be generated with .decl files -#define ITEM0_NO_START 0x0000 -#define NULL_NO ITEM0_NO_START -#define ITEM0_1_NO_START ITEM0_NO_START + 0x800 - -#define FTR0_NO_START 0x1000 - -#define ITEM1_NO_START 0x2000 -#define ITEM1_0_NO_START ITEM0_1_NO_START // paper -#define ITEM1_1_NO_START ITEM1_NO_START + 0x100 // money -#define ITEM1_2_NO_START ITEM1_NO_START + 0x200 // tools -#define ITEM1_3_NO_START ITEM1_NO_START + 0x300 // fish -#define ITEM1_4_NO_START ITEM1_NO_START + 0x400 // clothing -#define ITEM1_5_NO_START ITEM1_NO_START + 0x500 // etc -#define ITEM1_6_NO_START ITEM1_NO_START + 0x600 // carpets -#define ITEM1_7_NO_START ITEM1_NO_START + 0x700 // wallpaper -#define ITEM1_8_NO_START ITEM1_NO_START + 0x800 // food -#define ITEM1_9_NO_START ITEM1_NO_START + 0x900 // seeds -#define ITEM1_A_NO_START ITEM1_NO_START + 0xA00 // mini disks -#define ITEM1_B_NO_START ITEM1_NO_START + 0xB00 // diaries -#define ITEM1_C_NO_START ITEM1_NO_START + 0xC00 // tickets -#define ITEM1_D_NO_START ITEM1_NO_START + 0xD00 // insects -#define ITEM1_E_NO_START ITEM1_NO_START + 0xE00 // hukubukuro -#define ITEM1_F_NO_START ITEM1_NO_START + 0xF00 // kabu - -#define FTR1_NO_START 0x3000 - -#define GET_FG_ITEM0_CATEGORY(f) (((f)&0x800) >> 11) -#define GET_FG_ITEM1_CATEGORY(f) (((f)&0xF00) >> 8) -#define GET_FG_TYPE(f) (((f)&0xF000) >> 12) - - -#endif \ No newline at end of file diff --git a/rel/graph.c b/rel/graph.c index c71d6c81..ffcf1081 100644 --- a/rel/graph.c +++ b/rel/graph.c @@ -40,8 +40,8 @@ static void graph_setup_double_buffer(GRAPH* this) { sys_dynamic.start_magic = SYSDYNAMIC_START_MAGIC; sys_dynamic.end_magic = SYSDYNAMIC_END_MAGIC; - CONSTRUCT_THA_GA(&this->new0_thaga, new0, NEW0); - CONSTRUCT_THA_GA(&this->new1_thaga, new1, NEW1); + CONSTRUCT_THA_GA(&this->bg_opaque_thaga, new0, NEW0); + CONSTRUCT_THA_GA(&this->bg_translucent_thaga, new1, NEW1); CONSTRUCT_THA_GA(&this->polygon_opaque_thaga, poly_opa, POLY_OPA); CONSTRUCT_THA_GA(&this->polygon_translucent_thaga, poly_xlu, POLY_XLU); CONSTRUCT_THA_GA(&this->overlay_thaga, overlay, OVERLAY); @@ -139,9 +139,9 @@ static int graph_draw_finish(GRAPH* this) { OPEN_DISP(this); gSPBranchList(NOW_WORK_DISP++, this->Gfx_list10); - gSPBranchList(NOW_NEW0_DISP++, this->Gfx_list08); + gSPBranchList(NOW_BG_OPA_DISP++, this->Gfx_list08); gSPBranchList(NOW_SHADOW_DISP++, this->Gfx_list11); - gSPBranchList(NOW_NEW1_DISP++, this->Gfx_list00); + gSPBranchList(NOW_BG_XLU_DISP++, this->Gfx_list00); gSPBranchList(NOW_POLY_OPA_DISP++, this->Gfx_list01); gSPBranchList(NOW_POLY_XLU_DISP++, this->Gfx_list09); gSPBranchList(NOW_LIGHT_DISP++, this->Gfx_list07); @@ -188,11 +188,11 @@ static int graph_draw_finish(GRAPH* this) { err = TRUE; } - if (THA_GA_isCrash(&this->new0_thaga)) { + if (THA_GA_isCrash(&this->bg_opaque_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->new1_thaga)) { + if (THA_GA_isCrash(&this->bg_translucent_thaga)) { err = TRUE; } diff --git a/rel/m_debug.c b/rel/m_debug.c index ecf9992f..b8a4ad31 100644 --- a/rel/m_debug.c +++ b/rel/m_debug.c @@ -1,2 +1,21 @@ #include "m_debug.h" +#include "libc64/malloc.h" + +Debug_mode* debug_mode; + +extern void new_Debug_mode() { + int i; + + debug_mode = (Debug_mode*)malloc(sizeof(Debug_mode)); + + debug_mode->mode = 0; + debug_mode->type = 0; + debug_mode->input_r = 0; + debug_mode->old_key = 0; + debug_mode->key_wait = 0; + + for (i = 0; i < DEBUG_REG_COUNT; i++) { + debug_mode->r[i] = 0; + } +} diff --git a/rel/m_debug_hayakawa.c b/rel/m_debug_hayakawa.c new file mode 100644 index 00000000..c078c887 --- /dev/null +++ b/rel/m_debug_hayakawa.c @@ -0,0 +1,662 @@ +/** + * @file m_debug_hayakawa.c + * @brief Debug module for handling various debug features for Kendo Hayakawa. + * + * This module provides functions related to debugging in the application. + * The functions support displaying pad inputs, drawing safety frames, and handling + * hreg state index changes. + * + * Functions in this module: + * - debug_hayakawa_bitset(): Creates or restores a bitset representation of hreg arguments for a given state. + * - debug_hayakawa_draw(): Main function for handling various debug features. + * - pad_disp(): Displays pad input on the screen. + * - debug_hayakawa_draw_safetyframe(): Draws safety frames on the screen. + * - hreg_init_check(): Checks if the hreg state index has changed and initializes the hreg state arguments if it has. + */ + +#include "m_debug_hayakawa.h" + +#include "m_debug.h" +#include "libu64/u64types.h" +#include "dolphin/os.h" +#include "libjsys/jsyswrapper.h" +#include "libc64/__osMalloc.h" +#include "m_rcp.h" +#include "main.h" +#include "m_lib.h" +#include "libforest/osreport.h" +#include "libforest/emu64.h" +#include "gfxalloc.h" +#include "dolphin/vi.h" +#include "libu64/gfxprint.h" + +/** + * @brief Set or retrieve bits of a Hayakawa register based on the current state. + * + * This function updates the bits of a Hayakawa register if the current state + * matches the given state. If the state matches and the Hayakawa register has + * been initialized, the bits are set according to the given register. + * Otherwise, the bits are saved to the given register. + * + * @param n The Hayakawa state to check against the current state. + * @param reg The index of the Hayakawa register to set or retrieve bits from. + */ +static void debug_hayakawa_bitset(const int n, const int reg) { + // Check if the current Hayakawa state matches the given state. + if (GETREG(HREG, HREG_STATE_IDX) == n) { + // If the Hayakawa register has been initialized, set its bits. + if (hreg_init_check(n)) { + int set; + int i; + int setbit = GETREG(HREG, reg); + int bit = 1; + + // Loop through each bit in the register, setting the corresponding flag. + for (i = 0; i < HREG_STATE_ARGS_COUNT; i++) { + set = (setbit & bit) != 0; + bit <<= 1; + + SETREG(HREG, HREG_STATE_ARGS_START + i, set); + } + } + // If the Hayakawa register hasn't been initialized, save its bits. + else { + int i; + int savebit = 0; + int bit = 1; + + // Loop through each bit in the register, saving the corresponding flag. + for (i = 0; i < HREG_STATE_ARGS_COUNT; i++) { + if (GETREG(HREG, HREG_STATE_ARGS_START + i) != 0) { + savebit |= bit; + } + + bit <<= 1; + } + + SETREG(HREG, reg, savebit); + } + } +} + +/** + * @brief Executes a series of debug-related functions based on the HREG register state. + * + * This function provides various debugging features such as loading and storing + * HREG settings, modifying video settings, and toggling debug drawing features. + * It performs different actions based on the values set in the HREG register. + * + * @param pad Pointer to the pad_t structure, representing the input gamepad. + */ +extern void debug_hayakawa_move(pad_t* pad) { + debug_hayakawa_bitset(116, 16); + debug_hayakawa_bitset(117, 17); + debug_hayakawa_bitset(139, 39); + debug_hayakawa_bitset(140, 40); + debug_hayakawa_bitset(141, 41); + debug_hayakawa_bitset(142, 42); + debug_hayakawa_bitset(143, 43); + debug_hayakawa_bitset(144, 44); + debug_hayakawa_bitset(145, 45); + debug_hayakawa_bitset(146, 46); + debug_hayakawa_bitset(147, 47); + debug_hayakawa_bitset( 10, 46); + + switch ((int)GETREG(HREG, HREG_STATE_IDX)) { + /** + * Loads/Stores HREG settings into emu64 aflags. + * HREG[81] = saved emu64 aflag load/store start index + * HREG[95] = now emu64 aflag load/store start index + * + * HREG[81] == HREG[95]: Store 12 HREG values (82 - 93) into aflags + * HREG[81] != HREG[95]: Load 12 HREG values (82 - 93) from aflags + */ + case 1: + { + if (hreg_init_check(1)) { + SETREG(HREG, 95, -1); + } + + if (GETREG(HREG, HREG_STATE_ARGS_START) != GETREG(HREG, 95)) { + int i; + + SETREG(HREG, 95, GETREG(HREG, HREG_STATE_ARGS_START)); + for (i = 0; i < 12; i++) { + SETREG(HREG, 82 + i, emu64_get_aflags(GETREG(HREG, HREG_STATE_ARGS_START) + i)); + } + } + else { + int i; + for (i = 0; i < 12; i++) { + emu64_set_aflags(GETREG(HREG, HREG_STATE_ARGS_START) + i, GETREG(HREG, 82 + i)); + } + } + } + /* Fallthrough 1 -> 2 -> 3 -> 4 -> 6 */ + /** + * Loads the active thread count into HREG. + * HREG[81] = < 0, load threads + * HREG[82] = current active thread count + */ + case 2: + { + hreg_init_check(2); + if (GETREG(HREG, HREG_STATE_ARGS_START) < 0) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + SETREG(HREG, 82, OSCheckActiveThreads()); + } + } + /* Fallthrough 2 -> 3 -> 4 -> 6 */ + /** + * Dumps the root heap info to console along with free size of the heap. + * HREG[81] = < 0, check should dump + * HREG[82] = 1, print dump + */ + case 3: + { + hreg_init_check(3); + if (GETREG(HREG, HREG_STATE_ARGS_START) < 0) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + + switch (GETREG(HREG, 82)) { + case 1: + { + OSReport("*** RootHeapDump ***\n"); + JC_JKRHeap_dump(JC_JFWSystem_getRootHeap()); + OSReport("RootHeapFree=%08x\n", JC_JKRHeap_getTotalFreeSize(JC_JFWSystem_getRootHeap())); + } + break; + } + } + } + /* Fallthrough 3 -> 4 -> 6 */ + //break; + + /** + * Modifies video settings + * HREG[81] = < 0, switch mode + * HREG[82]: + * 1: Disable progressive mode + * 2: Enable progressive mode + * 3: Disable low resolution mode + * 4: Enable low resolution mode + */ + case 4: + { + hreg_init_check(4); + if (GETREG(HREG, HREG_STATE_ARGS_START) < 0) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + switch (GETREG(HREG, 82)) { + case 1: + JW_SetProgressiveMode(FALSE); + break; + + case 2: + JW_SetProgressiveMode(TRUE); + break; + + case 3: + JW_SetLowResoMode(FALSE); + break; + + case 4: + JW_SetLowResoMode(TRUE); + break; + } + } + } + /* Fallthrough 4 -> 6 */ + case 6: + { + if (hreg_init_check(6)) { + SETREG(HREG, HREG_STATE_ARGS_START, 1); + SETREG(HREG, 82, 1); + } + } + break; + + case 7: + break; + + case 8: + { + hreg_init_check(8); + if (GETREG(HREG, HREG_STATE_ARGS_START) < 0) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + } + } + break; + + /** + * Unknown function, but may relate to toggling some debug + * drawing feature which is removed. + * + * HREG[81]: + * 1: Set bit 3 (enable) + * 2: Clear bit 3 (disable) + * + * HREG[47] = modified register + */ + case 15: + { + hreg_init_check(15); + if (GETREG(HREG, HREG_STATE_ARGS_START) == 1) { + SETREG(HREG, 47, GETREG(HREG, 47) | 8); + } + else if (GETREG(HREG, HREG_STATE_ARGS_START) == 2) { + SETREG(HREG, 47, GETREG(HREG, 47) & (~8)); + } + } + break; + + /** + * Toggles 'FreeBlockTest' mode for __osMalloc. + * HREG[82] = BOOL enable + */ + case 20: + { + hreg_init_check(20); + __osMalloc_FreeBlockTest_Enable = GETREG(HREG, 82); + } + break; + + /** + * Safety frame bounds + * Sets the bounds for drawing saftey frame boundary in + * debug_hayakawa_draw. Minimum bounds are (0, 0) and + * maximum bounds are (ScreenWidth, ScreenHeight). + * + * HREG[81]: + * 1: Bounds set to [(0, 0), (SCREEN_WIDTH, SCREEN_HEIGHT)] + * 2: Bounds set to [(0, 0), (ScreenWidth, ScreenHeight)] + * + * HREG[82]: upper left y (uly) + * HREG[83]: lower right y (lry) + * HREG[84]: upper left x (ulx) + * HREG[85]: lower right x (lrx) + */ + case 25: + { + if (hreg_init_check(25)) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + SETREG(HREG, 82, 0); + SETREG(HREG, 83, ScreenHeight); + SETREG(HREG, 84, 0); + SETREG(HREG, 85, ScreenWidth); + } + + switch (GETREG(HREG, HREG_STATE_ARGS_START)) { + case 1: + { + SETREG(HREG, 82, 0); + SETREG(HREG, 83, SCREEN_HEIGHT); + SETREG(HREG, 84, 0); + SETREG(HREG, 85, SCREEN_WIDTH); + } + break; + + case 2: + { + SETREG(HREG, 82, 0); + SETREG(HREG, 83, ScreenHeight); + SETREG(HREG, 84, 0); + SETREG(HREG, 85, ScreenWidth); + } + break; + } + + if (GETREG(HREG, 82) < 0) { + SETREG(HREG, 82, 0); + } + + if (GETREG(HREG, 83) > ScreenHeight) { + SETREG(HREG, 83, ScreenHeight); + } + + if (GETREG(HREG, 84) < 0) { + SETREG(HREG, 84, 0); + } + + if (GETREG(HREG, 85) > ScreenWidth) { + SETREG(HREG, 85, ScreenWidth); + } + } + break; + + /** + * Unknown function. + * HREG[82], HREG[83], HREG[84] all contain bytes. Two of which are concatenated + * depending on value in HREG[81]. Result is stored in HREG[48] or HREG[49]. + * + * HREG[81] = Mode + * HREG[82] = byte0 + * HREG[83] = byte1 + * HREG[84] = byte2 + * HREG[48] = result_byte0_byte1 + * HREG[49] = result_byte1_byte2 + */ + case 39: + { + hreg_init_check(39); + + switch (GETREG(HREG, HREG_STATE_ARGS_START)) { + case 0: + break; + + case 1: + { + u16 v = ((GETREG(HREG, 82) & 0xFF) << 8) | (GETREG(HREG, 83) & 0xFF); + if (GETREG(HREG, 48) != v) { + SETREG(HREG, 48, v); + } + } + break; + + case 2: + { + if (GETREG(HREG, 48) != 0) { + SETREG(HREG, 48, 0); + } + } + break; + + case 3: + { + u16 v = ((GETREG(HREG, 83) & 0xFF) << 8) | (GETREG(HREG, 84) & 0xFF); + if (GETREG(HREG, 49) != v) { + SETREG(HREG, 49, v); + } + } + break; + } + } + break; + + /* Clear state arg for memory block (1MB blocks) */ + case 600: + { + hreg_init_check(600); + + if (GETREG(HREG, HREG_STATE_ARGS_START) < 0) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + } + } + /* Fallthrough 600 -> 666 */ + /* Get/Set byte at beginning of 1MB boundary blocks */ + case 666: + { + /** + * HREG[82] = index of 1MB block + * HREG[83] = byte to get/set for block + */ + hreg_init_check(666); + + switch (GETREG(HREG, HREG_STATE_ARGS_START)) { + /* Load */ + case 1: + { + SETREG(HREG, 83, *(u8*)(GETREG(HREG, 82) * 0x100000 - 0x80000000)); + } + break; + + /* Store */ + case 2: + { + *(u8*)(GETREG(HREG, 82) * 0x100000 - 0x80000000) = (u8)GETREG(HREG, 83); + } + break; + } + } + break; + } + + hreg_init_check(667); + hreg_init_check(34); + hreg_init_check(35); + hreg_init_check(38); + + if (GETREG(SREG, 21)) { + if (GETREG(SREG, 21) & 1) { + OSReportDisable(); + } + else { + if (OS_CONSOLE_IS_DEV()) { + OSReportEnable(); + } + } + + JC_JUTDbPrint_setVisible(JC_JUTDbPrint_getManager(), !(GETREG(SREG, 21) & 2)); + JC_JUTProcBar_setVisible(JC_JUTProcBar_getManager(), !(GETREG(SREG, 21) & 4)); + JC_JUTProcBar_setVisibleHeapBar(JC_JUTProcBar_getManager(), !(GETREG(SREG, 21) & 4)); + } +} + +/** + * @brief Displays a visualization of the input device state, including button press indicators. + * + * This function creates a visualization of the input device state by drawing colored rectangles + * for each button press. The display is organized by input device and button index. + * Colors are defined in the pad_color2 array, with specific colors for each button group. + * + * @param pad The index of the input device (controller) to display state for. + * @param button A 16-bit value representing the button state (1 = pressed, 0 = not pressed). + * @param gfx_pp Pointer to a pointer of Gfx type, which will be used to draw the button states. + */ +static void pad_disp(u8 pad, u16 button, Gfx** gfx_pp) { + static const rgba_t pad_color2[16] = { + /* Yellow for C-Stick */ + { 255, 255, 0, 255 }, /* C-Stick Right */ + { 255, 255, 0, 255 }, /* C-Stick Left */ + { 255, 255, 0, 255 }, /* C-Stick Down */ + { 255, 255, 0, 255 }, /* C-Stick Up */ + /* Gray for L, R, X, Y, D-Pad, & Start */ + { 127, 127, 127, 255 }, /* R */ + { 127, 127, 127, 255 }, /* L */ + { 127, 127, 127, 255 }, /* X */ + { 127, 127, 127, 255 }, /* Y */ + { 127, 127, 127, 255 }, /* D-Pad Right */ + { 127, 127, 127, 255 }, /* D-Pad Left */ + { 127, 127, 127, 255 }, /* D-Pad Down */ + { 127, 127, 127, 255 }, /* D-Pad Up */ + { 127, 127, 127, 255 }, /* Start */ + /* Blue for Z */ + { 0, 0, 255, 255 }, /* Z */ + /* Red for B */ + { 255, 0, 0, 255 }, /* B */ + /* Green for A */ + { 0, 255, 0, 255 } /* A */ + }; + + int i; + int pad_start_x = pad * 70 + 20; + Gfx* gfx = *gfx_pp; + + gDPPipeSync(gfx++); + gDPSetOtherMode(gfx++, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_1PRIMITIVE, G_AC_NONE | G_ZS_PIXEL | G_RM_OPA_SURF | G_RM_OPA_SURF2); + gDPSetCombineMode(gfx++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, 0); + gfx = gfx_gDPFillRectangle1(gfx, pad_start_x - 1, 225, pad_start_x + 65, 231); + + for (i = 0; i < 16; i++) { + if (button & (1 << i)) { + /* pad_color2 might be a union or a u32 array */ + gDPSetColor(gfx++, G_SETPRIMCOLOR, ((u32*)pad_color2)[i]); + gfx = gfx_gDPFillRectangle1(gfx, pad_start_x + (i * 4), 226, (pad_start_x + (i + 1) * 4) - 1, 229); + } + } + + gDPPipeSync(gfx++); + *gfx_pp = gfx; +} + +/** + * @brief Draws a safety frame around the specified screen region. + * + * This function creates a white frame around the specified region on the screen. + * The frame is one pixel wide and is drawn along the edges of the specified region. + * The frame is not drawn outside the screen boundaries. + * + * @param gfx_pp Pointer to a pointer of Gfx type, which will be used to draw the safety frame. + * @param ulx Upper-left x coordinate of the region. + * @param uly Upper-left y coordinate of the region. + * @param lrx Lower-right x coordinate of the region. + * @param lry Lower-right y coordinate of the region. + */ +static void debug_hayakawa_draw_safetyframe(Gfx** gfx_pp, u32 ulx, u32 uly, u32 lrx, u32 lry) { + Gfx* gfx = *gfx_pp; + + gDPPipeSync(gfx++); + gDPSetOtherMode(gfx++, G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_FILL | G_PM_NPRIMITIVE, G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2); + gDPSetFillColor(gfx++, 0xFFFFFFFF); + + if (uly > 1) { + gfx = gfx_gDPFillRectangleF(gfx, ulx, uly - 1, lrx + 1, uly); + } + + if (ulx > 1) { + gfx = gfx_gDPFillRectangleF(gfx, ulx - 1, uly, ulx, lry + 1); + } + + if (lry < SCREEN_HEIGHT - 1) { + gfx = gfx_gDPFillRectangleF(gfx, ulx, lry, lrx + 1, lry + 1); + } + + if (lrx < SCREEN_WIDTH - 1) { + gfx = gfx_gDPFillRectangleF(gfx, lrx, uly, lrx + 1, lry + 1); + } + + gDPPipeSync(gfx++); + *gfx_pp = gfx; +} + +#define DRAW_MAX_X (u32)(SCREEN_WIDTH - 1) +#define DRAW_MAX_Y (u32)(SCREEN_HEIGHT - 1) + +/** + * @brief Debug drawing function for various graphical elements and overlays. + * + * @param graph Pointer to the GRAPH struct which will be drawn to. + */ +extern void debug_hayakawa_draw(GRAPH* graph) { + Gfx* poly_opa_gfx; + Gfx* opened_gfx; + gfxprint_t gfxprint; + gfxprint_t* gfxprint_p = &gfxprint; + + OPEN_DISP(graph); + + poly_opa_gfx = NOW_POLY_OPA_DISP; + opened_gfx = gfxopen(poly_opa_gfx); + + gSPDisplayList(NOW_OVERLAY_DISP++, opened_gfx); + + /* Draw pad input */ + if (GETREG(HREG, 47) & 1) { + int i; + for (i = 0; i < MAXCONTROLLERS; i++) { + s16 button = GETREG(HREG, 40 + i); + if (button != 0) { + pad_disp(i, button, &opened_gfx); + } + } + } + + if (GETREG(HREG, HREG_STATE_IDX) == 41 && hreg_init_check(41)) { + SETREG(HREG, HREG_STATE_ARGS_START, (GETREG(HREG, 39) >> 1) & 1); + SETREG(HREG, 82, 31); + SETREG(HREG, 83, 22); + SETREG(HREG, 84, 289); + SETREG(HREG, 85, 218); + } + + /* Safety frame drawing check */ + if ((GETREG(HREG, 39) & 2) || (GETREG(HREG, HREG_STATE_IDX) == 41 && GETREG(HREG, HREG_STATE_ARGS_START) != 0)) { + u32 a = 31; + u32 b = 22; + u32 c = 289; + u32 d = 218; + + u32 ulx, uly, + lrx, lry; + + if (GETREG(HREG, HREG_STATE_IDX) == 41) { + a = GETREG(HREG, 82); + b = GETREG(HREG, 83); + c = GETREG(HREG, 84); + d = GETREG(HREG, 85); + } + + ulx = a <= DRAW_MAX_X ? a : DRAW_MAX_X; + uly = b <= DRAW_MAX_Y ? b : DRAW_MAX_Y; + lrx = c < ulx ? ulx : (c <= DRAW_MAX_X - 1 ? c : DRAW_MAX_X - 1); + lry = d < uly ? uly : (d <= DRAW_MAX_Y - 1 ? d : DRAW_MAX_Y - 1); + + debug_hayakawa_draw_safetyframe(&opened_gfx, ulx, uly, lrx, lry); + } + + /* Vertical Interrupt Pan Configuration */ + if (GETREG(HREG, HREG_STATE_IDX) == 42) { + if (hreg_init_check(42) || (GETREG(HREG, HREG_STATE_IDX) == 42 && GETREG(HREG, HREG_STATE_ARGS_START) != 0)) { + SETREG(HREG, HREG_STATE_ARGS_START, 0); + /* 4:5 aspect ratio? */ + SETREG(HREG, 82, 30); /* Pan x origin */ + SETREG(HREG, 83, 6); /* Pan y origin */ + SETREG(HREG, 84, 580); /* Pan width */ + SETREG(HREG, 85, 464); /* Pan height */ + } + + VIConfigurePan(GETREG(HREG, 82) & ~1, GETREG(HREG, 83) & ~1, GETREG(HREG, 84) & ~1, GETREG(HREG, 85) & ~1); + } + + /* Initialize display list segment at specific 1MB region */ + if (GETREG(HREG, HREG_STATE_IDX) == 667 && GETREG(HREG, HREG_STATE_ARGS_START)) { + int block = GETREG(HREG, 82) * 0x100000 + 0x80000000; + /* TODO: segment id 8 definitely needs a definition somewhere */ + gSPSegment(opened_gfx++, 8, block); + } + + gfxprint_init(gfxprint_p); + gfxprint_open(gfxprint_p, opened_gfx); + /* removed/debug code I guess? */ + opened_gfx = gfxprint_close(gfxprint_p); + gSPEndDisplayList(opened_gfx++); + gfxclose(poly_opa_gfx, opened_gfx); + SET_POLY_OPA_DISP(opened_gfx); + gfxprint_cleanup(gfxprint_p); + + CLOSE_DISP(graph); +} + +/** + * @brief Checks if the hreg state index has changed and initializes the hreg state arguments if it has. + * + * This function checks if the hreg state index (n) is different from the previous one. If it is, + * the function initializes the hreg state arguments to 0 and returns TRUE. Otherwise, it returns FALSE. + * + * @param n The hreg state index to check. + * @return TRUE if the hreg state index has changed and the hreg state arguments have been initialized, FALSE otherwise. + */ + +extern int hreg_init_check(const int n) { + // Check if the current hreg state index is different from the previous one + if (GETREG(HREG, HREG_STATE_IDX) == n && GETREG(HREG, 55) != n) { + int i; + int reg; + + // Set the previous hreg state index to the current one + SETREG(HREG, 55, n); + reg = HREG_STATE_ARGS_START; + + // Initialize the hreg state arguments to 0 + for (i = 0; i < 15; i++, reg++) { + SETREG(HREG, reg, 0); + } + + // Return TRUE if the hreg state index has changed and arguments have been initialized + return TRUE; + } + + // Return FALSE if the hreg state index has not changed + return FALSE; +} + diff --git a/rel/m_malloc.c b/rel/m_malloc.c index 1c98250b..a6c12aef 100644 --- a/rel/m_malloc.c +++ b/rel/m_malloc.c @@ -37,10 +37,10 @@ void zelda_AddBlockArena(void* start, u32 size){ __osMallocAddBlock(&zelda_arena,start, size); } -void zelda_CleanupArena(void){ +void zelda_CleanupArena() { __osMallocCleanup(&zelda_arena); } -void zelda_MallocIsInitalized(void){ - __osMallocIsInitalized(&zelda_arena); +extern int zelda_MallocIsInitalized() { + return __osMallocIsInitalized(&zelda_arena); } \ No newline at end of file diff --git a/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c b/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c index 4577018c..505c926b 100644 --- a/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c +++ b/rel/m_room_type/mRmTp_FtrItemNo2FtrIdx.c @@ -1,4 +1,4 @@ -#include "roomtype.h" +#include "m_room_type.h" #define FTR_NO_2_FTR_IDX(f) ((f) >> 2) #define NUM_FTR_IN_TYPE (FTR_NO_2_FTR_IDX(0x1000)) diff --git a/src/libc64/__osMalloc.c b/src/libc64/__osMalloc.c index e69de29b..8e7e0ffd 100644 --- a/src/libc64/__osMalloc.c +++ b/src/libc64/__osMalloc.c @@ -0,0 +1 @@ +int __osMalloc_FreeBlockTest_Enable;