From c8f4d66b009ad400f54538d6293afd5971c87776 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Wed, 2 Feb 2022 21:43:34 +0000 Subject: [PATCH] Documentation for fault.c and fault_drawer.c (#1106) * Mostly document fault and fault_drawer * FaultDrawer printf functions return s32 * Review Suggestions for comments Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Some further review suggestions * Further changes from suggestions * Fix Fault_AddClient doc comment * Bug comment for memdump overrun, add more to Fault_PadCallback bug comment * mb -> MB, comment about bss above externs * Fix color codes Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> --- data/fault.bss.s | 6 +- include/fault.h | 92 ++ include/functions.h | 60 - include/irqmgr.h | 30 + include/libc/stddef.h | 2 + include/padmgr.h | 40 + include/ultra64/convert.h | 2 + include/ultra64/thread.h | 2 + include/variables.h | 1 - include/vt.h | 5 +- include/z64.h | 128 +- src/code/audio_heap.c | 2 +- src/code/code_800E6840.c | 4 +- src/code/fault.c | 1025 ++++++++++------- src/code/fault_drawer.c | 232 ++-- src/code/game.c | 2 +- src/code/graph.c | 2 +- src/code/irqmgr.c | 4 +- src/code/padmgr.c | 4 +- src/code/sched.c | 2 +- src/code/z_onepointdemo.c | 2 +- src/libultra/os/createthread.c | 2 +- src/libultra/os/destroythread.c | 2 +- .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 2 +- .../ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 4 +- .../actors/ovl_En_Changer/z_en_changer.c | 8 +- .../actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c | 4 +- .../actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c | 2 +- .../actors/ovl_En_Encount1/z_en_encount1.c | 2 +- .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 4 +- .../actors/ovl_En_G_Switch/z_en_g_switch.c | 4 +- .../actors/ovl_En_Heishi1/z_en_heishi1.c | 16 +- .../actors/ovl_En_Heishi2/z_en_heishi2.c | 14 +- .../actors/ovl_En_Heishi4/z_en_heishi4.c | 2 +- .../actors/ovl_En_Kakasi3/z_en_kakasi3.c | 2 +- .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 4 +- .../ovl_En_Takara_Man/z_en_takara_man.c | 2 +- .../actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c | 2 +- .../ovl_En_Wonder_Talk/z_en_wonder_talk.c | 14 +- .../ovl_En_Wonder_Talk2/z_en_wonder_talk2.c | 24 +- .../ovl_En_Yabusame_Mark/z_en_yabusame_mark.c | 8 +- tools/vt_fmt.py | 8 +- 42 files changed, 1010 insertions(+), 767 deletions(-) create mode 100644 include/fault.h create mode 100644 include/irqmgr.h create mode 100644 include/padmgr.h diff --git a/data/fault.bss.s b/data/fault.bss.s index bda55d9b97..b66f9cf837 100644 --- a/data/fault.bss.s +++ b/data/fault.bss.s @@ -9,10 +9,10 @@ .balign 16 -glabel sFaultStructPtr +glabel sFaultInstance .space 4 -glabel sFaultIsWaitingForInput +glabel sFaultAwaitingInput .space 4 glabel sFaultStack @@ -21,5 +21,5 @@ glabel sFaultStack glabel sFaultThreadInfo .space 0x20 -glabel gFaultStruct +glabel gFaultMgr .space 0x850 diff --git a/include/fault.h b/include/fault.h new file mode 100644 index 0000000000..642d581d80 --- /dev/null +++ b/include/fault.h @@ -0,0 +1,92 @@ +#ifndef FAULT_H +#define FAULT_H + +#include "padmgr.h" + +// These are the same as the 3-bit ansi color codes +#define FAULT_COLOR_BLACK 0 +#define FAULT_COLOR_RED 1 +#define FAULT_COLOR_GREEN 2 +#define FAULT_COLOR_YELLOW 3 +#define FAULT_COLOR_BLUE 4 +#define FAULT_COLOR_MAGENTA 5 +#define FAULT_COLOR_CYAN 6 +#define FAULT_COLOR_WHITE 7 +// Additional color codes +#define FAULT_COLOR_DARK_GRAY 8 +#define FAULT_COLOR_LIGHT_GRAY 9 + +#define FAULT_COLOR_STRINGIFY(s) #s +#define FAULT_COLOR_EXPAND_AND_STRINGIFY(s) FAULT_COLOR_STRINGIFY(s) + +#define FAULT_ESC '\x1A' +#define FAULT_COLOR(n) "\x1A" FAULT_COLOR_EXPAND_AND_STRINGIFY(FAULT_COLOR_ ## n) + +typedef struct FaultClient { + /* 0x00 */ struct FaultClient* next; + /* 0x04 */ void* callback; + /* 0x08 */ void* arg0; + /* 0x0C */ void* arg1; +} FaultClient; // size = 0x10 + +typedef struct FaultAddrConvClient { + /* 0x00 */ struct FaultAddrConvClient* next; + /* 0x04 */ void* callback; + /* 0x08 */ void* arg; +} FaultAddrConvClient; // size = 0xC + +// Initialization + +void Fault_Init(void); + +// Fatal Errors + +void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2); +void Fault_AddHungupAndCrash(const char* file, s32 line); + +// Client Registration + +void Fault_AddClient(FaultClient* client, void* callback, void* arg0, void* arg1); +void Fault_RemoveClient(FaultClient* client); + +void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* arg); +void Fault_RemoveAddrConvClient(FaultAddrConvClient* client); + +// For use in Fault Client callbacks + +void Fault_WaitForInput(void); +void Fault_FillScreenBlack(void); +void Fault_SetFrameBuffer(void* fb, u16 w, u16 h); + +void FaultDrawer_SetForeColor(u16 color); +void FaultDrawer_SetBackColor(u16 color); +void FaultDrawer_SetFontColor(u16 color); +void FaultDrawer_SetCharPad(s8 padW, s8 padH); +void FaultDrawer_SetCursor(s32 x, s32 y); +s32 FaultDrawer_VPrintf(const char* fmt, va_list args); +s32 FaultDrawer_Printf(const char* fmt, ...); +void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...); + +typedef struct FaultMgr { + /* 0x000 */ OSThread thread; + /* 0x1B0 */ u8 unk_1B0[0x600]; + /* 0x7B0 */ OSMesgQueue queue; + /* 0x7C8 */ OSMesg msg; + /* 0x7CC */ u8 exit; + /* 0x7CD */ u8 msgId; + /* 0x7CE */ u8 faultHandlerEnabled; + /* 0x7CF */ u8 autoScroll; + /* 0x7D0 */ OSThread* faultedThread; + /* 0x7D4 */ void (*padCallback)(Input*); + /* 0x7D8 */ FaultClient* clients; + /* 0x7DC */ FaultAddrConvClient* addrConvClients; + /* 0x7E0 */ u8 unk_7E0[4]; + /* 0x7E4 */ Input padInput; + /* 0x7FC */ u16 colors[36]; + /* 0x844 */ void* fb; + /* 0x848 */ void* clientThreadSp; +} FaultMgr; // size = 0x850 + +extern FaultMgr gFaultMgr; + +#endif diff --git a/include/functions.h b/include/functions.h index 6a3f86265d..cd5f12d320 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1809,66 +1809,6 @@ void DebugArena_Check(void); void DebugArena_Init(void* start, u32 size); void DebugArena_Cleanup(void); u8 DebugArena_IsInitalized(void); -void Fault_SleepImpl(u32); -void Fault_ClientProcessThread(void* arg); -void Fault_ProcessClientContext(FaultClientContext*); -u32 Fault_ProcessClient(u32, u32, u32); -void Fault_AddClient(FaultClient*, void*, void*, void*); -void Fault_RemoveClient(FaultClient*); -void Fault_AddAddrConvClient(FaultAddrConvClient*, void*, void*); -void Fault_RemoveAddrConvClient(FaultAddrConvClient*); -u32 Fault_ConvertAddress(FaultAddrConvClient*); -void Fault_Sleep(u32); -void Fault_PadCallback(Input*); -void Fault_UpdatePadImpl(); -u32 Fault_WaitForInputImpl(); -void Fault_WaitForInput(); -void Fault_DrawRec(s32, s32, s32, s32, u16); -void Fault_FillScreenBlack(); -void Fault_FillScreenRed(); -void Fault_DrawCornerRec(u16); -void Fault_PrintFReg(s32, f32*); -void Fault_LogFReg(s32, f32*); -void Fault_PrintFPCR(u32); -void Fault_LogFPCR(u32); -void Fault_PrintThreadContext(OSThread*); -void Fault_LogThreadContext(OSThread*); -OSThread* Fault_FindFaultedThread(); -void Fault_Wait5Seconds(); -void Fault_WaitForButtonCombo(); -void Fault_DrawMemDumpPage(const char*, u32*, u32); -void Fault_DrawMemDump(u32, u32, u32, u32); -void Fault_WalkStack(u32* spPtr, u32* pcPtr, u32* raPtr); -void Fault_DrawStackTrace(OSThread* thread, s32 x, s32 y, s32 height); -void Fault_LogStackTrace(OSThread* thread, s32 height); -void Fault_ResumeThread(OSThread*); -void Fault_CommitFB(); -void Fault_ProcessClients(); -void Fault_UpdatePad(); -void Fault_ThreadEntry(void*); -void Fault_SetFB(void*, u16, u16); -void Fault_Init(void); -void Fault_HangupFaultClient(const char*, const char*); -void Fault_AddHungupAndCrashImpl(const char*, const char*); -void Fault_AddHungupAndCrash(const char*, u32); -void FaultDrawer_SetOsSyncPrintfEnabled(u32); -void FaultDrawer_DrawRecImpl(s32, s32, s32, s32, u16); -void FaultDrawer_DrawChar(char); -s32 FaultDrawer_ColorToPrintColor(u16); -void FaultDrawer_UpdatePrintColor(); -void FaultDrawer_SetForeColor(u16); -void FaultDrawer_SetBackColor(u16); -void FaultDrawer_SetFontColor(u16); -void FaultDrawer_SetCharPad(s8, s8); -void FaultDrawer_SetCursor(s32, s32); -void FaultDrawer_FillScreen(); -void* FaultDrawer_FormatStringFunc(void*, const char*, u32); -void FaultDrawer_VPrintf(const char*, char*); -void FaultDrawer_Printf(const char*, ...); -void FaultDrawer_DrawText(s32, s32, const char*, ...); -void FaultDrawer_SetDrawerFB(void*, u16, u16); -void FaultDrawer_SetInputCallback(void (*)()); -void FaultDrawer_SetDefault(); // ? UCodeDisas_TranslateAddr(?); // ? UCodeDisas_ParseCombineColor(?); // ? UCodeDisas_ParseCombineAlpha(?); diff --git a/include/irqmgr.h b/include/irqmgr.h new file mode 100644 index 0000000000..0f26fc3ce7 --- /dev/null +++ b/include/irqmgr.h @@ -0,0 +1,30 @@ +#ifndef IRQMGR_H +#define IRQMGR_H + +#include "ultra64.h" + +typedef struct { + /* 0x00 */ s16 type; + /* 0x02 */ char misc[0x1E]; +} OSScMsg; // size = 0x20 + +typedef struct IrqMgrClient { + /* 0x00 */ struct IrqMgrClient* prev; + /* 0x04 */ OSMesgQueue* queue; +} IrqMgrClient; + +typedef struct { + /* 0x000 */ OSScMsg retraceMsg; // this apparently got moved from OSSched + /* 0x020 */ OSScMsg prenmiMsg; // this apparently got moved from OSSched + /* 0x040 */ OSScMsg nmiMsg; + /* 0x060 */ OSMesgQueue queue; + /* 0x078 */ OSMesg msgBuf[8]; + /* 0x098 */ OSThread thread; + /* 0x248 */ IrqMgrClient* clients; + /* 0x24C */ u8 resetStatus; + /* 0x250 */ OSTime resetTime; + /* 0x258 */ OSTimer timer; + /* 0x278 */ OSTime retraceTime; +} IrqMgr; // size = 0x280 + +#endif diff --git a/include/libc/stddef.h b/include/libc/stddef.h index 7a481e97ed..ac71ed3629 100644 --- a/include/libc/stddef.h +++ b/include/libc/stddef.h @@ -5,4 +5,6 @@ typedef unsigned long size_t; +typedef unsigned int uintptr_t; + #endif diff --git a/include/padmgr.h b/include/padmgr.h new file mode 100644 index 0000000000..459bcfeba1 --- /dev/null +++ b/include/padmgr.h @@ -0,0 +1,40 @@ +#ifndef PADMGR_H +#define PADMGR_H + +#include "irqmgr.h" + +typedef struct { + /* 0x00 */ OSContPad cur; + /* 0x06 */ OSContPad prev; + /* 0x0C */ OSContPad press; // X/Y store delta from last frame + /* 0x12 */ OSContPad rel; // X/Y store adjusted +} Input; // size = 0x18 + +typedef struct PadMgr { + /* 0x0000 */ OSContStatus padStatus[4]; + /* 0x0010 */ OSMesg serialMsgBuf[1]; + /* 0x0014 */ OSMesg lockMsgBuf[1]; + /* 0x0018 */ OSMesg interruptMsgBuf[4]; + /* 0x0028 */ OSMesgQueue serialMsgQ; + /* 0x0040 */ OSMesgQueue lockMsgQ; + /* 0x0058 */ OSMesgQueue interruptMsgQ; + /* 0x0070 */ IrqMgrClient irqClient; + /* 0x0078 */ IrqMgr* irqMgr; + /* 0x0080 */ OSThread thread; + /* 0x0230 */ Input inputs[4]; + /* 0x0290 */ OSContPad pads[4]; + /* 0x02A8 */ vu8 validCtrlrsMask; + /* 0x02A9 */ u8 nControllers; + /* 0x02AA */ u8 ctrlrIsConnected[4]; // "Key_switch" originally + /* 0x02AE */ u8 pakType[4]; // 1 if rumble pack, 2 if mempak? + /* 0x02B2 */ vu8 rumbleEnable[4]; + /* 0x02B6 */ u8 rumbleCounter[4]; // not clear exact meaning + /* 0x02BC */ OSPfs pfs[4]; + /* 0x045C */ vu8 rumbleOffFrames; + /* 0x045D */ vu8 rumbleOnFrames; + /* 0x045E */ u8 preNMIShutdown; + /* 0x0460 */ void (*retraceCallback)(struct PadMgr* padmgr, s32 unk464); + /* 0x0464 */ u32 retraceCallbackValue; +} PadMgr; // size = 0x468 + +#endif diff --git a/include/ultra64/convert.h b/include/ultra64/convert.h index 13679fc5b0..62409158c1 100644 --- a/include/ultra64/convert.h +++ b/include/ultra64/convert.h @@ -15,4 +15,6 @@ #define OS_PHYSICAL_TO_K0(x) (void*)(((u32)(x)+0x80000000)) #define OS_PHYSICAL_TO_K1(x) (void*)(((u32)(x)+0xA0000000)) +#define OS_SEC_TO_CYCLES(n) OS_USEC_TO_CYCLES((n) * 1000 * 1000) + #endif diff --git a/include/ultra64/thread.h b/include/ultra64/thread.h index 69cbc775f0..6b901d4f2d 100644 --- a/include/ultra64/thread.h +++ b/include/ultra64/thread.h @@ -12,6 +12,8 @@ #define OS_PRIORITY_APPMAX 127 #define OS_PRIORITY_IDLE 0 +#define OS_PRIORITY_THREADTAIL -1 + #define OS_STATE_STOPPED 1 #define OS_STATE_RUNNABLE 2 #define OS_STATE_RUNNING 4 diff --git a/include/variables.h b/include/variables.h index 429e1a775e..392b58d738 100644 --- a/include/variables.h +++ b/include/variables.h @@ -208,7 +208,6 @@ extern volatile OSTime gRSPAudioTotalTime; extern volatile OSTime gRSPGFXTotalTime; extern volatile OSTime gRSPOtherTotalTime; extern volatile OSTime gRDPTotalTime; -extern FaultThreadStruct gFaultStruct; extern ActiveSound gActiveSounds[7][MAX_CHANNELS_PER_BANK]; // total size = 0xA8 extern u8 gSoundBankMuted[]; diff --git a/include/vt.h b/include/vt.h index 46cbf05e73..4f7c73641e 100644 --- a/include/vt.h +++ b/include/vt.h @@ -1,16 +1,15 @@ #ifndef VT_H #define VT_H +// 3-bit color codes #define VT_COLOR_BLACK 0 #define VT_COLOR_RED 1 #define VT_COLOR_GREEN 2 #define VT_COLOR_YELLOW 3 #define VT_COLOR_BLUE 4 -#define VT_COLOR_PURPLE 5 +#define VT_COLOR_MAGENTA 5 #define VT_COLOR_CYAN 6 #define VT_COLOR_WHITE 7 -#define VT_COLOR_LIGHTGRAY 8 -#define VT_COLOR_DARKGRAY 9 #define VT_COLOR_FOREGROUND 3 #define VT_COLOR_BACKGROUND 4 diff --git a/include/z64.h b/include/z64.h index 9483483f98..4fb0f5c47c 100644 --- a/include/z64.h +++ b/include/z64.h @@ -29,6 +29,9 @@ #include "color.h" #include "ichain.h" #include "regs.h" +#include "irqmgr.h" +#include "padmgr.h" +#include "fault.h" #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 @@ -145,13 +148,6 @@ typedef struct GraphicsContext { /* 0x02FC */ char unk_2FC[0x04]; } GraphicsContext; // size = 0x300 -typedef struct { - /* 0x00 */ OSContPad cur; - /* 0x06 */ OSContPad prev; - /* 0x0C */ OSContPad press; // X/Y store delta from last frame - /* 0x12 */ OSContPad rel; // X/Y store adjusted -} Input; // size = 0x18 - typedef struct { /* 0x0000 */ s32 topY; // uly (upper left y) /* 0x0004 */ s32 bottomY; // lry (lower right y) @@ -1452,73 +1448,6 @@ typedef enum { MTXMODE_APPLY // applies transformation to the current matrix } MatrixMode; -typedef struct FaultClient { - /* 0x00 */ struct FaultClient* next; - /* 0x04 */ u32 callback; - /* 0x08 */ u32 param1; - /* 0x0C */ u32 param2; -} FaultClient; // size = 0x10 - -typedef struct FaultAddrConvClient { - /* 0x00 */ struct FaultAddrConvClient* next; - /* 0x04 */ u32 callback; - /* 0x08 */ u32 param; -} FaultAddrConvClient; // size = 0xC - - -typedef struct { - /* 0x00 */ u32 (*callback)(u32, u32); - /* 0x04 */ u32 param0; - /* 0x08 */ u32 param1; - /* 0x0C */ u32 ret; - /* 0x10 */ OSMesgQueue* queue; - /* 0x14 */ OSMesg msg; -} FaultClientContext; // size = 0x18 - -typedef struct FaultThreadStruct { - /* 0x000 */ OSThread thread; - /* 0x1B0 */ u8 unk_1B0[0x600]; - /* 0x7B0 */ OSMesgQueue queue; - /* 0x7C8 */ OSMesg msg; - /* 0x7CC */ u8 exitDebugger; - /* 0x7CD */ u8 msgId; - /* 0x7CE */ u8 faultHandlerEnabled; - /* 0x7CF */ u8 faultActive; - /* 0x7D0 */ OSThread* faultedThread; - /* 0x7D4 */ void(*padCallback)(Input*); - /* 0x7D8 */ FaultClient* clients; - /* 0x7DC */ FaultAddrConvClient* addrConvClients; - /* 0x7E0 */ u8 unk_7E0[4]; - /* 0x7E4 */ Input padInput; - /* 0x7FC */ u16 colors[36]; - /* 0x844 */ void* fb; - /* 0x848 */ u32 currClientThreadSp; - /* 0x84C */ u8 unk_84C[4]; -} FaultThreadStruct; // size = 0x850 - -typedef struct { - /* 0x00 */ u16* fb; - /* 0x04 */ u16 w; - /* 0x08 */ u16 h; - /* 0x0A */ u16 yStart; - /* 0x0C */ u16 yEnd; - /* 0x0E */ u16 xStart; - /* 0x10 */ u16 xEnd; - /* 0x12 */ u16 foreColor; - /* 0x14 */ u16 backColor; - /* 0x14 */ u16 cursorX; - /* 0x16 */ u16 cursorY; - /* 0x18 */ const u32* fontData; - /* 0x1C */ u8 charW; - /* 0x1D */ u8 charH; - /* 0x1E */ s8 charWPad; - /* 0x1F */ s8 charHPad; - /* 0x20 */ u16 printColors[10]; - /* 0x34 */ u8 escCode; // bool - /* 0x35 */ u8 osSyncPrintfEnabled; - /* 0x38 */ void(*inputCallback)(); -} FaultDrawer; // size = 0x3C - typedef struct { /* 0x00 */ PrintCallback callback; /* 0x04 */ Gfx* dList; @@ -1595,57 +1524,6 @@ typedef struct { /* 0x10 */ u32 data[1]; } Yaz0Header; // size = 0x10 ("data" is not part of the header) -typedef struct { - /* 0x00 */ s16 type; - /* 0x02 */ char misc[0x1E]; -} OSScMsg; // size = 0x20 - -typedef struct IrqMgrClient { - /* 0x00 */ struct IrqMgrClient* prev; - /* 0x04 */ OSMesgQueue* queue; -} IrqMgrClient; - -typedef struct { - /* 0x000 */ OSScMsg retraceMsg; // this apparently got moved from OSSched - /* 0x020 */ OSScMsg prenmiMsg; // this apparently got moved from OSSched - /* 0x040 */ OSScMsg nmiMsg; - /* 0x060 */ OSMesgQueue queue; - /* 0x078 */ OSMesg msgBuf[8]; - /* 0x098 */ OSThread thread; - /* 0x248 */ IrqMgrClient* clients; - /* 0x24C */ u8 resetStatus; - /* 0x250 */ OSTime resetTime; - /* 0x258 */ OSTimer timer; - /* 0x278 */ OSTime retraceTime; -} IrqMgr; // size = 0x280 - -typedef struct PadMgr { - /* 0x0000 */ OSContStatus padStatus[4]; - /* 0x0010 */ OSMesg serialMsgBuf[1]; - /* 0x0014 */ OSMesg lockMsgBuf[1]; - /* 0x0018 */ OSMesg interruptMsgBuf[4]; - /* 0x0028 */ OSMesgQueue serialMsgQ; - /* 0x0040 */ OSMesgQueue lockMsgQ; - /* 0x0058 */ OSMesgQueue interruptMsgQ; - /* 0x0070 */ IrqMgrClient irqClient; - /* 0x0078 */ IrqMgr* irqMgr; - /* 0x0080 */ OSThread thread; - /* 0x0230 */ Input inputs[4]; - /* 0x0290 */ OSContPad pads[4]; - /* 0x02A8 */ vu8 validCtrlrsMask; - /* 0x02A9 */ u8 nControllers; - /* 0x02AA */ u8 ctrlrIsConnected[4]; // "Key_switch" originally - /* 0x02AE */ u8 pakType[4]; // 1 if rumble pack, 2 if mempak? - /* 0x02B2 */ vu8 rumbleEnable[4]; - /* 0x02B6 */ u8 rumbleCounter[4]; // not clear exact meaning - /* 0x02BC */ OSPfs pfs[4]; - /* 0x045C */ vu8 rumbleOffFrames; - /* 0x045D */ vu8 rumbleOnFrames; - /* 0x045E */ u8 preNMIShutdown; - /* 0x0460 */ void (*retraceCallback)(struct PadMgr* padmgr, s32 unk464); - /* 0x0464 */ u32 retraceCallbackValue; -} PadMgr; // size = 0x468 - // == Previously sched.h #define OS_SC_NEEDS_RDP 0x0001 diff --git a/src/code/audio_heap.c b/src/code/audio_heap.c index ba398c5c44..b81a5fc761 100644 --- a/src/code/audio_heap.c +++ b/src/code/audio_heap.c @@ -989,7 +989,7 @@ void AudioHeap_Init(void) { AudioLoad_InitAsyncLoads(); gAudioContext.unk_4 = 0x1000; AudioLoad_LoadPermanentSamples(); - intMask = osSetIntMask(1); + intMask = osSetIntMask(OS_IM_NONE); osWritebackDCacheAll(); osSetIntMask(intMask); } diff --git a/src/code/code_800E6840.c b/src/code/code_800E6840.c index 129502b529..caaaea3323 100644 --- a/src/code/code_800E6840.c +++ b/src/code/code_800E6840.c @@ -1,14 +1,14 @@ #include "global.h" void Audio_InvalDCache(void* buf, s32 size) { - OSIntMask prevMask = osSetIntMask(1); + OSIntMask prevMask = osSetIntMask(OS_IM_NONE); osInvalDCache(buf, size); osSetIntMask(prevMask); } void Audio_WritebackDCache(void* buf, s32 size) { - OSIntMask prevMask = osSetIntMask(1); + OSIntMask prevMask = osSetIntMask(OS_IM_NONE); osWritebackDCache(buf, size); osSetIntMask(prevMask); diff --git a/src/code/fault.c b/src/code/fault.c index 3897ba858b..e68ab9a26b 100644 --- a/src/code/fault.c +++ b/src/code/fault.c @@ -1,8 +1,56 @@ +/** + * @file fault.c + * + * This file implements the screen that may be viewed when the game crashes. + * This is the second version of the crash screen, originally used in Majora's Mask. + * + * When the game crashes, a red bar will be drawn to the top-left of the screen, indicating that the + * crash screen is available for use. Once this bar appears, it is possible to open the crash screen + * with the following button combination: + * + * (L & R & Z) + DPad-Up + C-Down + C-Up + DPad-Down + DPad-Left + C-Left + C-Right + DPad-Right + (B & A & START) + * + * When entering this button combination, buttons that are &'d together must all be pressed together. + * The L & R presses and B & A presses may be interchanged in the order they are pressed. + * + * "Clients" may be registered with the crash screen to extend its functionality. There are + * two kinds of client, "Client" and "AddressConverterClient". Clients contribute one or + * more pages to the crash debugger, while Address Converter Clients allow the crash screen to look up + * the virtual addresses of dynamically allocated overlays. + * + * The crash screen has multiple pages: + * - Thread Context + * This page shows information about the thread on which the program crashed. It displays + * the cause of the crash, state of general-purpose registers, state of floating-point registers + * and the floating-point status register. If a floating-point exception caused the crash, it will + * be displayed next to the floating-point status register. + * - Stack Trace + * This page displays a full backtrace from the crashing function back to the start of the thread. It + * displays the Program Counter for each function and, if applicable, the Virtual Program Counter + * for relocated functions in overlays. + * - Client Pages + * After the stack trace page, currently registered clients are processed and their pages are displayed. + * - Memory Dump + * This page implements a scrollable memory dump. + * - End Screen + * This page informs you that there are no more pages to display. + * + * To navigate the pages, START and A may be used to advance to the next page, and L toggles whether to + * automatically scroll to the next page after some time has passed. + * DPad-Up may be pressed to enable sending fault pages over osSyncPrintf as well as displaying them on-screen. + * DPad-Down disables sending fault pages over osSyncPrintf. + */ #include "global.h" #include "vt.h" #include "alloca.h" -// data +void FaultDrawer_Init(void); +void FaultDrawer_SetOsSyncPrintfEnabled(u32 enabled); +void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 color); +void FaultDrawer_FillScreen(void); +void FaultDrawer_SetInputCallback(void (*callback)(void)); +void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h); + const char* sExceptionNames[] = { "Interrupt", "TLB modification", @@ -22,119 +70,140 @@ const char* sExceptionNames[] = { "Floating point exception", "Watchpoint exception", "Virtual coherency on data", - "Unimplemented operation", - "Invalid operation", - "Division by zero", - "Overflow", - "Underflow", - "Inexact operation", }; -// bss -extern FaultThreadStruct* sFaultStructPtr; -extern u8 sFaultIsWaitingForInput; +const char* sFpExceptionNames[] = { + "Unimplemented operation", "Invalid operation", "Division by zero", "Overflow", "Underflow", "Inexact operation", +}; + +// TODO: import .bss (has reordering issues) +extern FaultMgr* sFaultInstance; +extern u8 sFaultAwaitingInput; extern char sFaultStack[0x600]; extern StackEntry sFaultThreadInfo; -extern FaultThreadStruct gFaultStruct; +extern FaultMgr gFaultMgr; -void Fault_SleepImpl(u32 duration) { - u64 value = (duration * OS_CPU_COUNTER) / 1000ull; +typedef struct { + /* 0x00 */ s32 (*callback)(void*, void*); + /* 0x04 */ void* arg0; + /* 0x08 */ void* arg1; + /* 0x0C */ s32 ret; + /* 0x10 */ OSMesgQueue* queue; + /* 0x14 */ OSMesg msg; +} FaultClientTask; // size = 0x18 - Sleep_Cycles(value); +void Fault_SleepImpl(u32 msec) { + u64 cycles = (msec * OS_CPU_COUNTER) / 1000ull; + + Sleep_Cycles(cycles); } void Fault_ClientProcessThread(void* arg) { - FaultClientContext* ctx = (FaultClientContext*)arg; + FaultClientTask* task = (FaultClientTask*)arg; - if (ctx->callback != 0) { - ctx->ret = ctx->callback(ctx->param0, ctx->param1); + // Run the callback + if (task->callback != NULL) { + task->ret = task->callback(task->arg0, task->arg1); } - if (ctx->queue != NULL) { - osSendMesg(ctx->queue, ctx->msg, OS_MESG_BLOCK); + // Send completion notification + if (task->queue != NULL) { + osSendMesg(task->queue, task->msg, OS_MESG_BLOCK); } } -void Fault_ProcessClientContext(FaultClientContext* ctx) { +void Fault_ClientRunTask(FaultClientTask* task) { OSMesgQueue queue; OSMesg msg; OSMesg recMsg; - OSThread* thread; + OSThread* thread = NULL; OSTimer timer; - u32 timerMsgVal; - - timerMsgVal = 666; - thread = NULL; + u32 timerMsgVal = 666; osCreateMesgQueue(&queue, &msg, 1); - ctx->queue = &queue; - ctx->msg = NULL; + task->queue = &queue; + task->msg = NULL; - if (sFaultStructPtr->currClientThreadSp != 0) { + if (sFaultInstance->clientThreadSp != NULL) { + // Run the fault client callback on a separate thread thread = alloca(sizeof(OSThread)); - osCreateThread(thread, 2, Fault_ClientProcessThread, ctx, sFaultStructPtr->currClientThreadSp, + + osCreateThread(thread, 2, Fault_ClientProcessThread, task, sFaultInstance->clientThreadSp, OS_PRIORITY_APPMAX - 1); osStartThread(thread); } else { - Fault_ClientProcessThread(ctx); + // Run the fault client callback on this thread + Fault_ClientProcessThread(task); } + // Await done while (true) { - osSetTimer(&timer, OS_USEC_TO_CYCLES(1000000), 0, &queue, (OSMesg)timerMsgVal); + osSetTimer(&timer, OS_SEC_TO_CYCLES(1), 0, &queue, (OSMesg)timerMsgVal); osRecvMesg(&queue, &recMsg, OS_MESG_BLOCK); if (recMsg != (OSMesg)666) { break; } - if (!sFaultIsWaitingForInput) { - ctx->ret = -1; + if (!sFaultAwaitingInput) { + task->ret = -1; break; } } osStopTimer(&timer); + // Destroy thread if a thread was used if (thread != NULL) { osStopThread(thread); osDestroyThread(thread); } } -u32 Fault_ProcessClient(u32 callback, u32 param0, u32 param1) { - FaultClientContext a; +s32 Fault_ProcessClient(void* callback, void* arg0, void* arg1) { + FaultClientTask task; - a.callback = callback; - a.param0 = param0; - a.param1 = param1; - a.ret = 0; - Fault_ProcessClientContext(&a); - return a.ret; + task.callback = callback; + task.arg0 = arg0; + task.arg1 = arg1; + task.ret = 0; + Fault_ClientRunTask(&task); + return task.ret; } -void Fault_AddClient(FaultClient* client, void* callback, void* param0, void* param1) { +/** + * Registers a fault client. + * + * Clients contribute at least one page to the crash screen, drawn by `callback`. + * Arguments are passed on to the callback through `arg0` and `arg1`. + * + * The callback is intended to be + * `void (*callback)(void* arg0, void* arg1)` + */ +void Fault_AddClient(FaultClient* client, void* callback, void* arg0, void* arg1) { OSIntMask mask; s32 alreadyExists = false; - mask = osSetIntMask(1); + mask = osSetIntMask(OS_IM_NONE); + // Ensure the client is not already registered { - FaultClient* iter = sFaultStructPtr->clients; + FaultClient* iterClient = sFaultInstance->clients; - while (iter != NULL) { - if (iter == client) { + while (iterClient != NULL) { + if (iterClient == client) { alreadyExists = true; goto end; } - iter = iter->next; + iterClient = iterClient->next; } } client->callback = callback; - client->param1 = param0; - client->param2 = param1; - client->next = sFaultStructPtr->clients; - sFaultStructPtr->clients = client; + client->arg0 = arg0; + client->arg1 = arg1; + client->next = sFaultInstance->clients; + sFaultInstance->clients = client; end: osSetIntMask(mask); @@ -143,35 +212,33 @@ end: } } +/** + * Removes a fault client so that the page is no longer displayed if a crash occurs. + */ void Fault_RemoveClient(FaultClient* client) { - FaultClient* iter; - FaultClient* lastIter; + FaultClient* iterClient = sFaultInstance->clients; + FaultClient* lastClient = NULL; OSIntMask mask; - u32 listIsEmpty; + s32 listIsEmpty = false; - iter = sFaultStructPtr->clients; - listIsEmpty = 0; - lastIter = NULL; + mask = osSetIntMask(OS_IM_NONE); - mask = osSetIntMask(1); - - while (iter != NULL) { - if (iter == client) { - if (lastIter != NULL) { - lastIter->next = client->next; + while (iterClient != NULL) { + if (iterClient == client) { + if (lastClient != NULL) { + lastClient->next = client->next; } else { - sFaultStructPtr->clients = client; - if (sFaultStructPtr->clients) { - sFaultStructPtr->clients = client->next; + sFaultInstance->clients = client; + if (sFaultInstance->clients) { + sFaultInstance->clients = client->next; } else { - listIsEmpty = 1; + listIsEmpty = true; } } break; } - - lastIter = iter; - iter = iter->next; + lastClient = iterClient; + iterClient = iterClient->next; } osSetIntMask(mask); @@ -181,28 +248,40 @@ void Fault_RemoveClient(FaultClient* client) { } } -void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* param) { +/** + * Registers an address converter client. This enables the crash screen to look up virtual + * addresses of overlays relocated during runtime. Address conversion is carried out by + * `callback`, which either returns a virtual address or NULL if the address could not + * be converted. + * + * The callback is intended to be + * `uintptr_t (*callback)(uintptr_t addr, void* arg)` + * The callback may return 0 if it could not convert the address + * The callback may return -1 to be unregistered + */ +void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* arg) { OSIntMask mask; - u32 alreadyExists = false; + s32 alreadyExists = false; - mask = osSetIntMask(1); + mask = osSetIntMask(OS_IM_NONE); + // Ensure the client is not already registered { - FaultAddrConvClient* iter = sFaultStructPtr->addrConvClients; + FaultAddrConvClient* iterClient = sFaultInstance->addrConvClients; - while (iter != NULL) { - if (iter == client) { + while (iterClient != NULL) { + if (iterClient == client) { alreadyExists = true; goto end; } - iter = iter->next; + iterClient = iterClient->next; } } client->callback = callback; - client->param = param; - client->next = sFaultStructPtr->addrConvClients; - sFaultStructPtr->addrConvClients = client; + client->arg = arg; + client->next = sFaultInstance->addrConvClients; + sFaultInstance->addrConvClients = client; end: osSetIntMask(mask); @@ -212,34 +291,30 @@ end: } void Fault_RemoveAddrConvClient(FaultAddrConvClient* client) { - FaultAddrConvClient* iter; - FaultAddrConvClient* lastIter; + FaultAddrConvClient* iterClient = sFaultInstance->addrConvClients; + FaultAddrConvClient* lastClient = NULL; OSIntMask mask; - u32 listIsEmpty; + s32 listIsEmpty = false; - iter = sFaultStructPtr->addrConvClients; - listIsEmpty = 0; - lastIter = NULL; + mask = osSetIntMask(OS_IM_NONE); - mask = osSetIntMask(1); - - while (iter != NULL) { - if (iter == client) { - if (lastIter != NULL) { - lastIter->next = client->next; + while (iterClient != NULL) { + if (iterClient == client) { + if (lastClient != NULL) { + lastClient->next = client->next; } else { - sFaultStructPtr->addrConvClients = client; - if (sFaultStructPtr->addrConvClients != NULL) { - sFaultStructPtr->addrConvClients = client->next; + sFaultInstance->addrConvClients = client; + + if (sFaultInstance->addrConvClients != NULL) { + sFaultInstance->addrConvClients = client->next; } else { - listIsEmpty = 1; + listIsEmpty = true; } } break; } - - lastIter = iter; - iter = iter->next; + lastClient = iterClient; + iterClient = iterClient->next; } osSetIntMask(mask); @@ -250,135 +325,157 @@ void Fault_RemoveAddrConvClient(FaultAddrConvClient* client) { } } -u32 Fault_ConvertAddress(FaultAddrConvClient* client) { - u32 ret; - FaultAddrConvClient* iter = sFaultStructPtr->addrConvClients; +/** + * Converts `addr` to a virtual address via the registered + * address converter clients + */ +uintptr_t Fault_ConvertAddress(uintptr_t addr) { + s32 ret; + FaultAddrConvClient* client = sFaultInstance->addrConvClients; - while (iter != NULL) { - if (iter->callback != 0) { - ret = Fault_ProcessClient(iter->callback, client, iter->param); - if ((s32)ret == -1) { - Fault_RemoveAddrConvClient(iter); + while (client != NULL) { + if (client->callback != NULL) { + ret = Fault_ProcessClient(client->callback, addr, client->arg); + if (ret == -1) { + Fault_RemoveAddrConvClient(client); } else if (ret != 0) { - return ret; + return (uintptr_t)ret; } } - iter = iter->next; + client = client->next; } return 0; } -void Fault_Sleep(u32 duration) { - Fault_SleepImpl(duration); +void Fault_Sleep(u32 msec) { + Fault_SleepImpl(msec); } +void PadMgr_RequestPadData(Input* input, s32 mode); + void Fault_PadCallback(Input* input) { - //! @bug This function is not called correctly and thus will crash from reading a bad pointer at 0x800C7E4C + //! @bug This function is not called correctly, it is missing a leading PadMgr* argument. This + //! renders the crash screen unusable. + //! In Majora's Mask, PadMgr functions were changed to not require this argument, and this was + //! likely just not addressed when backporting. PadMgr_RequestPadData(input, 0); } -void Fault_UpdatePadImpl() { - sFaultStructPtr->padCallback(&sFaultStructPtr->padInput); +void Fault_UpdatePadImpl(void) { + sFaultInstance->padCallback(&sFaultInstance->padInput); } -u32 Fault_WaitForInputImpl() { - Input* input = &sFaultStructPtr->padInput; +/** + * Awaits user input + * + * L toggles auto-scroll + * DPad-Up enables osSyncPrintf output + * DPad-Down disables osSyncPrintf output + * A and DPad-Right continues and returns true + * DPad-Left continues and returns false + */ +u32 Fault_WaitForInputImpl(void) { + Input* input = &sFaultInstance->padInput; s32 count = 600; - u32 kDown; + u32 pressedBtn; while (true) { - Fault_Sleep(0x10); + Fault_Sleep(1000 / 60); Fault_UpdatePadImpl(); - kDown = input->press.button; + pressedBtn = input->press.button; - if (kDown == BTN_L) { - sFaultStructPtr->faultActive = !sFaultStructPtr->faultActive; + if (pressedBtn == BTN_L) { + sFaultInstance->autoScroll = !sFaultInstance->autoScroll; } - if (sFaultStructPtr->faultActive) { + if (sFaultInstance->autoScroll) { if (count-- < 1) { return false; } } else { - if (kDown == BTN_A || kDown == BTN_DRIGHT) { + if (pressedBtn == BTN_A || pressedBtn == BTN_DRIGHT) { return false; } - if (kDown == BTN_DLEFT) { + if (pressedBtn == BTN_DLEFT) { return true; } - if (kDown == BTN_DUP) { + if (pressedBtn == BTN_DUP) { FaultDrawer_SetOsSyncPrintfEnabled(true); } - if (kDown == BTN_DDOWN) { + if (pressedBtn == BTN_DDOWN) { FaultDrawer_SetOsSyncPrintfEnabled(false); } } } } -void Fault_WaitForInput() { - sFaultIsWaitingForInput = 1; +void Fault_WaitForInput(void) { + sFaultAwaitingInput = true; Fault_WaitForInputImpl(); - sFaultIsWaitingForInput = 0; + sFaultAwaitingInput = false; } void Fault_DrawRec(s32 x, s32 y, s32 w, s32 h, u16 color) { FaultDrawer_DrawRecImpl(x, y, x + w - 1, y + h - 1, color); } -void Fault_FillScreenBlack() { - FaultDrawer_SetForeColor(0xFFFF); - FaultDrawer_SetBackColor(1); +void Fault_FillScreenBlack(void) { + FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1)); + FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 1)); FaultDrawer_FillScreen(); - FaultDrawer_SetBackColor(0); + FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 0)); } -void Fault_FillScreenRed() { - FaultDrawer_SetForeColor(0xFFFF); - FaultDrawer_SetBackColor(0xF001); +void Fault_FillScreenRed(void) { + FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1)); + FaultDrawer_SetBackColor(GPACK_RGBA5551(240, 0, 0, 1)); FaultDrawer_FillScreen(); - FaultDrawer_SetBackColor(0); + FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 0)); } void Fault_DrawCornerRec(u16 color) { - Fault_DrawRec(0x16, 0x10, 8, 1, color); + Fault_DrawRec(22, 16, 8, 1, color); } void Fault_PrintFReg(s32 idx, f32* value) { u32 raw = *(u32*)value; - s32 v0 = ((raw & 0x7F800000) >> 0x17) - 0x7F; + s32 exp = ((raw & 0x7F800000) >> 0x17) - 0x7F; - if ((v0 >= -0x7E && v0 < 0x80) || raw == 0) { + if ((exp >= -0x7E && exp < 0x80) || raw == 0) { FaultDrawer_Printf("F%02d:%14.7e ", idx, *value); } else { + // Print subnormal floats as their ieee-754 hex representation FaultDrawer_Printf("F%02d: %08x(16) ", idx, raw); } } void Fault_LogFReg(s32 idx, f32* value) { u32 raw = *(u32*)value; - s32 v0 = ((raw & 0x7F800000) >> 0x17) - 0x7F; + s32 exp = ((raw & 0x7F800000) >> 0x17) - 0x7F; - if ((v0 >= -0x7E && v0 < 0x80) || raw == 0) { + if ((exp >= -0x7E && exp < 0x80) || raw == 0) { osSyncPrintf("F%02d:%14.7e ", idx, *value); } else { osSyncPrintf("F%02d: %08x(16) ", idx, *(u32*)value); } } -void Fault_PrintFPCR(u32 value) { +void Fault_PrintFPCSR(u32 value) { s32 i; - u32 flag = 0x20000; + u32 flag = FPCSR_CE; FaultDrawer_Printf("FPCSR:%08xH ", value); - for (i = 0; i < 6; i++) { + + // Go through each of the six causes and print the name of + // the first cause that is set + for (i = 0; i < ARRAY_COUNT(sFpExceptionNames); i++) { if (value & flag) { - FaultDrawer_Printf("(%s)", sExceptionNames[i + 18]); + FaultDrawer_Printf("(%s)", sFpExceptionNames[i]); break; } flag >>= 1; @@ -386,37 +483,37 @@ void Fault_PrintFPCR(u32 value) { FaultDrawer_Printf("\n"); } -void Fault_LogFPCR(u32 value) { +void Fault_LogFPCSR(u32 value) { s32 i; - u32 flag = 0x20000; + u32 flag = FPCSR_CE; osSyncPrintf("FPCSR:%08xH ", value); - for (i = 0; i < 6; i++) { + for (i = 0; i < ARRAY_COUNT(sFpExceptionNames); i++) { if (value & flag) { - osSyncPrintf("(%s)\n", sExceptionNames[i + 18]); + osSyncPrintf("(%s)\n", sFpExceptionNames[i]); break; } flag >>= 1; } } -void Fault_PrintThreadContext(OSThread* t) { +void Fault_PrintThreadContext(OSThread* thread) { __OSThreadContext* ctx; - s32 causeStrIdx = (s32)((((u32)t->context.cause >> 2) & 0x1F) << 0x10) >> 0x10; + s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5); - if (causeStrIdx == 0x17) { - causeStrIdx = 0x10; + if (causeStrIdx == 23) { // Watchpoint + causeStrIdx = 16; } - if (causeStrIdx == 0x1F) { - causeStrIdx = 0x11; + if (causeStrIdx == 31) { // Virtual coherency on data + causeStrIdx = 17; } FaultDrawer_FillScreen(); FaultDrawer_SetCharPad(-2, 4); - FaultDrawer_SetCursor(0x16, 0x14); + FaultDrawer_SetCursor(22, 20); - ctx = &t->context; - FaultDrawer_Printf("THREAD:%d (%d:%s)\n", t->id, causeStrIdx, sExceptionNames[causeStrIdx]); + ctx = &thread->context; + FaultDrawer_Printf("THREAD:%d (%d:%s)\n", thread->id, causeStrIdx, sExceptionNames[causeStrIdx]); FaultDrawer_SetCharPad(-1, 0); FaultDrawer_Printf("PC:%08xH SR:%08xH VA:%08xH\n", (u32)ctx->pc, (u32)ctx->sr, (u32)ctx->badvaddr); @@ -431,8 +528,9 @@ void Fault_PrintThreadContext(OSThread* t) { FaultDrawer_Printf("T9:%08xH GP:%08xH SP:%08xH\n", (u32)ctx->t9, (u32)ctx->gp, (u32)ctx->sp); FaultDrawer_Printf("S8:%08xH RA:%08xH LO:%08xH\n\n", (u32)ctx->s8, (u32)ctx->ra, (u32)ctx->lo); - Fault_PrintFPCR(ctx->fpcsr); + Fault_PrintFPCSR(ctx->fpcsr); FaultDrawer_Printf("\n"); + Fault_PrintFReg(0, &ctx->fp0.f.f_even); Fault_PrintFReg(2, &ctx->fp2.f.f_even); FaultDrawer_Printf("\n"); @@ -440,40 +538,41 @@ void Fault_PrintThreadContext(OSThread* t) { Fault_PrintFReg(6, &ctx->fp6.f.f_even); FaultDrawer_Printf("\n"); Fault_PrintFReg(8, &ctx->fp8.f.f_even); - Fault_PrintFReg(0xA, &ctx->fp10.f.f_even); + Fault_PrintFReg(10, &ctx->fp10.f.f_even); FaultDrawer_Printf("\n"); - Fault_PrintFReg(0xC, &ctx->fp12.f.f_even); - Fault_PrintFReg(0xE, &ctx->fp14.f.f_even); + Fault_PrintFReg(12, &ctx->fp12.f.f_even); + Fault_PrintFReg(14, &ctx->fp14.f.f_even); FaultDrawer_Printf("\n"); - Fault_PrintFReg(0x10, &ctx->fp16.f.f_even); - Fault_PrintFReg(0x12, &ctx->fp18.f.f_even); + Fault_PrintFReg(16, &ctx->fp16.f.f_even); + Fault_PrintFReg(18, &ctx->fp18.f.f_even); FaultDrawer_Printf("\n"); - Fault_PrintFReg(0x14, &ctx->fp20.f.f_even); - Fault_PrintFReg(0x16, &ctx->fp22.f.f_even); + Fault_PrintFReg(20, &ctx->fp20.f.f_even); + Fault_PrintFReg(22, &ctx->fp22.f.f_even); FaultDrawer_Printf("\n"); - Fault_PrintFReg(0x18, &ctx->fp24.f.f_even); - Fault_PrintFReg(0x1A, &ctx->fp26.f.f_even); + Fault_PrintFReg(24, &ctx->fp24.f.f_even); + Fault_PrintFReg(26, &ctx->fp26.f.f_even); FaultDrawer_Printf("\n"); - Fault_PrintFReg(0x1C, &ctx->fp28.f.f_even); - Fault_PrintFReg(0x1E, &ctx->fp30.f.f_even); + Fault_PrintFReg(28, &ctx->fp28.f.f_even); + Fault_PrintFReg(30, &ctx->fp30.f.f_even); FaultDrawer_Printf("\n"); + FaultDrawer_SetCharPad(0, 0); } -void Fault_LogThreadContext(OSThread* t) { +void Fault_LogThreadContext(OSThread* thread) { __OSThreadContext* ctx; - s32 causeStrIdx = (s32)((((u32)t->context.cause >> 2) & 0x1F) << 0x10) >> 0x10; + s16 causeStrIdx = _SHIFTR((u32)thread->context.cause, 2, 5); - if (causeStrIdx == 0x17) { - causeStrIdx = 0x10; + if (causeStrIdx == 23) { // Watchpoint + causeStrIdx = 16; } - if (causeStrIdx == 0x1F) { - causeStrIdx = 0x11; + if (causeStrIdx == 31) { // Virtual coherency on data + causeStrIdx = 17; } - ctx = &t->context; + ctx = &thread->context; osSyncPrintf("\n"); - osSyncPrintf("THREAD ID:%d (%d:%s)\n", t->id, causeStrIdx, sExceptionNames[causeStrIdx]); + osSyncPrintf("THREAD ID:%d (%d:%s)\n", thread->id, causeStrIdx, sExceptionNames[causeStrIdx]); osSyncPrintf("PC:%08xH SR:%08xH VA:%08xH\n", (u32)ctx->pc, (u32)ctx->sr, (u32)ctx->badvaddr); osSyncPrintf("AT:%08xH V0:%08xH V1:%08xH\n", (u32)ctx->at, (u32)ctx->v0, (u32)ctx->v1); @@ -487,8 +586,10 @@ void Fault_LogThreadContext(OSThread* t) { osSyncPrintf("T9:%08xH GP:%08xH SP:%08xH\n", (u32)ctx->t9, (u32)ctx->gp, (u32)ctx->sp); osSyncPrintf("S8:%08xH RA:%08xH LO:%08xH\n", (u32)ctx->s8, (u32)ctx->ra, (u32)ctx->lo); osSyncPrintf("\n"); - Fault_LogFPCR(ctx->fpcsr); + + Fault_LogFPCSR(ctx->fpcsr); osSyncPrintf("\n"); + Fault_LogFReg(0, &ctx->fp0.f.f_even); Fault_LogFReg(2, &ctx->fp2.f.f_even); osSyncPrintf("\n"); @@ -496,55 +597,66 @@ void Fault_LogThreadContext(OSThread* t) { Fault_LogFReg(6, &ctx->fp6.f.f_even); osSyncPrintf("\n"); Fault_LogFReg(8, &ctx->fp8.f.f_even); - Fault_LogFReg(0xA, &ctx->fp10.f.f_even); + Fault_LogFReg(10, &ctx->fp10.f.f_even); osSyncPrintf("\n"); - Fault_LogFReg(0xC, &ctx->fp12.f.f_even); - Fault_LogFReg(0xE, &ctx->fp14.f.f_even); + Fault_LogFReg(12, &ctx->fp12.f.f_even); + Fault_LogFReg(14, &ctx->fp14.f.f_even); osSyncPrintf("\n"); - Fault_LogFReg(0x10, &ctx->fp16.f.f_even); - Fault_LogFReg(0x12, &ctx->fp18.f.f_even); + Fault_LogFReg(16, &ctx->fp16.f.f_even); + Fault_LogFReg(18, &ctx->fp18.f.f_even); osSyncPrintf("\n"); - Fault_LogFReg(0x14, &ctx->fp20.f.f_even); - Fault_LogFReg(0x16, &ctx->fp22.f.f_even); + Fault_LogFReg(20, &ctx->fp20.f.f_even); + Fault_LogFReg(22, &ctx->fp22.f.f_even); osSyncPrintf("\n"); - Fault_LogFReg(0x18, &ctx->fp24.f.f_even); - Fault_LogFReg(0x1A, &ctx->fp26.f.f_even); + Fault_LogFReg(24, &ctx->fp24.f.f_even); + Fault_LogFReg(26, &ctx->fp26.f.f_even); osSyncPrintf("\n"); - Fault_LogFReg(0x1C, &ctx->fp28.f.f_even); - Fault_LogFReg(0x1E, &ctx->fp30.f.f_even); + Fault_LogFReg(28, &ctx->fp28.f.f_even); + Fault_LogFReg(30, &ctx->fp30.f.f_even); osSyncPrintf("\n"); } -OSThread* Fault_FindFaultedThread() { - OSThread* iter = __osGetActiveQueue(); +/** + * Iterates through the active thread queue for a user thread with either + * the CPU break or Fault flag set. + */ +OSThread* Fault_FindFaultedThread(void) { + OSThread* thread = __osGetActiveQueue(); - while (iter->priority != -1) { - if (iter->priority > 0 && iter->priority < 0x7F && (iter->flags & 3)) { - return iter; + // OS_PRIORITY_THREADTAIL indicates the end of the thread queue + while (thread->priority != OS_PRIORITY_THREADTAIL) { + if (thread->priority > OS_PRIORITY_IDLE && thread->priority < OS_PRIORITY_APPMAX && + (thread->flags & (OS_FLAG_CPU_BREAK | OS_FLAG_FAULT))) { + return thread; } - iter = iter->tlnext; + thread = thread->tlnext; } return NULL; } void Fault_Wait5Seconds(void) { - OSTime start[2]; // to make the function allocate 0x28 bytes of stack instead of 0x20 + s32 pad; + OSTime start = osGetTime(); - start[0] = osGetTime(); do { - Fault_Sleep(0x10); - } while ((osGetTime() - start[0]) < OS_USEC_TO_CYCLES(5000000) + 1); + Fault_Sleep(1000 / 60); + } while ((osGetTime() - start) < OS_SEC_TO_CYCLES(5) + 1); - sFaultStructPtr->faultActive = true; + sFaultInstance->autoScroll = true; } -void Fault_WaitForButtonCombo() { - Input* input = &sFaultStructPtr->padInput; +/** + * Waits for the following button combination to be entered before returning: + * + * (L & R & Z) + DPad-Up + C-Down + C-Up + DPad-Down + DPad-Left + C-Left + C-Right + DPad-Right + (B & A & START) + */ +void Fault_WaitForButtonCombo(void) { + Input* input = &sFaultInstance->padInput; s32 state; u32 s1; u32 s2; - u32 kDown; - u32 kCur; + u32 pressedBtn; + u32 curBtn; if (1) {} if (1) {} @@ -556,43 +668,43 @@ void Fault_WaitForButtonCombo() { osSyncPrintf(VT_FGCOL(WHITE) "KeyWaitB'(LR左" VT_FGCOL(YELLOW) "右 +" VT_FGCOL(RED) "START" VT_FGCOL( WHITE) ")" VT_RST "\n"); - FaultDrawer_SetForeColor(0xFFFF); - FaultDrawer_SetBackColor(1); + FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1)); + FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 1)); state = 0; s1 = 0; s2 = 1; while (state != 11) { - Fault_Sleep(0x10); + Fault_Sleep(1000 / 60); Fault_UpdatePadImpl(); - kDown = input->press.button; - kCur = input->cur.button; + pressedBtn = input->press.button; + curBtn = input->cur.button; - if ((kCur == 0) && (s1 == s2)) { + if (curBtn == 0 && s1 == s2) { s1 = 0; - } else if (kDown != 0) { + } else if (pressedBtn != 0) { if (s1 == s2) { state = 0; } switch (state) { case 0: - if (kCur == (BTN_Z | BTN_L | BTN_R) && kDown == BTN_Z) { + if (curBtn == (BTN_Z | BTN_L | BTN_R) && pressedBtn == BTN_Z) { state = s2; s1 = s2; } break; case 1: - if (kDown == BTN_DUP) { + if (pressedBtn == BTN_DUP) { state = 2; } else { state = 0; } break; case 2: - if (kDown == BTN_CDOWN) { + if (pressedBtn == BTN_CDOWN) { state = 3; s1 = s2; } else { @@ -600,14 +712,14 @@ void Fault_WaitForButtonCombo() { } break; case 3: - if (kDown == BTN_CUP) { + if (pressedBtn == BTN_CUP) { state = 4; } else { state = 0; } break; case 4: - if (kDown == BTN_DDOWN) { + if (pressedBtn == BTN_DDOWN) { state = 5; s1 = s2; } else { @@ -615,14 +727,14 @@ void Fault_WaitForButtonCombo() { } break; case 5: - if (kDown == BTN_DLEFT) { + if (pressedBtn == BTN_DLEFT) { state = 6; } else { state = 0; } break; case 6: - if (kDown == BTN_CLEFT) { + if (pressedBtn == BTN_CLEFT) { state = 7; s1 = s2; } else { @@ -630,14 +742,14 @@ void Fault_WaitForButtonCombo() { } break; case 7: - if (kDown == BTN_CRIGHT) { + if (pressedBtn == BTN_CRIGHT) { state = 8; } else { state = 0; } break; case 8: - if (kDown == BTN_DRIGHT) { + if (pressedBtn == BTN_DRIGHT) { state = 9; s1 = s2; } else { @@ -645,32 +757,32 @@ void Fault_WaitForButtonCombo() { } break; case 9: - if (kDown == (BTN_A | BTN_B)) { + if (pressedBtn == (BTN_A | BTN_B)) { state = 10; - } else if (kDown == BTN_A) { + } else if (pressedBtn == BTN_A) { state = 0x5B; - } else if (kDown == BTN_B) { + } else if (pressedBtn == BTN_B) { state = 0x5C; } else { state = 0; } break; case 0x5B: - if (kDown == BTN_B) { + if (pressedBtn == BTN_B) { state = 10; } else { state = 0; } break; case 0x5C: - if (kDown == BTN_A) { + if (pressedBtn == BTN_A) { state = 10; } else { state = 0; } break; case 10: - if (kDown == BTN_START) { + if (pressedBtn == BTN_START) { state = 11; } else { state = 0; @@ -683,32 +795,40 @@ void Fault_WaitForButtonCombo() { } } -void Fault_DrawMemDumpPage(const char* title, u32* addr, u32 param_3) { - u32* alignedAddr; +void Fault_DrawMemDumpContents(const char* title, uintptr_t addr, u32 arg2) { + uintptr_t alignedAddr = addr; u32* writeAddr; s32 y; s32 x; - alignedAddr = addr; - - if (alignedAddr < (u32*)0x80000000) { - alignedAddr = (u32*)0x80000000; + // Ensure address is within the bounds of RDRAM (Fault_DrawMemDump has already done this) + if (alignedAddr < K0BASE) { + alignedAddr = K0BASE; } - if (alignedAddr > (u32*)0x807FFF00) { - alignedAddr = (u32*)0x807FFF00; + // 8MB RAM, leave room to display 0x100 bytes on the final page + //! @bug The loop below draws 22 * 4 * 4 = 0x160 bytes per page. Due to this, by scrolling further than + //! 0x807FFEA0 some invalid bytes are read from outside of 8MB RDRAM space. This does not cause a crash, + //! however the values it displays are meaningless. On N64 hardware these invalid addresses are read as 0. + if (alignedAddr > K0BASE + 0x800000 - 0x100) { + alignedAddr = K0BASE + 0x800000 - 0x100; } - alignedAddr = (u32*)((u32)alignedAddr & ~3); - writeAddr = alignedAddr; + // Ensure address is word-aligned + alignedAddr &= ~3; + writeAddr = (u32*)alignedAddr; + + // Reset screen Fault_FillScreenBlack(); FaultDrawer_SetCharPad(-2, 0); - FaultDrawer_DrawText(0x24, 0x12, "%s %08x", title != NULL ? title : "PrintDump", alignedAddr); - if (alignedAddr >= (u32*)0x80000000 && alignedAddr < (u32*)0xC0000000) { - for (y = 0x1C; y != 0xE2; y += 9) { - FaultDrawer_DrawText(0x18, y, "%06x", writeAddr); - for (x = 0x52; x != 0x122; x += 0x34) { - FaultDrawer_DrawText(x, y, "%08x", *writeAddr++); + FaultDrawer_DrawText(36, 18, "%s %08x", title != NULL ? title : "PrintDump", alignedAddr); + + // Draw memory page contents + if (alignedAddr >= K0BASE && alignedAddr < K2BASE) { + for (y = 0; y < 22; y++) { + FaultDrawer_DrawText(24, 28 + y * 9, "%06x", writeAddr); + for (x = 0; x < 4; x++) { + FaultDrawer_DrawText(82 + x * 52, 28 + y * 9, "%08x", *writeAddr++); } } } @@ -716,54 +836,79 @@ void Fault_DrawMemDumpPage(const char* title, u32* addr, u32 param_3) { FaultDrawer_SetCharPad(0, 0); } -void Fault_DrawMemDump(u32 pc, u32 sp, u32 unk0, u32 unk1) { - Input* input = &sFaultStructPtr->padInput; - u32 addr = pc; - s32 count; +/** + * Draws the memory dump page. + * + * DPad-Up scrolls up. + * DPad-Down scrolls down. + * Holding Z while scrolling speeds up scrolling by a factor of 0x10. + * Holding B while scrolling speeds up scrolling by a factor of 0x100. + * + * L toggles auto-scrolling pages. + * START and A move on to the next page. + * + * @param pc Program counter, pressing C-Up jumps to this address + * @param sp Stack pointer, pressing C-Down jumps to this address + * @param cLeftJump Unused parameter, pressing C-Left jumps to this address + * @param cRightJump Unused parameter, pressing C-Right jumps to this address + */ +void Fault_DrawMemDump(uintptr_t pc, uintptr_t sp, uintptr_t cLeftJump, uintptr_t cRightJump) { + Input* input = &sFaultInstance->padInput; + uintptr_t addr = pc; + s32 scrollCountdown; u32 off; do { - count = 0; - if (addr < 0x80000000) { - addr = 0x80000000; + scrollCountdown = 0; + // Ensure address is within the bounds of RDRAM + if (addr < K0BASE) { + addr = K0BASE; } - if (addr > 0x807FFF00) { - addr = 0x807FFF00; + // 8MB RAM, leave room to display 0x100 bytes on the final page + if (addr > K0BASE + 0x800000 - 0x100) { + addr = K0BASE + 0x800000 - 0x100; } + // Align the address to 0x10 bytes and draw the page contents addr &= ~0xF; - Fault_DrawMemDumpPage("Dump", (u32*)addr, 0); - count = 600; + Fault_DrawMemDumpContents("Dump", addr, 0); + scrollCountdown = 600; - while (sFaultStructPtr->faultActive) { - if (count == 0) { + while (sFaultInstance->autoScroll) { + // Count down until it's time to move on to the next page + if (scrollCountdown == 0) { return; } - count--; - Fault_Sleep(0x10); + scrollCountdown--; + Fault_Sleep(1000 / 60); Fault_UpdatePadImpl(); if (CHECK_BTN_ALL(input->press.button, BTN_L)) { - sFaultStructPtr->faultActive = false; + // Disable auto-scrolling + sFaultInstance->autoScroll = false; } } + // Wait for input do { - Fault_Sleep(0x10); + Fault_Sleep(1000 / 60); Fault_UpdatePadImpl(); } while (input->press.button == 0); + // Move to next page if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->cur.button, BTN_A)) { return; } + // Memory dump controls + off = 0x10; if (CHECK_BTN_ALL(input->cur.button, BTN_Z)) { - off = 0x100; + off *= 0x10; } if (CHECK_BTN_ALL(input->cur.button, BTN_B)) { - off <<= 8; + off *= 0x100; } if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) { @@ -779,107 +924,161 @@ void Fault_DrawMemDump(u32 pc, u32 sp, u32 unk0, u32 unk1) { addr = sp; } if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) { - addr = unk0; + addr = cLeftJump; } if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) { - addr = unk1; + addr = cRightJump; } } while (!CHECK_BTN_ALL(input->press.button, BTN_L)); - sFaultStructPtr->faultActive = true; + // Resume auto-scroll and move to next page + sFaultInstance->autoScroll = true; } -void Fault_WalkStack(u32* spPtr, u32* pcPtr, u32* raPtr) { - u32 sp = *spPtr; - u32 pc = *pcPtr; - u32 ra = *raPtr; - s32 count = 0x10000; - u32 lastOpc; - u32 opc; - u16 opcHi; - s16 opcLo; +/** + * Searches a single function's stack frame for the function it was called from. + * There are two cases that must be covered: Leaf and non-leaf functions. + * + * A leaf function is one that does not call any other function, in this case the + * return address need not be saved to the stack. Since a leaf function does not + * call other functions, only the function the stack trace begins in could possibly + * be a leaf function, in which case the return address is in the thread context's + * $ra already, as it never left. + * + * The procedure is therefore + * - Iterate instructions + * - Once jr $ra is found, set pc to $ra + * - Done after delay slot + * + * A non-leaf function calls other functions, it is necessary for the return address + * to be saved to the stack. In these functions, it is important to keep track of the + * stack frame size of each function. + * + * The procedure is therefore + * - Iterate instructions + * - If lw $ra ($sp) is found, fetch the saved $ra from stack memory + * - If addiu $sp, $sp, is found, modify $sp by the immediate value + * - If jr $ra is found, set pc to $ra + * - Done after delay slot + * + * Note that searching for one jr $ra is sufficient, as only leaf functions can have + * multiple jr $ra in the same function. + * + * There is also additional handling for eret and j. Neither of these instructions + * appear in IDO compiled C, however do show up in the exception handler. It is not + * possible to backtrace through an eret as an interrupt can occur at any time, so + * there is no choice but to give up here. For j instructions, they can be followed + * and the backtrace may continue as normal. + */ +void Fault_WalkStack(uintptr_t* spPtr, uintptr_t* pcPtr, uintptr_t* raPtr) { + uintptr_t sp = *spPtr; + uintptr_t pc = *pcPtr; + uintptr_t ra = *raPtr; + s32 count = 0x10000; // maximum number of instructions to search through + u32 lastInsn; + u32 insn; + u16 insnHi; + s16 insnLo; u32 imm; - if (sp & 3 || sp < 0x80000000 || sp >= 0xA0000000 || ra & 3 || ra < 0x80000000 || ra >= 0xA0000000) { - *spPtr = 0; - *pcPtr = 0; - *raPtr = 0; + // ensure $sp and $ra are aligned and valid pointers, if they aren't a stack + // trace cannot be generated + if (sp % 4 != 0 || !IS_KSEG0(sp) || ra % 4 != 0 || !IS_KSEG0(ra)) { + *raPtr = *pcPtr = *spPtr = 0; return; } - if (pc & 3 || pc < 0x80000000 || pc >= 0xA0000000) { + // ensure pc is aligned and a valid pointer, if not a stack trace cannot + // be generated + if (pc % 4 != 0 || !IS_KSEG0(pc)) { *pcPtr = ra; return; } - lastOpc = 0; + lastInsn = 0; while (true) { - opc = HW_REG(pc, u32); - opcHi = opc >> 16; - opcLo = opc & 0xFFFF; - imm = opcLo; - if (opcHi == 0x8FBF) { - ra = HW_REG(sp + imm, u32); - } else if (opcHi == 0x27BD) { + insn = *(u32*)K0_TO_K1(pc); + insnHi = insn >> 16; + insnLo = insn & 0xFFFF; + imm = insnLo; + + if (insnHi == 0x8FBF) { + // lw $ra, ($sp) + // read return address saved on the stack + ra = *(uintptr_t*)K0_TO_K1(sp + imm); + } else if (insnHi == 0x27BD) { + // addiu $sp, $sp, + // stack pointer increment or decrement sp += imm; - } else if (opc == 0x42000018) { - sp = 0; - pc = 0; - ra = 0; - goto end; + } else if (insn == 0x42000018) { + // eret + // cannot backtrace through an eret, give up + ra = pc = sp = 0; + goto done; } - if (lastOpc == 0x3E00008) { + if (lastInsn == 0x03E00008) { + // jr $ra + // return to previous function pc = ra; - goto end; - } else if (lastOpc >> 26 == 2) { - pc = pc >> 28 << 28 | lastOpc << 6 >> 4; - goto end; + goto done; + } else if (lastInsn >> 26 == 2) { + // j + // extract jump target + pc = pc >> 28 << 28 | lastInsn << 6 >> 4; + goto done; } - lastOpc = opc; - pc += 4; + + lastInsn = insn; + pc += sizeof(u32); if (count == 0) { break; } count--; } - sp = 0; - pc = 0; - ra = 0; + // Hit the maximum number of instructions to search, give up + ra = pc = sp = 0; -end: +done: *spPtr = sp; *pcPtr = pc; *raPtr = ra; } +/** + * Draws the stack trace page contents for the specified thread + */ void Fault_DrawStackTrace(OSThread* thread, s32 x, s32 y, s32 height) { s32 line; - u32 sp = thread->context.sp; - u32 ra = thread->context.ra; - u32 pc = thread->context.pc; - u32 addr; + uintptr_t sp = thread->context.sp; + uintptr_t ra = thread->context.ra; + uintptr_t pc = thread->context.pc; + uintptr_t addr; FaultDrawer_DrawText(x, y, "SP PC (VPC)"); - for (line = 1; line < height && (ra != 0 || sp != 0) && pc != (u32)__osCleanupThread; line++) { + + // Backtrace from the current function to the start of the thread + for (line = 1; line < height && (ra != 0 || sp != 0) && pc != (uintptr_t)__osCleanupThread; line++) { FaultDrawer_DrawText(x, y + line * 8, "%08x %08x", sp, pc); + // Convert relocated address to virtual address if applicable addr = Fault_ConvertAddress(pc); if (addr != 0) { FaultDrawer_Printf(" -> %08x", addr); } + // Search one function for the previous function Fault_WalkStack(&sp, &pc, &ra); } } void Fault_LogStackTrace(OSThread* thread, s32 height) { s32 line; - u32 sp = thread->context.sp; - u32 ra = thread->context.ra; - u32 pc = thread->context.pc; - u32 addr; + uintptr_t sp = thread->context.sp; + uintptr_t ra = thread->context.ra; + uintptr_t pc = thread->context.pc; + uintptr_t addr; s32 pad; osSyncPrintf("STACK TRACE\nSP PC (VPC)\n"); - for (line = 1; line < height && (ra != 0 || sp != 0) && pc != (u32)__osCleanupThread; line++) { + for (line = 1; line < height && (ra != 0 || sp != 0) && pc != (uintptr_t)__osCleanupThread; line++) { osSyncPrintf("%08x %08x", sp, pc); addr = Fault_ConvertAddress(pc); if (addr != 0) { @@ -890,30 +1089,30 @@ void Fault_LogStackTrace(OSThread* thread, s32 height) { } } -void Fault_ResumeThread(OSThread* t) { - t->context.cause = 0; - t->context.fpcsr = 0; - t->context.pc += 4; - *(u32*)t->context.pc = 0xD; - osWritebackDCache(t->context.pc, 4); - osInvalICache(t->context.pc, 4); - osStartThread(t); +void Fault_ResumeThread(OSThread* thread) { + thread->context.cause = 0; + thread->context.fpcsr = 0; + thread->context.pc += sizeof(u32); + *(u32*)thread->context.pc = 0x0000000D; // write in a break instruction + osWritebackDCache(thread->context.pc, 4); + osInvalICache(thread->context.pc, 4); + osStartThread(thread); } -void Fault_CommitFB() { - u16* fb; +void Fault_DisplayFrameBuffer(void) { + void* fb; osViSetYScale(1.0f); osViSetMode(&osViModeNtscLan1); osViSetSpecialFeatures(OS_VI_GAMMA_OFF | OS_VI_DITHER_FILTER_ON); osViBlack(false); - if (sFaultStructPtr->fb) { - fb = sFaultStructPtr->fb; + if (sFaultInstance->fb) { + fb = sFaultInstance->fb; } else { - fb = (u16*)osViGetNextFramebuffer(); - if ((u32)fb == 0x80000000) { - fb = (u16*)((osMemSize | 0x80000000) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])); + fb = osViGetNextFramebuffer(); + if ((uintptr_t)fb == K0BASE) { + fb = (PHYS_TO_K0(osMemSize) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])); } } @@ -921,56 +1120,63 @@ void Fault_CommitFB() { FaultDrawer_SetDrawerFB(fb, SCREEN_WIDTH, SCREEN_HEIGHT); } +/** + * Runs all registered fault clients. Each fault client displays a page + * on the crash screen. + */ void Fault_ProcessClients(void) { - FaultClient* iter = sFaultStructPtr->clients; + FaultClient* client = sFaultInstance->clients; s32 idx = 0; - while (iter != NULL) { - if (iter->callback != 0) { + while (client != NULL) { + if (client->callback != NULL) { Fault_FillScreenBlack(); FaultDrawer_SetCharPad(-2, 0); - FaultDrawer_Printf("\x1a" - "8CallBack (%d) %08x %08x %08x\n" - "\x1a" - "7", - idx++, iter, iter->param1, iter->param2); + FaultDrawer_Printf(FAULT_COLOR(DARK_GRAY) "CallBack (%d) %08x %08x %08x\n" FAULT_COLOR(WHITE), idx++, + client, client->arg0, client->arg1); FaultDrawer_SetCharPad(0, 0); - Fault_ProcessClient(iter->callback, iter->param1, iter->param2); + Fault_ProcessClient(client->callback, client->arg0, client->arg1); Fault_WaitForInput(); - Fault_CommitFB(); + Fault_DisplayFrameBuffer(); } - iter = iter->next; + client = client->next; } } -void Fault_UpdatePad() { +void Fault_UpdatePad(void) { Fault_UpdatePadImpl(); } +#define FAULT_MSG_CPU_BREAK ((OSMesg)1) +#define FAULT_MSG_FAULT ((OSMesg)2) +#define FAULT_MSG_UNK ((OSMesg)3) + void Fault_ThreadEntry(void* arg) { OSMesg msg; OSThread* faultedThread; s32 pad; - osSetEventMesg(OS_EVENT_CPU_BREAK, &sFaultStructPtr->queue, 1); - osSetEventMesg(OS_EVENT_FAULT, &sFaultStructPtr->queue, 2); + // Direct OS event messages to the fault event queue + osSetEventMesg(OS_EVENT_CPU_BREAK, &sFaultInstance->queue, FAULT_MSG_CPU_BREAK); + osSetEventMesg(OS_EVENT_FAULT, &sFaultInstance->queue, FAULT_MSG_FAULT); while (true) { do { - osRecvMesg(&sFaultStructPtr->queue, &msg, OS_MESG_BLOCK); + // Wait for a thread to hit a fault + osRecvMesg(&sFaultInstance->queue, &msg, OS_MESG_BLOCK); - if (msg == (OSMesg)1) { - sFaultStructPtr->msgId = 1; + if (msg == FAULT_MSG_CPU_BREAK) { + sFaultInstance->msgId = (u32)FAULT_MSG_CPU_BREAK; osSyncPrintf("フォルトマネージャ:OS_EVENT_CPU_BREAKを受信しました\n"); - } else if (1 && msg == (OSMesg)2) { - sFaultStructPtr->msgId = 2; + } else if (msg == FAULT_MSG_FAULT) { + sFaultInstance->msgId = (u32)FAULT_MSG_FAULT; osSyncPrintf("フォルトマネージャ:OS_EVENT_FAULTを受信しました\n"); - } else if (msg == (OSMesg)3) { + } else if (msg == FAULT_MSG_UNK) { Fault_UpdatePad(); faultedThread = NULL; continue; } else { - sFaultStructPtr->msgId = 3; + sFaultInstance->msgId = (u32)FAULT_MSG_UNK; osSyncPrintf("フォルトマネージャ:不明なメッセージを受信しました\n"); } @@ -983,97 +1189,120 @@ void Fault_ThreadEntry(void* arg) { } } while (faultedThread == NULL); - __osSetFpcCsr(__osGetFpcCsr() & -0xF81); - sFaultStructPtr->faultedThread = faultedThread; + // Disable floating-point related exceptions + __osSetFpcCsr(__osGetFpcCsr() & ~(FPCSR_EV | FPCSR_EZ | FPCSR_EO | FPCSR_EU | FPCSR_EI)); + sFaultInstance->faultedThread = faultedThread; - while (!sFaultStructPtr->faultHandlerEnabled) { + while (!sFaultInstance->faultHandlerEnabled) { Fault_Sleep(1000); } + Fault_Sleep(1000 / 2); - Fault_Sleep(500); - Fault_CommitFB(); + // Show fault framebuffer + Fault_DisplayFrameBuffer(); - if (sFaultStructPtr->faultActive) { + if (sFaultInstance->autoScroll) { Fault_Wait5Seconds(); } else { - Fault_DrawCornerRec(0xF801); + // Draw error bar signifying the crash screen is available + Fault_DrawCornerRec(GPACK_RGBA5551(255, 0, 0, 1)); Fault_WaitForButtonCombo(); } - sFaultStructPtr->faultActive = true; - FaultDrawer_SetForeColor(0xFFFF); - FaultDrawer_SetBackColor(0); + // Set auto-scrolling and default colors + sFaultInstance->autoScroll = true; + FaultDrawer_SetForeColor(GPACK_RGBA5551(255, 255, 255, 1)); + FaultDrawer_SetBackColor(GPACK_RGBA5551(0, 0, 0, 0)); + // Draw pages do { + // Thread context page Fault_PrintThreadContext(faultedThread); Fault_LogThreadContext(faultedThread); Fault_WaitForInput(); + // Stack trace page Fault_FillScreenBlack(); - FaultDrawer_DrawText(0x78, 0x10, "STACK TRACE"); - Fault_DrawStackTrace(faultedThread, 0x24, 0x18, 0x16); - Fault_LogStackTrace(faultedThread, 0x32); + FaultDrawer_DrawText(120, 16, "STACK TRACE"); + Fault_DrawStackTrace(faultedThread, 36, 24, 22); + Fault_LogStackTrace(faultedThread, 50); Fault_WaitForInput(); + // Client pages Fault_ProcessClients(); - Fault_DrawMemDump(faultedThread->context.pc - 0x100, (u32)faultedThread->context.sp, 0, 0); + // Memory dump page + Fault_DrawMemDump(faultedThread->context.pc - 0x100, (uintptr_t)faultedThread->context.sp, 0, 0); + // End page Fault_FillScreenRed(); - FaultDrawer_DrawText(0x40, 0x50, " CONGRATURATIONS! "); - FaultDrawer_DrawText(0x40, 0x5A, "All Pages are displayed."); - FaultDrawer_DrawText(0x40, 0x64, " THANK YOU! "); - FaultDrawer_DrawText(0x40, 0x6E, " You are great debugger!"); + FaultDrawer_DrawText(64, 80, " CONGRATURATIONS! "); + FaultDrawer_DrawText(64, 90, "All Pages are displayed."); + FaultDrawer_DrawText(64, 100, " THANK YOU! "); + FaultDrawer_DrawText(64, 110, " You are great debugger!"); Fault_WaitForInput(); - } while (!sFaultStructPtr->exitDebugger); + } while (!sFaultInstance->exit); - while (!sFaultStructPtr->exitDebugger) {} + while (!sFaultInstance->exit) {} Fault_ResumeThread(faultedThread); } } -void Fault_SetFB(void* fb, u16 w, u16 h) { - sFaultStructPtr->fb = fb; +void Fault_SetFrameBuffer(void* fb, u16 w, u16 h) { + sFaultInstance->fb = fb; FaultDrawer_SetDrawerFB(fb, w, h); } void Fault_Init(void) { - sFaultStructPtr = &gFaultStruct; - bzero(sFaultStructPtr, sizeof(FaultThreadStruct)); - FaultDrawer_SetDefault(); + sFaultInstance = &gFaultMgr; + bzero(sFaultInstance, sizeof(FaultMgr)); + FaultDrawer_Init(); FaultDrawer_SetInputCallback(Fault_WaitForInput); - sFaultStructPtr->exitDebugger = false; - sFaultStructPtr->msgId = 0; - sFaultStructPtr->faultHandlerEnabled = false; - sFaultStructPtr->faultedThread = NULL; - sFaultStructPtr->padCallback = Fault_PadCallback; - sFaultStructPtr->clients = NULL; - sFaultStructPtr->faultActive = false; - gFaultStruct.faultHandlerEnabled = true; - osCreateMesgQueue(&sFaultStructPtr->queue, &sFaultStructPtr->msg, 1); + sFaultInstance->exit = false; + sFaultInstance->msgId = 0; + sFaultInstance->faultHandlerEnabled = false; + sFaultInstance->faultedThread = NULL; + sFaultInstance->padCallback = Fault_PadCallback; + sFaultInstance->clients = NULL; + sFaultInstance->autoScroll = false; + gFaultMgr.faultHandlerEnabled = true; + osCreateMesgQueue(&sFaultInstance->queue, &sFaultInstance->msg, 1); StackCheck_Init(&sFaultThreadInfo, &sFaultStack, sFaultStack + sizeof(sFaultStack), 0, 0x100, "fault"); - osCreateThread(&sFaultStructPtr->thread, 2, Fault_ThreadEntry, 0, sFaultStack + sizeof(sFaultStack), + osCreateThread(&sFaultInstance->thread, 2, Fault_ThreadEntry, 0, sFaultStack + sizeof(sFaultStack), OS_PRIORITY_APPMAX); - osStartThread(&sFaultStructPtr->thread); + osStartThread(&sFaultInstance->thread); } -void Fault_HangupFaultClient(const char* arg0, const char* arg1) { - osSyncPrintf("HungUp on Thread %d\n", osGetThreadId(0)); - osSyncPrintf("%s\n", arg0 != NULL ? arg0 : "(NULL)"); - osSyncPrintf("%s\n", arg1 != NULL ? arg1 : "(NULL)"); - FaultDrawer_Printf("HungUp on Thread %d\n", osGetThreadId(0)); - FaultDrawer_Printf("%s\n", arg0 != NULL ? arg0 : "(NULL)"); - FaultDrawer_Printf("%s\n", arg1 != NULL ? arg1 : "(NULL)"); +/** + * Fault page for Hungup crashes. Displays the thread id and two messages + * specified in arguments to `Fault_AddHungupAndCrashImpl`. + */ +void Fault_HungupFaultClient(const char* exp1, const char* exp2) { + osSyncPrintf("HungUp on Thread %d\n", osGetThreadId(NULL)); + osSyncPrintf("%s\n", exp1 != NULL ? exp1 : "(NULL)"); + osSyncPrintf("%s\n", exp2 != NULL ? exp2 : "(NULL)"); + FaultDrawer_Printf("HungUp on Thread %d\n", osGetThreadId(NULL)); + FaultDrawer_Printf("%s\n", exp1 != NULL ? exp1 : "(NULL)"); + FaultDrawer_Printf("%s\n", exp2 != NULL ? exp2 : "(NULL)"); } -void Fault_AddHungupAndCrashImpl(const char* arg0, const char* arg1) { +/** + * Immediately crashes the current thread, for cases where an irrecoverable + * error occurs. The parameters specify two messages detailing the error, one + * or both may be NULL. + */ +void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2) { FaultClient client; s32 pad; - Fault_AddClient(&client, Fault_HangupFaultClient, (void*)arg0, (void*)arg1); - *(u32*)0x11111111 = 0; // trigger an exception + Fault_AddClient(&client, Fault_HungupFaultClient, (void*)exp1, (void*)exp2); + *(u32*)0x11111111 = 0; // trigger an exception via unaligned memory access } -void Fault_AddHungupAndCrash(const char* filename, u32 line) { +/** + * Like `Fault_AddHungupAndCrashImpl`, however provides a fixed message containing + * filename and line number + */ +void Fault_AddHungupAndCrash(const char* file, s32 line) { char msg[256]; - sprintf(msg, "HungUp %s:%d", filename, line); + sprintf(msg, "HungUp %s:%d", file, line); Fault_AddHungupAndCrashImpl(msg, NULL); } diff --git a/src/code/fault_drawer.c b/src/code/fault_drawer.c index 229200b15f..a9d99e37b1 100644 --- a/src/code/fault_drawer.c +++ b/src/code/fault_drawer.c @@ -1,7 +1,35 @@ +/** + * @file fault_drawer.c + * + * Implements routines for drawing text with a fixed font directly to a framebuffer, used in displaying + * the crash screen implemented by fault.c + */ #include "global.h" #include "vt.h" -// rodata +typedef struct { + /* 0x00 */ u16* fb; + /* 0x04 */ u16 w; + /* 0x08 */ u16 h; + /* 0x0A */ u16 yStart; + /* 0x0C */ u16 yEnd; + /* 0x0E */ u16 xStart; + /* 0x10 */ u16 xEnd; + /* 0x12 */ u16 foreColor; + /* 0x14 */ u16 backColor; + /* 0x14 */ u16 cursorX; + /* 0x16 */ u16 cursorY; + /* 0x18 */ const u32* fontData; + /* 0x1C */ u8 charW; + /* 0x1D */ u8 charH; + /* 0x1E */ s8 charWPad; + /* 0x1F */ s8 charHPad; + /* 0x20 */ u16 printColors[10]; + /* 0x34 */ u8 escCode; // bool + /* 0x35 */ u8 osSyncPrintfEnabled; + /* 0x38 */ void (*inputCallback)(void); +} FaultDrawer; // size = 0x3C + const u32 sFaultDrawerFont[] = { 0x00DFFD00, 0x0AEEFFA0, 0x0DF22DD0, 0x06611DC0, 0x01122DD0, 0x06719900, 0x011EED10, 0x077EF700, 0x01562990, 0x05589760, 0x0DD22990, 0x05599770, 0x04DFFD40, 0x026EF700, 0x00000000, 0x00000000, 0x08BFFB00, 0x0EFFFFC0, @@ -34,25 +62,27 @@ const u32 sFaultDrawerFont[] = { 0x05546F50, 0x00A99800, 0x02222080, 0x02001888, }; +#define FAULT_DRAWER_CURSOR_X 22 +#define FAULT_DRAWER_CURSOR_Y 16 + FaultDrawer sFaultDrawerDefault = { - (u16*)(0x80400000 - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])), // fb - SCREEN_WIDTH, // w - SCREEN_HEIGHT, // h - 16, // yStart - 223, // yEnd - 22, // xStart - 297, // xEnd - GPACK_RGBA5551(255, 255, 255, 255), // foreColor - GPACK_RGBA5551(0, 0, 0, 0), // backColor - 22, // cursorX - 16, // cursorY - sFaultDrawerFont, // font + (u16*)(PHYS_TO_K0(0x400000) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])), + SCREEN_WIDTH, + SCREEN_HEIGHT, + FAULT_DRAWER_CURSOR_Y, + SCREEN_HEIGHT - FAULT_DRAWER_CURSOR_Y - 1, + FAULT_DRAWER_CURSOR_X, + SCREEN_WIDTH - FAULT_DRAWER_CURSOR_X - 1, + GPACK_RGBA5551(255, 255, 255, 1), + GPACK_RGBA5551(0, 0, 0, 0), + FAULT_DRAWER_CURSOR_X, + FAULT_DRAWER_CURSOR_Y, + sFaultDrawerFont, 8, 8, 0, 0, { - // printColors GPACK_RGBA5551(0, 0, 0, 1), GPACK_RGBA5551(255, 0, 0, 1), GPACK_RGBA5551(0, 255, 0, 1), @@ -64,23 +94,23 @@ FaultDrawer sFaultDrawerDefault = { GPACK_RGBA5551(120, 120, 120, 1), GPACK_RGBA5551(176, 176, 176, 1), }, - 0, // escCode - 0, // osSyncPrintfEnabled - NULL, // inputCallback + false, + false, + NULL, }; -FaultDrawer sFaultDrawerStruct; +FaultDrawer sFaultDrawer; char D_8016B6C0[0x20]; void FaultDrawer_SetOsSyncPrintfEnabled(u32 enabled) { - sFaultDrawerStruct.osSyncPrintfEnabled = enabled; + sFaultDrawer.osSyncPrintfEnabled = enabled; } void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 color) { u16* fb; s32 x, y; - s32 xDiff = sFaultDrawerStruct.w - xStart; - s32 yDiff = sFaultDrawerStruct.h - yStart; + s32 xDiff = sFaultDrawer.w - xStart; + s32 yDiff = sFaultDrawer.h - yStart; s32 xSize = xEnd - xStart + 1; s32 ySize = yEnd - yStart + 1; @@ -93,12 +123,12 @@ void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 col ySize = yDiff; } - fb = sFaultDrawerStruct.fb + sFaultDrawerStruct.w * yStart + xStart; + fb = sFaultDrawer.fb + sFaultDrawer.w * yStart + xStart; for (y = 0; y < ySize; y++) { for (x = 0; x < xSize; x++) { *fb++ = color; } - fb += sFaultDrawerStruct.w - xSize; + fb += sFaultDrawer.w - xSize; } osWritebackDCacheAll(); @@ -110,31 +140,29 @@ void FaultDrawer_DrawChar(char c) { s32 x, y; const u32* dataPtr; u32 data; - s32 cursorX = sFaultDrawerStruct.cursorX; - s32 cursorY = sFaultDrawerStruct.cursorY; - const u32** fontData = &sFaultDrawerStruct.fontData; + s32 cursorX = sFaultDrawer.cursorX; + s32 cursorY = sFaultDrawer.cursorY; + const u32** fontData = &sFaultDrawer.fontData; s32 shift = c % 4; dataPtr = &fontData[0][(((c / 8) * 16) + ((c & 4) >> 2))]; - fb = sFaultDrawerStruct.fb + (sFaultDrawerStruct.w * cursorY) + cursorX; + fb = sFaultDrawer.fb + (sFaultDrawer.w * cursorY) + cursorX; - if ((sFaultDrawerStruct.xStart <= cursorX) && - ((sFaultDrawerStruct.charW + cursorX - 1) <= sFaultDrawerStruct.xEnd) && - (sFaultDrawerStruct.yStart <= cursorY) && - ((sFaultDrawerStruct.charH + cursorY - 1) <= sFaultDrawerStruct.yEnd)) { - for (y = 0; y < sFaultDrawerStruct.charH; y++) { + if ((sFaultDrawer.xStart <= cursorX) && ((sFaultDrawer.charW + cursorX - 1) <= sFaultDrawer.xEnd) && + (sFaultDrawer.yStart <= cursorY) && ((sFaultDrawer.charH + cursorY - 1) <= sFaultDrawer.yEnd)) { + for (y = 0; y < sFaultDrawer.charH; y++) { u32 mask = 0x10000000 << shift; data = *dataPtr; - for (x = 0; x < sFaultDrawerStruct.charW; x++) { + for (x = 0; x < sFaultDrawer.charW; x++) { if (mask & data) { - fb[x] = sFaultDrawerStruct.foreColor; - } else if (sFaultDrawerStruct.backColor & 1) { - fb[x] = sFaultDrawerStruct.backColor; + fb[x] = sFaultDrawer.foreColor; + } else if (sFaultDrawer.backColor & 1) { + fb[x] = sFaultDrawer.backColor; } mask >>= 4; } - fb += sFaultDrawerStruct.w; + fb += sFaultDrawer.w; dataPtr += 2; } } @@ -142,37 +170,40 @@ void FaultDrawer_DrawChar(char c) { s32 FaultDrawer_ColorToPrintColor(u16 color) { s32 i; - for (i = 0; i < 10; i++) { - if (color == sFaultDrawerStruct.printColors[i]) { + + for (i = 0; i < ARRAY_COUNT(sFaultDrawer.printColors); i++) { + if (color == sFaultDrawer.printColors[i]) { return i; } } return -1; } -void FaultDrawer_UpdatePrintColor() { +void FaultDrawer_UpdatePrintColor(void) { s32 idx; - if (sFaultDrawerStruct.osSyncPrintfEnabled) { + if (sFaultDrawer.osSyncPrintfEnabled) { osSyncPrintf(VT_RST); - idx = FaultDrawer_ColorToPrintColor(sFaultDrawerStruct.foreColor); - if (idx >= 0 && idx < 8) { + + idx = FaultDrawer_ColorToPrintColor(sFaultDrawer.foreColor); + if (idx >= 0 && idx < ARRAY_COUNT(sFaultDrawer.printColors) - 2) { osSyncPrintf(VT_SGR("3%d"), idx); } - idx = FaultDrawer_ColorToPrintColor(sFaultDrawerStruct.backColor); - if (idx >= 0 && idx < 8) { + + idx = FaultDrawer_ColorToPrintColor(sFaultDrawer.backColor); + if (idx >= 0 && idx < ARRAY_COUNT(sFaultDrawer.printColors) - 2) { osSyncPrintf(VT_SGR("4%d"), idx); } } } void FaultDrawer_SetForeColor(u16 color) { - sFaultDrawerStruct.foreColor = color; + sFaultDrawer.foreColor = color; FaultDrawer_UpdatePrintColor(); } void FaultDrawer_SetBackColor(u16 color) { - sFaultDrawerStruct.backColor = color; + sFaultDrawer.backColor = color; FaultDrawer_UpdatePrintColor(); } @@ -181,101 +212,102 @@ void FaultDrawer_SetFontColor(u16 color) { } void FaultDrawer_SetCharPad(s8 padW, s8 padH) { - sFaultDrawerStruct.charWPad = padW; - sFaultDrawerStruct.charHPad = padH; + sFaultDrawer.charWPad = padW; + sFaultDrawer.charHPad = padH; } void FaultDrawer_SetCursor(s32 x, s32 y) { - if (sFaultDrawerStruct.osSyncPrintfEnabled) { - osSyncPrintf(VT_CUP("%d", "%d"), - (y - sFaultDrawerStruct.yStart) / (sFaultDrawerStruct.charH + sFaultDrawerStruct.charHPad), - (x - sFaultDrawerStruct.xStart) / (sFaultDrawerStruct.charW + sFaultDrawerStruct.charWPad)); + if (sFaultDrawer.osSyncPrintfEnabled) { + osSyncPrintf(VT_CUP("%d", "%d"), (y - sFaultDrawer.yStart) / (sFaultDrawer.charH + sFaultDrawer.charHPad), + (x - sFaultDrawer.xStart) / (sFaultDrawer.charW + sFaultDrawer.charWPad)); } - sFaultDrawerStruct.cursorX = x; - sFaultDrawerStruct.cursorY = y; + sFaultDrawer.cursorX = x; + sFaultDrawer.cursorY = y; } -void FaultDrawer_FillScreen() { - if (sFaultDrawerStruct.osSyncPrintfEnabled) { +void FaultDrawer_FillScreen(void) { + if (sFaultDrawer.osSyncPrintfEnabled) { osSyncPrintf(VT_CLS); } - FaultDrawer_DrawRecImpl(sFaultDrawerStruct.xStart, sFaultDrawerStruct.yStart, sFaultDrawerStruct.xEnd, - sFaultDrawerStruct.yEnd, sFaultDrawerStruct.backColor | 1); - FaultDrawer_SetCursor(sFaultDrawerStruct.xStart, sFaultDrawerStruct.yStart); + FaultDrawer_DrawRecImpl(sFaultDrawer.xStart, sFaultDrawer.yStart, sFaultDrawer.xEnd, sFaultDrawer.yEnd, + sFaultDrawer.backColor | 1); + FaultDrawer_SetCursor(sFaultDrawer.xStart, sFaultDrawer.yStart); } -void* FaultDrawer_FormatStringFunc(void* arg, const char* str, u32 count) { +void* FaultDrawer_PrintCallback(void* arg, const char* str, u32 count) { for (; count != 0; count--, str++) { s32 curXStart; s32 curXEnd; - if (sFaultDrawerStruct.escCode) { - sFaultDrawerStruct.escCode = false; - if (*str > 0x30 && *str < 0x3A) { - FaultDrawer_SetForeColor(sFaultDrawerStruct.printColors[*str - 0x30]); + if (sFaultDrawer.escCode) { + sFaultDrawer.escCode = false; + if (*str > '0' && *str <= '9') { + FaultDrawer_SetForeColor(sFaultDrawer.printColors[*str - '0']); } - curXStart = sFaultDrawerStruct.cursorX; - curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW; + curXStart = sFaultDrawer.cursorX; + curXEnd = sFaultDrawer.xEnd - sFaultDrawer.charW; } else { switch (*str) { case '\n': - if (sFaultDrawerStruct.osSyncPrintfEnabled) { + if (sFaultDrawer.osSyncPrintfEnabled) { osSyncPrintf("\n"); } - sFaultDrawerStruct.cursorX = sFaultDrawerStruct.w; - curXStart = sFaultDrawerStruct.cursorX; - curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW; + sFaultDrawer.cursorX = sFaultDrawer.w; + curXStart = sFaultDrawer.cursorX; + curXEnd = sFaultDrawer.xEnd - sFaultDrawer.charW; break; - case '\x1A': - sFaultDrawerStruct.escCode = true; - curXStart = sFaultDrawerStruct.cursorX; - curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW; + case FAULT_ESC: + sFaultDrawer.escCode = true; + curXStart = sFaultDrawer.cursorX; + curXEnd = sFaultDrawer.xEnd - sFaultDrawer.charW; break; default: - if (sFaultDrawerStruct.osSyncPrintfEnabled) { + if (sFaultDrawer.osSyncPrintfEnabled) { osSyncPrintf("%c", *str); } FaultDrawer_DrawChar(*str); - sFaultDrawerStruct.cursorX += sFaultDrawerStruct.charW + sFaultDrawerStruct.charWPad; + sFaultDrawer.cursorX += sFaultDrawer.charW + sFaultDrawer.charWPad; - curXStart = sFaultDrawerStruct.cursorX; - curXEnd = sFaultDrawerStruct.xEnd - sFaultDrawerStruct.charW; + curXStart = sFaultDrawer.cursorX; + curXEnd = sFaultDrawer.xEnd - sFaultDrawer.charW; + break; } } if (curXEnd <= curXStart) { - sFaultDrawerStruct.cursorX = sFaultDrawerStruct.xStart; - sFaultDrawerStruct.cursorY += sFaultDrawerStruct.charH + sFaultDrawerStruct.charHPad; - if (sFaultDrawerStruct.yEnd - sFaultDrawerStruct.charH <= sFaultDrawerStruct.cursorY) { - if (sFaultDrawerStruct.inputCallback) { - sFaultDrawerStruct.inputCallback(); + sFaultDrawer.cursorX = sFaultDrawer.xStart; + sFaultDrawer.cursorY += sFaultDrawer.charH + sFaultDrawer.charHPad; + if (sFaultDrawer.yEnd - sFaultDrawer.charH <= sFaultDrawer.cursorY) { + if (sFaultDrawer.inputCallback) { + sFaultDrawer.inputCallback(); FaultDrawer_FillScreen(); } - sFaultDrawerStruct.cursorY = sFaultDrawerStruct.yStart; + sFaultDrawer.cursorY = sFaultDrawer.yStart; } } } - osWritebackDCacheAll(); return arg; } -void FaultDrawer_VPrintf(const char* str, char* args) { // va_list - _Printf(FaultDrawer_FormatStringFunc, (char*)&sFaultDrawerStruct, str, args); +s32 FaultDrawer_VPrintf(const char* fmt, va_list args) { + return _Printf(FaultDrawer_PrintCallback, &sFaultDrawer, fmt, args); } -void FaultDrawer_Printf(const char* fmt, ...) { +s32 FaultDrawer_Printf(const char* fmt, ...) { + s32 ret; va_list args; va_start(args, fmt); - FaultDrawer_VPrintf(fmt, args); + ret = FaultDrawer_VPrintf(fmt, args); va_end(args); + return ret; } void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) { @@ -289,20 +321,20 @@ void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) { } void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h) { - sFaultDrawerStruct.fb = fb; - sFaultDrawerStruct.w = w; - sFaultDrawerStruct.h = h; + sFaultDrawer.fb = fb; + sFaultDrawer.w = w; + sFaultDrawer.h = h; } -void FaultDrawer_SetInputCallback(void (*callback)()) { - sFaultDrawerStruct.inputCallback = callback; +void FaultDrawer_SetInputCallback(void (*callback)(void)) { + sFaultDrawer.inputCallback = callback; } -void FaultDrawer_WritebackFBDCache() { - osWritebackDCache(sFaultDrawerStruct.fb, sFaultDrawerStruct.w * sFaultDrawerStruct.h * 2); +void FaultDrawer_WritebackFBDCache(void) { + osWritebackDCache(sFaultDrawer.fb, sFaultDrawer.w * sFaultDrawer.h * sizeof(u16)); } -void FaultDrawer_SetDefault() { - bcopy(&sFaultDrawerDefault, &sFaultDrawerStruct, sizeof(FaultDrawer)); - sFaultDrawerStruct.fb = (u16*)((osMemSize | 0x80000000) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])); +void FaultDrawer_Init(void) { + bcopy(&sFaultDrawerDefault, &sFaultDrawer, sizeof(FaultDrawer)); + sFaultDrawer.fb = (u16*)(PHYS_TO_K0(osMemSize) - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])); } diff --git a/src/code/game.c b/src/code/game.c index cc7128616a..887141535d 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -17,7 +17,7 @@ void GameState_FaultPrint(void) { FaultDrawer_DrawText(120, 180, "%08x", sLastButtonPressed); for (i = 0; i < ARRAY_COUNT(sBtnChars); i++) { if (sLastButtonPressed & (1 << i)) { - FaultDrawer_DrawText((i * 8) + 0x78, 0xBE, "%c", sBtnChars[i]); + FaultDrawer_DrawText((i * 8) + 120, 190, "%c", sBtnChars[i]); } } } diff --git a/src/code/graph.c b/src/code/graph.c index 16f5393455..0567c016f2 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -134,7 +134,7 @@ void Graph_Init(GraphicsContext* gfxCtx) { gfxCtx->yScale = gViConfigYScale; osCreateMesgQueue(&gfxCtx->queue, gfxCtx->msgBuff, ARRAY_COUNT(gfxCtx->msgBuff)); func_800D31F0(); - Fault_AddClient(&sGraphFaultClient, Graph_FaultClient, 0, 0); + Fault_AddClient(&sGraphFaultClient, Graph_FaultClient, NULL, NULL); } void Graph_Destroy(GraphicsContext* gfxCtx) { diff --git a/src/code/irqmgr.c b/src/code/irqmgr.c index 6e7118bffe..50ba2def95 100644 --- a/src/code/irqmgr.c +++ b/src/code/irqmgr.c @@ -23,7 +23,7 @@ void IrqMgr_AddClient(IrqMgr* this, IrqMgrClient* c, OSMesgQueue* msgQ) { LogUtils_CheckNullPointer("c", c, "../irqmgr.c", 97); LogUtils_CheckNullPointer("msgQ", msgQ, "../irqmgr.c", 98); - prevInt = osSetIntMask(1); + prevInt = osSetIntMask(OS_IM_NONE); c->queue = msgQ; c->prev = this->clients; @@ -48,7 +48,7 @@ void IrqMgr_RemoveClient(IrqMgr* this, IrqMgrClient* c) { LogUtils_CheckNullPointer("this", this, "../irqmgr.c", 129); LogUtils_CheckNullPointer("c", c, "../irqmgr.c", 130); - prevInt = osSetIntMask(1); + prevInt = osSetIntMask(OS_IM_NONE); while (iter != NULL) { if (iter == c) { diff --git a/src/code/padmgr.c b/src/code/padmgr.c index e775006706..68c34d369c 100644 --- a/src/code/padmgr.c +++ b/src/code/padmgr.c @@ -165,7 +165,7 @@ void PadMgr_RumbleStop(PadMgr* padMgr) { for (i = 0; i < 4; i++) { if (osMotorInit(ctrlrQ, &padMgr->pfs[i], i) == 0) { - if ((gFaultStruct.msgId == 0) && (padMgr->rumbleOnFrames != 0)) { + if ((gFaultMgr.msgId == 0) && (padMgr->rumbleOnFrames != 0)) { osSyncPrintf(VT_FGCOL(YELLOW)); // "Stop vibration pack" osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック 停止"); @@ -297,7 +297,7 @@ void PadMgr_HandleRetraceMsg(PadMgr* padMgr) { } padMgr->validCtrlrsMask = mask; - if (gFaultStruct.msgId) { + if (gFaultMgr.msgId != 0) { PadMgr_RumbleStop(padMgr); } else if (padMgr->rumbleOffFrames > 0) { --padMgr->rumbleOffFrames; diff --git a/src/code/sched.c b/src/code/sched.c index bc14c9a7a1..cf8f6eced9 100644 --- a/src/code/sched.c +++ b/src/code/sched.c @@ -26,7 +26,7 @@ void Sched_SwapFrameBuffer(CfbInfo* cfbInfo) { (cfbInfo != NULL ? cfbInfo->swapBuffer : NULL)); } width = cfbInfo->viMode != NULL ? cfbInfo->viMode->comRegs.width : (u32)gScreenWidth; - Fault_SetFB(cfbInfo->swapBuffer, width, 0x10); + Fault_SetFrameBuffer(cfbInfo->swapBuffer, width, 0x10); if (HREG(80) == 0xD && HREG(95) != 0xD) { HREG(81) = 0; diff --git a/src/code/z_onepointdemo.c b/src/code/z_onepointdemo.c index 4a8f9e738f..22de34f2ef 100644 --- a/src/code/z_onepointdemo.c +++ b/src/code/z_onepointdemo.c @@ -1318,7 +1318,7 @@ s32 OnePointCutscene_Attention(GlobalContext* globalCtx, Actor* actor) { // If the previous attention cutscene has an actor in the same category, skip this actor. if (actor->category == vLastHigherCat) { - osSyncPrintf("→ " VT_FGCOL(PURPLE) "×" VT_RST " (%d)\n", actor->id); + osSyncPrintf("→ " VT_FGCOL(MAGENTA) "×" VT_RST " (%d)\n", actor->id); return SUBCAM_NONE; } osSyncPrintf("→ " VT_FGCOL(BLUE) "○" VT_RST " (%d)\n", actor->id); diff --git a/src/libultra/os/createthread.c b/src/libultra/os/createthread.c index d0952d246f..baed395259 100644 --- a/src/libultra/os/createthread.c +++ b/src/libultra/os/createthread.c @@ -1,6 +1,6 @@ #include "global.h" -OSThread* __osThreadTail[2] = { NULL, (OSThread*)-1 }; +OSThread* __osThreadTail[2] = { NULL, (OSThread*)OS_PRIORITY_THREADTAIL }; OSThread* __osRunQueue = (OSThread*)__osThreadTail; OSThread* __osActiveQueue = (OSThread*)__osThreadTail; OSThread* __osRunningThread = NULL; diff --git a/src/libultra/os/destroythread.c b/src/libultra/os/destroythread.c index 6f1ffff136..a3273cadee 100644 --- a/src/libultra/os/destroythread.c +++ b/src/libultra/os/destroythread.c @@ -16,7 +16,7 @@ void osDestroyThread(OSThread* thread) { __osActiveQueue = __osActiveQueue->tlnext; } else { s1 = __osActiveQueue; - while (s1->priority != -1) { + while (s1->priority != OS_PRIORITY_THREADTAIL) { s2 = s1->tlnext; if (s2 == thread) { s1->tlnext = thread->tlnext; diff --git a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 14833a9c55..41c4a0099d 100644 --- a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -244,7 +244,7 @@ void BgDyYoseizo_ChooseType(BgDyYoseizo* this, GlobalContext* globalCtx) { case FAIRY_UPGRADE_HALF_DAMAGE: if (!gSaveContext.doubleDefense) { // "Damage halved" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ ダメージ半減 ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ ダメージ半減 ☆☆☆☆☆ \n" VT_RST); this->givingSpell = true; givingReward = true; } diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index c016703b7f..2e93d70972 100644 --- a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -236,7 +236,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx) { this->gameResult = 1; // Won this->bowlPit->status = 0; // "Center HIT!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 中央HIT!!!! ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 中央HIT!!!! ☆☆☆☆☆ \n" VT_RST); } if ((globalCtx->bombchuBowlingStatus == -1) && @@ -244,7 +244,7 @@ void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx) { (this->wallStatus[0] != 1) && (this->wallStatus[1] != 1)) { this->gameResult = 2; // Lost // "Bombchu lost" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ボムチュウ消化 ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ ボムチュウ消化 ☆☆☆☆☆ \n" VT_RST); } } diff --git a/src/overlays/actors/ovl_En_Changer/z_en_changer.c b/src/overlays/actors/ovl_En_Changer/z_en_changer.c index e353c79498..b768e6136d 100644 --- a/src/overlays/actors/ovl_En_Changer/z_en_changer.c +++ b/src/overlays/actors/ovl_En_Changer/z_en_changer.c @@ -156,13 +156,13 @@ void EnChanger_Init(Actor* thisx, GlobalContext* globalCtx2) { if (this->leftChest != NULL) { // "Left treasure generation (what does it contain?)" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 左宝発生(ナニがはいってるの?) ☆☆☆☆☆ %x\n" VT_RST, leftChestParams); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 左宝発生(ナニがはいってるの?) ☆☆☆☆☆ %x\n" VT_RST, leftChestParams); // "What is the room number?" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 部屋番号は? %x\n" VT_RST, globalCtx->roomCtx.curRoom.num); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 部屋番号は? %x\n" VT_RST, globalCtx->roomCtx.curRoom.num); // "What is the bit?" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ビットはなぁに? %x\n" VT_RST, this->rightChestNum); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ ビットはなぁに? %x\n" VT_RST, this->rightChestNum); // "Sukesuke-kun" (something to do with being invisible) - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ すけすけ君? %x\n" VT_RST, rightChestItem); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ すけすけ君? %x\n" VT_RST, rightChestItem); osSyncPrintf("\n\n"); if (this->roomChestsOpened) { Flags_SetTreasure(globalCtx, this->leftChestNum & 0x1F); diff --git a/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c b/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c index de3ecfaebe..d850738787 100644 --- a/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c +++ b/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c @@ -196,7 +196,7 @@ void EnDntDemo_Judge(EnDntDemo* this, GlobalContext* globalCtx) { // "This is dangerous!" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ヤバいよこれ! ☆☆☆☆☆ \n" VT_RST); osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ ヤバいよこれ! ☆☆☆☆☆ \n" VT_RST); - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ヤバいよこれ! ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ ヤバいよこれ! ☆☆☆☆☆ \n" VT_RST); osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ ヤバいよこれ! ☆☆☆☆☆ \n" VT_RST); maskIdx = Rand_ZeroFloat(7.99f); } @@ -230,7 +230,7 @@ void EnDntDemo_Judge(EnDntDemo* this, GlobalContext* globalCtx) { // "What kind of evaluation?" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ どういう評価? ☆☆☆☆☆☆ %d\n" VT_RST, reaction); // "What kind of action?" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ どういうアクション? ☆☆☆ %d\n" VT_RST, this->action); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ どういうアクション? ☆☆☆ %d\n" VT_RST, this->action); osSyncPrintf("\n\n"); break; } diff --git a/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c b/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c index ac54bd7b7b..cf88b2f55d 100644 --- a/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c +++ b/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c @@ -146,7 +146,7 @@ void EnDntNomal_Init(Actor* thisx, GlobalContext* globalCtx) { if (this->objIndex < 0) { Actor_Kill(&this->actor); // "What?" - osSyncPrintf(VT_FGCOL(PURPLE) " なにみの? %d\n" VT_RST "\n", this->objIndex); + osSyncPrintf(VT_FGCOL(MAGENTA) " なにみの? %d\n" VT_RST "\n", this->objIndex); // "Bank is funny" osSyncPrintf(VT_FGCOL(CYAN) " バンクおかしいしぞ!%d\n" VT_RST "\n", this->actor.params); return; diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index b5b2a056e3..ffb1716688 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -57,7 +57,7 @@ void EnEncount1_Init(Actor* thisx, GlobalContext* globalCtx) { // "Type" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 種類\t\t ☆☆☆☆☆ %d\n" VT_RST, this->spawnType); // "Maximum number of simultaneous spawns" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 最大同時発生数 ☆☆☆☆☆ %d\n" VT_RST, this->maxCurSpawns); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 最大同時発生数 ☆☆☆☆☆ %d\n" VT_RST, this->maxCurSpawns); // "Maximum number of spawns" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 最大発生数 \t ☆☆☆☆☆ %d\n" VT_RST, this->maxTotalSpawns); // "Spawn check range" diff --git a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index e17327c6e7..773ce7a37e 100644 --- a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -110,7 +110,7 @@ void EnExItem_Init(Actor* thisx, GlobalContext* globalCtx) { // "What?" osSyncPrintf("なにみの? %d\n", this->actor.params); // "bank is funny" - osSyncPrintf(VT_FGCOL(PURPLE) " バンクおかしいしぞ!%d\n" VT_RST "\n", this->actor.params); + osSyncPrintf(VT_FGCOL(MAGENTA) " バンクおかしいしぞ!%d\n" VT_RST "\n", this->actor.params); return; } this->actionFunc = EnExItem_WaitForObject; @@ -125,7 +125,7 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 転送終了 ☆☆☆☆☆ %d\n" VT_RST, this->actor.params, this); osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 転送終了 ☆☆☆☆☆ %d\n" VT_RST, this->actor.params, this); osSyncPrintf(VT_FGCOL(BLUE) "☆☆☆☆☆ 転送終了 ☆☆☆☆☆ %d\n" VT_RST, this->actor.params, this); - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 転送終了 ☆☆☆☆☆ %d\n" VT_RST, this->actor.params, this); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 転送終了 ☆☆☆☆☆ %d\n" VT_RST, this->actor.params, this); osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 転送終了 ☆☆☆☆☆ %d\n\n" VT_RST, this->actor.params, this); this->actor.objBankIndex = this->objectIdx; this->actor.draw = EnExItem_Draw; diff --git a/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c b/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c index b53a199780..f32ef133a2 100644 --- a/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c +++ b/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c @@ -96,7 +96,7 @@ void EnGSwitch_Init(Actor* thisx, GlobalContext* globalCtx) { this->silverCount = this->actor.params >> 6; this->silverCount &= 0x3F; // "maximum number of checks" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 最大チェック数 ☆☆☆☆☆ %d\n" VT_RST, this->silverCount); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 最大チェック数 ☆☆☆☆☆ %d\n" VT_RST, this->silverCount); osSyncPrintf("\n\n"); if (Flags_GetSwitch(globalCtx, this->switchFlag)) { // This is a reference to Hokuto no Ken @@ -141,7 +141,7 @@ void EnGSwitch_Init(Actor* thisx, GlobalContext* globalCtx) { if (this->objIndex < 0) { Actor_Kill(&this->actor); // "what?" - osSyncPrintf(VT_FGCOL(PURPLE) " なにみの? %d\n" VT_RST "\n", this->objIndex); + osSyncPrintf(VT_FGCOL(MAGENTA) " なにみの? %d\n" VT_RST "\n", this->objIndex); // "bank is funny" osSyncPrintf(VT_FGCOL(CYAN) " バンクおかしいしぞ!%d\n" VT_RST "\n", this->actor.params); } diff --git a/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c b/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c index c6f4d725cb..6ccfc57782 100644 --- a/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c +++ b/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c @@ -84,21 +84,21 @@ void EnHeishi1_Init(Actor* thisx, GlobalContext* globalCtx) { osSyncPrintf(VT_FGCOL(GREEN) " 種類☆☆☆☆☆☆☆☆☆☆☆☆☆ %d\n" VT_RST, this->type); // "path data" osSyncPrintf(VT_FGCOL(YELLOW) " れえるでぇたぁ☆☆☆☆☆☆☆☆ %d\n" VT_RST, this->path); - osSyncPrintf(VT_FGCOL(PURPLE) " anime_frame_speed ☆☆☆☆☆☆ %f\n" VT_RST, this->animSpeed); + osSyncPrintf(VT_FGCOL(MAGENTA) " anime_frame_speed ☆☆☆☆☆☆ %f\n" VT_RST, this->animSpeed); // "interpolation frame" - osSyncPrintf(VT_FGCOL(PURPLE) " 補間フレーム☆☆☆☆☆☆☆☆☆ %f\n" VT_RST, this->transitionRate); + osSyncPrintf(VT_FGCOL(MAGENTA) " 補間フレーム☆☆☆☆☆☆☆☆☆ %f\n" VT_RST, this->transitionRate); // "targeted movement speed value between points" - osSyncPrintf(VT_FGCOL(PURPLE) " point間の移動スピード目標値 ☆ %f\n" VT_RST, this->moveSpeedTarget); + osSyncPrintf(VT_FGCOL(MAGENTA) " point間の移動スピード目標値 ☆ %f\n" VT_RST, this->moveSpeedTarget); // "maximum movement speed value between points" - osSyncPrintf(VT_FGCOL(PURPLE) " point間の移動スピード最大 ☆☆ %f\n" VT_RST, this->moveSpeedMax); + osSyncPrintf(VT_FGCOL(MAGENTA) " point間の移動スピード最大 ☆☆ %f\n" VT_RST, this->moveSpeedMax); // "(body) targeted turning angle speed value" - osSyncPrintf(VT_FGCOL(PURPLE) " (体)反転アングルスピード目標値 %f\n" VT_RST, this->bodyTurnSpeedTarget); + osSyncPrintf(VT_FGCOL(MAGENTA) " (体)反転アングルスピード目標値 %f\n" VT_RST, this->bodyTurnSpeedTarget); // "(body) maximum turning angle speed" - osSyncPrintf(VT_FGCOL(PURPLE) " (体)反転アングルスピード最大☆ %f\n" VT_RST, this->bodyTurnSpeedMax); + osSyncPrintf(VT_FGCOL(MAGENTA) " (体)反転アングルスピード最大☆ %f\n" VT_RST, this->bodyTurnSpeedMax); // "(head) targeted turning angle speed value" - osSyncPrintf(VT_FGCOL(PURPLE) " (頭)反転アングルスピード加算値 %f\n" VT_RST, this->headTurnSpeedScale); + osSyncPrintf(VT_FGCOL(MAGENTA) " (頭)反転アングルスピード加算値 %f\n" VT_RST, this->headTurnSpeedScale); // "(head) maximum turning angle speed" - osSyncPrintf(VT_FGCOL(PURPLE) " (頭)反転アングルスピード最大☆ %f\n" VT_RST, this->headTurnSpeedMax); + osSyncPrintf(VT_FGCOL(MAGENTA) " (頭)反転アングルスピード最大☆ %f\n" VT_RST, this->headTurnSpeedMax); osSyncPrintf(VT_FGCOL(GREEN) " 今時間 %d\n" VT_RST, ((void)0, gSaveContext.dayTime)); // "current time" osSyncPrintf(VT_FGCOL(YELLOW) " チェック時間 %d\n" VT_RST, 0xBAAA); // "check time" osSyncPrintf("\n\n"); diff --git a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index b9c5df889a..aa0514d5d5 100644 --- a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -100,7 +100,7 @@ void EnHeishi2_Init(Actor* thisx, GlobalContext* globalCtx) { } else { osSyncPrintf("\n\n"); // "No, I'm completely disappointed" (message for when shooting guard window in courtyard) - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ いやー ついうっかり ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ いやー ついうっかり ☆☆☆☆☆ \n" VT_RST); Actor_SetScale(&this->actor, 0.02f); @@ -155,7 +155,7 @@ void EnHeishi2_Init(Actor* thisx, GlobalContext* globalCtx) { // "Identification Completed!" osSyncPrintf(VT_FGCOL(YELLOW) " ☆☆☆☆☆ 識別完了! ☆☆☆☆☆ %d\n" VT_RST, this->type); // "Message completed!" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ メッセージ完了! ☆☆☆☆☆ %x\n\n" VT_RST, (this->actor.params >> 8) & 0xF); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ メッセージ完了! ☆☆☆☆☆ %x\n\n" VT_RST, (this->actor.params >> 8) & 0xF); } } @@ -211,12 +211,12 @@ void func_80A53278(EnHeishi2* this, GlobalContext* globalCtx) { } else if (gSaveContext.eventChkInf[1] & 4) { if (this->unk_30E == 0) { // "Start under the first sleeve!" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ 1回目袖の下開始! ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ 1回目袖の下開始! ☆☆☆☆☆ \n" VT_RST); this->actor.textId = 0x7071; this->unk_30E = 1; } else { // "Start under the second sleeve!" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ 2回目袖の下開始! ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ 2回目袖の下開始! ☆☆☆☆☆ \n" VT_RST); this->actor.textId = 0x7072; } this->unk_300 = TEXT_STATE_CHOICE; @@ -298,7 +298,7 @@ void func_80A53638(EnHeishi2* this, GlobalContext* globalCtx) { } } // "I've come!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆ きたきたきたぁ! ☆☆☆ %x\n" VT_RST, actor->dyna.actor.next); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆ きたきたきたぁ! ☆☆☆ %x\n" VT_RST, actor->dyna.actor.next); this->actionFunc = func_80A5372C; } } @@ -383,7 +383,7 @@ void func_80A5399C(EnHeishi2* this, GlobalContext* globalCtx) { this->actionFunc = func_80A5475C; } else { // "I don't know" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ とおしゃしねぇちゅーの ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ とおしゃしねぇちゅーの ☆☆☆☆☆ \n" VT_RST); this->actionFunc = func_80A53AD4; } } @@ -462,7 +462,7 @@ void func_80A53D0C(EnHeishi2* this, GlobalContext* globalCtx) { } } // "I've come!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆ きたきたきたぁ! ☆☆☆ %x\n" VT_RST, gate->dyna.actor.next); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆ きたきたきたぁ! ☆☆☆ %x\n" VT_RST, gate->dyna.actor.next); this->actionFunc = func_80A53DF8; } } diff --git a/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c index bc913afa5f..48f2f1656a 100644 --- a/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c +++ b/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c @@ -97,7 +97,7 @@ void EnHeishi4_Init(Actor* thisx, GlobalContext* globalCtx) { osSyncPrintf("\n\n"); osSyncPrintf(VT_FGCOL(GREEN) " ☆☆☆☆☆ 兵士2セット完了! ☆☆☆☆☆ %d\n" VT_RST, thisx->params); osSyncPrintf(VT_FGCOL(YELLOW) " ☆☆☆☆☆ 識別完了!\t ☆☆☆☆☆ %d\n" VT_RST, this->type); - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ メッセージ完了! ☆☆☆☆☆ %x\n\n" VT_RST, (thisx->params >> 8) & 0xF); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ メッセージ完了! ☆☆☆☆☆ %x\n\n" VT_RST, (thisx->params >> 8) & 0xF); osSyncPrintf("\n\n"); } diff --git a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c index 5d468f594f..1c62282cc5 100644 --- a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c +++ b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c @@ -343,7 +343,7 @@ void func_80A918E4(EnKakasi3* this, GlobalContext* globalCtx) { if (BREG(3) != 0) { // "No way!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ まさか! ☆☆☆☆☆ %d\n" VT_RST, globalCtx->msgCtx.ocarinaMode); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ まさか! ☆☆☆☆☆ %d\n" VT_RST, globalCtx->msgCtx.ocarinaMode); } if ((globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_04 || (globalCtx->msgCtx.ocarinaMode >= OCARINA_MODE_05 && globalCtx->msgCtx.ocarinaMode < OCARINA_MODE_0B)) && diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 6b6f8b0fba..a34d721a36 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -67,7 +67,7 @@ void EnOkarinaTag_Init(Actor* thisx, GlobalContext* globalCtx) { // "Type index" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 種類インデックス ☆☆☆☆☆ %d\n" VT_RST, this->type); // "Correct answer information" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 正解情報\t ☆☆☆☆☆ %d\n" VT_RST, this->ocarinaSong); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 正解情報\t ☆☆☆☆☆ %d\n" VT_RST, this->ocarinaSong); // "Range information" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 範囲情報\t ☆☆☆☆☆ %d\n" VT_RST, this->actor.world.rot.z); // "Processing range information" @@ -301,7 +301,7 @@ void func_80ABF708(EnOkarinaTag* this, GlobalContext* globalCtx) { void func_80ABF7CC(EnOkarinaTag* this, GlobalContext* globalCtx) { // "Open sesame sesame!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 開けゴマゴマゴマ! ☆☆☆☆☆ %d\n" VT_RST, Message_GetState(&globalCtx->msgCtx)); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 開けゴマゴマゴマ! ☆☆☆☆☆ %d\n" VT_RST, Message_GetState(&globalCtx->msgCtx)); if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(globalCtx)) { Message_CloseTextbox(globalCtx); diff --git a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c index be89bc67f1..2977137224 100644 --- a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c +++ b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c @@ -51,7 +51,7 @@ void EnTakaraMan_Init(Actor* thisx, GlobalContext* globalCtx) { sTakaraIsInitialized = true; osSyncPrintf("\n\n"); // "Bun! %x" (needs a better translation) - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ばぅん! ☆☆☆☆☆ %x\n" VT_RST, globalCtx->actorCtx.flags.chest); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ ばぅん! ☆☆☆☆☆ %x\n" VT_RST, globalCtx->actorCtx.flags.chest); globalCtx->actorCtx.flags.chest = 0; gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = -1; SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ts_Skel_004FE0, &object_ts_Anim_000498, this->jointTable, diff --git a/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c b/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c index 3a09029539..f2e18e7ee1 100644 --- a/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c +++ b/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c @@ -129,7 +129,7 @@ void EnWallTubo_SetWallFall(EnWallTubo* this, GlobalContext* globalCtx) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST); osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST); osSyncPrintf(VT_FGCOL(BLUE) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST); - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST); osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST); } diff --git a/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c b/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c index 9e7001e2de..4daf7e1bd5 100644 --- a/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c +++ b/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c @@ -66,7 +66,7 @@ void func_80B391CC(EnWonderTalk* this, GlobalContext* globalCtx) { this->height = 0.0f; this->unk_15C = 80.0f; // "Attention coordinates" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); if (!LINK_IS_ADULT) { this->actor.textId = 0x7040; // "Children" @@ -88,7 +88,7 @@ void func_80B391CC(EnWonderTalk* this, GlobalContext* globalCtx) { this->height = 30.0f; this->unk_15C = 40.0f; // "Attention coordinates" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 30.0f); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 30.0f); break; case 3: this->actor.textId = 0x501E; @@ -96,14 +96,14 @@ void func_80B391CC(EnWonderTalk* this, GlobalContext* globalCtx) { this->height = 0.0f; this->unk_15C = 110.0f; // "Attention coordinates" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); break; case 4: this->actor.textId = 0x5020; this->unk_156 = TEXT_STATE_DONE; this->height = 0.0f; // "Attention coordinates" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); this->unk_15C = 120.0f; if (gSaveContext.eventChkInf[1] & 0x2000) { Actor_Kill(&this->actor); @@ -115,7 +115,7 @@ void func_80B391CC(EnWonderTalk* this, GlobalContext* globalCtx) { this->height = 0.0f; this->unk_15C = 110.0f; // "Attention coordinates" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 注目座標\t \t☆☆☆☆☆ %f\n" VT_RST, 0.0f); break; default: this->actor.textId = 0x7072; @@ -158,7 +158,7 @@ void func_80B3943C(EnWonderTalk* this, GlobalContext* globalCtx) { // "Save information" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ セーブ情報\t\t☆☆☆☆☆ %d\n" VT_RST, this->switchFlag); // "Type index" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 種類インデックス\t☆☆☆☆☆ %d\n" VT_RST, this->unk_150); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 種類インデックス\t☆☆☆☆☆ %d\n" VT_RST, this->unk_150); // "Actual message type" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 実質メッセージ種類 %x\n" VT_RST, this->actor.textId); // "Specified range" @@ -198,7 +198,7 @@ void func_80B395F0(EnWonderTalk* this, GlobalContext* globalCtx) { break; case 1: // "Out!" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆☆☆☆ はずれ! ☆☆☆☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆☆☆☆ はずれ! ☆☆☆☆☆ \n" VT_RST); this->actor.textId = 0x5004; break; } diff --git a/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c index 880e4eba7a..adf159d81c 100644 --- a/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c +++ b/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c @@ -64,7 +64,7 @@ void EnWonderTalk2_Init(Actor* thisx, GlobalContext* globalCtx) { // "originally?" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 元は? ☆☆☆☆☆ %d\n" VT_RST, this->actor.world.rot.z); // "The range is?" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ レンジは? ☆☆☆☆☆ %d\n" VT_RST, this->actor.targetMode); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ レンジは? ☆☆☆☆☆ %d\n" VT_RST, this->actor.targetMode); // "Is the range?" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ は、範囲わ? ☆☆☆☆☆ %f\n" VT_RST, this->triggerRange); osSyncPrintf("\n\n"); @@ -121,7 +121,7 @@ void func_80B3A15C(EnWonderTalk2* this, GlobalContext* globalCtx) { if ((this->switchFlag >= 0) && (this->talkMode != 2)) { Flags_SetSwitch(globalCtx, this->switchFlag); // "I saved it! All of it!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ セーブしたよ!おもいっきり! %x\n" VT_RST, this->switchFlag); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ セーブしたよ!おもいっきり! %x\n" VT_RST, this->switchFlag); } this->actionFunc = func_80B3A10C; @@ -137,7 +137,7 @@ void func_80B3A15C(EnWonderTalk2* this, GlobalContext* globalCtx) { // "Save Information" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ セーブ情報 \t %x\n" VT_RST, this->switchFlag); // "Specified message type" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 指定メッセージ種類 %x\n" VT_RST, this->baseMsgId); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 指定メッセージ種類 %x\n" VT_RST, this->baseMsgId); // "Actual message type" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 実質メッセージ種類 %x\n" VT_RST, this->actor.textId); // "Specified range" @@ -147,15 +147,15 @@ void func_80B3A15C(EnWonderTalk2* this, GlobalContext* globalCtx) { switch (this->talkMode) { case 0: // "Normal" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆ 通常 ☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆ 通常 ☆☆ \n" VT_RST); break; case 2: // "Check only" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆ チェックのみ ☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆ チェックのみ ☆☆ \n" VT_RST); break; case 3: // "Lock only" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆ ロックのみ ☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆ ロックのみ ☆☆ \n" VT_RST); break; } } @@ -169,7 +169,7 @@ void func_80B3A15C(EnWonderTalk2* this, GlobalContext* globalCtx) { void func_80B3A3D4(EnWonderTalk2* this, GlobalContext* globalCtx) { if (BREG(2) != 0) { // "Oh" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ わー %d\n" VT_RST, Message_GetState(&globalCtx->msgCtx)); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ わー %d\n" VT_RST, Message_GetState(&globalCtx->msgCtx)); } switch (Message_GetState(&globalCtx->msgCtx)) { @@ -186,7 +186,7 @@ void func_80B3A3D4(EnWonderTalk2* this, GlobalContext* globalCtx) { if ((this->switchFlag >= 0) && (this->talkMode != 4)) { Flags_SetSwitch(globalCtx, this->switchFlag); // "(Forced) I saved it! All of it!" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ (強制)セーブしたよ!おもいっきり! %x\n" VT_RST, this->switchFlag); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ (強制)セーブしたよ!おもいっきり! %x\n" VT_RST, this->switchFlag); } if (this->talkMode == 4) { @@ -213,7 +213,7 @@ void func_80B3A4F8(EnWonderTalk2* this, GlobalContext* globalCtx) { } else if ((this->talkMode != 4) || !this->unk_15A) { if (BREG(2) != 0) { // "distance" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ きょり %f\n" VT_RST, this->actor.xzDistToPlayer); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ きょり %f\n" VT_RST, this->actor.xzDistToPlayer); } if (((this->actor.xzDistToPlayer < (40.0f + this->triggerRange)) && (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 100.0f)) && @@ -225,7 +225,7 @@ void func_80B3A4F8(EnWonderTalk2* this, GlobalContext* globalCtx) { // "Save Information" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ セーブ情報 \t %x\n" VT_RST, this->switchFlag); // "Specified message type" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 指定メッセージ種類 %x\n" VT_RST, this->baseMsgId); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 指定メッセージ種類 %x\n" VT_RST, this->baseMsgId); // "Real message type" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 実質メッセージ種類 %x\n" VT_RST, this->actor.textId); // "Specified range" @@ -233,13 +233,13 @@ void func_80B3A4F8(EnWonderTalk2* this, GlobalContext* globalCtx) { // "Processing range" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 処理範囲 %f\n" VT_RST, this->triggerRange); // "What is your range?" - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ レンジは? \t\t %d\n" VT_RST, this->actor.targetMode); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ レンジは? \t\t %d\n" VT_RST, this->actor.targetMode); osSyncPrintf("\n\n"); osSyncPrintf("\n\n"); switch (this->talkMode) { case 1: // "Compulsion" - osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆ 強制 ☆☆ \n" VT_RST); + osSyncPrintf(VT_FGCOL(MAGENTA) " ☆☆ 強制 ☆☆ \n" VT_RST); break; case 4: // "Gerudo Training Grounds Forced Check Only" diff --git a/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c b/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c index eeffd30336..88fac1426f 100644 --- a/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c +++ b/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c @@ -109,7 +109,7 @@ void EnYabusameMark_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_Kill(&this->actor); return; } - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 種類 ☆☆☆☆☆ %d\n" VT_RST, this->typeIndex); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 種類 ☆☆☆☆☆ %d\n" VT_RST, this->typeIndex); osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ さらに分類 ☆☆☆☆☆ %d\n" VT_RST, this->subTypeIndex); this->actionFunc = func_80B42F74; } @@ -166,9 +166,9 @@ void func_80B42F74(EnYabusameMark* this, GlobalContext* globalCtx) { osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ hitX ☆☆☆☆☆ %f\n" VT_RST, sTargetPos[this->subTypeIndex].x); osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ hitY ☆☆☆☆☆ %f\n" VT_RST, sTargetPos[this->subTypeIndex].y); osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ hitZ ☆☆☆☆☆ %f\n" VT_RST, sTargetPos[this->subTypeIndex].z); - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 小 ☆☆☆☆☆ %f\n" VT_RST, scoreDistance100); - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 大 ☆☆☆☆☆ %f\n" VT_RST, scoreDistance60); - osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ point ☆☆☆☆☆ %d\n" VT_RST, scoreIndex); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 小 ☆☆☆☆☆ %f\n" VT_RST, scoreDistance100); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 大 ☆☆☆☆☆ %f\n" VT_RST, scoreDistance60); + osSyncPrintf(VT_FGCOL(MAGENTA) "☆☆☆☆☆ point ☆☆☆☆☆ %d\n" VT_RST, scoreIndex); osSyncPrintf("\n\n"); if (scoreIndex == 2) { diff --git a/tools/vt_fmt.py b/tools/vt_fmt.py index 6925734f7b..e0929ff8be 100755 --- a/tools/vt_fmt.py +++ b/tools/vt_fmt.py @@ -15,8 +15,6 @@ COLORS = [ 'PURPLE', 'CYAN', 'WHITE', - 'LIGHTGRAY', - 'DARKGRAY', ] def re_match(exp, text): @@ -39,11 +37,11 @@ def vt_fmt(text): code = text[i:text.find('m', i)] i += len(code) - if re_match('^4[0-9];3[0-9]$', code): + if re_match('^4[0-7];3[0-7]$', code): chars += 'VT_COL(' + COLORS[int(code[1])] + ', ' + COLORS[int(code[4])] + ')' - elif re_match('^4[0-9]$', code): + elif re_match('^4[0-7]$', code): chars += 'VT_BGCOL(' + COLORS[int(code[1])] + ')' - elif re_match('^3[0-9]$', code): + elif re_match('^3[0-7]$', code): chars += 'VT_FGCOL(' + COLORS[int(code[1])] + ')' elif len(code) == 0: chars += 'VT_RST'