diff --git a/include/boot.h b/include/boot.h new file mode 100644 index 00000000..39c54d8b --- /dev/null +++ b/include/boot.h @@ -0,0 +1,16 @@ +#ifndef BOOT_H +#define BOOT_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char* boot_copyDate; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_all_grow.h b/include/m_all_grow.h new file mode 100644 index 00000000..ead3bb70 --- /dev/null +++ b/include/m_all_grow.h @@ -0,0 +1,17 @@ +#ifndef M_ALL_GROW_H +#define M_ALL_GROW_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mAGrw_PrintFossilHaniwa_debug(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_card.h b/include/m_card.h new file mode 100644 index 00000000..973f3979 --- /dev/null +++ b/include/m_card.h @@ -0,0 +1,17 @@ +#ifndef M_CARD_H +#define M_CARD_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mCD_PrintErrInfo(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_debug_hayakawa.h b/include/m_debug_hayakawa.h new file mode 100644 index 00000000..3c5a3594 --- /dev/null +++ b/include/m_debug_hayakawa.h @@ -0,0 +1,19 @@ +#ifndef M_DEBUG_HAYAKAWA_H +#define M_DEBUG_HAYAKAWA_H + +#include "types.h" +#include "graph.h" +#include "libu64/pad.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void debug_hayakawa_draw(GRAPH* graph); +extern void debug_hayakawa_move(pad_t* pad); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_debug_mode.h b/include/m_debug_mode.h new file mode 100644 index 00000000..c7179d78 --- /dev/null +++ b/include/m_debug_mode.h @@ -0,0 +1,44 @@ +#ifndef M_DEBUG_MODE_H +#define M_DEBUG_MODE_H + +#include "types.h" +#include "graph.h" +#include "m_debug.h" +#include "pad.h" +#include "game.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void Debug_mode_input(pad_t* pad); +extern void Debug_mode_output(GRAPH* graph); + +/* Defines for debug mode output colors */ +#define DEBUG_PRINT_COLOR_BLACK 0 +#define DEBUG_PRINT_COLOR_BLUE 1 +#define DEBUG_PRINT_COLOR_RED 2 +#define DEBUG_PRINT_COLOR_MAGENTA 3 +#define DEBUG_PRINT_COLOR_GREEN 4 +#define DEBUG_PRINT_COLOR_CYAN 5 +#define DEBUG_PRINT_COLOR_YELLOW 6 +#define DEBUG_PRINT_COLOR_WHITE 7 + +/* Defines for debug mode 2 output colors */ +#define DEBUG_PRINT2_COLOR_YELLOW 0 +#define DEBUG_PRINT2_COLOR_PINK 1 +#define DEBUG_PRINT2_COLOR_BROWN 2 +#define DEBUG_PRINT2_COLOR_DARKORANGE 3 +#define DEBUG_PRINT2_COLOR_LIGHTORANGE 4 +#define DEBUG_PRINT2_COLOR_GRAY 5 +#define DEBUG_PRINT2_COLOR_LILAC 6 +#define DEBUG_PRINT2_COLOR_LIMEGREEN 7 + +#define DEBUG_MODE_CHECK_TRIGGER(game, btn) (((game)->pads[1].on.button & (btn)) == (btn)) +#define DEBUG_MODE_CHECK_TRIGGER_GAME(btn) (DEBUG_MODE_CHECK_TRIGGER(gamePT, btn)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_event.h b/include/m_event.h new file mode 100644 index 00000000..b78c31e2 --- /dev/null +++ b/include/m_event.h @@ -0,0 +1,18 @@ +#ifndef M_EVENT_H +#define M_EVENT_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mEv_debug_print4f(gfxprint_t* gfxprint); +extern void mEv_sp_debug_print4f(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_field_assessment.h b/include/m_field_assessment.h new file mode 100644 index 00000000..da05ae60 --- /dev/null +++ b/include/m_field_assessment.h @@ -0,0 +1,17 @@ +#ifndef M_FIELD_ASSESSMENT_H +#define M_FIELD_ASSESSMENT_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mFAs_PrintFieldAssessment(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_flashrom.h b/include/m_flashrom.h new file mode 100644 index 00000000..403df437 --- /dev/null +++ b/include/m_flashrom.h @@ -0,0 +1,17 @@ +#ifndef M_FLASHROM_H +#define M_FLASHROM_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mFRm_PrintSavedDebug(gfxprint_t* gfxprint); +extern void mFRm_display_errInfo(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_fuusen.h b/include/m_fuusen.h new file mode 100644 index 00000000..08ae2bc3 --- /dev/null +++ b/include/m_fuusen.h @@ -0,0 +1,16 @@ +#ifndef M_FUUSEN_H +#define M_FUUSEN_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int fuusen_DEBUG_mode_flag; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_malloc.h b/include/m_malloc.h index 03b14ee1..5ee359d0 100644 --- a/include/m_malloc.h +++ b/include/m_malloc.h @@ -1,19 +1,29 @@ #ifndef M_MALLOC_H #define M_MALLOC_H + +#include "types.h" #include "libc64/__osMalloc.h" -Arena zelda_arena; +#ifdef __cplusplus +extern "C" { +#endif +extern Arena zelda_arena; -void zelda_malloc_align(u32,u32); -void zelda_malloc(u32); -void zelda_malloc_r(u32); -void zelda_free(void*); -void zelda_GetFreeArena(u32*,u32*,u32*); -u32 zelda_GetTotalFreeSize(void); -u32 zelda_GetMemBlockSize(void*); -void zelda_InitArena(void*, u32); -void zelda_AddBlockArena(void*, u32); -void zelda_CleanupArena(void); -void zelda_MallocIsInitialized(void); -#endif \ No newline at end of file +extern void zelda_malloc_align(u32,u32); +extern void zelda_malloc(u32); +extern void zelda_malloc_r(u32); +extern void zelda_free(void*); +extern void zelda_GetFreeArena(size_t* max, size_t* free, size_t* alloc); +extern u32 zelda_GetTotalFreeSize(void); +extern u32 zelda_GetMemBlockSize(void*); +extern void zelda_InitArena(void*, u32); +extern void zelda_AddBlockArena(void*, u32); +extern void zelda_CleanupArena(void); +extern int zelda_MallocIsInitalized(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_npc.h b/include/m_npc.h new file mode 100644 index 00000000..cb82d58a --- /dev/null +++ b/include/m_npc.h @@ -0,0 +1,18 @@ +#ifndef M_NPC_H +#define M_NPC_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); +extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_quest.h b/include/m_quest.h new file mode 100644 index 00000000..6a2878e9 --- /dev/null +++ b/include/m_quest.h @@ -0,0 +1,17 @@ +#ifndef M_QUEST_H +#define M_QUEST_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mQst_PrintQuestInfo(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_room_type.h b/include/m_room_type.h new file mode 100644 index 00000000..e731fc5e --- /dev/null +++ b/include/m_room_type.h @@ -0,0 +1,61 @@ +#ifndef ROOM_TYPE_H +#define ROOM_TYPE_H + +#include "types.h" +#include "libu64/gfxprint.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) + +extern void mRmTp_DrawFamicomInfo(gfxprint_t* gfxprint); +extern void mRmTp_MakeFamicom_Fdebug(); + +#endif \ No newline at end of file diff --git a/include/m_shop.h b/include/m_shop.h new file mode 100644 index 00000000..e64a31b5 --- /dev/null +++ b/include/m_shop.h @@ -0,0 +1,20 @@ +#ifndef M_SHOP_H +#define M_SHOP_H + +#include "types.h" +#include "libu64/gfxprint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mSP_PrintNowShopSalesSum(gfxprint_t* gfxprint); + +extern void mItemDebug_ItemDebugMain(); +extern void mItemDebug_ItemDebugDraw(gfxprint_t* gfxprint); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rel/m_debug_mode.c b/rel/m_debug_mode.c new file mode 100644 index 00000000..96671632 --- /dev/null +++ b/rel/m_debug_mode.c @@ -0,0 +1,729 @@ +#include "m_debug_mode.h" + +#include "libu64/gfxprint.h" +#include "m_lib.h" +#include "m_malloc.h" +#include "THA_GA.h" +#include "gfxalloc.h" +#include "graph.h" +#include "game.h" +#include "m_debug_hayakawa.h" +#include "m_fuusen.h" +#include "m_field_info.h" +#include "m_private.h" +#include "m_quest.h" +#include "m_event.h" +#include "m_msg.h" +#include "m_shop.h" +#include "zurumode.h" +#include "m_nmibuf.h" +#include "m_room_type.h" +#include "m_npc.h" +#include "m_field_assessment.h" +#include "m_all_grow.h" +#include "m_card.h" +#include "m_flashrom.h" +#include "dolphin/dvd.h" +#include "libjsys/jsyswrapper.h" +#include "boot.h" + +#define DEBUG_MODE_PRINT_BUF_COUNT 6 +#define DEBUG_MODE_PRINT_OUTPUT_X 26 +#define DEBUG_MODE_PRINT_OUTPUT_Y 20 +#define DEBUG_MODE_PRINT_OUTPUT_Y_LAST (DEBUG_MODE_PRINT_OUTPUT_Y + DEBUG_MODE_PRINT_BUF_COUNT) + +#define DEBUG_MODE_PRINT_FLAG 1 +#define DEBUG_MODE_PRINT2_FLAG 2 + +static int debug_print_flg; +static s16 debug_print2_count; + +typedef struct debug_mode_print_buffer_s { + u8 color; + u8 msg[11]; +} debug_mode_print_buf_t; + +static debug_mode_print_buf_t debug_print_buffer[DEBUG_MODE_PRINT_BUF_COUNT] = { + { + DEBUG_PRINT_COLOR_BLACK, + " \0", + }, + { + DEBUG_PRINT_COLOR_BLACK, + " \0", + }, + { + DEBUG_PRINT_COLOR_BLACK, + " \0", + }, + { + DEBUG_PRINT_COLOR_BLACK, + " \0", + }, + { + DEBUG_PRINT_COLOR_BLACK, + " \0", + }, + { + DEBUG_PRINT_COLOR_BLACK, + " \0", + } +}; + +#pragma pool_data on + +static void Debug_Print_output(gfxprint_t* gfxprint) { + static rgba_t print_color[8] = { + { 0, 0, 0, 64 }, /* Black */ + { 0, 0, 255, 64 }, /* Blue */ + { 255, 0, 0, 64 }, /* Red */ + { 255, 0, 255, 64 }, /* Magenta */ + { 0, 255, 0, 64 }, /* Green */ + { 0, 255, 255, 64 }, /* Cyan */ + { 255, 255, 0, 64 }, /* Yellow */ + { 255, 255, 255, 64 } /* White */ + }; + + debug_mode_print_buf_t* print_buf = debug_print_buffer; + int y; + + for (y = DEBUG_MODE_PRINT_OUTPUT_Y; y < DEBUG_MODE_PRINT_OUTPUT_Y_LAST;) { + rgba_t* color; + gfxprint_locate8x8(gfxprint, DEBUG_MODE_PRINT_OUTPUT_X, y); + color = print_color + print_buf->color; + gfxprint_color(gfxprint, color->r, color->g, color->b, color->a); + gfxprint_printf(gfxprint, "%s", print_buf->msg); + + y++; + print_buf->msg[0] = '\0'; + print_buf++; + } +} + +#pragma pool_data reset + +#define DEBUG_MODE_PRINT2_BUF_COUNT 80 + +typedef struct debug_mode_print2_buffer_s { + u8 x; + u8 y; + u8 color; + u8 msg[41]; +} debug_mode_print2_buf_t; + +static debug_mode_print2_buf_t debug_print2_buffer[DEBUG_MODE_PRINT2_BUF_COUNT]; + +static void Debug_Print2_output(gfxprint_t* gfxprint) { + static rgba_t print_color[8] = { + { 255, 255, 32, 192 }, /* Yellow */ + { 255, 150, 128, 192 }, /* Pink */ + { 128, 96, 0, 64 }, /* Brown */ + { 196, 128, 16, 128 }, /* Dark Orange */ + { 255, 196, 32, 128 }, /* Light Orange */ + { 230, 230, 220, 64 }, /* White/Gray */ + { 128, 150, 255, 128 }, /* Lilac */ + { 128, 255, 32, 128 } /* Lime green */ + }; + + int i; + for (i = 0; i < debug_print2_count; i++) { + gfxprint_color( + gfxprint, + print_color[debug_print2_buffer[i].color].r, + print_color[debug_print2_buffer[i].color].g, + print_color[debug_print2_buffer[i].color].b, + print_color[debug_print2_buffer[i].color].a + ); + + gfxprint_locate8x8(gfxprint, debug_print2_buffer[i].x, debug_print2_buffer[i].y); + gfxprint_printf(gfxprint, "%s", debug_print2_buffer[i].msg); + } +} + +#define PAD_BUTTON_DOWN(buttons, button) (((int)(buttons) | (~(int)(button))) == -1) + +static int Debug_console(pad_t* pad) { + static f32 console_scroll; + static f32 console_offset_x; + + void* sys_console = JC_JFWSystem_getSystemConsole(); + + if (sys_console != NULL) { + /* Toggle console visiblity when Z button is released */ + if (PAD_BUTTON_DOWN(pad->on.button, BUTTON_Z) && (pad->now.button & (~BUTTON_Z)) == 0) { + JC_JUTConsole_setVisible(sys_console, !JC_JUTConsole_isVisible(sys_console)); + } + + if (JC_JUTConsole_isVisible(sys_console)) { + int scroll_x, scroll_y; + f32 log_stick_x = (f32)pad->off.stick_x / 60.0f; + f32 log_stick_y = (f32)pad->off.stick_y / 60.0f; + + /* B button clears console */ + if (PAD_BUTTON_DOWN(pad->on.button, BUTTON_B)) { + JC_JUTConsole_clear(sys_console); + } + + /* L button to scroll */ + if (PAD_BUTTON_DOWN(pad->now.button, BUTTON_L)) { + console_scroll -= log_stick_y; + + if (console_scroll > 1.0f) { + scroll_y = (int)console_scroll; + } + else if (console_scroll < -1.0f) { + scroll_y = -(int)-console_scroll; /* nice double neg */ + } + else { + scroll_y = 0; + } + + if (scroll_y != 0) { + console_scroll -= scroll_y; + JC_JUTConsole_scroll(sys_console, scroll_y); + } + + console_offset_x -= log_stick_x; + if (console_offset_x > 1.0f) { + scroll_x = (int)console_offset_x; + } + else if (console_offset_x < -1.0f) { + scroll_x = -(int)-console_offset_x; /* nice double neg */ + } + else { + scroll_x = 0; + } + + if (scroll_x != 0) { + console_offset_x -= scroll_x; + JC_JUTConsole_setPosition(sys_console, scroll_x + JC_JUTConsole_getPositionX(sys_console), 42); + } + + JW_JUTReport( + 30, 440, + 1, + "SCROLL:%3d %3d Output=%1x", + JC_JUTConsole_getLineOffset(sys_console), + JC_JUTConsole_getPositionX(sys_console), + JC_JUTConsole_getOutput(sys_console) + ); + } + + /* R button re-prints console */ + if (PAD_BUTTON_DOWN(pad->on.button, BUTTON_R)) { + JC_JUTConsole_dumpToTerminal(sys_console, -1); /* -1 is probably a define */ + JC_JUTConsole_setOutput(sys_console, 3); /* Again, 3 is probably a define */ + } + + return TRUE; + } + } + + return FALSE; +} + +static int draw_status; +static int bg_draw_status; +static int bg_draw_status2; +static int quest_draw_status; +static int shop_draw_status; +static int event_status; +static int zelda_malloc_status; +static int famicom_status; +static int npc_draw_status; +static int field_assessment_status; + +typedef struct debug_reg_keycombo_s { + u16 held; /* Previously held */ + u16 pressed; /* Pressed this frame */ +} debug_reg_keycombo_t; + +#pragma pool_data on +extern void Debug_mode_input(pad_t* pad) { + int r_ofs = (-1 + debug_mode->mode + debug_mode->type * DEBUG_REG_GROUP) * DEBUG_REG_SIZE; + + if (famicom_status != 0 || Debug_console(pad) == 0) { + u16 now_button = pad->now.button; + int dpad = now_button & (BUTTON_DRIGHT | BUTTON_DLEFT | BUTTON_DDOWN | BUTTON_DUP); + + /* L + R held shows the disk info, copy date, and zurumode/appNMI buffer state */ + if (PAD_BUTTON_DOWN(now_button, BUTTON_L) && PAD_BUTTON_DOWN(now_button, BUTTON_R)) { + DVDDiskID* diskid = DVDGetCurrentDiskID(); + if (diskid != NULL) { + JW_JUTReport(50, 50, 1, "%.4s %.2s 0x%02x(%d)", diskid->gameName, diskid->company, diskid->gameVersion, diskid->gameVersion); + } + + if (boot_copyDate != NULL) { + JW_JUTReport(320, 50, 1, "%.19s", boot_copyDate); + } + + JW_JUTReport(50, 60, 1, "Z=%d Z2=%d, ANB=%08x", zurumode_flag != 0, zurumode_flag >= 2, APPNMI_GETVAL()); + + /* Additionally, pressing Z after L + R will print out each bit in debug appNMI buffer */ + if (PAD_BUTTON_DOWN(pad->now.button, BUTTON_Z)) { + int i; + for (i = 0; i < 32; i++) { + JW_JUTReport(50 + i * 12, 70, 1, "%1x", (APPNMI_GETVAL() >> (31 - i)) & 1); + } + } + } + + if (zurumode_flag >= 2 && (PAD_BUTTON_DOWN(pad->now.button, BUTTON_L) || PAD_BUTTON_DOWN(pad->now.button, BUTTON_R) || PAD_BUTTON_DOWN(pad->now.button, BUTTON_START))) { + /* Button combos to get to each register */ + static debug_reg_keycombo_t key_data[DEBUG_REG_MAX] = { + {BUTTON_L, BUTTON_CUP}, /* REG */ + {BUTTON_L, BUTTON_CLEFT}, /* SREG */ + {BUTTON_L, BUTTON_CDOWN}, /* OREG */ + {BUTTON_L, BUTTON_A}, /* PREG */ + {BUTTON_R, BUTTON_CDOWN}, /* QREG */ + {BUTTON_L, BUTTON_CRIGHT}, /* MREG */ + {BUTTON_L, BUTTON_R}, /* SBREG */ + {BUTTON_L, BUTTON_DLEFT}, /* DREG */ + {BUTTON_L, BUTTON_DRIGHT}, /* UREG */ + {BUTTON_L, BUTTON_DUP}, /* IREG */ + {BUTTON_L, BUTTON_B}, /* ZREG */ + {BUTTON_L, BUTTON_Z}, /* CRV */ + {BUTTON_L, BUTTON_DDOWN}, /* NS1 */ + {BUTTON_R, BUTTON_A}, /* SND */ + {BUTTON_R, BUTTON_B}, /* XREG */ + {BUTTON_R, BUTTON_Z}, /* CRV2 */ + {BUTTON_R, BUTTON_L}, /* DEMOREG */ + {BUTTON_R, BUTTON_CUP}, /* TREG */ + {BUTTON_R, BUTTON_CRIGHT}, /* WREG */ + {BUTTON_R, BUTTON_DLEFT}, /* AREG */ + {BUTTON_R, BUTTON_CLEFT}, /* VREG */ + {BUTTON_R, BUTTON_START}, /* HREG */ + {BUTTON_L, BUTTON_START}, /* GREG */ + {BUTTON_R, BUTTON_DRIGHT}, /* mREG */ + {BUTTON_R, BUTTON_DUP}, /* nREG */ + {BUTTON_START, BUTTON_R}, /* BREG */ + {BUTTON_START, BUTTON_A}, /* DORO */ + {BUTTON_START, BUTTON_Y}, /* kREG */ + {BUTTON_START, BUTTON_CRIGHT}, /* BAK */ + {BUTTON_START, BUTTON_CLEFT}, /* PLAYERREG */ + {BUTTON_START, BUTTON_CDOWN}, /* NMREG */ + {BUTTON_START, BUTTON_L}, /* NIIREG */ + {BUTTON_START, BUTTON_Z}, /* GENREG */ + {BUTTON_START, BUTTON_CUP}, /* MYKREG */ + {BUTTON_START, BUTTON_DUP}, /* CAMREG */ + {BUTTON_START, BUTTON_DRIGHT}, /* SAKREG */ + {BUTTON_START, BUTTON_DLEFT}, /* TAKREG */ + {BUTTON_START, BUTTON_DDOWN} /* PL2REG */ + }; + + int i; + + for (i = 0; i < DEBUG_REG_MAX; i++) { + if (PAD_BUTTON_DOWN(pad->now.button, key_data[i].held) && + PAD_BUTTON_DOWN(pad->on.button, key_data[i].pressed)) { + break; + } + } + + if (i < DEBUG_REG_MAX) { + if (i == debug_mode->type) { + /* Switch register group */ + debug_mode->mode = (debug_mode->mode + 1) % (DEBUG_REG_GROUP + 1); + } else { + /* Switch registers */ + debug_mode->type = i; + debug_mode->mode = 0; + } + } + } + else { + int increment; + switch ((int)debug_mode->mode) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if (dpad == debug_mode->old_key) { + if (debug_mode->key_wait <= 0) { + debug_mode->key_wait = 1; + } else { + debug_mode->key_wait--; + dpad ^= debug_mode->old_key; + } + } else { + debug_mode->key_wait = 16; + debug_mode->old_key = dpad; + } + + /** + * Register increment key combos: + * - D-Pad Right: positive + * - D-Pad Left: negative + * + * Increment modifiers (held) + * - C-Stick Up: 0x1000 + * - C-Stick Down: 0x100 + * - A + B: 1000 + * - A: 100 + * - B: 10 + * - Default: 1 + **/ + if (dpad & BUTTON_DRIGHT) { + u16 btn = pad->now.button; + if (PAD_BUTTON_DOWN(btn, BUTTON_CUP)) { + increment = 0x1000; + } else if (PAD_BUTTON_DOWN(btn, BUTTON_CDOWN)) { + increment = 0x100; + } else if (PAD_BUTTON_DOWN(btn, BUTTON_A | BUTTON_B)) { + increment = 1000; + } else if (PAD_BUTTON_DOWN(btn, BUTTON_A)) { + increment = 100; + } else { + increment = 1; + if (PAD_BUTTON_DOWN(btn, BUTTON_B)) { + increment = 10; + } + } + } else if (dpad & BUTTON_DLEFT) { + u16 btn = pad->now.button; + if (PAD_BUTTON_DOWN(btn, BUTTON_CUP)) { + increment = -0x1000; + } else if (PAD_BUTTON_DOWN(btn, BUTTON_CDOWN)) { + increment = -0x100; + } else if (PAD_BUTTON_DOWN(btn, BUTTON_A | BUTTON_B)) { + increment = -1000; + } + /* lol the missed duplicated case */ + else if (PAD_BUTTON_DOWN(btn, BUTTON_A | BUTTON_B)) { + increment = -1000; + } else if (PAD_BUTTON_DOWN(btn, BUTTON_A)) { + increment = -100; + } else { + increment = -1; + if (PAD_BUTTON_DOWN(btn, BUTTON_B)) { + increment = -10; + } + } + } else { + increment = 0; + } + + /* Adjust selected register value */ + debug_mode->r[debug_mode->input_r + r_ofs] += increment; + + /* Adjust selected register index */ + if (dpad & BUTTON_DUP) { + if (debug_mode->input_r <= 0) { + debug_mode->input_r = (DEBUG_REG_SIZE - 1); + } else { + debug_mode->input_r--; + } + } else if (dpad & BUTTON_DDOWN) { + if (debug_mode->input_r >= (DEBUG_REG_SIZE - 1)) { + debug_mode->input_r = 0; + } else { + debug_mode->input_r++; + } + } + } break; + } + } + + /* Hayakawa debug functions controlled by previous controller */ + debug_hayakawa_move(pad - 1); + + /** + * Summary of display toggle buttons + * A: + * - bg_draw_status + * - quest_draw_status + * - event_status (non-special) + * - draw_status + * D-Pad Left: + * - event_status (special) + * D-Pad Up: + * - shop_draw_status + * C-Stick Up + * - zelda_malloc_status + * D-Pad Down (zurumode 2 enabled): + * - famicom_status + * (missing: C-Stick Down, perhaps for bg_draw_status2) + * D-Pad Right: + * - npc_draw_status + * C-Stick Right: + * - field_assessment_status + **/ + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_A)) { + bg_draw_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_A)) { + quest_draw_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_A)) { + event_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_DLEFT)) { + event_status ^= 2; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_A)) { + draw_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_DUP)) { + shop_draw_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_CUP)) { + zelda_malloc_status ^= 1; + } + + if (zurumode_flag >= 2 && DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_DDOWN)) { + famicom_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_DRIGHT)) { + npc_draw_status ^= 1; + } + + if (DEBUG_MODE_CHECK_TRIGGER_GAME(BUTTON_CRIGHT)) { + field_assessment_status ^= 1; + } + } +} +#pragma pool_data reset + +#pragma pool_data on +static void Debug_mode_output_sub(gfxprint_t* gfxprint) { + static u8 reg_name_data[] = " SOPQMYDUIZCNKXcsiWAVHGmnBdkb*********"; + static char* long_reg_name_data[] = { + "REG", + "SREG", + "OREG", + "PREG", + "QREG", + "MREG", + "SBREG", + "DREG", + "UREG", + "IREG", + "ZREG", + "CRV", + "NS1", + "SND", + "XREG", + "CRV2", + "DEMOREG", + "TREG", + "WREG", + "AREG", + "VREG", + "HREG", + "GREG", + "mREG", + "nREG", + "BREG", + "DORO", + "kREG", + "BAK", + "PLAYERREG", + "NMREG", + "NIIREG", + "GENREG", + "MYKREG", + "CAMREG", + "SAKREG", + "TAKREG", + "PL2REG" + }; + + int i; + int mode; + int adj; + int ofs; + + mode = (debug_mode->mode - 1); + adj = mode * DEBUG_REG_SIZE; + ofs = (mode + debug_mode->type * DEBUG_REG_GROUP) * DEBUG_REG_SIZE; + + gfxprint_color(gfxprint, 0, 128, 128, 128); /* Color -> xlu dark cyan */ + gfxprint_locate8x8(gfxprint, 3, 8); + gfxprint_printf(gfxprint, "%c(%s)", reg_name_data[debug_mode->type], long_reg_name_data[debug_mode->type]); + gfxprint_color(gfxprint, 0, 128, 128, 128); /* Reset color... back to dark cyan? */ + + for (i = 0; i < DEBUG_REG_SIZE; i++) { + if (i == debug_mode->input_r) { + gfxprint_color(gfxprint, 0, 255, 255, 255); /* Color -> opaque cyan */ + } + + gfxprint_locate8x8(gfxprint, 3, i + 9); + gfxprint_printf(gfxprint, "%02d%6d", i + adj, debug_mode->r[i + ofs]); + + if (i == debug_mode->input_r) { + gfxprint_color(gfxprint, 0, 128, 128, 128); /* Color -> xlu dark cyan */ + } + } +} +#pragma pool_data reset + +#pragma pool_data on +static void Debug_mode_zelda_malloc_info_output(gfxprint_t* gfxprint) { + u32 max, free, alloc; + u32 graph_alloc; + + if (zelda_MallocIsInitalized()) { + graph_alloc = THA_GA_getFreeBytes(&gamePT->graph->polygon_opaque_thaga); + zelda_GetFreeArena(&max, &free, &alloc); + + gfxprint_color(gfxprint, 200, 200, 250, 255); /* color -> opaque lilac */ + gfxprint_locate8x8(gfxprint, 3, 23); + gfxprint_printf(gfxprint, "zelda_malloc サイダイアキ%x", max); + gfxprint_locate8x8(gfxprint, 3, 24); + gfxprint_printf(gfxprint, " アキ%x", free); + gfxprint_locate8x8(gfxprint, 3, 25); + gfxprint_printf(gfxprint, "graph_alloc ノコリ %x", graph_alloc); + } +} +#pragma pool_data reset + +static void DebugHaniwaTempo(gfxprint_t* gfxprint) { + /* TODO: this requires implementing m_home & m_house */ +} + +#define GFXLIST_RESERVED_SIZE (int)(512 * sizeof(Gfx)) /* requires 0x1000 bytes, or 512 free Gfx */ + +#pragma pool_data on +extern void Debug_mode_output(GRAPH* graph) { + static int glist_used_bytes; + Gfx* start_gfx; + Gfx* last_gfx; + int poly_free_bytes; + int d_col_r; + int d_col_g; + gfxprint_t gfxprint; + gfxprint_t* print_p = &gfxprint; + + debug_hayakawa_draw(graph); + poly_free_bytes = THA_GA_getFreeBytes(&graph->polygon_opaque_thaga); + if (poly_free_bytes >= glist_used_bytes + GFXLIST_RESERVED_SIZE) { + Gfx* gfx; + gfxprint_init(print_p); + + OPEN_DISP(graph); + + start_gfx = NOW_POLY_OPA_DISP; + gfx = gfxopen(start_gfx); + gSPDisplayList(NOW_OVERLAY_DISP++, gfx); + + gfxprint_open(print_p, gfx); + + if (debug_print_flg & DEBUG_MODE_PRINT2_FLAG) { + Debug_Print2_output(print_p); + } + + if (debug_mode->mode != 0) { + Debug_mode_output_sub(print_p); + } + + debug_print2_count = 0; + + if (debug_print_flg & DEBUG_MODE_PRINT_FLAG) { + Debug_Print_output(print_p); + } + + if (debug_mode->mode == 0) { + fuusen_DEBUG_mode_flag = 1; + + if (bg_draw_status & 1) { + mFI_PrintNowBGNum(print_p); + mFI_PrintFgAttr(print_p); + gfxprint_color(print_p, 200, 200, 250, 255); /* color -> lilac */ + gfxprint_locate8x8(print_p, 3, 9); + gfxprint_printf(print_p, "%3d %3d", mPr_GetMoneyPower(), mPr_GetGoodsPower()); + } + + if (quest_draw_status & 1) { + mQst_PrintQuestInfo(print_p); + } + + if (event_status & 1) { + mEv_debug_print4f(print_p); + } + + if (event_status & 2) { + mEv_sp_debug_print4f(print_p); + } + + if (draw_status & 1) { + mMsg_debug_draw(print_p); + } + + if (zurumode_flag >= 2) { + mItemDebug_ItemDebugMain(); + mItemDebug_ItemDebugDraw(print_p); + } + + if (shop_draw_status & 1) { + mSP_PrintNowShopSalesSum(print_p); + DebugHaniwaTempo(print_p); + } + + if (zelda_malloc_status & 1) { + Debug_mode_zelda_malloc_info_output(print_p); + } + + if (zurumode_flag >= 2 && (famicom_status & 1)) { + mRmTp_DrawFamicomInfo(print_p); + mRmTp_MakeFamicom_Fdebug(); + } + + d_col_g = APPNMI_RESETEXEMPT_GET() ? 125 : 250; + d_col_r = zurumode_flag >= 2 ? 125 : 250; + + /** + * debug 'D' colors: + * Base: Yellow + * ResetExempt: Pink + * Zurumode2/Zurumode3: Green + * ResetExempt & Zurumode2/Zurumode3: Blue-gray + */ + gfxprint_color(print_p, d_col_r, d_col_g, 140, 255); + gfxprint_locate8x8(print_p, 36, 3); + gfxprint_printf(print_p, "D"); + + if (npc_draw_status & 1) { + mNpc_PrintRemoveInfo(print_p); + } + + if (field_assessment_status & 1) { + mFAs_PrintFieldAssessment(print_p); + mAGrw_PrintFossilHaniwa_debug(print_p); + + /* Maybe a macro like 'IS_FDEBUG()' */ + if (zurumode_flag >= 2) { + mNpc_PrintFriendship_fdebug(print_p); + } + + mPr_PrintMapInfo_debug(print_p); + } + + mFRm_PrintSavedDebug(print_p); + mCD_PrintErrInfo(print_p); + mFRm_display_errInfo(print_p); + } + + last_gfx = gfxprint_close(print_p); + gSPEndDisplayList(last_gfx++); + + glist_used_bytes = (int)last_gfx - (int)start_gfx; + gfxclose(start_gfx, last_gfx); + SET_POLY_OPA_DISP(last_gfx); + gfxprint_cleanup(print_p); + + CLOSE_DISP(graph); + } +} +#pragma pool_data reset diff --git a/rel/m_malloc.c b/rel/m_malloc.c index 1fd66155..1c98250b 100644 --- a/rel/m_malloc.c +++ b/rel/m_malloc.c @@ -1,6 +1,6 @@ #include "m_malloc.h" -extern Arena zelda_arena; +Arena zelda_arena; void zelda_malloc_align(u32 size, u32 align){ __osMallocAlign(&zelda_arena, size, align); diff --git a/tools/ppcdis b/tools/ppcdis index eca3f301..83260829 160000 --- a/tools/ppcdis +++ b/tools/ppcdis @@ -1 +1 @@ -Subproject commit eca3f3015a86bf0c78d1e415aeff2dda1851194f +Subproject commit 83260829c50f37dd9fe54889cf8971c8fe14c54e