From 9bcba6a2dc88894273b3ad4e858ce79cbc646b18 Mon Sep 17 00:00:00 2001 From: Gregory Heskett Date: Tue, 30 Apr 2024 02:31:34 -0400 Subject: [PATCH 1/7] # This is a combination of 2 commits. # This is the 1st commit message: Update to newest UNF (d5f2ad100b76e372036453f8d25f9b6fbbbd2d1a) (November 22 2023) # This is the commit message #2: Add option for .local/share/HackerSM64/UNFLoader-dir.txt This allows referencing a custom UNFLoader path to be used, ideally for placing on the C drive for WSL instances. UNFLoader tends to hang for an unbearably long time when saved somewhere within the WSL directory structure, and simply using the Linux build isn't an option because it can't access Windows USB devices trivially. --- Makefile | 27 +- src/usb/debug.c | 1359 +++++++++++++++++++++++++++++---- src/usb/debug.h | 40 +- src/usb/usb.c | 153 ++-- src/usb/usb.h | 89 +-- tools/get_latest_unfloader.py | 18 +- 6 files changed, 1393 insertions(+), 293 deletions(-) diff --git a/Makefile b/Makefile index 1f74791573..680ffe6004 100644 --- a/Makefile +++ b/Makefile @@ -563,10 +563,19 @@ endif EMU_FLAGS = +# Adding a txt file to this location will then reference a UNFLoader path specified in the file, instead of locally. +# This is expecially important for WSL users because UNFLoader.exe is incredibly slow when run within WSL's filesystem, so this can be used to point to the C drive. +# The file should only contain the directory path that contains UNFLoader[.exe] (do not specify the filename). +LOADER_DIR_FILE_SPECIFICATION_PATH = ~/.local/share/HackerSM64/UNFLoader-dir.txt +LOADER_DIR = ./$(TOOLS_DIR) + +ifneq (,$(wildcard $(LOADER_DIR_FILE_SPECIFICATION_PATH))) + LOADER_DIR = $(shell cat $(LOADER_DIR_FILE_SPECIFICATION_PATH)) +endif ifneq (,$(call find-command,wslview)) - LOADER = ./$(TOOLS_DIR)/UNFLoader.exe + LOADER_EXEC = $(LOADER_DIR)/UNFLoader.exe else - LOADER = ./$(TOOLS_DIR)/UNFLoader + LOADER_EXEC = $(LOADER_DIR)/UNFLoader endif SHA1SUM = sha1sum @@ -622,17 +631,17 @@ test-pj64: $(ROM) # someone2639 # download and extract most recent unfloader build if needed -$(LOADER): -ifeq (,$(wildcard $(LOADER))) +$(LOADER_EXEC): +ifeq (,$(wildcard $(LOADER_EXEC))) @$(PRINT) "Downloading latest UNFLoader...$(NO_COL)\n" - $(PYTHON) $(TOOLS_DIR)/get_latest_unfloader.py $(TOOLS_DIR) + $(PYTHON) $(TOOLS_DIR)/get_latest_unfloader.py $(LOADER_DIR) endif -load: $(ROM) $(LOADER) - $(LOADER) -r $< +load: $(ROM) $(LOADER_EXEC) + $(LOADER_EXEC) -r $< -unf: $(ROM) $(LOADER) - $(LOADER) -d -r $< +unf: $(ROM) $(LOADER_EXEC) + $(LOADER_EXEC) -d -r $< libultra: $(BUILD_DIR)/libultra.a diff --git a/src/usb/debug.c b/src/usb/debug.c index 0685789ced..059e2e4426 100644 --- a/src/usb/debug.c +++ b/src/usb/debug.c @@ -5,38 +5,55 @@ A basic debug library that makes use of the USB library for N64 flashcarts. https://github.com/buu342/N64-UNFLoader ***************************************************************/ + #include "debug.h" #ifndef LIBDRAGON - #include + #include #include // Needed for Crash's Linux toolchain #else #include #include - #include #endif +#include #include +#include #include - #if DEBUG_MODE /********************************* Definitions *********************************/ - #define MSG_FAULT 0x10 - #define MSG_READ 0x11 - #define MSG_WRITE 0x12 + // USB thread messages + #define MSG_FAULT 0x10 + #define MSG_READ 0x11 + #define MSG_WRITE 0x12 - #define USBERROR_NONE 0 - #define USBERROR_NOTTEXT 1 - #define USBERROR_UNKNOWN 2 - #define USBERROR_TOOMUCH 3 - #define USBERROR_CUSTOM 4 + #define USBERROR_NONE 0 + #define USBERROR_NOTTEXT 1 + #define USBERROR_UNKNOWN 2 + #define USBERROR_TOOMUCH 3 + #define USBERROR_CUSTOM 4 + + // RDB thread messages (Libultra) + #ifndef LIBDRAGON + #define MSG_RDB_PACKET 0x10 + #define MSG_RDB_BPHIT 0x11 + #define MSG_RDB_PAUSE 0x12 + #endif + + // Breakpoints + #define BPOINT_COUNT 10 + #define MAKE_BREAKPOINT_INDEX(indx) (0x0000000D | ((indx) << 6)) + #define GET_BREAKPOINT_INDEX(addr) ((((addr) >> 6) & 0x0000FFFF)) - #define HASHTABLE_SIZE 7 - #define COMMAND_TOKENS 10 - #define BUFFER_SIZE 256 + // Helpful stuff + #define HASHTABLE_SIZE 7 + #define COMMAND_TOKENS 10 + #define BUFFER_SIZE 256 + #define REGISTER_COUNT 72 // 32 GPRs + 6 SPRs + 16 FPRs + fsr + fir (fcr0) + #define REGISTER_SIZE 16 // GDB expects the registers to be 64-bits /********************************* @@ -44,12 +61,21 @@ flashcarts. *********************************/ #ifdef LIBDRAGON - typedef unsigned char u8; + #ifndef TRUE + #define TRUE 1 + #endif + #ifndef FALSE + #define FALSE 0 + #endif + #define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000)) + #define OS_PHYSICAL_TO_K1(x) (void *)(((u32)(x)+0xa0000000)) + + typedef unsigned char u8; typedef unsigned short u16; typedef unsigned long u32; typedef unsigned long long u64; - typedef signed char s8; + typedef signed char s8; typedef short s16; typedef long s32; typedef long long s64; @@ -66,6 +92,9 @@ flashcarts. typedef float f32; typedef double f64; + + typedef void* OSMesg; + typedef exception_t OSThread; #endif @@ -81,6 +110,12 @@ flashcarts. char *string; } regDesc; + // Because of the thread context's messy struct, this'll come in handy + typedef struct { + int size; + void* ptr; + } regType; + // Thread message struct typedef struct { @@ -99,24 +134,61 @@ flashcarts. void* next; } debugCommand; + // Remote debugger packet lookup table + typedef struct + { + char* command; + void (*func)(); + } RDBPacketLUT; + + // Breakpoint struct + typedef struct + { + u32* addr; + u32 instruction; + } bPoint; + /********************************* Function Prototypes *********************************/ + // Threads + static void debug_thread_usb(void* arg); #ifndef LIBDRAGON - // Threads #if USE_FAULTTHREAD - static void debug_thread_fault(void *arg); + static void debug_thread_fault(void* arg); #endif - static void debug_thread_usb(void *arg); - - // Other + #else + #if AUTOPOLL_ENABLED + static void debug_timer_usb(int overflow); + #endif + #endif + #if USE_RDBTHREAD + #ifndef LIBDRAGON + static void debug_thread_rdb(void* arg); + #else + static void debug_thread_rdb(exception_t* arg); + static void debug_thread_rdb_pause(); + #endif + static void debug_thread_rdb_loop(OSThread* t); + static void debug_rdb_qsupported(OSThread* t); + static void debug_rdb_haltreason(OSThread* t); + static void debug_rdb_dumpregisters(OSThread* t); + static void debug_rdb_writeregisters(OSThread* t); + static void debug_rdb_readmemory(OSThread* t); + static void debug_rdb_writememory(OSThread* t); + static void debug_rdb_addbreakpoint(OSThread* t); + static void debug_rdb_removebreakpoint(OSThread* t); + static void debug_rdb_continue(OSThread* t); + static void debug_rdb_pause(OSThread* t); + #endif + + // Other + #ifndef LIBDRAGON #if OVERWRITE_OSPRINT static void* debug_osSyncPrintf_implementation(void *unused, const char *str, size_t len); #endif - #else - static void debug_thread_usb(void *arg); #endif static inline void debug_handle_64drivebutton(); @@ -160,112 +232,151 @@ flashcarts. static u64 debug_64dbut_hold = 0; #ifndef LIBDRAGON - // Fault thread globals - #if USE_FAULTTHREAD - static OSMesgQueue faultMessageQ; - static OSMesg faultMessageBuf; - static OSThread faultThread; - static u64 faultThreadStack[FAULT_THREAD_STACK/sizeof(u64)]; - #endif // USB thread globals static OSMesgQueue usbMessageQ; static OSMesg usbMessageBuf; static OSThread usbThread; static u64 usbThreadStack[USB_THREAD_STACK/sizeof(u64)]; + #if AUTOPOLL_ENABLED + static OSTimer usbThreadTimer; + #endif - // List of error causes - static regDesc causeDesc[] = { - {CAUSE_BD, CAUSE_BD, "BD"}, - {CAUSE_IP8, CAUSE_IP8, "IP8"}, - {CAUSE_IP7, CAUSE_IP7, "IP7"}, - {CAUSE_IP6, CAUSE_IP6, "IP6"}, - {CAUSE_IP5, CAUSE_IP5, "IP5"}, - {CAUSE_IP4, CAUSE_IP4, "IP4"}, - {CAUSE_IP3, CAUSE_IP3, "IP3"}, - {CAUSE_SW2, CAUSE_SW2, "IP2"}, - {CAUSE_SW1, CAUSE_SW1, "IP1"}, - {CAUSE_EXCMASK, EXC_INT, "Interrupt"}, - {CAUSE_EXCMASK, EXC_MOD, "TLB modification exception"}, - {CAUSE_EXCMASK, EXC_RMISS, "TLB exception on load or instruction fetch"}, - {CAUSE_EXCMASK, EXC_WMISS, "TLB exception on store"}, - {CAUSE_EXCMASK, EXC_RADE, "Address error on load or instruction fetch"}, - {CAUSE_EXCMASK, EXC_WADE, "Address error on store"}, - {CAUSE_EXCMASK, EXC_IBE, "Bus error exception on instruction fetch"}, - {CAUSE_EXCMASK, EXC_DBE, "Bus error exception on data reference"}, - {CAUSE_EXCMASK, EXC_SYSCALL, "System call exception"}, - {CAUSE_EXCMASK, EXC_BREAK, "Breakpoint exception"}, - {CAUSE_EXCMASK, EXC_II, "Reserved instruction exception"}, - {CAUSE_EXCMASK, EXC_CPU, "Coprocessor unusable exception"}, - {CAUSE_EXCMASK, EXC_OV, "Arithmetic overflow exception"}, - {CAUSE_EXCMASK, EXC_TRAP, "Trap exception"}, - {CAUSE_EXCMASK, EXC_VCEI, "Virtual coherency exception on intruction fetch"}, - {CAUSE_EXCMASK, EXC_FPE, "Floating point exception (see fpcsr)"}, - {CAUSE_EXCMASK, EXC_WATCH, "Watchpoint exception"}, - {CAUSE_EXCMASK, EXC_VCED, "Virtual coherency exception on data reference"}, - {0, 0, ""} - }; + // Fault thread globals + #if USE_FAULTTHREAD + static OSMesgQueue faultMessageQ; + static OSMesg faultMessageBuf; + static OSThread faultThread; + static u64 faultThreadStack[FAULT_THREAD_STACK/sizeof(u64)]; - // List of register descriptions - static regDesc srDesc[] = { - {SR_CU3, SR_CU3, "CU3"}, - {SR_CU2, SR_CU2, "CU2"}, - {SR_CU1, SR_CU1, "CU1"}, - {SR_CU0, SR_CU0, "CU0"}, - {SR_RP, SR_RP, "RP"}, - {SR_FR, SR_FR, "FR"}, - {SR_RE, SR_RE, "RE"}, - {SR_BEV, SR_BEV, "BEV"}, - {SR_TS, SR_TS, "TS"}, - {SR_SR, SR_SR, "SR"}, - {SR_CH, SR_CH, "CH"}, - {SR_CE, SR_CE, "CE"}, - {SR_DE, SR_DE, "DE"}, - {SR_IBIT8, SR_IBIT8, "IM8"}, - {SR_IBIT7, SR_IBIT7, "IM7"}, - {SR_IBIT6, SR_IBIT6, "IM6"}, - {SR_IBIT5, SR_IBIT5, "IM5"}, - {SR_IBIT4, SR_IBIT4, "IM4"}, - {SR_IBIT3, SR_IBIT3, "IM3"}, - {SR_IBIT2, SR_IBIT2, "IM2"}, - {SR_IBIT1, SR_IBIT1, "IM1"}, - {SR_KX, SR_KX, "KX"}, - {SR_SX, SR_SX, "SX"}, - {SR_UX, SR_UX, "UX"}, - {SR_KSU_MASK, SR_KSU_USR, "USR"}, - {SR_KSU_MASK, SR_KSU_SUP, "SUP"}, - {SR_KSU_MASK, SR_KSU_KER, "KER"}, - {SR_ERL, SR_ERL, "ERL"}, - {SR_EXL, SR_EXL, "EXL"}, - {SR_IE, SR_IE, "IE"}, - {0, 0, ""} - }; + // List of error causes + static regDesc causeDesc[] = { + {CAUSE_BD, CAUSE_BD, "BD"}, + {CAUSE_IP8, CAUSE_IP8, "IP8"}, + {CAUSE_IP7, CAUSE_IP7, "IP7"}, + {CAUSE_IP6, CAUSE_IP6, "IP6"}, + {CAUSE_IP5, CAUSE_IP5, "IP5"}, + {CAUSE_IP4, CAUSE_IP4, "IP4"}, + {CAUSE_IP3, CAUSE_IP3, "IP3"}, + {CAUSE_SW2, CAUSE_SW2, "IP2"}, + {CAUSE_SW1, CAUSE_SW1, "IP1"}, + {CAUSE_EXCMASK, EXC_INT, "Interrupt"}, + {CAUSE_EXCMASK, EXC_MOD, "TLB modification exception"}, + {CAUSE_EXCMASK, EXC_RMISS, "TLB exception on load or instruction fetch"}, + {CAUSE_EXCMASK, EXC_WMISS, "TLB exception on store"}, + {CAUSE_EXCMASK, EXC_RADE, "Address error on load or instruction fetch"}, + {CAUSE_EXCMASK, EXC_WADE, "Address error on store"}, + {CAUSE_EXCMASK, EXC_IBE, "Bus error exception on instruction fetch"}, + {CAUSE_EXCMASK, EXC_DBE, "Bus error exception on data reference"}, + {CAUSE_EXCMASK, EXC_SYSCALL, "System call exception"}, + {CAUSE_EXCMASK, EXC_BREAK, "Breakpoint exception"}, + {CAUSE_EXCMASK, EXC_II, "Reserved instruction exception"}, + {CAUSE_EXCMASK, EXC_CPU, "Coprocessor unusable exception"}, + {CAUSE_EXCMASK, EXC_OV, "Arithmetic overflow exception"}, + {CAUSE_EXCMASK, EXC_TRAP, "Trap exception"}, + {CAUSE_EXCMASK, EXC_VCEI, "Virtual coherency exception on intruction fetch"}, + {CAUSE_EXCMASK, EXC_FPE, "Floating point exception (see fpcsr)"}, + {CAUSE_EXCMASK, EXC_WATCH, "Watchpoint exception"}, + {CAUSE_EXCMASK, EXC_VCED, "Virtual coherency exception on data reference"}, + {0, 0, ""} + }; + + // List of register descriptions + static regDesc srDesc[] = { + {SR_CU3, SR_CU3, "CU3"}, + {SR_CU2, SR_CU2, "CU2"}, + {SR_CU1, SR_CU1, "CU1"}, + {SR_CU0, SR_CU0, "CU0"}, + {SR_RP, SR_RP, "RP"}, + {SR_FR, SR_FR, "FR"}, + {SR_RE, SR_RE, "RE"}, + {SR_BEV, SR_BEV, "BEV"}, + {SR_TS, SR_TS, "TS"}, + {SR_SR, SR_SR, "SR"}, + {SR_CH, SR_CH, "CH"}, + {SR_CE, SR_CE, "CE"}, + {SR_DE, SR_DE, "DE"}, + {SR_IBIT8, SR_IBIT8, "IM8"}, + {SR_IBIT7, SR_IBIT7, "IM7"}, + {SR_IBIT6, SR_IBIT6, "IM6"}, + {SR_IBIT5, SR_IBIT5, "IM5"}, + {SR_IBIT4, SR_IBIT4, "IM4"}, + {SR_IBIT3, SR_IBIT3, "IM3"}, + {SR_IBIT2, SR_IBIT2, "IM2"}, + {SR_IBIT1, SR_IBIT1, "IM1"}, + {SR_KX, SR_KX, "KX"}, + {SR_SX, SR_SX, "SX"}, + {SR_UX, SR_UX, "UX"}, + {SR_KSU_MASK, SR_KSU_USR, "USR"}, + {SR_KSU_MASK, SR_KSU_SUP, "SUP"}, + {SR_KSU_MASK, SR_KSU_KER, "KER"}, + {SR_ERL, SR_ERL, "ERL"}, + {SR_EXL, SR_EXL, "EXL"}, + {SR_IE, SR_IE, "IE"}, + {0, 0, ""} + }; + + // List of floating point registers descriptions + static regDesc fpcsrDesc[] = { + {FPCSR_FS, FPCSR_FS, "FS"}, + {FPCSR_C, FPCSR_C, "C"}, + {FPCSR_CE, FPCSR_CE, "Unimplemented operation"}, + {FPCSR_CV, FPCSR_CV, "Invalid operation"}, + {FPCSR_CZ, FPCSR_CZ, "Division by zero"}, + {FPCSR_CO, FPCSR_CO, "Overflow"}, + {FPCSR_CU, FPCSR_CU, "Underflow"}, + {FPCSR_CI, FPCSR_CI, "Inexact operation"}, + {FPCSR_EV, FPCSR_EV, "EV"}, + {FPCSR_EZ, FPCSR_EZ, "EZ"}, + {FPCSR_EO, FPCSR_EO, "EO"}, + {FPCSR_EU, FPCSR_EU, "EU"}, + {FPCSR_EI, FPCSR_EI, "EI"}, + {FPCSR_FV, FPCSR_FV, "FV"}, + {FPCSR_FZ, FPCSR_FZ, "FZ"}, + {FPCSR_FO, FPCSR_FO, "FO"}, + {FPCSR_FU, FPCSR_FU, "FU"}, + {FPCSR_FI, FPCSR_FI, "FI"}, + {FPCSR_RM_MASK, FPCSR_RM_RN, "RN"}, + {FPCSR_RM_MASK, FPCSR_RM_RZ, "RZ"}, + {FPCSR_RM_MASK, FPCSR_RM_RP, "RP"}, + {FPCSR_RM_MASK, FPCSR_RM_RM, "RM"}, + {0, 0, ""} + }; + #endif + #endif - // List of floating point registers descriptions - static regDesc fpcsrDesc[] = { - {FPCSR_FS, FPCSR_FS, "FS"}, - {FPCSR_C, FPCSR_C, "C"}, - {FPCSR_CE, FPCSR_CE, "Unimplemented operation"}, - {FPCSR_CV, FPCSR_CV, "Invalid operation"}, - {FPCSR_CZ, FPCSR_CZ, "Division by zero"}, - {FPCSR_CO, FPCSR_CO, "Overflow"}, - {FPCSR_CU, FPCSR_CU, "Underflow"}, - {FPCSR_CI, FPCSR_CI, "Inexact operation"}, - {FPCSR_EV, FPCSR_EV, "EV"}, - {FPCSR_EZ, FPCSR_EZ, "EZ"}, - {FPCSR_EO, FPCSR_EO, "EO"}, - {FPCSR_EU, FPCSR_EU, "EU"}, - {FPCSR_EI, FPCSR_EI, "EI"}, - {FPCSR_FV, FPCSR_FV, "FV"}, - {FPCSR_FZ, FPCSR_FZ, "FZ"}, - {FPCSR_FO, FPCSR_FO, "FO"}, - {FPCSR_FU, FPCSR_FU, "FU"}, - {FPCSR_FI, FPCSR_FI, "FI"}, - {FPCSR_RM_MASK, FPCSR_RM_RN, "RN"}, - {FPCSR_RM_MASK, FPCSR_RM_RZ, "RZ"}, - {FPCSR_RM_MASK, FPCSR_RM_RP, "RP"}, - {FPCSR_RM_MASK, FPCSR_RM_RM, "RM"}, - {0, 0, ""} + #if USE_RDBTHREAD + // Remote debugger thread globals + #ifndef LIBDRAGON + static OSMesgQueue rdbMessageQ; + static OSMesg rdbMessageBuf; + static OSThread rdbThread; + static u64 rdbThreadStack[RDB_THREAD_STACK/sizeof(u64)]; + #endif + + // RDB status globals + static vu8 debug_rdbpaused = FALSE; + #ifndef LIBDRAGON + static OSTime debug_pausetime = 0; + #else + static u32 debug_pausetime = 0; + static u8 debug_ismanualpause = FALSE; + #endif + static bPoint debug_bpoints[BPOINT_COUNT]; + + // Remote debugger packet lookup table + RDBPacketLUT lut_rdbpackets[] = { + // Due to the use of strncmp, the order of strings matters! + {"qSupported", debug_rdb_qsupported}, + {"?", debug_rdb_haltreason}, + {"g", debug_rdb_dumpregisters}, + {"G", debug_rdb_writeregisters}, + {"m", debug_rdb_readmemory}, + {"M", debug_rdb_writememory}, + {"Z0", debug_rdb_addbreakpoint}, + {"z0", debug_rdb_removebreakpoint}, + {"c", debug_rdb_continue}, + {"\x03", debug_rdb_pause}, }; #endif @@ -280,17 +391,31 @@ flashcarts. ==============================*/ void debug_initialize() - { + { // Initialize the USB functions if (!usb_initialize()) return; - // Overwrite osSyncPrintf + // Initialize globals + memset(debug_commands_hashtable, 0, sizeof(debugCommand*)*HASHTABLE_SIZE); + memset(debug_commands_elements, 0, sizeof(debugCommand)*MAX_COMMANDS); + + // Libultra functions #ifndef LIBDRAGON + // Overwrite osSyncPrintf #if OVERWRITE_OSPRINT __printfunc = (void*)debug_osSyncPrintf_implementation; #endif + // Initialize the USB thread + osCreateThread(&usbThread, USB_THREAD_ID, debug_thread_usb, 0, + (usbThreadStack+USB_THREAD_STACK/sizeof(u64)), + USB_THREAD_PRI); + osStartThread(&usbThread); + #if AUTOPOLL_ENABLED + osSetTimer(&usbThreadTimer, 0, OS_USEC_TO_CYCLES(AUTOPOLL_TIME*1000), &usbMessageQ, (OSMesg)NULL); + #endif + // Initialize the fault thread #if USE_FAULTTHREAD osCreateThread(&faultThread, FAULT_THREAD_ID, debug_thread_fault, 0, @@ -299,11 +424,34 @@ flashcarts. osStartThread(&faultThread); #endif - // Initialize the USB thread - osCreateThread(&usbThread, USB_THREAD_ID, debug_thread_usb, 0, - (usbThreadStack+USB_THREAD_STACK/sizeof(u64)), - USB_THREAD_PRI); - osStartThread(&usbThread); + // Initialize the remote debugger thread + #if USE_RDBTHREAD + osCreateThread(&rdbThread, RDB_THREAD_ID, debug_thread_rdb, (void*)osGetThreadId(NULL), + (rdbThreadStack+RDB_THREAD_STACK/sizeof(u64)), + RDB_THREAD_PRI); + osStartThread(&rdbThread); + + // Initialize breakpoints + osSetEventMesg(OS_EVENT_CPU_BREAK, &rdbMessageQ, (OSMesg)MSG_RDB_BPHIT); + memset(debug_bpoints, 0, BPOINT_COUNT*sizeof(bPoint)); + + // Pause the main thread + usb_purge(); + usb_write(DATATYPE_TEXT, "Pausing main thread until GDB connects and resumes\n", 51+1); + osSendMesg(&rdbMessageQ, (OSMesg)MSG_RDB_PAUSE, OS_MESG_BLOCK); + #endif + #else + timer_init(); // If the timer subsystem has been initialized already, it's not a problem to call it again. + #if AUTOPOLL_ENABLED + new_timer(TIMER_TICKS(AUTOPOLL_TIME*1000), TF_CONTINUOUS, debug_timer_usb); + #endif + #if USE_RDBTHREAD + memset(debug_bpoints, 0, BPOINT_COUNT*sizeof(bPoint)); + register_exception_handler(debug_thread_rdb); + usb_purge(); + usb_write(DATATYPE_TEXT, "Pausing main thread until GDB connects and resumes\n", 51+1); + debug_thread_rdb_pause(); + #endif #endif // Mark the debug mode as initialized @@ -345,7 +493,7 @@ flashcarts. usbMesg msg; va_list args; - // use the internal libultra printf function to format the string + // Use the internal libultra printf function to format the string va_start(args, message); #ifndef LIBDRAGON len = _Printf(&printf_handler, debug_buffer, message, args); @@ -471,7 +619,14 @@ flashcarts. #endif // Intentionally cause a TLB exception on load/instruction fetch + #ifdef LIBDRAGON + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #endif crash = *(volatile char *)1; + #ifdef LIBDRAGON + #pragma GCC diagnostic pop + #endif (void)crash; } @@ -570,9 +725,6 @@ flashcarts. // Ensure debug mode is initialized if (!debug_initialized) return; - - // Handle 64Drive button polling - debug_handle_64drivebutton(); // Send a read message to the USB thread msg.msgtype = MSG_READ; @@ -734,12 +886,12 @@ flashcarts. dataleft = 0; break; } - // fallthrough + FALL_THROUGH; case '@': filestep++; if (filestep < 3) break; - // fallthrough + FALL_THROUGH; default: // Decide what to do based on the file handle if (filestep == 0 && debug_command_incoming_start[tok] == -1) @@ -776,6 +928,24 @@ flashcarts. // Rewind the USB fully usb_rewind(datasize); } + + #ifdef LIBDRAGON + #if AUTOPOLL_ENABLED + /*============================== + debug_timer_usb + A function that's called by the auto-poll timer + @param How many ticks the timer overflew by (unused) + ==============================*/ + + static void debug_timer_usb(int overflow) + { + usbMesg msg; + (void)overflow; // To prevent unused variable errors + msg.msgtype = MSG_READ; + debug_thread_usb(&msg); + } + #endif + #endif /*============================== @@ -811,6 +981,29 @@ flashcarts. int header = usb_poll(); debugCommand* entry; + // RDB packets should be rerouted to the RDB thread + #if USE_RDBTHREAD + if (USBHEADER_GETTYPE(header) == DATATYPE_RDBPACKET) + { + #ifndef LIBDRAGON + osSendMesg(&rdbMessageQ, (OSMesg)MSG_RDB_PACKET, OS_MESG_BLOCK); + #else + + // Exceptional case, handle pausing through CTRL+C + char packetstart; + usb_read(&packetstart, 1); + if (packetstart == '\x03') + { + usb_rewind(1); + debug_thread_rdb_pause(); + } + else + debug_thread_rdb_loop(NULL); + #endif + continue; + } + #endif + // Ensure we're receiving a text command if (USBHEADER_GETTYPE(header) != DATATYPE_TEXT) { @@ -863,6 +1056,9 @@ flashcarts. } } + // Handle 64Drive button polling + debug_handle_64drivebutton(); + // Spit out an error if there was one during the command parsing if (errortype != USBERROR_NONE) { @@ -885,14 +1081,18 @@ flashcarts. errortype = USBERROR_NONE; } + // Handle the other USB messages - switch (threadMsg->msgtype) + if (threadMsg != NULL) { - case MSG_WRITE: - if (usb_timedout()) - usb_sendheartbeat(); - usb_write(threadMsg->datatype, threadMsg->buff, threadMsg->size); - break; + switch (threadMsg->msgtype) + { + case MSG_WRITE: + if (usb_timedout()) + usb_sendheartbeat(); + usb_write(threadMsg->datatype, threadMsg->buff, threadMsg->size); + break; + } } // If we're in libdragon, break out of the loop as we don't need it @@ -934,8 +1134,10 @@ flashcarts. return ret; } - #endif - + #endif + #endif + + #ifndef LIBDRAGON #if USE_FAULTTHREAD /*============================== @@ -949,7 +1151,7 @@ flashcarts. static void debug_printreg(u32 value, char *name, regDesc *desc) { char first = 1; - debug_printf("%s\t\t0x%08x <", name, value); + debug_printf("%s\t\t0x%16x <", name, value); while (desc->mask != 0) { if ((value & desc->mask) == desc->value) @@ -990,15 +1192,33 @@ flashcarts. { __OSThreadContext* context = &curr->context; + // If the debug or rdb thread crashed, restart it + if (curr->id == USB_THREAD_ID) + { + osCreateThread(&usbThread, USB_THREAD_ID, debug_thread_usb, 0, + (usbThreadStack+USB_THREAD_STACK/sizeof(u64)), + USB_THREAD_PRI); + osStartThread(&usbThread); + } + #if USE_RDBTHREAD + else if (curr->id == RDB_THREAD_ID) + { + osCreateThread(&rdbThread, RDB_THREAD_ID, debug_thread_rdb, (void*)osGetThreadId(NULL), + (rdbThreadStack+RDB_THREAD_STACK/sizeof(u64)), + RDB_THREAD_PRI); + osStartThread(&rdbThread); + } + #endif + // Print the basic info debug_printf("Fault in thread: %d\n\n", curr->id); - debug_printf("pc\t\t0x%08x\n", context->pc); + debug_printf("pc\t\t0x%16x\n", context->pc); if (assert_file == NULL) debug_printreg(context->cause, "cause", causeDesc); else debug_printf("cause\t\tAssertion failed in file '%s', line %d.\n", assert_file, assert_line); debug_printreg(context->sr, "sr", srDesc); - debug_printf("badvaddr\t0x%08x\n\n", context->badvaddr); + debug_printf("badvaddr\t0x%16x\n\n", context->badvaddr); // Print the registers debug_printf("at 0x%016llx v0 0x%016llx v1 0x%016llx\n", context->at, context->v0, context->v1); @@ -1026,8 +1246,857 @@ flashcarts. } } } - #endif #endif + #if USE_RDBTHREAD + #ifndef LIBDRAGON + /*============================== + debug_thread_rdb + Handles the remote debugger thread (Libultra) + @param Arbitrary data that the thread can receive. + Used for passing the main thread ID. + ==============================*/ + + static void debug_thread_rdb(void *arg) + { + OSId mainid = (OSId)arg; + OSThread* mainthread = &rdbThread; + + // Find the main thread pointer given its ID + while (mainthread->id != mainid) + mainthread = mainthread->tlnext; + + // Create the message queue for the rdb messages + osCreateMesgQueue(&rdbMessageQ, &rdbMessageBuf, 1); + + // Thread loop + while (1) + { + OSMesg msg; + OSThread* affected = NULL; + + // Wait for an rdb message to arrive + osRecvMesg(&rdbMessageQ, &msg, OS_MESG_BLOCK); + + // Exceptional case, handle pausing through CTRL+C + if (USBHEADER_GETTYPE(usb_poll()) == DATATYPE_RDBPACKET) + { + char packetstart; + usb_read(&packetstart, 1); + if (packetstart == '\x03') + msg = (OSMesg)MSG_RDB_PAUSE; + usb_rewind(1); + } + + + // Check what message we received + switch ((s32)msg) + { + case MSG_RDB_PACKET: + break; // Do nothing + case MSG_RDB_BPHIT: + affected = mainthread; + debug_rdbpaused = TRUE; + debug_pausetime = osGetTime(); + + // Find out which thread hit the bp exception + while (1) + { + if (affected->flags & OS_FLAG_CPU_BREAK) + break; + affected = affected->tlnext; + } + usb_purge(); + usb_write(DATATYPE_RDBPACKET, "T05swbreak:;", 12+1); + break; + case MSG_RDB_PAUSE: + affected = mainthread; + debug_rdbpaused = TRUE; + debug_pausetime = osGetTime(); + break; + } + + // Do the RDB thread main loop + debug_thread_rdb_loop(affected); + } + } + #else + + /*============================== + debug_thread_rdb_pause + "Pauses" the program execution in Libdragon. + @param The received exception + ==============================*/ + + static void debug_thread_rdb_pause() + { + debug_ismanualpause = TRUE; + debug_pausetime = C0_COUNT(); + asm volatile("break"); // Jank workaround because I can't "message" the exception handler "thread" + } + + + /*============================== + debug_thread_rdb + Handles the remote debugger logic (Libdragon) + @param The received exception + ==============================*/ + + static void debug_thread_rdb(exception_t* exc) + { + switch (exc->code) + { + case EXCEPTION_CODE_BREAKPOINT: + debug_rdbpaused = TRUE; + if (!debug_ismanualpause) + { + usb_purge(); + usb_write(DATATYPE_RDBPACKET, "T05swbreak:;", 12+1); + } + debug_pausetime = C0_COUNT(); + debug_thread_rdb_loop(exc); + if (debug_ismanualpause) + { + debug_ismanualpause = FALSE; + exc->regs->epc += 4; // Gotta increment PC otherwise the program will likely hit the breakpoint again in debug_initialize + } + break; + default: + exception_default_handler(exc); + break; + } + } + #endif + + + /*============================== + debug_thread_rdb_loop + Handles the loop of the remote debugger thread + @param (Libultra) A pointer to the affected thread + (Libdragon) A pointer to the exception struct + ==============================*/ + + static void debug_thread_rdb_loop(OSThread* affected) + { + // Handle the RDB packet + do + { + int usbheader = usb_poll(); + if (USBHEADER_GETTYPE(usbheader) == DATATYPE_RDBPACKET) + { + int i; + u8 found = FALSE; + u32 size = USBHEADER_GETSIZE(usbheader); + + // Read the GDB packet from USB + memset(debug_buffer, 0, BUFFER_SIZE); + usb_read(&debug_buffer, (size <= BUFFER_SIZE) ? size : BUFFER_SIZE); + + // Run a function based on what we received + for (i=0; i<(sizeof(lut_rdbpackets)/sizeof(lut_rdbpackets[0])); i++) + { + if (!strncmp(lut_rdbpackets[i].command, debug_buffer, strlen(lut_rdbpackets[i].command))) + { + found = TRUE; + lut_rdbpackets[i].func(affected); + break; + } + } + + // If we didn't find a supported command, then reply back with nothing + if (!found) + { + usb_purge(); + usb_write(DATATYPE_RDBPACKET, "\0", 1); + } + } + usb_purge(); + } + while (debug_rdbpaused); // Loop forever while we are paused + } + + /*============================== + debug_rdb_qsupported + Responds to GDB with the supported features + @param The affected thread, if any + ==============================*/ + + static void debug_rdb_qsupported(OSThread* t) + { + sprintf(debug_buffer, "swbreak+"); + usb_purge(); + usb_write(DATATYPE_RDBPACKET, debug_buffer, strlen(debug_buffer)); + } + + + /*============================== + debug_rdb_haltreason + Responds to GDB with the halt reason + @param The affected thread, if any + ==============================*/ + + static void debug_rdb_haltreason(OSThread* t) + { + usb_purge(); + usb_write(DATATYPE_RDBPACKET, "S02", 3+1); + } + + + #ifndef LIBDRAGON + /*============================== + register_fromindex + Gets a register type from a given index + @param The affected thread context + @param The register index + @returns The regType that matches the given index + ==============================*/ + + static regType register_fromindex(__OSThreadContext* context, int index) + { + regType reg = {0, NULL}; + switch (index) + { + case 0: // Zero register + case 26: // K0 + case 27: // K1 + case 71: // FCR0 + return reg; + case 32: reg.size = 4; reg.ptr = ((u32*)&context->sr); return reg; + case 33: reg.size = 8; reg.ptr = ((u64*)&context->lo); return reg; + case 34: reg.size = 8; reg.ptr = ((u64*)&context->hi); return reg; + case 35: reg.size = 4; reg.ptr = ((u32*)&context->badvaddr); return reg; + case 36: reg.size = 4; reg.ptr = ((u32*)&context->cause); return reg; + case 37: reg.size = 4; reg.ptr = ((u32*)&context->pc); return reg; + case 70: reg.size = 4; reg.ptr = ((u32*)&context->fpcsr); return reg; + default: + if (index < 32) + { + reg.size = 8; + if (index > 27) + reg.ptr = ((u64*)&context->gp)+(index-28); + else + reg.ptr = ((u64*)&context->at)+(index-1); + return reg; + } + else + { + reg.size = 8; + reg.ptr = ((u64*)&context->fp0)+(((u32)(index-38))/2); + return reg; + } + } + } + #else + /*============================== + register_fromindex + Gets a register type from a given index + @param The affected thread context + @param The register index + @returns The regType that matches the given index + ==============================*/ + + static regType register_fromindex(reg_block_t* context, int index) + { + regType reg = {0, NULL}; + switch (index) + { + case 0: // Zero register + case 26: // K0 + case 27: // K1 + case 71: // FCR0 + case 35: // BadVAddr + case 37: // pc + return reg; + case 32: reg.size = 4; reg.ptr = ((u32*)&context->sr); return reg; + case 33: reg.size = 8; reg.ptr = ((u64*)&context->lo); return reg; + case 34: reg.size = 8; reg.ptr = ((u64*)&context->hi); return reg; + case 36: reg.size = 4; reg.ptr = ((u32*)&context->cr); return reg; + case 70: reg.size = 4; reg.ptr = ((u32*)&context->fc31); return reg; + default: + if (index < 32) + { + reg.size = 8; + reg.ptr = (u64*)&context->gpr[index-1]; + return reg; + } + else + { + reg.size = 8; + reg.ptr = (u64*)&context->fpr[index-38]; + return reg; + } + } + return reg; + } + #endif + + + /*============================== + debug_rdb_printreg_rle + Sprintf's a register value into a buffer, + compressed with Run-Length Encoding + @param The buffer to write to + @param The register type + @returns The number of bytes written + ==============================*/ + + static u32 debug_rdb_printreg_rle(char* buf, regType reg) + { + if (reg.ptr != NULL) + { + int i; + u8 count; + u32 totalwrote = 0; + char last; + char temp[REGISTER_SIZE+1]; + + // Read the register value into a string + if (reg.size == 8) + sprintf(temp, "%016llx", (u64)(*(u64*)reg.ptr)); + else + sprintf(temp, "%016llx", (u64)(*(u32*)reg.ptr)); + last = temp[0]; + count = 1; + + // Find repeated characters + for (i=1; i<(REGISTER_SIZE+1); i++) + { + if (temp[i] != last) + { + // If the repeat was more than 3, then it's worth RLE'ing + if (count > 3) + { + // Because 6 (#) and 7 ($) are special characters in GDB, we have to do them differently + if (count == 7) + totalwrote += sprintf(buf+totalwrote, "%c*\"%c", last, last); + else if (count == 8) + totalwrote += sprintf(buf+totalwrote, "%c*\"%c%c", last, last, last); + else + totalwrote += sprintf(buf+totalwrote, "%c*%c", last, ' '+(count-4)); + } + else + { + int j; + for (j=0; jcontext; + #else + reg_block_t* context = t->regs; + #endif + + // Start by sending a HEADER packet with the chunk count + header[0] = DATATYPE_RDBPACKET; + header[1] = chunkcount; + usb_purge(); + usb_write(DATATYPE_HEADER, &header, sizeof(u32)*2); + + // Perform the humpty dumpty + offset += sprintf(debug_buffer+offset, "0*,"); // Zero register + for (i=1; iepc)); + #endif + else + { + regType reg = register_fromindex(context, i); + offset += debug_rdb_printreg_rle(debug_buffer+offset, reg); + } + + // Send a chunk if we're about to overrun the debug buffer + if ((strlen(debug_buffer)+REGISTER_SIZE+1) > BUFFER_SIZE || i == (REGISTER_COUNT-1)) + { + usb_write(DATATYPE_RDBPACKET, debug_buffer, strlen(debug_buffer)+1); + memset(debug_buffer, 0, BUFFER_SIZE); + offset = 0; + chunkcount--; + } + } + + // Finish sending the other chunks + for (i=chunkcount; i>=0; i--) + usb_write(DATATYPE_RDBPACKET, "\0", 1); + } + else + { + usb_purge(); + usb_write(DATATYPE_RDBPACKET, "E00", 3+1); + } + } + + + /*============================== + hex2u64 + Converts a string containing a hexadecimal value + into a number. This exists because strtol is broken + on ModernSDK. + @param The string with the hexadecimal number + @returns The converted value + ==============================*/ + + static u64 hex2u64(char* addr) + { + int i = 0; + u64 ret = 0; + while (addr[i] != '\0') + { + u32 val; + if (addr[i] <= '9') + val = addr[i]-'0'; + else if (addr[i] <= 'F') + val = 10 + addr[i] - 'A'; + else + val = 10 + addr[i] - 'a'; + ret = (ret << 4) | (val & 0xF); + i++; + } + return ret; + } + + + /*============================== + debug_rdb_writeregisters + Writes a set of registers from a GDB packet + @param The affected thread, if any + ==============================*/ + + static void debug_rdb_writeregisters(OSThread* t) + { + if (t != NULL) + { + int i; + #ifndef LIBDRAGON + __OSThreadContext* context = &t->context; + #else + reg_block_t* context = t->regs; + #endif + + // The incoming data probably won't fit in the buffer, so we'll go bit by bit + usb_rewind(BUFFER_SIZE); + + // Skip the 'G' at the start of the command + usb_skip(1); + + // Do the writing + for (i=0; i= 0x80000000 && addr < 0x80000000 + osMemSize) + { + #ifndef LIBDRAGON + osWritebackDCache((u32*)addr, size); + #else + data_cache_hit_writeback((u32*)addr, size); + #endif + validaddress = TRUE; + } + + // Read the memory address, one byte at a time + while (read < size) + { + u8 val = 0; + if (validaddress) + val = *((vu8*)(addr+read)); + written += sprintf(debug_buffer+written, "%02x", val); + + // Send the partial address dump if we're almost overrunning the buffer, or if we've finished + read++; + if (written+3 >= BUFFER_SIZE || read == size) + { + usb_write(DATATYPE_RDBPACKET, &debug_buffer, strlen(debug_buffer)+1); + written = 0; + chunkcount--; + } + } + + // Finish sending the other chunks + for (i=chunkcount; i>=0; i--) + usb_write(DATATYPE_RDBPACKET, "\0", 1); + } + + + /*============================== + debug_rdb_writememory + Writes the memory from a GDB packet + @param The affected thread, if any + ==============================*/ + + static void debug_rdb_writememory(OSThread* t) + { + int i; + u32 addr; + u32 size; + #ifdef LIBDRAGON + u32 osMemSize = get_memory_size(); + #endif + char* commandp = &debug_buffer[0]; + + // Skip the 'M' at the start of the command + commandp++; + + // Extract the address value + strtok(commandp, ","); + addr = (u32)hex2u64(commandp); + + // Extract the size value + commandp = strtok(NULL, ":"); + size = (u32)hex2u64(commandp); + + // Finally, point to the data we're actually gonna write + commandp = strtok(NULL, "\0"); + + // We need to translate the address before trying to read it + addr = debug_rdb_translateaddr(addr); + + // Ensure we are writing to a valid memory address + if (addr >= 0x80000000 && addr < 0x80000000 + osMemSize) + { + // Read the memory address, one byte at a time + for (i=0; i= 0x80000000 && addr < 0x80000000 + osMemSize) + { + for (i=0; i= 0x80000000 && addr < 0x80000000 + osMemSize) + { + index = GET_BREAKPOINT_INDEX(*((u32*)addr))-1; + if (debug_bpoints[index].addr == (u32*)addr) + { + int i; + + // Remove the breakpoint + *((vu32*)addr) = debug_bpoints[index].instruction; + #ifndef LIBDRAGON + osWritebackDCache((u32*)addr, 4); + osInvalICache((u32*)addr, 4); + #else + data_cache_hit_writeback((u32*)addr, 4); + inst_cache_hit_invalidate((u32*)addr, 4); + #endif + + // Move all the breakpoints in front of it back + for (i=index; i 0) { @@ -642,17 +642,17 @@ void usb_read(void* buffer, int nbytes) left = usb_dataleft; if (block > left) block = left; - + // Call the read function if we're reading a new block if (usb_readblock != blockoffset) { usb_readblock = blockoffset; funcPointer_read(); } - + // Copy from the USB buffer to the supplied buffer - memcpy(buffer+read, usb_buffer+copystart, block); - + memcpy((void*)(((u32)buffer)+read), usb_buffer+copystart, block); + // Increment/decrement all our counters read += block; left -= block; @@ -729,7 +729,7 @@ char usb_timedout() version. ==============================*/ -void usb_sendheartbeat() +void usb_sendheartbeat(void) { u8 buffer[4]; @@ -900,7 +900,7 @@ static u32 usb_64drive_cui_read(u32 offset) // Wait until USB FIFO is disarmed while ((usb_io_read(D64_REG_USBCOMSTAT) & D64_CUI_ARM_MASK) != D64_CUI_ARM_IDLE) ; - + // Due to a 64drive bug, we need to ignore the last 512 bytes of the transfer if it's larger than 512 bytes if (size > 512) size -= 512; @@ -921,7 +921,7 @@ static u32 usb_64drive_cui_read(u32 offset) static void usb_64drive_write(int datatype, const void* data, int size) { - u32 left = size; + s32 left = size; u32 pi_address = D64_BASE + DEBUG_ADDRESS; // Return if previous transfer timed out @@ -942,12 +942,16 @@ static void usb_64drive_write(int datatype, const void* data, int size) // Copy data to PI DMA aligned buffer memcpy(usb_buffer, data, block); + + // Pad the buffer with zeroes if it wasn't 4 byte aligned + while (block%4) + usb_buffer[block++] = 0; // Copy block of data from RDRAM to SDRAM usb_dma_write(usb_buffer, pi_address, ALIGN(block, 2)); // Update pointers and variables - data += block; + data = (void*)(((u32)data) + block); left -= block; pi_address += block; } @@ -1015,7 +1019,7 @@ static void usb_64drive_read(void) @return FALSE on success, TRUE on failure ==============================*/ -static char usb_everdrive_usbbusy(void) +static char usb_everdrive_usbbusy(void) { u32 val; u32 timeout = usb_timeout_start(); @@ -1025,6 +1029,7 @@ static char usb_everdrive_usbbusy(void) if (usb_timeout_check(timeout, ED_TIMEOUT)) { usb_io_write(ED_REG_USBCFG, ED_USBMODE_RDNOP); + usb_didtimeout = TRUE; return TRUE; } } @@ -1039,11 +1044,11 @@ static char usb_everdrive_usbbusy(void) @return TRUE if it can read, FALSE if not ==============================*/ -static char usb_everdrive_canread(void) +static char usb_everdrive_canread(void) { u32 val; u32 status = ED_USBSTAT_POWER; - + // Read the USB register and check its status val = usb_io_read(ED_REG_USBCFG); status = val & (ED_USBSTAT_POWER | ED_USBSTAT_RXF); @@ -1063,15 +1068,15 @@ static char usb_everdrive_canread(void) static void usb_everdrive_readusb(void* buffer, int size) { u16 block, addr; - - while (size) + + while (size) { // Get the block size block = BUFFER_SIZE; if (block > size) block = size; addr = BUFFER_SIZE - block; - + // Request to read from the USB usb_io_write(ED_REG_USBCFG, ED_USBMODE_RD | addr); @@ -1104,7 +1109,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) int left = size; int offset = 8; u32 header = (size & 0x00FFFFFF) | (datatype << 24); - + // Put in the DMA header along with length and type information in the global buffer usb_buffer[0] = 'D'; usb_buffer[1] = 'M'; @@ -1114,7 +1119,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) usb_buffer[5] = (header >> 16) & 0xFF; usb_buffer[6] = (header >> 8) & 0xFF; usb_buffer[7] = header & 0xFF; - + // Write data to USB until we've finished while (left > 0) { @@ -1122,10 +1127,10 @@ static void usb_everdrive_write(int datatype, const void* data, int size) int blocksend, baddr; if (block+offset > BUFFER_SIZE) block = BUFFER_SIZE-offset; - + // Copy the data to the next available spots in the global buffer memcpy(usb_buffer+offset, (void*)((char*)data+read), block); - + // Restart the loop to write the CMP signal if we've finished if (!wrotecmp && read+block >= size) { @@ -1136,7 +1141,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) read = 0; continue; } - + // Ensure the data is 2 byte aligned and the block address is correct blocksend = ALIGN((block+offset), 2); baddr = BUFFER_SIZE - blocksend; @@ -1144,7 +1149,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) // Set USB to write mode and send data through USB usb_io_write(ED_REG_USBCFG, ED_USBMODE_WRNOP); usb_dma_write(usb_buffer, ED_REG_USBDAT + baddr, blocksend); - + // Set USB to write mode with the new address and wait for USB to end (or stop if it times out) usb_io_write(ED_REG_USBCFG, ED_USBMODE_WR | baddr); if (usb_everdrive_usbbusy()) @@ -1152,7 +1157,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) usb_didtimeout = TRUE; return; } - + // Keep track of what we've read so far left -= block; read += block; @@ -1171,49 +1176,49 @@ static void usb_everdrive_write(int datatype, const void* data, int size) static u32 usb_everdrive_poll(void) { - int len; - int offset = 0; - char buffaligned[32]; - char* buff = (char*)OS_DCACHE_ROUNDUP_ADDR(buffaligned); - + int len; + int offset = 0; + unsigned char buffaligned[32]; + unsigned char* buff = (unsigned char*)OS_DCACHE_ROUNDUP_ADDR(buffaligned); + // Wait for the USB to be ready if (usb_everdrive_usbbusy()) return 0; - + // Check if the USB is ready to be read if (!usb_everdrive_canread()) return 0; - + // Read the first 8 bytes that are being received and check if they're valid usb_everdrive_readusb(buff, 8); if (buff[0] != 'D' || buff[1] != 'M' || buff[2] != 'A' || buff[3] != '@') return 0; - + // Store information about the incoming data - usb_datatype = (int)buff[4]; - usb_datasize = (int)buff[5]<<16 | (int)buff[6]<<8 | (int)buff[7]<<0; + usb_datatype = buff[4]; + usb_datasize = (buff[5] << 16) | (buff[6] << 8) | (buff[7] << 0); usb_dataleft = usb_datasize; usb_readblock = -1; - + // Get the aligned data size. Must be 2 byte aligned len = ALIGN(usb_datasize, 2); - + // While there's data to service - while (len > 0) + while (len > 0) { u32 bytes_do = BUFFER_SIZE; if (len < BUFFER_SIZE) bytes_do = len; - + // Read a chunk from USB and store it into our temp buffer usb_everdrive_readusb(usb_buffer, bytes_do); - + // Copy received block to ROM usb_dma_write(usb_buffer, ED_BASE + DEBUG_ADDRESS + offset, bytes_do); offset += bytes_do; len -= bytes_do; } - + // Read the CMP Signal if (usb_everdrive_usbbusy()) return 0; @@ -1227,7 +1232,7 @@ static u32 usb_everdrive_poll(void) usb_readblock = -1; return 0; } - + // Return the data header return USBHEADER_CREATE(usb_datatype, usb_datasize); } @@ -1358,7 +1363,7 @@ static void usb_sc64_write(int datatype, const void* data, int size) usb_dma_write(usb_buffer, pi_address, ALIGN(block, 2)); // Update pointers and variables - data += block; + data = (void*)(((u32)data) + block); left -= block; pi_address += block; } @@ -1414,7 +1419,7 @@ static u32 usb_sc64_poll(void) // Return 0 if there's no data if (size == 0) return 0; - + // Fill USB read data variables usb_datatype = datatype; usb_dataleft = size; diff --git a/src/usb/usb.h b/src/usb/usb.h index 2155774687..27262fc325 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -6,60 +6,61 @@ /********************************* DataType macros *********************************/ - + // UNCOMMENT THE #DEFINE IF USING LIBDRAGON //#define LIBDRAGON - + // Settings #define USE_OSRAW 0 // Use if you're doing USB operations without the PI Manager (libultra only) #define DEBUG_ADDRESS_SIZE 8*1024*1024 // Max size of USB I/O. The bigger this value, the more ROM you lose! #define CHECK_EMULATOR 0 // Stops the USB library from working if it detects an emulator to prevent problems - + // Cart definitions #define CART_NONE 0 #define CART_64DRIVE 1 #define CART_EVERDRIVE 2 #define CART_SC64 3 - + // Data types defintions - #define DATATYPE_TEXT 0x01 - #define DATATYPE_RAWBINARY 0x02 - #define DATATYPE_HEADER 0x03 - #define DATATYPE_SCREENSHOT 0x04 - #define DATATYPE_HEARTBEAT 0x05 - - + #define DATATYPE_TEXT 0x01 + #define DATATYPE_RAWBINARY 0x02 + #define DATATYPE_HEADER 0x03 + #define DATATYPE_SCREENSHOT 0x04 + #define DATATYPE_HEARTBEAT 0x05 + #define DATATYPE_RDBPACKET 0x06 + + /********************************* Convenience macros *********************************/ - + // Use these to conveniently read the header from usb_poll() - #define USBHEADER_GETTYPE(header) ((header & 0xFF000000) >> 24) - #define USBHEADER_GETSIZE(header) ((header & 0x00FFFFFF)) - - + #define USBHEADER_GETTYPE(header) (((header) & 0xFF000000) >> 24) + #define USBHEADER_GETSIZE(header) (((header) & 0x00FFFFFF)) + + /********************************* USB Functions *********************************/ - + /*============================== usb_initialize Initializes the USB buffers and pointers @return 1 if the USB initialization was successful, 0 if not ==============================*/ - - extern char usb_initialize(); - - + + extern char usb_initialize(void); + + /*============================== usb_getcart Returns which flashcart is currently connected @return The CART macro that corresponds to the identified flashcart ==============================*/ - - extern char usb_getcart(); - - + + extern char usb_getcart(void); + + /*============================== usb_write Writes data to the USB. @@ -68,54 +69,54 @@ @param A buffer with the data to send @param The size of the data being sent ==============================*/ - + extern void usb_write(int datatype, const void* data, int size); - - + + /*============================== usb_poll Returns the header of data being received via USB The first byte contains the data type, the next 3 the number of bytes left to read @return The data header, or 0 ==============================*/ - + extern u32 usb_poll(); - - + + /*============================== usb_read Reads bytes from USB into the provided buffer @param The buffer to put the read data in @param The number of bytes to read ==============================*/ - + extern void usb_read(void* buffer, int size); - - + + /*============================== usb_skip Skips a USB read by the specified amount of bytes @param The number of bytes to skip ==============================*/ - + extern void usb_skip(int nbytes); - - + + /*============================== usb_rewind Rewinds a USB read by the specified amount of bytes @param The number of bytes to rewind ==============================*/ - + extern void usb_rewind(int nbytes); - - + + /*============================== usb_purge Purges the incoming USB data ==============================*/ - - extern void usb_purge(); + + extern void usb_purge(void); /*============================== @@ -124,7 +125,7 @@ @return 1 if the USB timed out, 0 if not ==============================*/ - extern char usb_timedout(); + extern char usb_timedout(void); /*============================== @@ -136,6 +137,6 @@ version. ==============================*/ - extern void usb_sendheartbeat(); + extern void usb_sendheartbeat(void); #endif diff --git a/tools/get_latest_unfloader.py b/tools/get_latest_unfloader.py index 3da3e3d9c0..868729618b 100644 --- a/tools/get_latest_unfloader.py +++ b/tools/get_latest_unfloader.py @@ -13,7 +13,9 @@ def get_latest_build_artifacts_url(): return os.path.join(body['value'][0]['url'], 'artifacts') def main(): - destpath = sys.argv[1] if len(sys.argv) > 1 else './' + destpath = sys.argv[1] if len(sys.argv) > 1 else '.' + unfloader_zip_path = os.path.join(destpath, "UNFLoader.zip") + os.makedirs(destpath, exist_ok=True) is_wsl = 'microsoft-standard' in str(platform.uname()).lower() unf_fn = 'UNFLoader.exe' if is_wsl else 'UNFLoader' artifact_url = get_latest_build_artifacts_url() @@ -32,24 +34,24 @@ def main(): # download unf zipfile artifact_res = request('GET', platform_artifact_url) - with open('UNFLoader.zip', 'wb') as unf_fp: + with open(unfloader_zip_path, 'wb') as unf_fp: unf_fp.write(artifact_res.content) # only extract the specific file that we need unfpath = None - with zipfile.ZipFile('UNFLoader.zip', 'r') as zip_ref: + with zipfile.ZipFile(unfloader_zip_path, 'r') as zip_ref: for zipinfo in zip_ref.infolist(): if not zipinfo.is_dir(): - unfpath = zip_ref.extract(zipinfo) + unfpath = zip_ref.extract(zipinfo, destpath) unf_bin_path = os.path.join(destpath, unf_fn) - # file gets extracted to ./unfloader-{platform}/UNFLoader[.exe], - # so move binary to ./UNFLoader[.exe] + # file gets extracted to [destpath]/unfloader-{platform}/UNFLoader[.exe], + # so move binary to [destpath]/UNFLoader[.exe] os.rename(unfpath, unf_bin_path) - # remove ./unfloader-{platform}/ directory + # remove [destpath]/unfloader-{platform}/ directory os.rmdir(unfpath.rstrip(unf_fn)) # remove UNFLoader.zip - os.remove('UNFLoader.zip') + os.remove(unfloader_zip_path) # now need to add executable file permissions to unfloader st = os.stat(unf_bin_path) From 810b4c6464fd7508888b8005c7795d77f8126fc7 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Wed, 29 Jan 2025 21:21:21 -0500 Subject: [PATCH 2/7] Update to newest UNF (d5f2ad100b76e372036453f8d25f9b6fbbbd2d1a) (November 22 2023) Add option for .local/share/HackerSM64/UNFLoader-dir.txt This allows referencing a custom UNFLoader path to be used, ideally for placing on the C drive for WSL instances. UNFLoader tends to hang for an unbearably long time when saved somewhere within the WSL directory structure, and simply using the Linux build isn't an option because it can't access Windows USB devices trivially. Dialogs in dialogs.h no longer have to be in order (#832) reset adjacent rooms when loading a new area (#704) Check for opensuse's cross mips gcc package (#842) Makes it possible to rely on the official repo. Ideally the following instructions would also be added to the wiki for opensuse: ``` sudo zypper install cross-mips-binutils git capstone pkgconf python311 cross-mips-gcc14 sudo zypper install --type pattern devel_basis ``` Support pre word-swapped textures, fix puppyprint rendering for lowercase z and tilde, minor font fixes (#838) * Fix puppyprint rendering lowercase z and tilde, minor font fixes * Add support for generating pre word swapped textures * Use image for fasttext font texture * Adjustments to fasttext font and puppyprint outline font Place stack canaries behind DEBUG_ASSERTIONS instead of DEBUG (#843) Add action continue/finish defines; mario.c labeled airborne actions labeled all actions labeled last labels i swear actual last one --- Makefile | 9 +- Makefile.split | 52 ++------ bin/segment2.c | 8 +- src/boot/main.c | 6 +- src/game/area.c | 4 + src/game/fasttext.c | 14 +-- src/game/mario.c | 10 +- src/game/mario.h | 5 + src/game/mario_actions_airborne.c | 108 ++++++++-------- src/game/mario_actions_automatic.c | 40 +++--- src/game/mario_actions_cutscene.c | 112 ++++++++--------- src/game/mario_actions_moving.c | 104 +++++++-------- src/game/mario_actions_object.c | 28 ++--- src/game/mario_actions_stationary.c | 118 +++++++++--------- src/game/mario_actions_submerged.c | 84 ++++++------- src/game/newfont2_swapped.bin | Bin 4032 -> 0 bytes src/game/puppyprint.c | 4 +- text/define_text.inc.c | 43 +++---- textures/fasttext/newfont2.ia4.preswap.png | Bin 0 -> 1334 bytes textures/segment2/custom_text.i4.png | Bin 2001 -> 0 bytes textures/segment2/custom_text.i4.preswap.png | Bin 0 -> 1308 bytes textures/segment2/custom_text2.ia4.png | Bin 1560 -> 0 bytes .../segment2/custom_text2.ia4.preswap.png | Bin 0 -> 1329 bytes textures/segment2/custom_text3.i4.png | Bin 1200 -> 0 bytes textures/segment2/custom_text3.i4.preswap.png | Bin 0 -> 776 bytes textures/segment2/custom_text4.i4.png | Bin 937 -> 0 bytes textures/segment2/custom_text4.i4.preswap.png | Bin 0 -> 848 bytes tools/n64graphics.c | 74 ++++++++--- 28 files changed, 416 insertions(+), 407 deletions(-) delete mode 100644 src/game/newfont2_swapped.bin create mode 100644 textures/fasttext/newfont2.ia4.preswap.png delete mode 100644 textures/segment2/custom_text.i4.png create mode 100644 textures/segment2/custom_text.i4.preswap.png delete mode 100644 textures/segment2/custom_text2.ia4.png create mode 100644 textures/segment2/custom_text2.ia4.preswap.png delete mode 100644 textures/segment2/custom_text3.i4.png create mode 100644 textures/segment2/custom_text3.i4.preswap.png delete mode 100644 textures/segment2/custom_text4.i4.png create mode 100644 textures/segment2/custom_text4.i4.preswap.png diff --git a/Makefile b/Makefile index 680ffe6004..d380528f9f 100644 --- a/Makefile +++ b/Makefile @@ -450,6 +450,8 @@ else ifneq ($(call find-command,mips64-none-elf-ld),) CROSS := mips64-none-elf- else ifneq ($(call find-command,mips-ld),) CROSS := mips- +else ifneq ($(call find-command,mips-suse-linux-ld ),) + CROSS := mips-suse-linux- else $(error Unable to detect a suitable MIPS toolchain installed) endif @@ -651,6 +653,7 @@ patch: $(ROM) # Extra object file dependencies $(BUILD_DIR)/asm/ipl3.o: $(IPL3_RAW_FILES) $(BUILD_DIR)/src/game/crash_screen.o: $(CRASH_TEXTURE_C_FILES) +$(BUILD_DIR)/src/game/fasttext.o: $(FASTTEXT_TEXTURE_C_FILES) $(BUILD_DIR)/src/game/version.o: $(BUILD_DIR)/src/game/version_data.h $(BUILD_DIR)/lib/aspMain.o: $(BUILD_DIR)/rsp/audio.bin $(SOUND_BIN_DIR)/sound_data.o: $(SOUND_BIN_DIR)/sound_data.ctl $(SOUND_BIN_DIR)/sound_data.tbl $(SOUND_BIN_DIR)/sequences.bin $(SOUND_BIN_DIR)/bank_sets @@ -701,9 +704,13 @@ $(BUILD_DIR)/%: %.png $(call print,Converting:,$<,$@) $(V)$(N64GRAPHICS) -s raw -i $@ -g $< -f $(lastword $(subst ., ,$@)) +$(BUILD_DIR)/%.preswap.inc.c: %.preswap.png + $(call print,Converting:,$<,$@) + $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$*)) -S + $(BUILD_DIR)/%.inc.c: %.png $(call print,Converting:,$<,$@) - $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$(basename $<))) + $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$*)) # Color Index CI8 $(BUILD_DIR)/%.ci8.inc.c: %.ci8.png diff --git a/Makefile.split b/Makefile.split index 9fe299e79f..8be88378b0 100644 --- a/Makefile.split +++ b/Makefile.split @@ -41,21 +41,15 @@ LEVEL_FILES := $(addsuffix leveldata,$(LEVEL_DIRS)) LEVEL_ELF_FILES := $(foreach level_dir,$(LEVEL_DIRS),$(BUILD_DIR)/levels/$(level_dir)leveldata.elf) -VANILLA_ACTORS_FILES := $(addsuffix data,$(VNL_ACTRS_DIRS)) - -VANILLA_ACTORS_ELF_FILES := $(foreach level_dir,$(VNL_ACTRS_DIRS),$(BUILD_DIR)/actors/vanilla_actors/$(level_dir)data.elf) - SEG_FILES := \ $(SEGMENTS:%=$(BUILD_DIR)/bin/%.elf) \ $(ACTOR_GROUPS:%=$(BUILD_DIR)/actors/%.elf) \ - $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.elf) \ - $(VANILLA_ACTORS_FILES:%=$(BUILD_DIR)/actors/vanilla_actors/%.elf) + $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.elf) YAY0_FILES := \ $(SEGMENTS:%=$(BUILD_DIR)/bin/%.szp) \ $(ACTOR_GROUPS:%=$(BUILD_DIR)/actors/%.szp) \ - $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.szp) \ - $(VANILLA_ACTORS_FILES:%=$(BUILD_DIR)/actors/vanilla_actors/%.szp) + $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.szp) YAY0_OBJ_FILES := $(YAY0_FILES:.szp=.szp.o) @@ -249,11 +243,9 @@ $(BUILD_DIR)/bin/machine.elf: SEGMENT_ADDRESS := 0x09000000 $(BUILD_DIR)/bin/mountain.elf: SEGMENT_ADDRESS := 0x09000000 $(BUILD_DIR)/bin/grass.elf: SEGMENT_ADDRESS := 0x09000000 # EU segment 19 translations -$(BUILD_DIR)/bin/translation_de.elf: SEGMENT_ADDRESS := 0x1B000000 -$(BUILD_DIR)/bin/translation_en.elf: SEGMENT_ADDRESS := 0x1B000000 -$(BUILD_DIR)/bin/translation_fr.elf: SEGMENT_ADDRESS := 0x1B000000 -$(BUILD_DIR)/bin/translation_jp.elf: SEGMENT_ADDRESS := 0x1B000000 -$(BUILD_DIR)/bin/translation_es.elf: SEGMENT_ADDRESS := 0x1B000000 +$(BUILD_DIR)/bin/eu/translation_de.elf: SEGMENT_ADDRESS := 0x19000000 +$(BUILD_DIR)/bin/eu/translation_en.elf: SEGMENT_ADDRESS := 0x19000000 +$(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 # -------------------------------------- # Skybox Rules @@ -279,35 +271,5 @@ IPL3_RAW_FILES := $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%,$(IP CRASH_TEXTURE_FILES := $(wildcard $(TEXTURE_DIR)/crash_custom/*.png) CRASH_TEXTURE_C_FILES := $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%.inc.c,$(CRASH_TEXTURE_FILES))) -# -------------------------------------- -# Vanilla Objects Rules -# -------------------------------------- - -define vanilla_objects_rules = - VANILLA_ACTORS_$(1)_TEXTURE_FILES := $$(patsubst %.png,%.inc.c,$$(wildcard actors/vanilla_actors/$(1)/*.png)) - $$(BUILD_DIR)/actors/vanilla_actors/$(1)/data.o: $$(addprefix $$(BUILD_DIR)/,$$(VANILLA_ACTORS_$(1)_TEXTURE_FILES)) - $$(BUILD_DIR)/actors/vanilla_actors/$(1)/data.elf: SEGMENT_ADDRESS := 0x0e000000 - $$(BUILD_DIR)/actors/vanilla_actors/$(1)/data.elf: TEXTURE_BIN := $(2) -endef - -$(eval $(call vanilla_objects_rules,bob,generic)) -$(eval $(call vanilla_objects_rules,wf,grass)) -$(eval $(call vanilla_objects_rules,jrb,water)) -$(eval $(call vanilla_objects_rules,ccm,snow)) -$(eval $(call vanilla_objects_rules,bbh,spooky)) -$(eval $(call vanilla_objects_rules,hmc,cave)) -$(eval $(call vanilla_objects_rules,lll,fire)) -$(eval $(call vanilla_objects_rules,ssl,generic)) -$(eval $(call vanilla_objects_rules,ddd,water)) -$(eval $(call vanilla_objects_rules,sl,snow)) -$(eval $(call vanilla_objects_rules,wdw,grass)) -$(eval $(call vanilla_objects_rules,ttm,mountain)) -$(eval $(call vanilla_objects_rules,thi,grass)) -$(eval $(call vanilla_objects_rules,ttc,machine)) -$(eval $(call vanilla_objects_rules,rr,sky)) -$(eval $(call vanilla_objects_rules,bitdw,sky)) -$(eval $(call vanilla_objects_rules,bitfs,sky)) -$(eval $(call vanilla_objects_rules,bits,sky)) -$(eval $(call vanilla_objects_rules,vcutm,outside)) -$(eval $(call vanilla_objects_rules,castle_inside,inside)) -$(eval $(call vanilla_objects_rules,castle_grounds,outside)) +FASTTEXT_TEXTURE_FILES := $(wildcard $(TEXTURE_DIR)/fasttext/*.png) +FASTTEXT_TEXTURE_C_FILES := $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%.inc.c,$(FASTTEXT_TEXTURE_FILES))) diff --git a/bin/segment2.c b/bin/segment2.c index 3a660b31c8..dea2cf2b9c 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -12,16 +12,16 @@ // SM64 (US/JP/EU/SH) Segment 02 #ifdef PUPPYPRINT ALIGNED8 static const Texture small_font_default[] = { -#include "textures/segment2/custom_text.i4.inc.c" +#include "textures/segment2/custom_text.i4.preswap.inc.c" }; ALIGNED8 static const Texture small_font_outline[] = { -#include "textures/segment2/custom_text2.ia4.inc.c" +#include "textures/segment2/custom_text2.ia4.preswap.inc.c" }; ALIGNED8 static const Texture small_font_plain[] = { -#include "textures/segment2/custom_text3.i4.inc.c" +#include "textures/segment2/custom_text3.i4.preswap.inc.c" }; ALIGNED8 static const Texture small_font_vanilla[] = { -#include "textures/segment2/custom_text4.i4.inc.c" +#include "textures/segment2/custom_text4.i4.preswap.inc.c" }; const u8 small_font_kerning_default[] = { diff --git a/src/boot/main.c b/src/boot/main.c index 2fe93aaff3..093bfffea8 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -320,7 +320,7 @@ void alert_rcp_hung_up(void) { * Increment the first and last values of the stack. * If they're different, that means an error has occured, so trigger a crash. */ -#ifdef DEBUG +#ifdef DEBUG_ASSERTIONS void check_stack_validity(void) { gIdleThreadStack[0]++; gIdleThreadStack[THREAD1_STACK - 1]++; @@ -379,7 +379,7 @@ void thread3_main(UNUSED void *arg) { } else { gBorderHeight = BORDER_HEIGHT_CONSOLE; } -#ifdef DEBUG +#ifdef DEBUG_ASSERTIONS gIdleThreadStack[0] = 0; gIdleThreadStack[THREAD1_STACK - 1] = 0; gThread3Stack[0] = 0; @@ -403,7 +403,7 @@ void thread3_main(UNUSED void *arg) { while (TRUE) { OSMesg msg; osRecvMesg(&gIntrMesgQueue, &msg, OS_MESG_BLOCK); -#ifdef DEBUG +#ifdef DEBUG_ASSERTIONS check_stack_validity(); #endif switch ((uintptr_t) msg) { diff --git a/src/game/area.c b/src/game/area.c index a693e6b25b..de14ab6aec 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -224,6 +224,10 @@ void load_area(s32 index) { gMarioCurrentRoom = 0; + if (gCurrentArea->surfaceRooms != NULL) { + bzero(gDoorAdjacentRooms, sizeof(gDoorAdjacentRooms)); + } + if (gCurrentArea->terrainData != NULL) { load_area_terrain(gCurrentArea->terrainData, gCurrentArea->surfaceRooms); } diff --git a/src/game/fasttext.c b/src/game/fasttext.c index 20357cb725..1c4804cabe 100644 --- a/src/game/fasttext.c +++ b/src/game/fasttext.c @@ -2,22 +2,16 @@ // See the original repo for more details. #include +#include "macros.h" #define TEX_ASCII_START '!' #define TAB_WIDTH 16 #define G_CC_TEXT PRIMITIVE, 0, TEXEL0, 0, 0, 0, 0, TEXEL0 -__asm__( - ".section \".rodata\", \"a\", @progbits\n" - ".balign 16\n" - ".global fast_font\n" - "fast_font:\n" - ".incbin \"src/game/newfont2_swapped.bin\"\n" - ".previous\n" -); - -extern u8 fast_font[]; +ALIGNED8 static const u8 fast_font[] = { +#include "textures/fasttext/newfont2.ia4.preswap.inc.c" +}; int computeS(unsigned char letter) { int idx = letter; diff --git a/src/game/mario.c b/src/game/mario.c index af26781131..dde8a5b831 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -966,7 +966,7 @@ u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg) { m->actionState = 0; m->actionTimer = 0; - return TRUE; + return ACTION_CONTINUE; } /** @@ -1021,7 +1021,7 @@ s32 set_jump_from_landing(struct MarioState *m) { m->doubleJumpTimer = 0; - return TRUE; + return ACTION_CONTINUE; } /** @@ -1044,7 +1044,7 @@ s32 set_jumping_action(struct MarioState *m, u32 action, u32 actionArg) { set_mario_action(m, action, actionArg); } - return TRUE; + return ACTION_CONTINUE; } /** @@ -1083,7 +1083,7 @@ s32 check_common_action_exits(struct MarioState *m) { return set_mario_action(m, ACT_BEGIN_SLIDING, 0); } - return FALSE; + return ACTION_FINISH; } /** @@ -1095,7 +1095,7 @@ s32 check_common_hold_action_exits(struct MarioState *m) { if (m->input & INPUT_OFF_FLOOR ) return set_mario_action(m, ACT_HOLD_FREEFALL, 0); if (m->input & INPUT_NONZERO_ANALOG) return set_mario_action(m, ACT_HOLD_WALKING, 0); if (m->input & INPUT_ABOVE_SLIDE ) return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0); - return FALSE; + return ACTION_FINISH; } /** diff --git a/src/game/mario.h b/src/game/mario.h index cb2df1a1e1..f640a0b6ab 100644 --- a/src/game/mario.h +++ b/src/game/mario.h @@ -6,6 +6,11 @@ #include "macros.h" #include "types.h" +// Continues running action logic, e.g. after Mario's action changes +#define ACTION_CONTINUE TRUE +// Finishes running action logic for the current frame +#define ACTION_FINISH FALSE + s32 is_anim_at_end(struct MarioState *m); s32 is_anim_past_end(struct MarioState *m); s16 set_mario_animation(struct MarioState *m, s32 targetAnimID); diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index c6e1526773..e6e8b9af3d 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -130,7 +130,7 @@ s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) { #if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif - return TRUE; + return ACTION_CONTINUE; } return check_fall_damage(m, hardFallAction); @@ -430,7 +430,7 @@ u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation, s32 act_jump(struct MarioState *m) { if (check_kick_or_dive_in_air(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->input & INPUT_Z_PRESSED) { @@ -440,7 +440,7 @@ s32 act_jump(struct MarioState *m) { play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0); common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SINGLE_JUMP, AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG); - return FALSE; + return ACTION_FINISH; } s32 act_double_jump(struct MarioState *m) { @@ -449,7 +449,7 @@ s32 act_double_jump(struct MarioState *m) { : MARIO_ANIM_DOUBLE_JUMP_FALL; if (check_kick_or_dive_in_air(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->input & INPUT_Z_PRESSED) { @@ -459,7 +459,7 @@ s32 act_double_jump(struct MarioState *m) { play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_HOOHOO); common_air_action_step(m, ACT_DOUBLE_JUMP_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG); - return FALSE; + return ACTION_FINISH; } s32 act_triple_jump(struct MarioState *m) { @@ -484,7 +484,7 @@ s32 act_triple_jump(struct MarioState *m) { } #endif play_flip_sounds(m, 2, 8, 20); - return FALSE; + return ACTION_FINISH; } s32 act_backflip(struct MarioState *m) { @@ -500,7 +500,7 @@ s32 act_backflip(struct MarioState *m) { } #endif play_flip_sounds(m, 2, 3, 17); - return FALSE; + return ACTION_FINISH; } s32 act_freefall(struct MarioState *m) { @@ -527,7 +527,7 @@ s32 act_freefall(struct MarioState *m) { } common_air_action_step(m, ACT_FREEFALL_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB); - return FALSE; + return ACTION_FINISH; } s32 act_hold_jump(struct MarioState *m) { @@ -546,7 +546,7 @@ s32 act_hold_jump(struct MarioState *m) { play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0); common_air_action_step(m, ACT_HOLD_JUMP_LAND, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ, AIR_STEP_CHECK_LEDGE_GRAB); - return FALSE; + return ACTION_FINISH; } s32 act_hold_freefall(struct MarioState *m) { @@ -570,7 +570,7 @@ s32 act_hold_freefall(struct MarioState *m) { } common_air_action_step(m, ACT_HOLD_FREEFALL_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB); - return FALSE; + return ACTION_FINISH; } s32 act_side_flip(struct MarioState *m) { @@ -594,7 +594,7 @@ s32 act_side_flip(struct MarioState *m) { if (m->marioObj->header.gfx.animInfo.animFrame == 6) { play_sound(SOUND_ACTION_SIDE_FLIP_UNK, m->marioObj->header.gfx.cameraToObject); } - return FALSE; + return ACTION_FINISH; } s32 act_wall_kick_air(struct MarioState *m) { @@ -608,7 +608,7 @@ s32 act_wall_kick_air(struct MarioState *m) { play_mario_jump_sound(m); common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SLIDEJUMP, AIR_STEP_CHECK_LEDGE_GRAB); - return FALSE; + return ACTION_FINISH; } s32 act_long_jump(struct MarioState *m) { @@ -632,7 +632,7 @@ s32 act_long_jump(struct MarioState *m) { queue_rumble_data(5, 40); } #endif - return FALSE; + return ACTION_FINISH; } s32 act_riding_shell_air(struct MarioState *m) { @@ -656,7 +656,7 @@ s32 act_riding_shell_air(struct MarioState *m) { } m->marioObj->header.gfx.pos[1] += 42.0f; - return FALSE; + return ACTION_FINISH; } s32 act_twirling(struct MarioState *m) { @@ -707,7 +707,7 @@ s32 act_twirling(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 act_dive(struct MarioState *m) { @@ -722,7 +722,7 @@ s32 act_dive(struct MarioState *m) { mario_grab_used_object(m); m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; if (m->action != ACT_DIVE) { - return TRUE; + return ACTION_CONTINUE; } } @@ -774,7 +774,7 @@ s32 act_dive(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_air_throw(struct MarioState *m) { @@ -802,7 +802,7 @@ s32 act_air_throw(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_water_jump(struct MarioState *m) { @@ -834,7 +834,7 @@ s32 act_water_jump(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_hold_water_jump(struct MarioState *m) { @@ -864,7 +864,7 @@ s32 act_hold_water_jump(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_steep_jump(struct MarioState *m) { @@ -894,7 +894,7 @@ s32 act_steep_jump(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP); m->marioObj->header.gfx.angle[1] = m->marioObj->oMarioSteepJumpYaw; - return FALSE; + return ACTION_FINISH; } s32 act_ground_pound(struct MarioState *m) { @@ -961,7 +961,7 @@ s32 act_ground_pound(struct MarioState *m) { #endif } - return FALSE; + return ACTION_FINISH; } s32 act_burning_jump(struct MarioState *m) { @@ -986,7 +986,7 @@ s32 act_burning_jump(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 act_burning_fall(struct MarioState *m) { @@ -1008,7 +1008,7 @@ s32 act_burning_fall(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 act_crazy_box_bounce(struct MarioState *m) { @@ -1072,7 +1072,7 @@ s32 act_crazy_box_bounce(struct MarioState *m) { } m->marioObj->header.gfx.angle[0] = atan2s(m->forwardVel, -m->vel[1]); - return FALSE; + return ACTION_FINISH; } u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFallAction, s32 animation, @@ -1132,34 +1132,34 @@ s32 check_wall_kick(struct MarioState *m) { s32 act_backward_air_kb(struct MarioState *m) { if (check_wall_kick(m)) { - return TRUE; + return ACTION_CONTINUE; } play_knockback_sound(m); common_air_knockback_step(m, ACT_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, -16.0f); - return FALSE; + return ACTION_FINISH; } s32 act_forward_air_kb(struct MarioState *m) { if (check_wall_kick(m)) { - return TRUE; + return ACTION_CONTINUE; } play_knockback_sound(m); common_air_knockback_step(m, ACT_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB, MARIO_ANIM_AIR_FORWARD_KB, 16.0f); - return FALSE; + return ACTION_FINISH; } s32 act_hard_backward_air_kb(struct MarioState *m) { play_knockback_sound(m); common_air_knockback_step(m, ACT_HARD_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, -16.0f); - return FALSE; + return ACTION_FINISH; } s32 act_hard_forward_air_kb(struct MarioState *m) { play_knockback_sound(m); common_air_knockback_step(m, ACT_HARD_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB, MARIO_ANIM_AIR_FORWARD_KB, 16.0f); - return FALSE; + return ACTION_FINISH; } s32 act_thrown_backward(struct MarioState *m) { @@ -1175,7 +1175,7 @@ s32 act_thrown_backward(struct MarioState *m) { common_air_knockback_step(m, landAction, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, m->forwardVel); m->forwardVel *= 0.98f; - return FALSE; + return ACTION_FINISH; } s32 act_thrown_forward(struct MarioState *m) { @@ -1200,18 +1200,18 @@ s32 act_thrown_forward(struct MarioState *m) { } m->forwardVel *= 0.98f; - return FALSE; + return ACTION_FINISH; } s32 act_soft_bonk(struct MarioState *m) { if (check_wall_kick(m)) { - return TRUE; + return ACTION_CONTINUE; } play_knockback_sound(m); common_air_knockback_step(m, ACT_FREEFALL_LAND, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_GENERAL_FALL, m->forwardVel); - return FALSE; + return ACTION_FINISH; } s32 act_getting_blown(struct MarioState *m) { @@ -1256,7 +1256,7 @@ s32 act_getting_blown(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_air_hit_wall(struct MarioState *m) { @@ -1292,7 +1292,7 @@ s32 act_air_hit_wall(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_START_WALLKICK); - return TRUE; + return ACTION_CONTINUE; } s32 act_forward_rollout(struct MarioState *m) { @@ -1333,7 +1333,7 @@ s32 act_forward_rollout(struct MarioState *m) { if (m->actionState == 1 && is_anim_past_end(m)) { m->actionState = 2; } - return FALSE; + return ACTION_FINISH; } s32 act_backward_rollout(struct MarioState *m) { @@ -1374,7 +1374,7 @@ s32 act_backward_rollout(struct MarioState *m) { if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 2) { m->actionState = 2; } - return FALSE; + return ACTION_FINISH; } s32 act_butt_slide_air(struct MarioState *m) { @@ -1409,7 +1409,7 @@ s32 act_butt_slide_air(struct MarioState *m) { } set_mario_animation(m, MARIO_ANIM_SLIDE); - return FALSE; + return ACTION_FINISH; } s32 act_hold_butt_slide_air(struct MarioState *m) { @@ -1450,7 +1450,7 @@ s32 act_hold_butt_slide_air(struct MarioState *m) { } set_mario_animation(m, MARIO_ANIM_SLIDING_ON_BOTTOM_WITH_LIGHT_OBJ); - return FALSE; + return ACTION_FINISH; } s32 act_lava_boost(struct MarioState *m) { @@ -1519,7 +1519,7 @@ s32 act_lava_boost(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 act_slide_kick(struct MarioState *m) { @@ -1570,7 +1570,7 @@ s32 act_slide_kick(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_jump_kick(struct MarioState *m) { @@ -1603,7 +1603,7 @@ s32 act_jump_kick(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_shot_from_cannon(struct MarioState *m) { @@ -1663,7 +1663,7 @@ s32 act_shot_from_cannon(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 act_flying(struct MarioState *m) { @@ -1785,7 +1785,7 @@ s32 act_flying(struct MarioState *m) { play_sound(SOUND_MOVING_FLYING, m->marioObj->header.gfx.cameraToObject); adjust_sound_for_speed(m); - return FALSE; + return ACTION_FINISH; } s32 act_riding_hoot(struct MarioState *m) { @@ -1817,7 +1817,7 @@ s32 act_riding_hoot(struct MarioState *m) { vec3f_set(m->vel, 0.0f, 0.0f, 0.0f); vec3f_set(m->marioObj->header.gfx.pos, m->pos[0], m->pos[1], m->pos[2]); vec3s_set(m->marioObj->header.gfx.angle, 0, 0x4000 - m->faceAngle[1], 0); - return FALSE; + return ACTION_FINISH; } s32 act_flying_triple_jump(struct MarioState *m) { @@ -1887,13 +1887,13 @@ s32 act_flying_triple_jump(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_top_of_pole_jump(struct MarioState *m) { play_mario_jump_sound(m); common_air_action_step(m, ACT_FREEFALL_LAND, MARIO_ANIM_HANDSTAND_JUMP, AIR_STEP_CHECK_LEDGE_GRAB); - return FALSE; + return ACTION_FINISH; } s32 act_vertical_wind(struct MarioState *m) { @@ -1931,7 +1931,7 @@ s32 act_vertical_wind(struct MarioState *m) { m->marioObj->header.gfx.angle[0] = (s16)(6144.0f * intendedMag * coss(intendedDYaw)); m->marioObj->header.gfx.angle[2] = (s16)(-4096.0f * intendedMag * sins(intendedDYaw)); - return FALSE; + return ACTION_FINISH; } s32 act_special_triple_jump(struct MarioState *m) { @@ -1971,7 +1971,7 @@ s32 act_special_triple_jump(struct MarioState *m) { } m->particleFlags |= PARTICLE_SPARKLES; - return FALSE; + return ACTION_FINISH; } s32 check_common_airborne_cancels(struct MarioState *m) { @@ -1988,14 +1988,14 @@ s32 check_common_airborne_cancels(struct MarioState *m) { } m->quicksandDepth = 0.0f; - return FALSE; + return ACTION_FINISH; } s32 mario_execute_airborne_action(struct MarioState *m) { - u32 cancel = FALSE; + u32 cancel = ACTION_FINISH; if (check_common_airborne_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } #ifndef NO_FALL_DAMAGE_SOUND diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 6fd5ea36bc..d100f5b789 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -146,7 +146,7 @@ s32 act_holding_pole(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_IDLE_ON_POLE); } - return FALSE; + return ACTION_FINISH; } s32 act_climbing_pole(struct MarioState *m) { @@ -180,7 +180,7 @@ s32 act_climbing_pole(struct MarioState *m) { play_climbing_sounds(m, 1); } - return FALSE; + return ACTION_FINISH; } s32 act_grab_pole_slow(struct MarioState *m) { @@ -194,7 +194,7 @@ s32 act_grab_pole_slow(struct MarioState *m) { add_tree_leaf_particles(m); } - return FALSE; + return ACTION_FINISH; } s32 act_grab_pole_fast(struct MarioState *m) { @@ -215,7 +215,7 @@ s32 act_grab_pole_fast(struct MarioState *m) { add_tree_leaf_particles(m); } - return FALSE; + return ACTION_FINISH; } s32 act_top_of_pole_transition(struct MarioState *m) { @@ -234,7 +234,7 @@ s32 act_top_of_pole_transition(struct MarioState *m) { } set_pole_position(m, return_mario_anim_y_translation(m)); - return FALSE; + return ACTION_FINISH; } s32 act_top_of_pole(struct MarioState *m) { @@ -249,7 +249,7 @@ s32 act_top_of_pole(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_HANDSTAND_IDLE); set_pole_position(m, return_mario_anim_y_translation(m)); - return FALSE; + return ACTION_FINISH; } s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) { @@ -404,7 +404,7 @@ s32 act_start_hanging(struct MarioState *m) { set_mario_action(m, ACT_HANGING, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_hanging(struct MarioState *m) { @@ -440,7 +440,7 @@ s32 act_hanging(struct MarioState *m) { update_hang_stationary(m); - return FALSE; + return ACTION_FINISH; } s32 act_hang_moving(struct MarioState *m) { @@ -507,7 +507,7 @@ s32 act_hang_moving(struct MarioState *m) { } #endif - return FALSE; + return ACTION_FINISH; } s32 let_go_of_ledge(struct MarioState *m) { @@ -610,7 +610,7 @@ s32 act_ledge_grab(struct MarioState *m) { stop_and_set_height_to_floor(m); set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE); - return FALSE; + return ACTION_FINISH; } s32 act_ledge_climb_slow(struct MarioState *m) { @@ -636,7 +636,7 @@ s32 act_ledge_climb_slow(struct MarioState *m) { m->action = ACT_LEDGE_CLIMB_SLOW_2; } - return FALSE; + return ACTION_FINISH; } s32 act_ledge_climb_down(struct MarioState *m) { @@ -649,7 +649,7 @@ s32 act_ledge_climb_down(struct MarioState *m) { update_ledge_climb(m, MARIO_ANIM_CLIMB_DOWN_LEDGE, ACT_LEDGE_GRAB); m->actionArg = 1; - return FALSE; + return ACTION_FINISH; } s32 act_ledge_climb_fast(struct MarioState *m) { @@ -666,7 +666,7 @@ s32 act_ledge_climb_fast(struct MarioState *m) { } update_ledge_climb_camera(m); - return FALSE; + return ACTION_FINISH; } s32 act_grabbed(struct MarioState *m) { @@ -684,7 +684,7 @@ s32 act_grabbed(struct MarioState *m) { } set_mario_animation(m, MARIO_ANIM_BEING_GRABBED); - return FALSE; + return ACTION_FINISH; } s32 act_in_cannon(struct MarioState *m) { @@ -751,7 +751,7 @@ s32 act_in_cannon(struct MarioState *m) { queue_rumble_data(60, 70); #endif m->usedObj->oAction = OPENED_CANNON_ACT_SHOOT; - return FALSE; + return ACTION_FINISH; } else if (m->faceAngle[0] != startFacePitch || m->faceAngle[1] != startFaceYaw) { play_sound(SOUND_MOVING_AIM_CANNON, marioObj->header.gfx.cameraToObject); #if ENABLE_RUMBLE @@ -764,7 +764,7 @@ s32 act_in_cannon(struct MarioState *m) { vec3s_set(marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); set_mario_animation(m, MARIO_ANIM_DIVE); - return FALSE; + return ACTION_FINISH; } s32 act_tornado_twirling(struct MarioState *m) { @@ -844,7 +844,7 @@ s32 act_tornado_twirling(struct MarioState *m) { reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 check_common_automatic_cancels(struct MarioState *m) { @@ -852,14 +852,14 @@ s32 check_common_automatic_cancels(struct MarioState *m) { return set_water_plunge_action(m); } - return FALSE; + return ACTION_FINISH; } s32 mario_execute_automatic_action(struct MarioState *m) { - s32 cancel = FALSE; + s32 cancel = ACTION_FINISH; if (check_common_automatic_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } m->quicksandDepth = 0.0f; diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index e09a64b4ac..3524076f94 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -374,7 +374,7 @@ s32 act_reading_npc_dialog(struct MarioState *m) { m->actionState++; } - return FALSE; + return ACTION_FINISH; } // puts Mario in a state where he's waiting for (npc) dialog; doesn't do much @@ -383,7 +383,7 @@ s32 act_waiting_for_dialog(struct MarioState *m) { : MARIO_ANIM_IDLE_WITH_LIGHT_OBJ); vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); - return FALSE; + return ACTION_FINISH; } // makes Mario disappear and triggers warp @@ -397,7 +397,7 @@ s32 act_disappeared(struct MarioState *m) { level_trigger_warp(m, m->actionArg >> 16); } } - return FALSE; + return ACTION_FINISH; } s32 act_reading_automatic_dialog(struct MarioState *m) { @@ -450,7 +450,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { } // apply head turn vec3s_set(m->marioBodyState->headAngle, m->actionTimer, 0, 0); - return FALSE; + return ACTION_FINISH; } s32 act_reading_sign(struct MarioState *m) { @@ -492,7 +492,7 @@ s32 act_reading_sign(struct MarioState *m) { vec3f_copy(marioObj->header.gfx.pos, m->pos); vec3s_set(marioObj->header.gfx.angle, 0x0, m->faceAngle[1], 0x0); - return FALSE; + return ACTION_FINISH; } s32 act_debug_free_move(struct MarioState *m) { @@ -549,7 +549,7 @@ s32 act_debug_free_move(struct MarioState *m) { f32 floorHeight = find_floor(pos[0], pos[1], pos[2], &floor); f32 ceilHeight = find_mario_ceil(pos, floorHeight, &ceil); - if (floor == NULL) return FALSE; + if (floor == NULL) return ACTION_FINISH; if (ceilHeight - floorHeight >= 160.0f) { if (floor != NULL && pos[1] < floorHeight) { @@ -565,7 +565,7 @@ s32 act_debug_free_move(struct MarioState *m) { vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); - return FALSE; + return ACTION_FINISH; } void general_star_dance_handler(struct MarioState *m, s32 isInWater) { @@ -638,7 +638,7 @@ s32 act_star_dance(struct MarioState *m) { m->marioBodyState->handState = MARIO_HAND_PEACE_SIGN; } stop_and_set_height_to_floor(m); - return FALSE; + return ACTION_FINISH; } s32 act_star_dance_water(struct MarioState *m) { @@ -651,7 +651,7 @@ s32 act_star_dance_water(struct MarioState *m) { if (m->actionState != ACT_STATE_STAR_DANCE_RETURN && m->actionTimer >= 62) { m->marioBodyState->handState = MARIO_HAND_PEACE_SIGN; } - return FALSE; + return ACTION_FINISH; } s32 act_fall_after_star_grab(struct MarioState *m) { @@ -666,7 +666,7 @@ s32 act_fall_after_star_grab(struct MarioState *m) { m->actionArg); } set_mario_animation(m, MARIO_ANIM_GENERAL_FALL); - return FALSE; + return ACTION_FINISH; } s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWarp) { @@ -692,19 +692,19 @@ s32 act_standing_death(struct MarioState *m) { if (m->marioObj->header.gfx.animInfo.animFrame == 77) { play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); } - return FALSE; + return ACTION_FINISH; } s32 act_electrocution(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_MARIO_DYING, MARIO_ACTION_SOUND_PLAYED); common_death_handler(m, MARIO_ANIM_ELECTROCUTION, 43); - return FALSE; + return ACTION_FINISH; } s32 act_suffocation(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_MARIO_DYING, MARIO_ACTION_SOUND_PLAYED); common_death_handler(m, MARIO_ANIM_SUFFOCATING, 86); - return FALSE; + return ACTION_FINISH; } s32 act_death_on_back(struct MarioState *m) { @@ -712,7 +712,7 @@ s32 act_death_on_back(struct MarioState *m) { if (common_death_handler(m, MARIO_ANIM_DYING_ON_BACK, 54) == 40) { play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); } - return FALSE; + return ACTION_FINISH; } s32 act_death_on_stomach(struct MarioState *m) { @@ -720,7 +720,7 @@ s32 act_death_on_stomach(struct MarioState *m) { if (common_death_handler(m, MARIO_ANIM_DYING_ON_STOMACH, 37) == 37) { play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); } - return FALSE; + return ACTION_FINISH; } s32 act_quicksand_death(struct MarioState *m) { @@ -740,7 +740,7 @@ s32 act_quicksand_death(struct MarioState *m) { } stationary_ground_step(m); play_sound(SOUND_MOVING_QUICKSAND_DEATH, m->marioObj->header.gfx.cameraToObject); - return FALSE; + return ACTION_FINISH; } s32 act_eaten_by_bubba(struct MarioState *m) { @@ -754,7 +754,7 @@ s32 act_eaten_by_bubba(struct MarioState *m) { if (m->actionTimer++ == 60) { level_trigger_warp(m, WARP_OP_DEATH); } - return FALSE; + return ACTION_FINISH; } // set animation and forwardVel; when perform_air_step returns AIR_STEP_LANDED, @@ -809,7 +809,7 @@ s32 act_unlocking_key_door(struct MarioState *m) { } m->actionTimer++; - return FALSE; + return ACTION_FINISH; } s32 act_unlocking_star_door(struct MarioState *m) { @@ -850,7 +850,7 @@ s32 act_unlocking_star_door(struct MarioState *m) { update_mario_pos_for_anim(m); stop_and_set_height_to_floor(m); - return FALSE; + return ACTION_FINISH; } s32 act_entering_star_door(struct MarioState *m) { @@ -911,7 +911,7 @@ s32 act_entering_star_door(struct MarioState *m) { set_mario_action(m, ACT_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_going_through_door(struct MarioState *m) { @@ -943,7 +943,7 @@ s32 act_going_through_door(struct MarioState *m) { } m->actionTimer++; - return FALSE; + return ACTION_FINISH; } s32 act_warp_door_spawn(struct MarioState *m) { @@ -967,7 +967,7 @@ s32 act_warp_door_spawn(struct MarioState *m) { } set_mario_animation(m, MARIO_ANIM_FIRST_PERSON); stop_and_set_height_to_floor(m); - return FALSE; + return ACTION_FINISH; } s32 act_emerge_from_pipe(struct MarioState *m) { @@ -975,7 +975,7 @@ s32 act_emerge_from_pipe(struct MarioState *m) { if (m->actionTimer++ < 11) { marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - return FALSE; + return ACTION_FINISH; } marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; @@ -995,7 +995,7 @@ s32 act_emerge_from_pipe(struct MarioState *m) { mario_set_forward_vel(m, 0.0f); play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); } - return FALSE; + return ACTION_FINISH; } s32 act_spawn_spin_airborne(struct MarioState *m) { @@ -1027,7 +1027,7 @@ s32 act_spawn_spin_airborne(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_GENERAL_FALL); } - return FALSE; + return ACTION_FINISH; } s32 act_spawn_spin_landing(struct MarioState *m) { @@ -1037,7 +1037,7 @@ s32 act_spawn_spin_landing(struct MarioState *m) { load_level_init_text(0); set_mario_action(m, ACT_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } /** @@ -1062,7 +1062,7 @@ s32 act_exit_airborne(struct MarioState *m) { // rotate him to face away from the entrance m->marioObj->header.gfx.angle[1] += 0x8000; m->particleFlags |= PARTICLE_SPARKLES; - return FALSE; + return ACTION_FINISH; } s32 act_falling_exit_airborne(struct MarioState *m) { @@ -1076,7 +1076,7 @@ s32 act_falling_exit_airborne(struct MarioState *m) { // rotate Mario to face away from the entrance m->marioObj->header.gfx.angle[1] += 0x8000; m->particleFlags |= PARTICLE_SPARKLES; - return FALSE; + return ACTION_FINISH; } s32 act_exit_land_save_dialog(struct MarioState *m) { @@ -1155,7 +1155,7 @@ s32 act_exit_land_save_dialog(struct MarioState *m) { } m->marioObj->header.gfx.angle[1] += 0x8000; - return FALSE; + return ACTION_FINISH; } s32 act_death_exit(struct MarioState *m) { @@ -1176,7 +1176,7 @@ s32 act_death_exit(struct MarioState *m) { #ifdef BREATH_METER m->breath = 0x880; #endif - return FALSE; + return ACTION_FINISH; } s32 act_unused_death_exit(struct MarioState *m) { @@ -1193,7 +1193,7 @@ s32 act_unused_death_exit(struct MarioState *m) { #ifdef BREATH_METER m->breath = 0x880; #endif - return FALSE; + return ACTION_FINISH; } s32 act_falling_death_exit(struct MarioState *m) { @@ -1213,7 +1213,7 @@ s32 act_falling_death_exit(struct MarioState *m) { #ifdef BREATH_METER m->breath = 0x880; #endif - return FALSE; + return ACTION_FINISH; } // waits 11 frames before actually executing, also has reduced fvel @@ -1227,7 +1227,7 @@ s32 act_special_exit_airborne(struct MarioState *m) { if (m->actionTimer++ < 11) { marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - return FALSE; + return ACTION_FINISH; } if (launch_mario_until_land(m, ACT_EXIT_LAND_SAVE_DIALOG, MARIO_ANIM_SINGLE_JUMP, -24.0f)) { @@ -1242,7 +1242,7 @@ s32 act_special_exit_airborne(struct MarioState *m) { // show Mario marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; - return FALSE; + return ACTION_FINISH; } s32 act_special_death_exit(struct MarioState *m) { @@ -1250,7 +1250,7 @@ s32 act_special_death_exit(struct MarioState *m) { if (m->actionTimer++ < 11) { marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; - return FALSE; + return ACTION_FINISH; } if (launch_mario_until_land(m, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, -24.0f)) { @@ -1270,7 +1270,7 @@ s32 act_special_death_exit(struct MarioState *m) { m->breath = 0x880; #endif - return FALSE; + return ACTION_FINISH; } s32 act_spawn_no_spin_airborne(struct MarioState *m) { @@ -1278,7 +1278,7 @@ s32 act_spawn_no_spin_airborne(struct MarioState *m) { if (m->pos[1] < m->waterLevel - 100) { set_water_plunge_action(m); } - return FALSE; + return ACTION_FINISH; } s32 act_spawn_no_spin_landing(struct MarioState *m) { @@ -1289,7 +1289,7 @@ s32 act_spawn_no_spin_landing(struct MarioState *m) { load_level_init_text(0); set_mario_action(m, ACT_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_bbh_enter_spin(struct MarioState *m) { @@ -1370,7 +1370,7 @@ s32 act_bbh_enter_spin(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_bbh_enter_jump(struct MarioState *m) { @@ -1398,7 +1398,7 @@ s32 act_bbh_enter_jump(struct MarioState *m) { set_mario_action(m, ACT_BBH_ENTER_SPIN, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_teleport_fade_out(struct MarioState *m) { @@ -1425,7 +1425,7 @@ s32 act_teleport_fade_out(struct MarioState *m) { stop_and_set_height_to_floor(m); - return FALSE; + return ACTION_FINISH; } s32 act_teleport_fade_in(struct MarioState *m) { @@ -1461,7 +1461,7 @@ s32 act_teleport_fade_in(struct MarioState *m) { m->pos[1] = m->floorHeight; stop_and_set_height_to_floor(m); - return FALSE; + return ACTION_FINISH; } s32 act_shocked(struct MarioState *m) { @@ -1488,7 +1488,7 @@ s32 act_shocked(struct MarioState *m) { stop_and_set_height_to_floor(m); } - return FALSE; + return ACTION_FINISH; } s32 act_squished(struct MarioState *m) { @@ -1572,7 +1572,7 @@ s32 act_squished(struct MarioState *m) { // instant un-squish m->squishTimer = 0; set_mario_action(m, ACT_IDLE, 0); - return FALSE; + return ACTION_FINISH; } } @@ -1587,7 +1587,7 @@ s32 act_squished(struct MarioState *m) { } stop_and_set_height_to_floor(m); set_mario_animation(m, MARIO_ANIM_A_POSE); - return FALSE; + return ACTION_FINISH; } s32 act_putting_on_cap(struct MarioState *m) { @@ -1607,7 +1607,7 @@ s32 act_putting_on_cap(struct MarioState *m) { } stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } void stuck_in_ground_handler(struct MarioState *m, s32 animation, s32 unstuckFrame, s32 target2, @@ -1642,17 +1642,17 @@ void stuck_in_ground_handler(struct MarioState *m, s32 animation, s32 unstuckFra s32 act_head_stuck_in_ground(struct MarioState *m) { stuck_in_ground_handler(m, MARIO_ANIM_HEAD_STUCK_IN_GROUND, 96, 105, 135, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_butt_stuck_in_ground(struct MarioState *m) { stuck_in_ground_handler(m, MARIO_ANIM_BOTTOM_STUCK_IN_GROUND, 127, 136, -2, ACT_GROUND_POUND_LAND); - return FALSE; + return ACTION_FINISH; } s32 act_feet_stuck_in_ground(struct MarioState *m) { stuck_in_ground_handler(m, MARIO_ANIM_LEGS_STUCK_IN_GROUND, 116, 129, -2, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } /** @@ -1793,7 +1793,7 @@ static s32 act_intro_cutscene(struct MarioState *m) { intro_cutscene_set_mario_to_idle(m); break; } - return FALSE; + return ACTION_FINISH; } // jumbo star cutscene: Mario lands after grabbing the jumbo star @@ -1934,7 +1934,7 @@ static s32 act_jumbo_star_cutscene(struct MarioState *m) { jumbo_star_cutscene_flying(m); break; } - return FALSE; + return ACTION_FINISH; } void generate_yellow_sparkles(s16 x, s16 y, s16 z, f32 radius) { @@ -2516,7 +2516,7 @@ static s32 act_end_peach_cutscene(struct MarioState *m) { sEndCutsceneVp.vp.vtrans[1] = SCREEN_HEIGHT * 2; override_viewport_and_clip(NULL, &sEndCutsceneVp, 0, 0, 0); - return FALSE; + return ACTION_FINISH; } #define TIMER_CREDITS_SHOW 61 @@ -2574,7 +2574,7 @@ static s32 act_credits_cutscene(struct MarioState *m) { m->marioObj->header.gfx.angle[1] += (gCurrCreditsEntry->actNum & 0xC0) << 8; - return FALSE; + return ACTION_FINISH; } static s32 act_end_waving_cutscene(struct MarioState *m) { @@ -2612,7 +2612,7 @@ static s32 act_end_waving_cutscene(struct MarioState *m) { level_trigger_warp(m, WARP_OP_CREDITS_END); } - return FALSE; + return ACTION_FINISH; } static s32 check_for_instant_quicksand(struct MarioState *m) { @@ -2621,14 +2621,14 @@ static s32 check_for_instant_quicksand(struct MarioState *m) { update_mario_sound_and_camera(m); return drop_and_set_mario_action(m, ACT_QUICKSAND_DEATH, 0); } - return FALSE; + return ACTION_FINISH; } s32 mario_execute_cutscene_action(struct MarioState *m) { s32 cancel; if (check_for_instant_quicksand(m)) { - return TRUE; + return ACTION_CONTINUE; } /* clang-format off */ diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 67cd50fa92..98d8a0ecc1 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -775,7 +775,7 @@ s32 act_walking(struct MarioState *m) { } if (check_ground_dive_or_punch(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->input & INPUT_IDLE) { @@ -820,7 +820,7 @@ s32 act_walking(struct MarioState *m) { check_ledge_climb_down(m); tilt_body_walking(m, startYaw); - return FALSE; + return ACTION_FINISH; } s32 act_move_punching(struct MarioState *m) { @@ -855,7 +855,7 @@ s32 act_move_punching(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } s32 act_hold_walking(struct MarioState *m) { @@ -909,7 +909,7 @@ s32 act_hold_walking(struct MarioState *m) { m->particleFlags |= PARTICLE_DUST; } - return FALSE; + return ACTION_FINISH; } s32 act_hold_heavy_walking(struct MarioState *m) { @@ -942,7 +942,7 @@ s32 act_hold_heavy_walking(struct MarioState *m) { } anim_and_audio_for_heavy_walk(m); - return FALSE; + return ACTION_FINISH; } s32 act_turning_around(struct MarioState *m) { @@ -993,7 +993,7 @@ s32 act_turning_around(struct MarioState *m) { } } - return FALSE; + return ACTION_FINISH; } s32 act_finish_turning_around(struct MarioState *m) { @@ -1032,7 +1032,7 @@ s32 act_finish_turning_around(struct MarioState *m) { #else m->marioObj->header.gfx.angle[1] += 0x8000; #endif - return FALSE; + return ACTION_FINISH; } s32 act_braking(struct MarioState *m) { @@ -1067,7 +1067,7 @@ s32 act_braking(struct MarioState *m) { play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject); adjust_sound_for_speed(m); set_mario_animation(m, MARIO_ANIM_SKID_ON_GROUND); - return FALSE; + return ACTION_FINISH; } s32 act_decelerating(struct MarioState *m) { @@ -1083,7 +1083,7 @@ s32 act_decelerating(struct MarioState *m) { } if (check_ground_dive_or_punch(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->input & INPUT_NONZERO_ANALOG) { @@ -1129,7 +1129,7 @@ s32 act_decelerating(struct MarioState *m) { play_step_sound(m, 10, 49); } - return FALSE; + return ACTION_FINISH; } s32 act_hold_decelerating(struct MarioState *m) { @@ -1195,7 +1195,7 @@ s32 act_hold_decelerating(struct MarioState *m) { play_step_sound(m, 12, 62); } - return FALSE; + return ACTION_FINISH; } s32 act_riding_shell_ground(struct MarioState *m) { @@ -1242,7 +1242,7 @@ s32 act_riding_shell_ground(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } s32 act_crawling(struct MarioState *m) { @@ -1259,7 +1259,7 @@ s32 act_crawling(struct MarioState *m) { } if (check_ground_dive_or_punch(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->input & INPUT_IDLE) { @@ -1294,7 +1294,7 @@ s32 act_crawling(struct MarioState *m) { s32 animSpeed = (s32)(m->intendedMag * 2.0f * 0x10000); set_mario_anim_with_accel(m, MARIO_ANIM_CRAWLING, animSpeed); play_step_sound(m, 26, 79); - return FALSE; + return ACTION_FINISH; } s32 act_burning_ground(struct MarioState *m) { @@ -1346,7 +1346,7 @@ s32 act_burning_ground(struct MarioState *m) { #if ENABLE_RUMBLE reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } void tilt_body_butt_slide(struct MarioState *m) { @@ -1434,7 +1434,7 @@ s32 common_slide_action_with_jump(struct MarioState *m, u32 stopAction, u32 jump } common_slide_action(m, stopAction, airAction, animation); - return FALSE; + return ACTION_FINISH; } s32 act_butt_slide(struct MarioState *m) { @@ -1517,7 +1517,7 @@ s32 act_slide_kick_slide(struct MarioState *m) { play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject); m->particleFlags |= PARTICLE_DUST; - return FALSE; + return ACTION_FINISH; } s32 stomach_slide_action(struct MarioState *m, u32 stopAction, u32 airAction, s32 animation) { @@ -1538,7 +1538,7 @@ s32 stomach_slide_action(struct MarioState *m, u32 stopAction, u32 airAction, s3 } common_slide_action(m, stopAction, airAction, animation); - return FALSE; + return ACTION_FINISH; } s32 act_stomach_slide(struct MarioState *m) { @@ -1577,11 +1577,11 @@ s32 act_dive_slide(struct MarioState *m) { if (mario_check_object_grab(m)) { mario_grab_used_object(m); m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; - return TRUE; + return ACTION_CONTINUE; } common_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_DIVE); - return FALSE; + return ACTION_FINISH; } s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 checkFrame, s32 playLandingSound, s32 actionArg) { @@ -1646,7 +1646,7 @@ s32 act_hard_backward_ground_kb(struct MarioState *m) { play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING); } - return FALSE; + return ACTION_FINISH; } s32 act_hard_forward_ground_kb(struct MarioState *m) { @@ -1656,27 +1656,27 @@ s32 act_hard_forward_ground_kb(struct MarioState *m) { set_mario_action(m, ACT_DEATH_ON_STOMACH, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_backward_ground_kb(struct MarioState *m) { common_ground_knockback_action(m, MARIO_ANIM_BACKWARD_KB, 22, TRUE, m->actionArg); - return FALSE; + return ACTION_FINISH; } s32 act_forward_ground_kb(struct MarioState *m) { common_ground_knockback_action(m, MARIO_ANIM_FORWARD_KB, 20, TRUE, m->actionArg); - return FALSE; + return ACTION_FINISH; } s32 act_soft_backward_ground_kb(struct MarioState *m) { common_ground_knockback_action(m, MARIO_ANIM_SOFT_BACK_KB, 100, FALSE, m->actionArg); - return FALSE; + return ACTION_FINISH; } s32 act_soft_forward_ground_kb(struct MarioState *m) { common_ground_knockback_action(m, MARIO_ANIM_SOFT_FRONT_KB, 100, FALSE, m->actionArg); - return FALSE; + return ACTION_FINISH; } s32 act_ground_bonk(struct MarioState *m) { @@ -1685,7 +1685,7 @@ s32 act_ground_bonk(struct MarioState *m) { if (animFrame == 32) { play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); } - return FALSE; + return ACTION_FINISH; } s32 act_death_exit_land(struct MarioState *m) { @@ -1707,7 +1707,7 @@ s32 act_death_exit_land(struct MarioState *m) { set_mario_action(m, ACT_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } u32 common_landing_action(struct MarioState *m, s16 animation, u32 airAction) { @@ -1777,36 +1777,36 @@ s32 common_landing_cancels(struct MarioState *m, struct LandingAction *landingAc return set_mario_action(m, landingAction->offFloorAction, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_jump_land(struct MarioState *m) { if (common_landing_cancels(m, &sJumpLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } common_landing_action(m, MARIO_ANIM_LAND_FROM_SINGLE_JUMP, ACT_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_freefall_land(struct MarioState *m) { if (common_landing_cancels(m, &sFreefallLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } common_landing_action(m, MARIO_ANIM_GENERAL_LAND, ACT_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_side_flip_land(struct MarioState *m) { if (common_landing_cancels(m, &sSideFlipLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } if (common_landing_action(m, MARIO_ANIM_SLIDEFLIP_LAND, ACT_FREEFALL) != GROUND_STEP_HIT_WALL) { m->marioObj->header.gfx.angle[1] += 0x8000; } - return FALSE; + return ACTION_FINISH; } s32 act_hold_jump_land(struct MarioState *m) { @@ -1815,11 +1815,11 @@ s32 act_hold_jump_land(struct MarioState *m) { } if (common_landing_cancels(m, &sHoldJumpLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } common_landing_action(m, MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_hold_freefall_land(struct MarioState *m) { @@ -1828,11 +1828,11 @@ s32 act_hold_freefall_land(struct MarioState *m) { } if (common_landing_cancels(m, &sHoldFreefallLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } common_landing_action(m, MARIO_ANIM_FALL_LAND_WITH_LIGHT_OBJ, ACT_HOLD_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_long_jump_land(struct MarioState *m) { @@ -1848,7 +1848,7 @@ s32 act_long_jump_land(struct MarioState *m) { } if (common_landing_cancels(m, &sLongJumpLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } if (!(m->input & INPUT_NONZERO_ANALOG)) { @@ -1859,22 +1859,22 @@ s32 act_long_jump_land(struct MarioState *m) { !m->marioObj->oMarioLongJumpIsSlow ? MARIO_ANIM_CROUCH_FROM_FAST_LONGJUMP : MARIO_ANIM_CROUCH_FROM_SLOW_LONGJUMP, ACT_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_double_jump_land(struct MarioState *m) { if (common_landing_cancels(m, &sDoubleJumpLandAction, set_triple_jump_action)) { - return TRUE; + return ACTION_CONTINUE; } common_landing_action(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_triple_jump_land(struct MarioState *m) { m->input &= ~INPUT_A_PRESSED; if (common_landing_cancels(m, &sTripleJumpLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } if (!(m->input & INPUT_NONZERO_ANALOG)) { @@ -1882,7 +1882,7 @@ s32 act_triple_jump_land(struct MarioState *m) { } common_landing_action(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 act_backflip_land(struct MarioState *m) { @@ -1891,7 +1891,7 @@ s32 act_backflip_land(struct MarioState *m) { } if (common_landing_cancels(m, &sBackflipLandAction, set_jumping_action)) { - return TRUE; + return ACTION_CONTINUE; } if (!(m->input & INPUT_NONZERO_ANALOG)) { @@ -1899,7 +1899,7 @@ s32 act_backflip_land(struct MarioState *m) { } common_landing_action(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_FREEFALL); - return FALSE; + return ACTION_FINISH; } s32 quicksand_jump_land_action(struct MarioState *m, s32 animation1, s32 animation2, u32 endAction, @@ -1925,7 +1925,7 @@ s32 quicksand_jump_land_action(struct MarioState *m, s32 animation1, s32 animati set_mario_action(m, airAction, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_quicksand_jump_land(struct MarioState *m) { @@ -1961,18 +1961,18 @@ s32 check_common_moving_cancels(struct MarioState *m) { } } - return FALSE; + return ACTION_FINISH; } s32 mario_execute_moving_action(struct MarioState *m) { - s32 cancel = FALSE; + s32 cancel = ACTION_FINISH; if (check_common_moving_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (mario_update_quicksand(m, 0.25f)) { - return TRUE; + return ACTION_CONTINUE; } /* clang-format off */ diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index 3dd32c3a9f..c95c9a59d5 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -169,7 +169,7 @@ s32 act_punching(struct MarioState *m) { mario_update_punch_sequence(m); perform_ground_step(m); - return FALSE; + return ACTION_FINISH; } s32 act_picking_up(struct MarioState *m) { @@ -207,7 +207,7 @@ s32 act_picking_up(struct MarioState *m) { } stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } s32 act_dive_picking_up(struct MarioState *m) { @@ -236,7 +236,7 @@ s32 act_dive_picking_up(struct MarioState *m) { #endif animated_stationary_ground_step(m, MARIO_ANIM_STOP_SLIDE_LIGHT_OBJ, ACT_HOLD_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_placing_down(struct MarioState *m) { @@ -253,7 +253,7 @@ s32 act_placing_down(struct MarioState *m) { } animated_stationary_ground_step(m, MARIO_ANIM_PLACE_LIGHT_OBJ, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_throwing(struct MarioState *m) { @@ -279,7 +279,7 @@ s32 act_throwing(struct MarioState *m) { } animated_stationary_ground_step(m, MARIO_ANIM_GROUND_THROW, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_heavy_throw(struct MarioState *m) { @@ -301,7 +301,7 @@ s32 act_heavy_throw(struct MarioState *m) { } animated_stationary_ground_step(m, MARIO_ANIM_HEAVY_THROW, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_stomach_slide_stop(struct MarioState *m) { @@ -318,7 +318,7 @@ s32 act_stomach_slide_stop(struct MarioState *m) { } animated_stationary_ground_step(m, MARIO_ANIM_SLOW_LAND_FROM_DIVE, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_picking_up_bowser(struct MarioState *m) { @@ -339,7 +339,7 @@ s32 act_picking_up_bowser(struct MarioState *m) { } stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } s32 act_holding_bowser(struct MarioState *m) { @@ -410,7 +410,7 @@ s32 act_holding_bowser(struct MarioState *m) { m->marioObj->header.gfx.angle[0] = m->angleVel[1]; } - return FALSE; + return ACTION_FINISH; } s32 act_releasing_bowser(struct MarioState *m) { @@ -430,7 +430,7 @@ s32 act_releasing_bowser(struct MarioState *m) { m->angleVel[1] = 0; animated_stationary_ground_step(m, MARIO_ANIM_RELEASE_BOWSER, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 check_common_object_cancels(struct MarioState *m) { @@ -447,18 +447,18 @@ s32 check_common_object_cancels(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_STANDING_DEATH, 0); } - return FALSE; + return ACTION_FINISH; } s32 mario_execute_object_action(struct MarioState *m) { - s32 cancel = FALSE; + s32 cancel = ACTION_FINISH; if (check_common_object_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (mario_update_quicksand(m, 0.5f)) { - return TRUE; + return ACTION_CONTINUE; } /* clang-format off */ diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index b0692e54aa..59815bdb3f 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -56,7 +56,7 @@ s32 check_common_idle_cancels(struct MarioState *m) { return set_mario_action(m, ACT_START_CROUCHING, 0); } - return FALSE; + return ACTION_FINISH; } s32 check_common_hold_idle_cancels(struct MarioState *m) { @@ -99,7 +99,7 @@ s32 check_common_hold_idle_cancels(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_START_CROUCHING, 0); } - return FALSE; + return ACTION_FINISH; } //! TODO: actionArg names @@ -117,7 +117,7 @@ s32 act_idle(struct MarioState *m) { } if (check_common_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->actionState == ACT_STATE_IDLE_RESET_OR_SLEEP) { @@ -177,7 +177,7 @@ s32 act_idle(struct MarioState *m) { stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } void play_anim_sound(struct MarioState *m, u32 actionState, s32 animFrame, u32 sound) { @@ -190,7 +190,7 @@ s32 act_start_sleeping(struct MarioState *m) { s32 animFrame = 0; if (check_common_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->quicksandDepth > 30.0f) { @@ -238,7 +238,7 @@ s32 act_start_sleeping(struct MarioState *m) { } stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } s32 act_sleeping(struct MarioState *m) { @@ -298,7 +298,7 @@ s32 act_sleeping(struct MarioState *m) { play_sound_if_no_flag(m, SOUND_MARIO_SNORING3, MARIO_ACTION_SOUND_PLAYED); break; } - return FALSE; + return ACTION_FINISH; } s32 act_waking_up(struct MarioState *m) { @@ -331,7 +331,7 @@ s32 act_waking_up(struct MarioState *m) { set_mario_animation(m, !m->actionArg ? MARIO_ANIM_WAKE_FROM_SLEEP : MARIO_ANIM_WAKE_FROM_LYING); - return FALSE; + return ACTION_FINISH; } s32 act_shivering(struct MarioState *m) { @@ -385,14 +385,14 @@ s32 act_shivering(struct MarioState *m) { } break; } - return FALSE; + return ACTION_FINISH; } s32 act_coughing(struct MarioState *m) { s32 animFrame; if (check_common_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } stationary_ground_step(m); @@ -409,7 +409,7 @@ s32 act_coughing(struct MarioState *m) { play_sound(SOUND_MARIO_COUGHING1, m->marioObj->header.gfx.cameraToObject); } - return FALSE; + return ACTION_FINISH; } s32 act_hold_idle(struct MarioState *m) { @@ -426,12 +426,12 @@ s32 act_hold_idle(struct MarioState *m) { } if (check_common_hold_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } stationary_ground_step(m); set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ); - return FALSE; + return ACTION_FINISH; } s32 act_hold_heavy_idle(struct MarioState *m) { @@ -457,7 +457,7 @@ s32 act_hold_heavy_idle(struct MarioState *m) { stationary_ground_step(m); set_mario_animation(m, MARIO_ANIM_IDLE_HEAVY_OBJ); - return FALSE; + return ACTION_FINISH; } s32 act_standing_against_wall(struct MarioState *m) { @@ -479,7 +479,7 @@ s32 act_standing_against_wall(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_STAND_AGAINST_WALL); stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } s32 act_in_quicksand(struct MarioState *m) { @@ -488,7 +488,7 @@ s32 act_in_quicksand(struct MarioState *m) { } if (check_common_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->quicksandDepth > 70.0f) { @@ -498,7 +498,7 @@ s32 act_in_quicksand(struct MarioState *m) { } stationary_ground_step(m); - return FALSE; + return ACTION_FINISH; } s32 act_crouching(struct MarioState *m) { @@ -536,7 +536,7 @@ s32 act_crouching(struct MarioState *m) { stationary_ground_step(m); set_mario_animation(m, MARIO_ANIM_CROUCHING); - return FALSE; + return ACTION_FINISH; } s32 act_panting(struct MarioState *m) { @@ -549,7 +549,7 @@ s32 act_panting(struct MarioState *m) { } if (check_common_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (set_mario_animation(m, MARIO_ANIM_WALK_PANTING) == 1) { @@ -559,7 +559,7 @@ s32 act_panting(struct MarioState *m) { stationary_ground_step(m); m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED; - return FALSE; + return ACTION_FINISH; } s32 act_hold_panting_unused(struct MarioState *m) { @@ -576,13 +576,13 @@ s32 act_hold_panting_unused(struct MarioState *m) { } if (check_common_hold_idle_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } set_mario_animation(m, MARIO_ANIM_WALK_PANTING); stationary_ground_step(m); m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED; - return FALSE; + return ACTION_FINISH; } void stopping_step(struct MarioState *m, s32 animID, u32 action) { @@ -612,7 +612,7 @@ s32 act_braking_stop(struct MarioState *m) { } stopping_step(m, MARIO_ANIM_STOP_SKID, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_butt_slide_stop(struct MarioState *m) { @@ -629,7 +629,7 @@ s32 act_butt_slide_stop(struct MarioState *m) { play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); } - return FALSE; + return ACTION_FINISH; } s32 act_hold_butt_slide_stop(struct MarioState *m) { @@ -650,7 +650,7 @@ s32 act_hold_butt_slide_stop(struct MarioState *m) { } stopping_step(m, MARIO_ANIM_STAND_UP_FROM_SLIDING_WITH_LIGHT_OBJ, ACT_HOLD_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_slide_kick_slide_stop(struct MarioState *m) { @@ -663,7 +663,7 @@ s32 act_slide_kick_slide_stop(struct MarioState *m) { } stopping_step(m, MARIO_ANIM_CROUCH_FROM_SLIDE_KICK, ACT_CROUCHING); - return FALSE; + return ACTION_FINISH; } s32 act_start_crouching(struct MarioState *m) { @@ -688,7 +688,7 @@ s32 act_start_crouching(struct MarioState *m) { if (is_anim_past_end(m)) { set_mario_action(m, ACT_CROUCHING, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_stop_crouching(struct MarioState *m) { @@ -713,7 +713,7 @@ s32 act_stop_crouching(struct MarioState *m) { if (is_anim_past_end(m)) { set_mario_action(m, ACT_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_start_crawling(struct MarioState *m) { @@ -739,7 +739,7 @@ s32 act_start_crawling(struct MarioState *m) { set_mario_action(m, ACT_CRAWLING, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_stop_crawling(struct MarioState *m) { @@ -760,7 +760,7 @@ s32 act_stop_crawling(struct MarioState *m) { if (is_anim_past_end(m)) { set_mario_action(m, ACT_CROUCHING, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_shockwave_bounce(struct MarioState *m) { @@ -797,7 +797,7 @@ s32 act_shockwave_bounce(struct MarioState *m) { vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); set_mario_animation(m, MARIO_ANIM_A_POSE); - return FALSE; + return ACTION_FINISH; } s32 landing_step(struct MarioState *m, s32 animID, u32 action) { @@ -806,7 +806,7 @@ s32 landing_step(struct MarioState *m, s32 animID, u32 action) { if (is_anim_at_end(m)) { return set_mario_action(m, action, 0); } - return FALSE; + return ACTION_FINISH; } s32 check_common_landing_cancels(struct MarioState *m, u32 action) { @@ -834,53 +834,53 @@ s32 check_common_landing_cancels(struct MarioState *m, u32 action) { return set_mario_action(m, ACT_PUNCHING, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_jump_land_stop(struct MarioState *m) { if (check_common_landing_cancels(m, 0)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_LAND_FROM_SINGLE_JUMP, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_double_jump_land_stop(struct MarioState *m) { if (check_common_landing_cancels(m, 0)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_side_flip_land_stop(struct MarioState *m) { if (check_common_landing_cancels(m, 0)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_SLIDEFLIP_LAND, ACT_IDLE); m->marioObj->header.gfx.angle[1] += 0x8000; - return FALSE; + return ACTION_FINISH; } s32 act_freefall_land_stop(struct MarioState *m) { if (check_common_landing_cancels(m, 0)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_GENERAL_LAND, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_triple_jump_land_stop(struct MarioState *m) { if (check_common_landing_cancels(m, ACT_JUMP)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_backflip_land_stop(struct MarioState *m) { @@ -889,34 +889,34 @@ s32 act_backflip_land_stop(struct MarioState *m) { } if (check_common_landing_cancels(m, ACT_BACKFLIP)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_lava_boost_land(struct MarioState *m) { m->input &= ~(INPUT_FIRST_PERSON | INPUT_B_PRESSED); if (check_common_landing_cancels(m, 0)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, MARIO_ANIM_STAND_UP_FROM_LAVA_BOOST, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_long_jump_land_stop(struct MarioState *m) { m->input &= ~INPUT_B_PRESSED; if (check_common_landing_cancels(m, ACT_JUMP)) { - return TRUE; + return ACTION_CONTINUE; } landing_step(m, !m->marioObj->oMarioLongJumpIsSlow ? MARIO_ANIM_CROUCH_FROM_FAST_LONGJUMP : MARIO_ANIM_CROUCH_FROM_SLOW_LONGJUMP, ACT_CROUCHING); - return FALSE; + return ACTION_FINISH; } s32 act_hold_jump_land_stop(struct MarioState *m) { @@ -937,7 +937,7 @@ s32 act_hold_jump_land_stop(struct MarioState *m) { } landing_step(m, MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_hold_freefall_land_stop(struct MarioState *m) { @@ -957,7 +957,7 @@ s32 act_hold_freefall_land_stop(struct MarioState *m) { return set_mario_action(m, ACT_THROWING, 0); } landing_step(m, MARIO_ANIM_FALL_LAND_WITH_LIGHT_OBJ, ACT_HOLD_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_air_throw_land(struct MarioState *m) { @@ -974,7 +974,7 @@ s32 act_air_throw_land(struct MarioState *m) { } landing_step(m, MARIO_ANIM_THROW_LIGHT_OBJECT, ACT_IDLE); - return FALSE; + return ACTION_FINISH; } s32 act_twirl_land(struct MarioState *m) { @@ -1004,7 +1004,7 @@ s32 act_twirl_land(struct MarioState *m) { set_mario_action(m, ACT_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } s32 act_ground_pound_land(struct MarioState *m) { @@ -1022,7 +1022,7 @@ s32 act_ground_pound_land(struct MarioState *m) { } landing_step(m, MARIO_ANIM_GROUND_POUND_LANDING, ACT_BUTT_SLIDE_STOP); - return FALSE; + return ACTION_FINISH; } s32 act_first_person(struct MarioState *m) { @@ -1054,7 +1054,7 @@ s32 act_first_person(struct MarioState *m) { stationary_ground_step(m); set_mario_animation(m, MARIO_ANIM_FIRST_PERSON); - return FALSE; + return ACTION_FINISH; } s32 check_common_stationary_cancels(struct MarioState *m) { @@ -1077,18 +1077,18 @@ s32 check_common_stationary_cancels(struct MarioState *m) { return drop_and_set_mario_action(m, ACT_STANDING_DEATH, 0); } } - return FALSE; + return ACTION_FINISH; } s32 mario_execute_stationary_action(struct MarioState *m) { s32 cancel; if (check_common_stationary_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } if (mario_update_quicksand(m, 0.5f)) { - return TRUE; + return ACTION_FINISH; } /* clang-format off */ @@ -1129,7 +1129,7 @@ s32 mario_execute_stationary_action(struct MarioState *m) { case ACT_BRAKING_STOP: cancel = act_braking_stop(m); break; case ACT_BUTT_SLIDE_STOP: cancel = act_butt_slide_stop(m); break; case ACT_HOLD_BUTT_SLIDE_STOP: cancel = act_hold_butt_slide_stop(m); break; - default: cancel = TRUE; break; + default: cancel = ACTION_CONTINUE; break; } /* clang-format on */ diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 6c8a737293..b67d90abfd 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -343,7 +343,7 @@ static s32 act_water_idle(struct MarioState *m) { } common_idle_step(m, MARIO_ANIM_WATER_IDLE, animAccel); - return FALSE; + return ACTION_FINISH; } static s32 act_hold_water_idle(struct MarioState *m) { @@ -364,7 +364,7 @@ static s32 act_hold_water_idle(struct MarioState *m) { } common_idle_step(m, MARIO_ANIM_WATER_IDLE_WITH_OBJ, 0); - return FALSE; + return ACTION_FINISH; } static s32 act_water_action_end(struct MarioState *m) { @@ -384,7 +384,7 @@ static s32 act_water_action_end(struct MarioState *m) { if (is_anim_at_end(m)) { set_mario_action(m, ACT_WATER_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_water_action_end(struct MarioState *m) { @@ -410,7 +410,7 @@ static s32 act_hold_water_action_end(struct MarioState *m) { if (is_anim_at_end(m)) { set_mario_action(m, ACT_HOLD_WATER_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } static void reset_bob_variables(struct MarioState *m) { @@ -502,7 +502,7 @@ static s32 check_water_jump(struct MarioState *m) { } } - return FALSE; + return ACTION_FINISH; } static s32 act_breaststroke(struct MarioState *m) { @@ -523,7 +523,7 @@ static s32 act_breaststroke(struct MarioState *m) { } if (check_water_jump(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->actionTimer < 6) { @@ -562,7 +562,7 @@ static s32 act_breaststroke(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_SWIM_PART1); common_swimming_step(m, sSwimStrength); - return FALSE; + return ACTION_FINISH; } static s32 act_swimming_end(struct MarioState *m) { @@ -579,7 +579,7 @@ static s32 act_swimming_end(struct MarioState *m) { } if (check_water_jump(m)) { - return TRUE; + return ACTION_CONTINUE; } if ((m->input & INPUT_A_DOWN) && m->actionTimer >= 7) { @@ -599,7 +599,7 @@ static s32 act_swimming_end(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_SWIM_PART2); common_swimming_step(m, sSwimStrength); - return FALSE; + return ACTION_FINISH; } static s32 act_flutter_kick(struct MarioState *m) { @@ -628,7 +628,7 @@ static s32 act_flutter_kick(struct MarioState *m) { } common_swimming_step(m, sSwimStrength); - return FALSE; + return ACTION_FINISH; } static s32 act_hold_breaststroke(struct MarioState *m) { @@ -649,7 +649,7 @@ static s32 act_hold_breaststroke(struct MarioState *m) { } if (check_water_jump(m)) { - return TRUE; + return ACTION_CONTINUE; } if (m->actionTimer < 6) { @@ -679,7 +679,7 @@ static s32 act_hold_breaststroke(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_SWIM_WITH_OBJ_PART1); common_swimming_step(m, 160); - return FALSE; + return ACTION_FINISH; } static s32 act_hold_swimming_end(struct MarioState *m) { @@ -700,7 +700,7 @@ static s32 act_hold_swimming_end(struct MarioState *m) { } if (check_water_jump(m)) { - return TRUE; + return ACTION_CONTINUE; } if ((m->input & INPUT_A_DOWN) && m->actionTimer >= 7) { @@ -712,7 +712,7 @@ static s32 act_hold_swimming_end(struct MarioState *m) { m->forwardVel -= 0.25f; set_mario_animation(m, MARIO_ANIM_SWIM_WITH_OBJ_PART2); common_swimming_step(m, 160); - return FALSE; + return ACTION_FINISH; } static s32 act_hold_flutter_kick(struct MarioState *m) { @@ -738,7 +738,7 @@ static s32 act_hold_flutter_kick(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_FLUTTERKICK_WITH_OBJ); } common_swimming_step(m, 160); - return FALSE; + return ACTION_FINISH; } static s32 act_water_shell_swimming(struct MarioState *m) { @@ -763,7 +763,7 @@ static s32 act_water_shell_swimming(struct MarioState *m) { set_mario_animation(m, MARIO_ANIM_FLUTTERKICK_WITH_OBJ); common_swimming_step(m, 300); - return FALSE; + return ACTION_FINISH; } static s32 check_water_grab(struct MarioState *m) { @@ -780,11 +780,11 @@ static s32 check_water_grab(struct MarioState *m) { m->usedObj = object; mario_grab_used_object(m); m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ; - return TRUE; + return ACTION_CONTINUE; } } - return FALSE; + return ACTION_FINISH; } static s32 act_water_throw(struct MarioState *m) { @@ -810,7 +810,7 @@ static s32 act_water_throw(struct MarioState *m) { set_mario_action(m, ACT_WATER_IDLE, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_water_punch(struct MarioState *m) { @@ -856,7 +856,7 @@ static s32 act_water_punch(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } static void common_water_knockback_step(struct MarioState *m, s32 animation, u32 endAction, s32 actionArg) { @@ -877,12 +877,12 @@ static void common_water_knockback_step(struct MarioState *m, s32 animation, u32 static s32 act_backward_water_kb(struct MarioState *m) { common_water_knockback_step(m, MARIO_ANIM_BACKWARDS_WATER_KB, ACT_WATER_IDLE, m->actionArg); - return FALSE; + return ACTION_FINISH; } static s32 act_forward_water_kb(struct MarioState *m) { common_water_knockback_step(m, MARIO_ANIM_WATER_FORWARD_KB, ACT_WATER_IDLE, m->actionArg); - return FALSE; + return ACTION_FINISH; } static s32 act_water_shocked(struct MarioState *m) { @@ -903,7 +903,7 @@ static s32 act_water_shocked(struct MarioState *m) { stationary_slow_down(m); perform_water_step(m); m->marioBodyState->headAngle[0] = 0; - return FALSE; + return ACTION_FINISH; } static s32 act_drowning(struct MarioState *m) { @@ -929,7 +929,7 @@ static s32 act_drowning(struct MarioState *m) { stationary_slow_down(m); perform_water_step(m); - return FALSE; + return ACTION_FINISH; } static s32 act_water_death(struct MarioState *m) { @@ -943,7 +943,7 @@ static s32 act_water_death(struct MarioState *m) { level_trigger_warp(m, WARP_OP_DEATH); } - return FALSE; + return ACTION_FINISH; } static s32 act_water_plunge(struct MarioState *m) { @@ -1030,7 +1030,7 @@ static s32 act_water_plunge(struct MarioState *m) { } m->particleFlags |= PARTICLE_PLUNGE_BUBBLE; - return FALSE; + return ACTION_FINISH; } static s32 act_caught_in_whirlpool(struct MarioState *m) { @@ -1090,7 +1090,7 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) { reset_rumble_timers_slip(); #endif - return FALSE; + return ACTION_FINISH; } static void play_metal_water_jumping_sound(struct MarioState *m, u32 landing) { @@ -1196,7 +1196,7 @@ static s32 act_metal_water_standing(struct MarioState *m) { m->particleFlags |= PARTICLE_IDLE_WATER_WAVE; } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_metal_water_standing(struct MarioState *m) { @@ -1218,7 +1218,7 @@ static s32 act_hold_metal_water_standing(struct MarioState *m) { stop_and_set_height_to_floor(m); set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ); - return FALSE; + return ACTION_FINISH; } static s32 act_metal_water_walking(struct MarioState *m) { @@ -1258,7 +1258,7 @@ static s32 act_metal_water_walking(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_metal_water_walking(struct MarioState *m) { @@ -1300,7 +1300,7 @@ static s32 act_hold_metal_water_walking(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } static s32 act_metal_water_jump(struct MarioState *m) { @@ -1325,7 +1325,7 @@ static s32 act_metal_water_jump(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_metal_water_jump(struct MarioState *m) { @@ -1354,7 +1354,7 @@ static s32 act_hold_metal_water_jump(struct MarioState *m) { break; } - return FALSE; + return ACTION_FINISH; } static s32 act_metal_water_falling(struct MarioState *m) { @@ -1373,7 +1373,7 @@ static s32 act_metal_water_falling(struct MarioState *m) { set_mario_action(m, ACT_METAL_WATER_FALL_LAND, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_metal_water_falling(struct MarioState *m) { @@ -1396,7 +1396,7 @@ static s32 act_hold_metal_water_falling(struct MarioState *m) { set_mario_action(m, ACT_HOLD_METAL_WATER_FALL_LAND, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_metal_water_jump_land(struct MarioState *m) { @@ -1417,7 +1417,7 @@ static s32 act_metal_water_jump_land(struct MarioState *m) { return set_mario_action(m, ACT_METAL_WATER_STANDING, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_metal_water_jump_land(struct MarioState *m) { @@ -1442,7 +1442,7 @@ static s32 act_hold_metal_water_jump_land(struct MarioState *m) { return set_mario_action(m, ACT_HOLD_METAL_WATER_STANDING, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_metal_water_fall_land(struct MarioState *m) { @@ -1463,7 +1463,7 @@ static s32 act_metal_water_fall_land(struct MarioState *m) { return set_mario_action(m, ACT_METAL_WATER_STANDING, 0); } - return FALSE; + return ACTION_FINISH; } static s32 act_hold_metal_water_fall_land(struct MarioState *m) { @@ -1488,7 +1488,7 @@ static s32 act_hold_metal_water_fall_land(struct MarioState *m) { return set_mario_action(m, ACT_HOLD_METAL_WATER_STANDING, 0); } - return FALSE; + return ACTION_FINISH; } static s32 check_common_submerged_cancels(struct MarioState *m) { @@ -1520,14 +1520,14 @@ static s32 check_common_submerged_cancels(struct MarioState *m) { set_mario_action(m, ACT_DROWNING, 0); } - return FALSE; + return ACTION_FINISH; } s32 mario_execute_submerged_action(struct MarioState *m) { - s32 cancel = FALSE; + s32 cancel = ACTION_FINISH; if (check_common_submerged_cancels(m)) { - return TRUE; + return ACTION_CONTINUE; } m->quicksandDepth = 0.0f; diff --git a/src/game/newfont2_swapped.bin b/src/game/newfont2_swapped.bin deleted file mode 100644 index 72cf2c53ed95e374a692e3647832d7c2fdec7223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4032 zcmd6pOP1U)2t_^d{yfpx`(J>^%DoR!<*u%LIyuP+Dj5j@f+sB3wr$%OW1EYZD%i#$ zKf+y#{KF#}A0+?P|9M zmTTAYS08_SzOTTa(5{g&5`Fg?_4E5t?Qd`x69AzHeiPgf_58fRX z4+P*G$^idOZf9_vb6$>{XAM)$O9!E=?T%r?D#YiHUZD)&`%^57gQye`%<>DFwyQcGE!h#$aH{xW} zZH&nCByQ#4tU25>IOO6RdDis9n&Z~h&Nha!)^DzUYdraqfj@PU_Xkdn>GeJhYR24@ z+s)J_rs@R~YdAJJ(bBkBi{|ZFddFNOmQv5hxDN7l6ZWe2-nFr07K3XRuDK#-f4F@j zDOEPU=PIUlb#!%aZCx_m?9ouKY)<`tY6ODrUEaP2dne<09VeZs?@~DNWqf+3NuByM zm*C5I=@%~>ZJDEUYn)XYYr-K$lH+@QdLMZ2)Ly06lXKz}lAA{W$3U>0Q(J?zN)(P_ z&?g@7w#W8{0gxDHx<1kH0;!*J@<3kwW>*UMeaKeL6FYk%=S&JM^M2{pXYjjNvuH%> znk9SDrGCqvRqRL^-POibFRnE>7m20R^X!G9vP8tgH3A>v!6Q81D-bYubFo-X@(wRK zF=`Z)u+t%K#3rpZiP1Q(lIyR0fhAFt{=+6dkr6}f9bXG`<47!=gYkoFXI>n+_uvCx zwD5z^`u3h@BL#opHd5ESXV6%qmzrbV-@LiVeed6QY-kf(R|@CCj!C5uxp{DX5_3|^ zBe^ZK9Jl@&7e2T3(${TcTatmGWE0*^J=@H)e4~}4esYe?!wF^v`oLh-nHUFCunc-6 z`qc5;9BE+({=r*aFsW|~cK~(S-94 z#whhz{n*9_m@FMR9ekEAkz%eLqm08Dm+Yx`-y`q(;G0DYmiS1Xb?>FV(9gXomfi)` z^ml=sv09_mN;Zri39(z(6fxh2M_r10Y7`y!nu{FY>yz)BA4AR}YW1$0Zz6;bEwmY_ zVbnveD7$x+)mLVoIRnPaWc~NivZ!r){*jj-Wjim0j^lUn=&pZJkF|rI z5z!NiYZ;5fb1b%rExNszHVU{hVqEP_vUDemz8^3Q? CYbyf) diff --git a/src/game/puppyprint.c b/src/game/puppyprint.c index 6afdc709a6..74f3be39d4 100644 --- a/src/game/puppyprint.c +++ b/src/game/puppyprint.c @@ -1595,7 +1595,7 @@ void print_small_text(s32 x, s32 y, const char *str, s32 align, s32 amount, u8 f lines = 0; shakeTablePos = gGlobalTimer % sizeof(sTextShakeTable); - gDPLoadTextureBlock_4b(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, 0, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock_4bS(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, 0, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, G_TX_NOLOD, G_TX_NOLOD); for (s32 i = 0, j = 0; i < textLength; i++, j++) { if (str[i] == '\n') { @@ -1717,7 +1717,7 @@ void print_small_text_light(s32 x, s32 y, const char *str, s32 align, s32 amount } lines = 0; - gDPLoadTextureBlock_4b(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, 0, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock_4bS(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, 0, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, G_TX_NOLOD, G_TX_NOLOD); for (s32 i = 0, j = 0; i < textLength; i++, j++) { if (str[i] == '\n') { diff --git a/text/define_text.inc.c b/text/define_text.inc.c index c2abf7dcbe..069b13e369 100644 --- a/text/define_text.inc.c +++ b/text/define_text.inc.c @@ -1,27 +1,26 @@ // == dialog == // (defines en_dialog_table etc.) -#include "game/ingame_menu.h" +#include "dialog_ids.h" -#undef DEFINE_DIALOG #define DEFINE_DIALOG(id, _1, _2, _3, _4, str) \ - static const char dialog_text_ ## id[] = { str }; + static const u8 dialog_text_ ## id[] = { str }; -#include DIALOG_FILE +#include "dialogs.h" #undef DEFINE_DIALOG -#define DEFINE_DIALOG(id, voice, linesPerBox, leftOffset, width, _) \ +#define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \ static const struct DialogEntry dialog_entry_ ## id = { \ - voice, linesPerBox, leftOffset, width, dialog_text_ ## id \ + unused, linesPerBox, leftOffset, width, dialog_text_ ## id \ }; -#include DIALOG_FILE +#include "dialogs.h" #undef DEFINE_DIALOG -#define DEFINE_DIALOG(id, _1, _2, _3, _4, _5) &dialog_entry_ ## id, +#define DEFINE_DIALOG(id, _1, _2, _3, _4, _5) [id] = &dialog_entry_ ## id, -const struct DialogEntry *const DIALOG_TABLE[] = { -#include DIALOG_FILE +const struct DialogEntry *const seg2_dialog_table[] = { +#include "dialogs.h" NULL }; @@ -31,27 +30,28 @@ const struct DialogEntry *const DIALOG_TABLE[] = { // The game duplicates this in levels/menu/leveldata.c in EU, so we split // it out into a separate include file. +#define COURSE_TABLE seg2_course_name_table #include "define_courses.inc.c" // == acts == // (defines en_act_name_table etc.) #define COURSE_ACTS(id, name, a,b,c,d,e,f) \ - static const char act_name_ ## id ## _1[] = { a }; \ - static const char act_name_ ## id ## _2[] = { b }; \ - static const char act_name_ ## id ## _3[] = { c }; \ - static const char act_name_ ## id ## _4[] = { d }; \ - static const char act_name_ ## id ## _5[] = { e }; \ - static const char act_name_ ## id ## _6[] = { f }; + static const u8 act_name_ ## id ## _1[] = { a }; \ + static const u8 act_name_ ## id ## _2[] = { b }; \ + static const u8 act_name_ ## id ## _3[] = { c }; \ + static const u8 act_name_ ## id ## _4[] = { d }; \ + static const u8 act_name_ ## id ## _5[] = { e }; \ + static const u8 act_name_ ## id ## _6[] = { f }; #define SECRET_STAR(id, name) #define CASTLE_SECRET_STARS(str) #undef EXTRA_TEXT #define EXTRA_TEXT(id, str) \ - static const char extra_text_ ## id[] = { str }; + static const u8 extra_text_ ## id[] = { str }; -#include COURSE_FILE +#include "courses.h" #undef COURSE_ACTS #undef EXTRA_TEXT @@ -61,10 +61,7 @@ const struct DialogEntry *const DIALOG_TABLE[] = { act_name_ ## id ## _4, act_name_ ## id ## _5, act_name_ ## id ## _6, #define EXTRA_TEXT(id, str) extra_text_ ## id, -const char *const ACT_NAME_TABLE[] = { -#include COURSE_FILE +const u8 *const seg2_act_name_table[] = { +#include "courses.h" NULL }; - -#undef COURSE_ACTS -#undef EXTRA_TEXT diff --git a/textures/fasttext/newfont2.ia4.preswap.png b/textures/fasttext/newfont2.ia4.preswap.png new file mode 100644 index 0000000000000000000000000000000000000000..590447e4d5b8607748d3a7071584c2a31cc08cb4 GIT binary patch literal 1334 zcmV-61Px#1ZP1_K>z@;j|==^1poj52~bQ_MO9T*|Ns90001W_y!rqD00VSVPE-H?0N2V5 zK>z>%32;bRa{vGi!2kdb!2!6DYwZ941gA+vK~!i%?Np0$961Q|`u{&V^a~-)ti9P> z%2!v{6$CU5XlBRx_%uF<&(FsJmkX-%NZ#k_WAY8wjQ{cb_>aE5dMv=7QR9OJ)E`x> zz~i>jcW887eJlZIkg3ePwtL?3vUk4=k>VzKyj3S<(m%_eb{LMMVzSjq^|jaO8x~j zhgT^j0*rUwycne{3^()k+Pb`W%`YIG`sDN##IJgc1l|+;;I*g1N)}&7JJr6(D|p?c zuU&OwHGy||V&m9()lUuLJN_-aIiT9cV=nN;V>e0l!VnMaW-_(}#a*z?NIzzQDb?DJF8U_!5SVZusx5 zkhzyy<}iR#KI;p3S9uHCKXVa#JvqGIDm)(wKwReEMLcrxXmfw&-R(&($2m{Tb7O8W zm<~{}%2xq4*M44rlZ_QBvK)_3ry8nzPJLw>2VQ4+Qfk0Ms7@#*uZbd;mrhfbC%;TG zYd79ga~legH-m|J1z^`}iw=3bjp-$4;OFpp7zKG97awpG?(vOhF!>5p_aNMXc@-3k zX=< zu2*#!_rOX-Ij3{j@vu4nG>y+*vbVa6c~^JswRPG^h~43G_7pgIo(Oo$`vD?|jTTuesGZ2SAL1_1ss1^n7nCAHKjD0LD+K z(?!61gL^f&+>&Cj0<76SQ0_a%cAh@Y!*q645O1EEkuM(X=#M9xDx-pD$WHz6(x^)* za$6I({AnymcRSB{ZrZu3#g+sIGAVLWh?#)<#JjycczXi2YKbFOdW0L z%JqEIIEQHlNY7dYq|qlm{o*wzU^;+F&^63Aijo2+14Hw<2dU-I6XApOx=lodatq-j z={#QS%I$fO&R)EslpC9VctULozh%Cg6a0t{(>KuXpRd63@jvMO1^)I|^K9== s;@@y5+~J?N#T@b{1E2N!Gcq2JUqxRcOwRY=3;+NC07*qoM6N<$f*)m*s{jB1 literal 0 HcmV?d00001 diff --git a/textures/segment2/custom_text.i4.png b/textures/segment2/custom_text.i4.png deleted file mode 100644 index 4bf8a055d40f36dde7b39ef35afe493c4f429301..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2001 zcmV;?2QK)DP)w7V%H#erb^^?3-*nj$}^l0f6658FpO|KZffx zzV~Hq(`BIdPi?Sz?0uAA&8m4_`;NK|{?SJt-P3;IUR_^TulJhMJ&2(8JqTm#^WpEr z|1?H+mb$Tb;CCi}NYWLy>4VkZqKY4-7qK#fW%eEB^$q{u+k5}%g2x2?Ssm|k z-}_95gv(EIc)82FveEw{#bWB;m9YJ;?5?cO??6D6&uV{LA)u-LsRWeOyLvFYgMfZD z28n;GfB9X-|EwH6X)6o&DhH5&vOkj}VAVJAFD*C~e*oYw{SE{aeZu%zu2)Hy>hJ0Z z4@&i&AUeYnDUjX3$eEcc`s$K&yF8sDi zK-ruwKltK-*x?+#T`iJ{sH!d4{Ku>>=ID* zl9t9-wtLQdEp*?y9Y&sd9~b}X_=LPMJxf3xIqdWH9H6~k`_7N#&~@=*>X?N(xdF9HNxgPv%c`0uX&vRj$pa^RamRDk6m8ag(Ss*)ef!;wm-Y| zRdcg=RUIMeX8xx839g^Ba^OTO3;QAmWN~AX5V*wOG%iIBoJ=>^YESH*8Ovf#;x9Qv zKv`esH`{!euQ*>{RLozTLml`?LYeR7+u4hbQ+GM(_R#i(uiG#tJXE_I&*qw5tC(C( zK$QO4gFGnEL@e`p{xH^2*e2Ty*64GO11Qgq+^`Yuu^>9pZaPd2v zEPq%Z46l^LAZGa6`LFDyHBxiAI(6%d5vjy~*4}+l;~hRzds?#z2H1ueul%mK6`mz- z?WlNGE-O909XZlMy3v8(Kq+CjE_DM){B!-z5>S@FGdS*Qz1$@6m#h*{7oQ?;ET22R1XPiF}z`pD+)xb&PWqU_cIi*bj1G91(Rr*%7xXP4zJ4s+%I z>I;<9XcR5XRu57%MfKE6i2PFGHeq)D_B1YB6 z*Nd&84gp2-&0^^5tj05Fg^%ruC)v`!pUl|L&vNt{e!=>Os0I$wr3+p@2+4O8}nw1OQsSn}9k$ z@P>$+(-c#$4VF75jx2XOZ2oBxsyEhB9cZf0 z>N-OonXfoM6E!c(PjY~%`B~2Uno0;B`iKNEA@JxYizSV3<#mzG!NyN@j+n4RSIy^q zRQXe}B(e4J{i3AeXSJ=?P*NYvhN_dqw%ZF;-WWcton4ODrHqZQzKVb*{`Y-^*}jv2 zx^stNfH+|86wWG7(*+K(au-l_zM-U;?#i)}xSJffUELutwO{4`OLkt#luoaokG@Cm z%I%~7rj|T4_2{FsrWfR{|I*spd0b4f+~j{>?!a5L3N^iXrtz)Vz9X)8V)*ELbNlGO jt4~cm`skzIU3cX_gOe_a1yQ#E00000NkvXXu0mjfE5r;z diff --git a/textures/segment2/custom_text.i4.preswap.png b/textures/segment2/custom_text.i4.preswap.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2425b587b0b63fd7947b0e0112e79d9ec9af2b GIT binary patch literal 1308 zcmV+%1>^dOP)~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj53{Xr|MF0Q*r>Cd?|Nl=z>%32;bRa{vGi z!vFvd!vV){sAK>D1er-hK~z}7&6f>wBPk4p1zZ5|1pr-uCilPFz9-Qgx8tN{cc-QX zR~v`sM|^q`L|E#qbL=9!)QPV$rJ#Cl|12rX-(1%BufnLaqmJ0Y8cq1S|Bt2O$l>Cb z#=HStS(+T(>> z7f?y>f%e)B{7-AF?Y2j%dIQRGHe|)ZB~11NTuFTcO|MHHvb1LMI`YyI$Q;C2tv-vy zwsN)4IbuX~4hoObiz9-Goig5aQIuG;0)X5)&31o%swf!YxJ9Vj2^%@elSp8fIhIIFK*L~?|?SEUoBX3 z=r&OpjWEQVdKQf&!;!(ol<^fjiLX+XCfePy`nm|QPpcU;a>5|HZkWalO^rF&MP8R0;@D=BQlkz%&o+@1r zIxklPOs8Ny;47HP?OXUAxK<=?QLa_xN1!w^lx*=bwoKVxcOI={C&kG3C(xQB!?6P> zB#2gXfQ9E{d&dA^eWVojtp+k(K)E>&{S8#TT~(WQD1`#TD627dq_;OvfRY#hlnz^% zIh?tAZQvf}1kXts%50A((6ZNBw1=pIsk86YKrx&^?Gqj=@jR%QA?XXy{sL5Sz`z5q zK))#TcmkU2WI{L+XzG!f6q{QQ9#&5$QK9_^_k6Sy=-A-|DE+3;ZJO5BbS(qQzFtpT z?*tmCrBw^liEYqD!#r#6i?}K+JekJFx&a+}2g-CYCZoV_15)(@O4r7998S5o5^g|0 z?m)wlwMadz?Wd4$mbg8KQh89Rs~A9)tUbqGr=GYJnGRr_(vFvqFE^ku`zGUT5d02x zW2N+%jo3hwHVJh->_`HjEgG&bJ55}*3n<%Bb*Xl{4&1IyA~&GXLW)-yUOk6}BVq1qXr_hs zzRwFNZ&r~03S6d+R{hkSzS!vJwFw6;a~>5BaMB2m`I!Au^)TjG%lE7+Q(0(>3<0$6 zG*icF1@HZo=NvXMZ)ikhKrtPDSLAgE%632HKY?;P*eDh2Yr%2F9Ln3@>nShaNLJol z>_3keIpp7!IOR8$sPYGjUod~R`suj+HK4EmdWNUVZTn9K{+9Ar{>$t1#`p(aQN;qW SV`XOm0000lD)}_PWXjl2Fc;Z_&9e-M?Z)@al62rSVP!h3q=ApBjt~?|`z~Vy} zmwOigD{9SwNQeWb7NoL7@s34c!r`j~)zSF}6mhTom43xg4+X-5uua|Htp{=L*jfFG zo4f1j@Hx%5I$!6Jp=xvOPm5iYhbF2)VzLW>EiYTr=#$}N zG2Et#gOf%5)XGn>)kb%^&?^z09uSvz=o5!1Bjf zS$r4&4*xDcOyBJyPlG1&G|m_}L7wKCl|%z_a}5$L^!}j7JvJwKIH-7uSyByE?Tq`JiTt9#A#oB<0dN)&-E*r=1cWo^`*;Khu_M4B4NGm@Y~7n+Ozk=eP2-BY}e3!Dr{99^)J&AZ?Olg zCe&Y)FSE1Qjz7X(jUWHpPmJKhm@Fs!iQ>?pO3G|5N#@{Y7!_z&D|*emQk@ z^SS3rM=>h(-L3EPx5}&bBj#ncj(-JTjH&i5`bR8r|6XZlwX^v^^NQj-I*ZSGv-+#P zv7S`;$#lnG)!6aR_(vEO{y5{&hw;DKtNyHa%Y5WVn^Si@#!Lcy{Ki zQeTE~GXAcmfr zV!8D>xvNWp{Ida4d?@Y|x6Ut%@6?m|JMk;FN_>ZZr@!$L%5uBh@AS8m|I_AcH~y>f zW&Eu(GLe5`Ka_uV=FXFQ?(jJ=pP7G!zlyzr9rNR*&QF&fU&@C>*=| zb?bBaoc#W4$=d-KauIqx?9q0eBhq*AU-41y31M{|d5yUJ?JW0^e@oVP>g@E9BS$`6 z-v0gfb^xYS|MIwG7ysQK9_ORxy>dP*k4(y$rz1y>{4KKk{r4ZrYN-}RmpEMj0000< KMNUMnLSTZ#09qIT diff --git a/textures/segment2/custom_text2.ia4.preswap.png b/textures/segment2/custom_text2.ia4.preswap.png new file mode 100644 index 0000000000000000000000000000000000000000..d9a1df8b1f8ce685479323a16487a545e6b5eadb GIT binary patch literal 1329 zcmV-11Px#1ZP1_K>z@;j|==^1poj52~bQ_MO9T*|Ns90001W_y!rqD00VSVPE-H?0N2V5 zK>z>%32;bRa{vGi!Tw zkOdTRqTWee^8=Oq6KD>v!dvnJ$(t9Wl!f7D-d~35-R%R_z}H}hZ&Tx{iQ}Ey@&e3(TYQ*?w^u)d*F7{~`n|@J z4`hx+9oc8|TYb~!`5kL5JRS_de);6O=crqdzUX-v8?Qf$bsHQB*Vmk}CqnJp`tPP0 zh=KO_wI-m#nuhrXy6V72CYJGn3b1DNLB8n>rv)|Wv7yujC{k`;2mCfQ7a{*JP9OfI z0b6c;`vUjorkKdZ;!7Ady5YaJLgqednZp1|`K&MCt?~-mKXVa#9XWdC&FhZ>%##X_ zT)gM>yq+TqFQN54^JeL{cZ0!nfQnUq3b48M^8%b`tWc5V`19#hLv_!ouT0~>>nu-7 z4Y<7OgktiVC~|q}G-Y}6%OtaQ<2^OEp%8g9n3yL3yPhpN# zfTM7aFFXT!jl~qzdyMlc;6CO{Cwwr zPP0$_X4V}Xea~GrO^#=f8)3h)!1byQUgH!yXA(?|U&sCHju8`Uw`a+ddhgX&!9+>OX-Ij3{j@vu4nG>y+*vRB>1 zysNwR+B$6{#BTg)*Lk+ww7EL$HrsRs%mn;JwRiiw|0Vc^I{uF@;LoV>csTP7(--LX&sSji_!sp4dHn6K n=GESRiJy3C7{5BwJ>C4L{O%{22+E4`Y+PBe=gLE3QgM291e_#9;f^v2);e^+e%ecbNFBZ^Vb1 zBZ|jx|?kA+04b+on2vB;S8abP4l(m{A9RyZ%qGL49@!B6G8 zi?xfVp0Nv}6xaX|>e;t@I3ha)|5t`^hauxx;i|GhF|hF}>{V_wf23EOp`3nQ@Ag~C zSLHzSDY55+=nLUb6wR6?Q^5?2^z0cxTxe?zALxd;tNAaWB)c6ij z^0PYIf7ZYIj&Q(mIO|I6)jx_EnMMbjT2AANhiNLC$4=st+O>N@jElpjX&Sd zzq{|Z_4zn<>xup9#_#S}_Y5_$5rDj$3_jHk#oxu*6$C%KEDj!7o>YJ2e%H6C$4~dC z(ktv;K2>he{GAv`Jy8sXpZPcYj@}*pWBt`RQ1>m?|jwaU=~Ql|Ab_@SFDJw62Ha@c{ta@7*{H$hX?%vj!e!21?{31FV8}VV^yZpN2vG+=T2OsP` zD&6{6zFB`J$9!D;c6WivyNkot6X`o{6#m$GVtMK46=!Ju&K>KX(FI`u@Z)#=UU4Zn zE1&Eg!H@FOZLm@sGJwc(Wic2|RvW~(vO(*r{Mk3AzbN*T`VIri9otV-uX4EgU}j!< z@8&;MFM6NVi^MpMkCoH>s`aWhy7^^xq1(UtclUjYU!|T7M{K_JR2-^&u-F+s)HBq? zMgS$ztNqTG9U69k5d3O>2mdExU-9)IvRUsVJ)61go%OBoWVIpwReebOE`L>h^Bt2D zv31wSa>(Xq{F#2R`+;EW%x4yxeP3-*f2J1q{G-^^`0Bhk_KV#ornd~nECv$$i~H3* zgIVN50K#}(Y)k{x`qaEv{tdbPz2cHPOIKD={^tBo!gBIIarngCbkA?vm{S!252LXF O0000~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj522e~?MF0Q*|NsA`*`M72000SaNLh0L01m?d01m?e z$8V@)0007uNklZ;`1{9(&5jCIvW4`zEWj^QnKNAmfO-E}LWY}hs0<^OSr2E0wdfIG!=Kj1cXONY#4;f1(5{=%NJo@FQT8L(g z&TWwIb|&ES$MhReLl|j5ccf#F!VUM3!nm$==V;RbrTu9Kgm60k1j^{@SI7~lP$GAr zYOOQJB^3Qq4a|=!VJ$rRD4kbT{SnNPu}w4NU^&Z4kf)9q>I0~b zdU^uQJTA4*3(BXavwj^bJbm)F9ulX>ZOvAf!yC{DYi6Jkm(r=tr+lFXqF1x6e6(9YXD5sE z;9~0zROqiw9t^2a`SbCUYuoq>|7`G$e{a~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj52~bQ_MF0Q*|NsB|{QScj8AAX7010qNS#tmY4#NNd z4#NS*Z>VGd00SvWL_t(o!|j({y5k@ShQSr!4m|FEkt6Vdm^Mx4nVY#dral_fsIUB3 z(j-jOkqC)J8&*l)M!)G}+WgvjS@c4{im*9Qg{e^A16{3?&=Hx&k}YA=a(JmZlGO(_ z9fxk#&$3R7w$-3@vhGvMVc*xbj%-RGtMI&j!d6@Fb+vM-@I~HHmj_}G?YBTh)pd-V zhxi_-ZCb=tTytxH&`2LGEl1KiU|DW9J#v8xZ%mK$mS9RV9anNFZ#Jug5(hk3&~ zDuVX1lXpOEd_VhKQ`MCXbesZRTx)yoPe9cYeI}*=9B{Ulwe$!9)E@`vP9X9t&{2R6 zJ7|9bsJN}83ZPO~c@pt)a>(CVyp%&J!;jRy0cs;hSxf+ZIYKHx#ZJ=zsmn9}N$`tv zyI4RTZ3FcF3U1gqTcdLi?=dthLLCa`!{+kA zqhXP2wbyIs2Fi?WK4@qG8gaAD`59;dHxAQ3fsU%7SD@i13(!s{P`Lrx;9`9jrPtLYw^R{U+4ynaB+dj_v?13l*Qezv&w1XP_ZR5araRQU>2$EuUJ z3wHMj)Fm|d$f#d|#+`ps>5Iihn`!IZcLj!bV%#-j4XH)$8PEGAOTIJHIVRxCYfwrp z$02lp=g?dhKQ!_69zcn11c1r3f&R~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj522e~?MF0Q*|NsA`*`M72000SaNLh0L01m+b01m+c zxRGn^0008hNkl{_Mxv<-!pH#6vWW?F(+U zco{FpuJ|b}>g@mZ_G*3`<`2Cz_%?U|-7q)Qd!W0a(Gk4@r_WugJ)4A&?{;)Me&^Xe zvhJs1zuR$NyF~P9{hTBSKl;MY8~ex$mlwa-7vJ%L*oXQ@pxEgO)HvqPKw~0^6yJ|K zgY#2c_6o`i)_G#>_z1+Tx6>uu8&~^*JE(lIZFyh$l>sQbi;sT-_#2=*pau%A^CzI3 z*eM%e2G`aOHGBkCl?^q4B4HD#+XR}s=LIM`b8lGV1+15u+yOo9*YtTI;CDbV4VgJP z_B)_Rku8Lf;PSV(DiA1Jj)enzyaI&)h1>}g^o0V2MmdQ@I}H2Xj)yFYG#{6L1Jop- z0rX`FO@Our9?4sIn(bnVlrsCh0fzsc08YDHAE49&=P_ryhUO+fGfkBacplah@UUm$5de^sA#`^%NCozH>qFcFTimtw5c-zD`i|7Io4JP05XJ zLjVfsg3Vj9Re;Ljd-A3gn^{C(1*(Uf+03#!HyL4NA9^eW6^kr&*~b~nD~mIQub-U_ z)Kl3$WT*hmb2Fg70V?1yw*CYP&Cn~*)JXxlYy!mt&{QH@b_word_swap = 1; + break; case 'v': g_verbosity = 1; break; @@ -900,22 +906,6 @@ int main(int argc, char *argv[]) } if (config.mode == MODE_IMPORT) { - if (0 == strcmp("-", config.bin_filename)) { - bin_fp = stdout; - } else { - if (config.bin_truncate) { - bin_fp = fopen(config.bin_filename, "wb"); - } else { - bin_fp = fopen(config.bin_filename, "r+b"); - } - } - if (!bin_fp) { - ERROR("Error opening \"%s\"\n", config.bin_filename); - return -1; - } - if (!config.bin_truncate) { - fseek(bin_fp, config.bin_offset, SEEK_SET); - } switch (config.format.format) { case IMG_FORMAT_RGBA: imgr = png2rgba(config.img_filename, &config.width, &config.height); @@ -1026,6 +1016,56 @@ int main(int argc, char *argv[]) ERROR("Error converting to raw format\n"); return EXIT_FAILURE; } + if (config.word_swap) { + if (config.format.depth == 1) { + ERROR("Word swapping unavailable for IA1 texture format\n"); + return EXIT_FAILURE; + } else if (config.format.format == IMG_FORMAT_CI) { + ERROR("Word swapping unavailable for CI texture formats\n"); + return EXIT_FAILURE; + } + + int swap_bytes = (config.format.depth == 32) ? 8 : 4; + int required_width = 2 * swap_bytes * 8; + if ((config.width * config.format.depth) % required_width == 0) { + uint8_t tmp; + int line_size = config.width * config.format.depth / 8; + for (int line = 1; line < config.height; line += 2) { + for (int x = 0; x < line_size; x += 2 * swap_bytes) { + int word_offset = line * line_size + x; + for (int i = 0; i < swap_bytes; i++) { + tmp = raw[word_offset + i]; + raw[word_offset + i] = raw[word_offset + swap_bytes + i]; + raw[word_offset + swap_bytes + i] = tmp; + } + } + } + } else { + for (unsigned i = 0; i < DIM(format_table); i++) { + if (format_table[i].format.format == config.format.format && format_table[i].format.depth == config.format.depth) { + ERROR("Image must be a multiple of %d pixels wide to create pre-swapped %s texture\n", required_width / config.format.depth, format_table[i].name); + break; + } + } + return EXIT_FAILURE; + } + } + if (0 == strcmp("-", config.bin_filename)) { + bin_fp = stdout; + } else { + if (config.bin_truncate) { + bin_fp = fopen(config.bin_filename, "wb"); + } else { + bin_fp = fopen(config.bin_filename, "r+b"); + } + } + if (!bin_fp) { + ERROR("Error opening \"%s\"\n", config.bin_filename); + return -1; + } + if (!config.bin_truncate) { + fseek(bin_fp, config.bin_offset, SEEK_SET); + } INFO("Writing 0x%X bytes to offset 0x%X of \"%s\"\n", length, config.bin_offset, config.bin_filename); flength = fprint_write_output(bin_fp, config.encoding, raw, length); if (config.encoding == ENCODING_RAW && flength != length) { From 3a021e0d82d72cc0fd10f8256b7bce8dca50dc9a Mon Sep 17 00:00:00 2001 From: someone2639 Date: Wed, 29 Jan 2025 21:23:53 -0500 Subject: [PATCH 3/7] oops i added one incorrect commit to rebase --- bin/segment2.c | 8 +- src/boot/main.c | 6 +- src/usb/debug.c | 1359 +++--------------------- src/usb/debug.h | 40 +- src/usb/usb.c | 153 ++- src/usb/usb.h | 89 +- text/define_text.inc.c | 43 +- textures/segment2/custom_text.i4.png | Bin 0 -> 2001 bytes textures/segment2/custom_text2.ia4.png | Bin 0 -> 1560 bytes textures/segment2/custom_text3.i4.png | Bin 0 -> 1200 bytes textures/segment2/custom_text4.i4.png | Bin 0 -> 937 bytes tools/get_latest_unfloader.py | 18 +- tools/n64graphics.c | 74 +- 13 files changed, 331 insertions(+), 1459 deletions(-) create mode 100644 textures/segment2/custom_text.i4.png create mode 100644 textures/segment2/custom_text2.ia4.png create mode 100644 textures/segment2/custom_text3.i4.png create mode 100644 textures/segment2/custom_text4.i4.png diff --git a/bin/segment2.c b/bin/segment2.c index dea2cf2b9c..3a660b31c8 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -12,16 +12,16 @@ // SM64 (US/JP/EU/SH) Segment 02 #ifdef PUPPYPRINT ALIGNED8 static const Texture small_font_default[] = { -#include "textures/segment2/custom_text.i4.preswap.inc.c" +#include "textures/segment2/custom_text.i4.inc.c" }; ALIGNED8 static const Texture small_font_outline[] = { -#include "textures/segment2/custom_text2.ia4.preswap.inc.c" +#include "textures/segment2/custom_text2.ia4.inc.c" }; ALIGNED8 static const Texture small_font_plain[] = { -#include "textures/segment2/custom_text3.i4.preswap.inc.c" +#include "textures/segment2/custom_text3.i4.inc.c" }; ALIGNED8 static const Texture small_font_vanilla[] = { -#include "textures/segment2/custom_text4.i4.preswap.inc.c" +#include "textures/segment2/custom_text4.i4.inc.c" }; const u8 small_font_kerning_default[] = { diff --git a/src/boot/main.c b/src/boot/main.c index 093bfffea8..2fe93aaff3 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -320,7 +320,7 @@ void alert_rcp_hung_up(void) { * Increment the first and last values of the stack. * If they're different, that means an error has occured, so trigger a crash. */ -#ifdef DEBUG_ASSERTIONS +#ifdef DEBUG void check_stack_validity(void) { gIdleThreadStack[0]++; gIdleThreadStack[THREAD1_STACK - 1]++; @@ -379,7 +379,7 @@ void thread3_main(UNUSED void *arg) { } else { gBorderHeight = BORDER_HEIGHT_CONSOLE; } -#ifdef DEBUG_ASSERTIONS +#ifdef DEBUG gIdleThreadStack[0] = 0; gIdleThreadStack[THREAD1_STACK - 1] = 0; gThread3Stack[0] = 0; @@ -403,7 +403,7 @@ void thread3_main(UNUSED void *arg) { while (TRUE) { OSMesg msg; osRecvMesg(&gIntrMesgQueue, &msg, OS_MESG_BLOCK); -#ifdef DEBUG_ASSERTIONS +#ifdef DEBUG check_stack_validity(); #endif switch ((uintptr_t) msg) { diff --git a/src/usb/debug.c b/src/usb/debug.c index 059e2e4426..0685789ced 100644 --- a/src/usb/debug.c +++ b/src/usb/debug.c @@ -5,55 +5,38 @@ A basic debug library that makes use of the USB library for N64 flashcarts. https://github.com/buu342/N64-UNFLoader ***************************************************************/ - #include "debug.h" #ifndef LIBDRAGON - #include + #include #include // Needed for Crash's Linux toolchain #else #include #include + #include #endif -#include #include -#include #include + #if DEBUG_MODE /********************************* Definitions *********************************/ - // USB thread messages - #define MSG_FAULT 0x10 - #define MSG_READ 0x11 - #define MSG_WRITE 0x12 + #define MSG_FAULT 0x10 + #define MSG_READ 0x11 + #define MSG_WRITE 0x12 - #define USBERROR_NONE 0 - #define USBERROR_NOTTEXT 1 - #define USBERROR_UNKNOWN 2 - #define USBERROR_TOOMUCH 3 - #define USBERROR_CUSTOM 4 - - // RDB thread messages (Libultra) - #ifndef LIBDRAGON - #define MSG_RDB_PACKET 0x10 - #define MSG_RDB_BPHIT 0x11 - #define MSG_RDB_PAUSE 0x12 - #endif - - // Breakpoints - #define BPOINT_COUNT 10 - #define MAKE_BREAKPOINT_INDEX(indx) (0x0000000D | ((indx) << 6)) - #define GET_BREAKPOINT_INDEX(addr) ((((addr) >> 6) & 0x0000FFFF)) + #define USBERROR_NONE 0 + #define USBERROR_NOTTEXT 1 + #define USBERROR_UNKNOWN 2 + #define USBERROR_TOOMUCH 3 + #define USBERROR_CUSTOM 4 - // Helpful stuff - #define HASHTABLE_SIZE 7 - #define COMMAND_TOKENS 10 - #define BUFFER_SIZE 256 - #define REGISTER_COUNT 72 // 32 GPRs + 6 SPRs + 16 FPRs + fsr + fir (fcr0) - #define REGISTER_SIZE 16 // GDB expects the registers to be 64-bits + #define HASHTABLE_SIZE 7 + #define COMMAND_TOKENS 10 + #define BUFFER_SIZE 256 /********************************* @@ -61,21 +44,12 @@ flashcarts. *********************************/ #ifdef LIBDRAGON - #ifndef TRUE - #define TRUE 1 - #endif - #ifndef FALSE - #define FALSE 0 - #endif - #define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000)) - #define OS_PHYSICAL_TO_K1(x) (void *)(((u32)(x)+0xa0000000)) - - typedef unsigned char u8; + typedef unsigned char u8; typedef unsigned short u16; typedef unsigned long u32; typedef unsigned long long u64; - typedef signed char s8; + typedef signed char s8; typedef short s16; typedef long s32; typedef long long s64; @@ -92,9 +66,6 @@ flashcarts. typedef float f32; typedef double f64; - - typedef void* OSMesg; - typedef exception_t OSThread; #endif @@ -110,12 +81,6 @@ flashcarts. char *string; } regDesc; - // Because of the thread context's messy struct, this'll come in handy - typedef struct { - int size; - void* ptr; - } regType; - // Thread message struct typedef struct { @@ -134,61 +99,24 @@ flashcarts. void* next; } debugCommand; - // Remote debugger packet lookup table - typedef struct - { - char* command; - void (*func)(); - } RDBPacketLUT; - - // Breakpoint struct - typedef struct - { - u32* addr; - u32 instruction; - } bPoint; - /********************************* Function Prototypes *********************************/ - // Threads - static void debug_thread_usb(void* arg); #ifndef LIBDRAGON + // Threads #if USE_FAULTTHREAD - static void debug_thread_fault(void* arg); - #endif - #else - #if AUTOPOLL_ENABLED - static void debug_timer_usb(int overflow); - #endif - #endif - #if USE_RDBTHREAD - #ifndef LIBDRAGON - static void debug_thread_rdb(void* arg); - #else - static void debug_thread_rdb(exception_t* arg); - static void debug_thread_rdb_pause(); + static void debug_thread_fault(void *arg); #endif - static void debug_thread_rdb_loop(OSThread* t); - static void debug_rdb_qsupported(OSThread* t); - static void debug_rdb_haltreason(OSThread* t); - static void debug_rdb_dumpregisters(OSThread* t); - static void debug_rdb_writeregisters(OSThread* t); - static void debug_rdb_readmemory(OSThread* t); - static void debug_rdb_writememory(OSThread* t); - static void debug_rdb_addbreakpoint(OSThread* t); - static void debug_rdb_removebreakpoint(OSThread* t); - static void debug_rdb_continue(OSThread* t); - static void debug_rdb_pause(OSThread* t); - #endif - - // Other - #ifndef LIBDRAGON + static void debug_thread_usb(void *arg); + + // Other #if OVERWRITE_OSPRINT static void* debug_osSyncPrintf_implementation(void *unused, const char *str, size_t len); #endif + #else + static void debug_thread_usb(void *arg); #endif static inline void debug_handle_64drivebutton(); @@ -232,151 +160,112 @@ flashcarts. static u64 debug_64dbut_hold = 0; #ifndef LIBDRAGON + // Fault thread globals + #if USE_FAULTTHREAD + static OSMesgQueue faultMessageQ; + static OSMesg faultMessageBuf; + static OSThread faultThread; + static u64 faultThreadStack[FAULT_THREAD_STACK/sizeof(u64)]; + #endif // USB thread globals static OSMesgQueue usbMessageQ; static OSMesg usbMessageBuf; static OSThread usbThread; static u64 usbThreadStack[USB_THREAD_STACK/sizeof(u64)]; - #if AUTOPOLL_ENABLED - static OSTimer usbThreadTimer; - #endif - // Fault thread globals - #if USE_FAULTTHREAD - static OSMesgQueue faultMessageQ; - static OSMesg faultMessageBuf; - static OSThread faultThread; - static u64 faultThreadStack[FAULT_THREAD_STACK/sizeof(u64)]; + // List of error causes + static regDesc causeDesc[] = { + {CAUSE_BD, CAUSE_BD, "BD"}, + {CAUSE_IP8, CAUSE_IP8, "IP8"}, + {CAUSE_IP7, CAUSE_IP7, "IP7"}, + {CAUSE_IP6, CAUSE_IP6, "IP6"}, + {CAUSE_IP5, CAUSE_IP5, "IP5"}, + {CAUSE_IP4, CAUSE_IP4, "IP4"}, + {CAUSE_IP3, CAUSE_IP3, "IP3"}, + {CAUSE_SW2, CAUSE_SW2, "IP2"}, + {CAUSE_SW1, CAUSE_SW1, "IP1"}, + {CAUSE_EXCMASK, EXC_INT, "Interrupt"}, + {CAUSE_EXCMASK, EXC_MOD, "TLB modification exception"}, + {CAUSE_EXCMASK, EXC_RMISS, "TLB exception on load or instruction fetch"}, + {CAUSE_EXCMASK, EXC_WMISS, "TLB exception on store"}, + {CAUSE_EXCMASK, EXC_RADE, "Address error on load or instruction fetch"}, + {CAUSE_EXCMASK, EXC_WADE, "Address error on store"}, + {CAUSE_EXCMASK, EXC_IBE, "Bus error exception on instruction fetch"}, + {CAUSE_EXCMASK, EXC_DBE, "Bus error exception on data reference"}, + {CAUSE_EXCMASK, EXC_SYSCALL, "System call exception"}, + {CAUSE_EXCMASK, EXC_BREAK, "Breakpoint exception"}, + {CAUSE_EXCMASK, EXC_II, "Reserved instruction exception"}, + {CAUSE_EXCMASK, EXC_CPU, "Coprocessor unusable exception"}, + {CAUSE_EXCMASK, EXC_OV, "Arithmetic overflow exception"}, + {CAUSE_EXCMASK, EXC_TRAP, "Trap exception"}, + {CAUSE_EXCMASK, EXC_VCEI, "Virtual coherency exception on intruction fetch"}, + {CAUSE_EXCMASK, EXC_FPE, "Floating point exception (see fpcsr)"}, + {CAUSE_EXCMASK, EXC_WATCH, "Watchpoint exception"}, + {CAUSE_EXCMASK, EXC_VCED, "Virtual coherency exception on data reference"}, + {0, 0, ""} + }; - // List of error causes - static regDesc causeDesc[] = { - {CAUSE_BD, CAUSE_BD, "BD"}, - {CAUSE_IP8, CAUSE_IP8, "IP8"}, - {CAUSE_IP7, CAUSE_IP7, "IP7"}, - {CAUSE_IP6, CAUSE_IP6, "IP6"}, - {CAUSE_IP5, CAUSE_IP5, "IP5"}, - {CAUSE_IP4, CAUSE_IP4, "IP4"}, - {CAUSE_IP3, CAUSE_IP3, "IP3"}, - {CAUSE_SW2, CAUSE_SW2, "IP2"}, - {CAUSE_SW1, CAUSE_SW1, "IP1"}, - {CAUSE_EXCMASK, EXC_INT, "Interrupt"}, - {CAUSE_EXCMASK, EXC_MOD, "TLB modification exception"}, - {CAUSE_EXCMASK, EXC_RMISS, "TLB exception on load or instruction fetch"}, - {CAUSE_EXCMASK, EXC_WMISS, "TLB exception on store"}, - {CAUSE_EXCMASK, EXC_RADE, "Address error on load or instruction fetch"}, - {CAUSE_EXCMASK, EXC_WADE, "Address error on store"}, - {CAUSE_EXCMASK, EXC_IBE, "Bus error exception on instruction fetch"}, - {CAUSE_EXCMASK, EXC_DBE, "Bus error exception on data reference"}, - {CAUSE_EXCMASK, EXC_SYSCALL, "System call exception"}, - {CAUSE_EXCMASK, EXC_BREAK, "Breakpoint exception"}, - {CAUSE_EXCMASK, EXC_II, "Reserved instruction exception"}, - {CAUSE_EXCMASK, EXC_CPU, "Coprocessor unusable exception"}, - {CAUSE_EXCMASK, EXC_OV, "Arithmetic overflow exception"}, - {CAUSE_EXCMASK, EXC_TRAP, "Trap exception"}, - {CAUSE_EXCMASK, EXC_VCEI, "Virtual coherency exception on intruction fetch"}, - {CAUSE_EXCMASK, EXC_FPE, "Floating point exception (see fpcsr)"}, - {CAUSE_EXCMASK, EXC_WATCH, "Watchpoint exception"}, - {CAUSE_EXCMASK, EXC_VCED, "Virtual coherency exception on data reference"}, - {0, 0, ""} - }; - - // List of register descriptions - static regDesc srDesc[] = { - {SR_CU3, SR_CU3, "CU3"}, - {SR_CU2, SR_CU2, "CU2"}, - {SR_CU1, SR_CU1, "CU1"}, - {SR_CU0, SR_CU0, "CU0"}, - {SR_RP, SR_RP, "RP"}, - {SR_FR, SR_FR, "FR"}, - {SR_RE, SR_RE, "RE"}, - {SR_BEV, SR_BEV, "BEV"}, - {SR_TS, SR_TS, "TS"}, - {SR_SR, SR_SR, "SR"}, - {SR_CH, SR_CH, "CH"}, - {SR_CE, SR_CE, "CE"}, - {SR_DE, SR_DE, "DE"}, - {SR_IBIT8, SR_IBIT8, "IM8"}, - {SR_IBIT7, SR_IBIT7, "IM7"}, - {SR_IBIT6, SR_IBIT6, "IM6"}, - {SR_IBIT5, SR_IBIT5, "IM5"}, - {SR_IBIT4, SR_IBIT4, "IM4"}, - {SR_IBIT3, SR_IBIT3, "IM3"}, - {SR_IBIT2, SR_IBIT2, "IM2"}, - {SR_IBIT1, SR_IBIT1, "IM1"}, - {SR_KX, SR_KX, "KX"}, - {SR_SX, SR_SX, "SX"}, - {SR_UX, SR_UX, "UX"}, - {SR_KSU_MASK, SR_KSU_USR, "USR"}, - {SR_KSU_MASK, SR_KSU_SUP, "SUP"}, - {SR_KSU_MASK, SR_KSU_KER, "KER"}, - {SR_ERL, SR_ERL, "ERL"}, - {SR_EXL, SR_EXL, "EXL"}, - {SR_IE, SR_IE, "IE"}, - {0, 0, ""} - }; - - // List of floating point registers descriptions - static regDesc fpcsrDesc[] = { - {FPCSR_FS, FPCSR_FS, "FS"}, - {FPCSR_C, FPCSR_C, "C"}, - {FPCSR_CE, FPCSR_CE, "Unimplemented operation"}, - {FPCSR_CV, FPCSR_CV, "Invalid operation"}, - {FPCSR_CZ, FPCSR_CZ, "Division by zero"}, - {FPCSR_CO, FPCSR_CO, "Overflow"}, - {FPCSR_CU, FPCSR_CU, "Underflow"}, - {FPCSR_CI, FPCSR_CI, "Inexact operation"}, - {FPCSR_EV, FPCSR_EV, "EV"}, - {FPCSR_EZ, FPCSR_EZ, "EZ"}, - {FPCSR_EO, FPCSR_EO, "EO"}, - {FPCSR_EU, FPCSR_EU, "EU"}, - {FPCSR_EI, FPCSR_EI, "EI"}, - {FPCSR_FV, FPCSR_FV, "FV"}, - {FPCSR_FZ, FPCSR_FZ, "FZ"}, - {FPCSR_FO, FPCSR_FO, "FO"}, - {FPCSR_FU, FPCSR_FU, "FU"}, - {FPCSR_FI, FPCSR_FI, "FI"}, - {FPCSR_RM_MASK, FPCSR_RM_RN, "RN"}, - {FPCSR_RM_MASK, FPCSR_RM_RZ, "RZ"}, - {FPCSR_RM_MASK, FPCSR_RM_RP, "RP"}, - {FPCSR_RM_MASK, FPCSR_RM_RM, "RM"}, - {0, 0, ""} - }; - #endif - #endif + // List of register descriptions + static regDesc srDesc[] = { + {SR_CU3, SR_CU3, "CU3"}, + {SR_CU2, SR_CU2, "CU2"}, + {SR_CU1, SR_CU1, "CU1"}, + {SR_CU0, SR_CU0, "CU0"}, + {SR_RP, SR_RP, "RP"}, + {SR_FR, SR_FR, "FR"}, + {SR_RE, SR_RE, "RE"}, + {SR_BEV, SR_BEV, "BEV"}, + {SR_TS, SR_TS, "TS"}, + {SR_SR, SR_SR, "SR"}, + {SR_CH, SR_CH, "CH"}, + {SR_CE, SR_CE, "CE"}, + {SR_DE, SR_DE, "DE"}, + {SR_IBIT8, SR_IBIT8, "IM8"}, + {SR_IBIT7, SR_IBIT7, "IM7"}, + {SR_IBIT6, SR_IBIT6, "IM6"}, + {SR_IBIT5, SR_IBIT5, "IM5"}, + {SR_IBIT4, SR_IBIT4, "IM4"}, + {SR_IBIT3, SR_IBIT3, "IM3"}, + {SR_IBIT2, SR_IBIT2, "IM2"}, + {SR_IBIT1, SR_IBIT1, "IM1"}, + {SR_KX, SR_KX, "KX"}, + {SR_SX, SR_SX, "SX"}, + {SR_UX, SR_UX, "UX"}, + {SR_KSU_MASK, SR_KSU_USR, "USR"}, + {SR_KSU_MASK, SR_KSU_SUP, "SUP"}, + {SR_KSU_MASK, SR_KSU_KER, "KER"}, + {SR_ERL, SR_ERL, "ERL"}, + {SR_EXL, SR_EXL, "EXL"}, + {SR_IE, SR_IE, "IE"}, + {0, 0, ""} + }; - #if USE_RDBTHREAD - // Remote debugger thread globals - #ifndef LIBDRAGON - static OSMesgQueue rdbMessageQ; - static OSMesg rdbMessageBuf; - static OSThread rdbThread; - static u64 rdbThreadStack[RDB_THREAD_STACK/sizeof(u64)]; - #endif - - // RDB status globals - static vu8 debug_rdbpaused = FALSE; - #ifndef LIBDRAGON - static OSTime debug_pausetime = 0; - #else - static u32 debug_pausetime = 0; - static u8 debug_ismanualpause = FALSE; - #endif - static bPoint debug_bpoints[BPOINT_COUNT]; - - // Remote debugger packet lookup table - RDBPacketLUT lut_rdbpackets[] = { - // Due to the use of strncmp, the order of strings matters! - {"qSupported", debug_rdb_qsupported}, - {"?", debug_rdb_haltreason}, - {"g", debug_rdb_dumpregisters}, - {"G", debug_rdb_writeregisters}, - {"m", debug_rdb_readmemory}, - {"M", debug_rdb_writememory}, - {"Z0", debug_rdb_addbreakpoint}, - {"z0", debug_rdb_removebreakpoint}, - {"c", debug_rdb_continue}, - {"\x03", debug_rdb_pause}, + // List of floating point registers descriptions + static regDesc fpcsrDesc[] = { + {FPCSR_FS, FPCSR_FS, "FS"}, + {FPCSR_C, FPCSR_C, "C"}, + {FPCSR_CE, FPCSR_CE, "Unimplemented operation"}, + {FPCSR_CV, FPCSR_CV, "Invalid operation"}, + {FPCSR_CZ, FPCSR_CZ, "Division by zero"}, + {FPCSR_CO, FPCSR_CO, "Overflow"}, + {FPCSR_CU, FPCSR_CU, "Underflow"}, + {FPCSR_CI, FPCSR_CI, "Inexact operation"}, + {FPCSR_EV, FPCSR_EV, "EV"}, + {FPCSR_EZ, FPCSR_EZ, "EZ"}, + {FPCSR_EO, FPCSR_EO, "EO"}, + {FPCSR_EU, FPCSR_EU, "EU"}, + {FPCSR_EI, FPCSR_EI, "EI"}, + {FPCSR_FV, FPCSR_FV, "FV"}, + {FPCSR_FZ, FPCSR_FZ, "FZ"}, + {FPCSR_FO, FPCSR_FO, "FO"}, + {FPCSR_FU, FPCSR_FU, "FU"}, + {FPCSR_FI, FPCSR_FI, "FI"}, + {FPCSR_RM_MASK, FPCSR_RM_RN, "RN"}, + {FPCSR_RM_MASK, FPCSR_RM_RZ, "RZ"}, + {FPCSR_RM_MASK, FPCSR_RM_RP, "RP"}, + {FPCSR_RM_MASK, FPCSR_RM_RM, "RM"}, + {0, 0, ""} }; #endif @@ -391,31 +280,17 @@ flashcarts. ==============================*/ void debug_initialize() - { + { // Initialize the USB functions if (!usb_initialize()) return; - // Initialize globals - memset(debug_commands_hashtable, 0, sizeof(debugCommand*)*HASHTABLE_SIZE); - memset(debug_commands_elements, 0, sizeof(debugCommand)*MAX_COMMANDS); - - // Libultra functions + // Overwrite osSyncPrintf #ifndef LIBDRAGON - // Overwrite osSyncPrintf #if OVERWRITE_OSPRINT __printfunc = (void*)debug_osSyncPrintf_implementation; #endif - // Initialize the USB thread - osCreateThread(&usbThread, USB_THREAD_ID, debug_thread_usb, 0, - (usbThreadStack+USB_THREAD_STACK/sizeof(u64)), - USB_THREAD_PRI); - osStartThread(&usbThread); - #if AUTOPOLL_ENABLED - osSetTimer(&usbThreadTimer, 0, OS_USEC_TO_CYCLES(AUTOPOLL_TIME*1000), &usbMessageQ, (OSMesg)NULL); - #endif - // Initialize the fault thread #if USE_FAULTTHREAD osCreateThread(&faultThread, FAULT_THREAD_ID, debug_thread_fault, 0, @@ -424,34 +299,11 @@ flashcarts. osStartThread(&faultThread); #endif - // Initialize the remote debugger thread - #if USE_RDBTHREAD - osCreateThread(&rdbThread, RDB_THREAD_ID, debug_thread_rdb, (void*)osGetThreadId(NULL), - (rdbThreadStack+RDB_THREAD_STACK/sizeof(u64)), - RDB_THREAD_PRI); - osStartThread(&rdbThread); - - // Initialize breakpoints - osSetEventMesg(OS_EVENT_CPU_BREAK, &rdbMessageQ, (OSMesg)MSG_RDB_BPHIT); - memset(debug_bpoints, 0, BPOINT_COUNT*sizeof(bPoint)); - - // Pause the main thread - usb_purge(); - usb_write(DATATYPE_TEXT, "Pausing main thread until GDB connects and resumes\n", 51+1); - osSendMesg(&rdbMessageQ, (OSMesg)MSG_RDB_PAUSE, OS_MESG_BLOCK); - #endif - #else - timer_init(); // If the timer subsystem has been initialized already, it's not a problem to call it again. - #if AUTOPOLL_ENABLED - new_timer(TIMER_TICKS(AUTOPOLL_TIME*1000), TF_CONTINUOUS, debug_timer_usb); - #endif - #if USE_RDBTHREAD - memset(debug_bpoints, 0, BPOINT_COUNT*sizeof(bPoint)); - register_exception_handler(debug_thread_rdb); - usb_purge(); - usb_write(DATATYPE_TEXT, "Pausing main thread until GDB connects and resumes\n", 51+1); - debug_thread_rdb_pause(); - #endif + // Initialize the USB thread + osCreateThread(&usbThread, USB_THREAD_ID, debug_thread_usb, 0, + (usbThreadStack+USB_THREAD_STACK/sizeof(u64)), + USB_THREAD_PRI); + osStartThread(&usbThread); #endif // Mark the debug mode as initialized @@ -493,7 +345,7 @@ flashcarts. usbMesg msg; va_list args; - // Use the internal libultra printf function to format the string + // use the internal libultra printf function to format the string va_start(args, message); #ifndef LIBDRAGON len = _Printf(&printf_handler, debug_buffer, message, args); @@ -619,14 +471,7 @@ flashcarts. #endif // Intentionally cause a TLB exception on load/instruction fetch - #ifdef LIBDRAGON - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Warray-bounds" - #endif crash = *(volatile char *)1; - #ifdef LIBDRAGON - #pragma GCC diagnostic pop - #endif (void)crash; } @@ -725,6 +570,9 @@ flashcarts. // Ensure debug mode is initialized if (!debug_initialized) return; + + // Handle 64Drive button polling + debug_handle_64drivebutton(); // Send a read message to the USB thread msg.msgtype = MSG_READ; @@ -886,12 +734,12 @@ flashcarts. dataleft = 0; break; } - FALL_THROUGH; + // fallthrough case '@': filestep++; if (filestep < 3) break; - FALL_THROUGH; + // fallthrough default: // Decide what to do based on the file handle if (filestep == 0 && debug_command_incoming_start[tok] == -1) @@ -928,24 +776,6 @@ flashcarts. // Rewind the USB fully usb_rewind(datasize); } - - #ifdef LIBDRAGON - #if AUTOPOLL_ENABLED - /*============================== - debug_timer_usb - A function that's called by the auto-poll timer - @param How many ticks the timer overflew by (unused) - ==============================*/ - - static void debug_timer_usb(int overflow) - { - usbMesg msg; - (void)overflow; // To prevent unused variable errors - msg.msgtype = MSG_READ; - debug_thread_usb(&msg); - } - #endif - #endif /*============================== @@ -981,29 +811,6 @@ flashcarts. int header = usb_poll(); debugCommand* entry; - // RDB packets should be rerouted to the RDB thread - #if USE_RDBTHREAD - if (USBHEADER_GETTYPE(header) == DATATYPE_RDBPACKET) - { - #ifndef LIBDRAGON - osSendMesg(&rdbMessageQ, (OSMesg)MSG_RDB_PACKET, OS_MESG_BLOCK); - #else - - // Exceptional case, handle pausing through CTRL+C - char packetstart; - usb_read(&packetstart, 1); - if (packetstart == '\x03') - { - usb_rewind(1); - debug_thread_rdb_pause(); - } - else - debug_thread_rdb_loop(NULL); - #endif - continue; - } - #endif - // Ensure we're receiving a text command if (USBHEADER_GETTYPE(header) != DATATYPE_TEXT) { @@ -1056,9 +863,6 @@ flashcarts. } } - // Handle 64Drive button polling - debug_handle_64drivebutton(); - // Spit out an error if there was one during the command parsing if (errortype != USBERROR_NONE) { @@ -1081,18 +885,14 @@ flashcarts. errortype = USBERROR_NONE; } - // Handle the other USB messages - if (threadMsg != NULL) + switch (threadMsg->msgtype) { - switch (threadMsg->msgtype) - { - case MSG_WRITE: - if (usb_timedout()) - usb_sendheartbeat(); - usb_write(threadMsg->datatype, threadMsg->buff, threadMsg->size); - break; - } + case MSG_WRITE: + if (usb_timedout()) + usb_sendheartbeat(); + usb_write(threadMsg->datatype, threadMsg->buff, threadMsg->size); + break; } // If we're in libdragon, break out of the loop as we don't need it @@ -1134,10 +934,8 @@ flashcarts. return ret; } - #endif - #endif - - #ifndef LIBDRAGON + #endif + #if USE_FAULTTHREAD /*============================== @@ -1151,7 +949,7 @@ flashcarts. static void debug_printreg(u32 value, char *name, regDesc *desc) { char first = 1; - debug_printf("%s\t\t0x%16x <", name, value); + debug_printf("%s\t\t0x%08x <", name, value); while (desc->mask != 0) { if ((value & desc->mask) == desc->value) @@ -1192,33 +990,15 @@ flashcarts. { __OSThreadContext* context = &curr->context; - // If the debug or rdb thread crashed, restart it - if (curr->id == USB_THREAD_ID) - { - osCreateThread(&usbThread, USB_THREAD_ID, debug_thread_usb, 0, - (usbThreadStack+USB_THREAD_STACK/sizeof(u64)), - USB_THREAD_PRI); - osStartThread(&usbThread); - } - #if USE_RDBTHREAD - else if (curr->id == RDB_THREAD_ID) - { - osCreateThread(&rdbThread, RDB_THREAD_ID, debug_thread_rdb, (void*)osGetThreadId(NULL), - (rdbThreadStack+RDB_THREAD_STACK/sizeof(u64)), - RDB_THREAD_PRI); - osStartThread(&rdbThread); - } - #endif - // Print the basic info debug_printf("Fault in thread: %d\n\n", curr->id); - debug_printf("pc\t\t0x%16x\n", context->pc); + debug_printf("pc\t\t0x%08x\n", context->pc); if (assert_file == NULL) debug_printreg(context->cause, "cause", causeDesc); else debug_printf("cause\t\tAssertion failed in file '%s', line %d.\n", assert_file, assert_line); debug_printreg(context->sr, "sr", srDesc); - debug_printf("badvaddr\t0x%16x\n\n", context->badvaddr); + debug_printf("badvaddr\t0x%08x\n\n", context->badvaddr); // Print the registers debug_printf("at 0x%016llx v0 0x%016llx v1 0x%016llx\n", context->at, context->v0, context->v1); @@ -1246,857 +1026,8 @@ flashcarts. } } } - #endif - #endif - - #if USE_RDBTHREAD - #ifndef LIBDRAGON - /*============================== - debug_thread_rdb - Handles the remote debugger thread (Libultra) - @param Arbitrary data that the thread can receive. - Used for passing the main thread ID. - ==============================*/ - - static void debug_thread_rdb(void *arg) - { - OSId mainid = (OSId)arg; - OSThread* mainthread = &rdbThread; - - // Find the main thread pointer given its ID - while (mainthread->id != mainid) - mainthread = mainthread->tlnext; - // Create the message queue for the rdb messages - osCreateMesgQueue(&rdbMessageQ, &rdbMessageBuf, 1); - - // Thread loop - while (1) - { - OSMesg msg; - OSThread* affected = NULL; - - // Wait for an rdb message to arrive - osRecvMesg(&rdbMessageQ, &msg, OS_MESG_BLOCK); - - // Exceptional case, handle pausing through CTRL+C - if (USBHEADER_GETTYPE(usb_poll()) == DATATYPE_RDBPACKET) - { - char packetstart; - usb_read(&packetstart, 1); - if (packetstart == '\x03') - msg = (OSMesg)MSG_RDB_PAUSE; - usb_rewind(1); - } - - - // Check what message we received - switch ((s32)msg) - { - case MSG_RDB_PACKET: - break; // Do nothing - case MSG_RDB_BPHIT: - affected = mainthread; - debug_rdbpaused = TRUE; - debug_pausetime = osGetTime(); - - // Find out which thread hit the bp exception - while (1) - { - if (affected->flags & OS_FLAG_CPU_BREAK) - break; - affected = affected->tlnext; - } - usb_purge(); - usb_write(DATATYPE_RDBPACKET, "T05swbreak:;", 12+1); - break; - case MSG_RDB_PAUSE: - affected = mainthread; - debug_rdbpaused = TRUE; - debug_pausetime = osGetTime(); - break; - } - - // Do the RDB thread main loop - debug_thread_rdb_loop(affected); - } - } - #else - - /*============================== - debug_thread_rdb_pause - "Pauses" the program execution in Libdragon. - @param The received exception - ==============================*/ - - static void debug_thread_rdb_pause() - { - debug_ismanualpause = TRUE; - debug_pausetime = C0_COUNT(); - asm volatile("break"); // Jank workaround because I can't "message" the exception handler "thread" - } - - - /*============================== - debug_thread_rdb - Handles the remote debugger logic (Libdragon) - @param The received exception - ==============================*/ - - static void debug_thread_rdb(exception_t* exc) - { - switch (exc->code) - { - case EXCEPTION_CODE_BREAKPOINT: - debug_rdbpaused = TRUE; - if (!debug_ismanualpause) - { - usb_purge(); - usb_write(DATATYPE_RDBPACKET, "T05swbreak:;", 12+1); - } - debug_pausetime = C0_COUNT(); - debug_thread_rdb_loop(exc); - if (debug_ismanualpause) - { - debug_ismanualpause = FALSE; - exc->regs->epc += 4; // Gotta increment PC otherwise the program will likely hit the breakpoint again in debug_initialize - } - break; - default: - exception_default_handler(exc); - break; - } - } - #endif - - - /*============================== - debug_thread_rdb_loop - Handles the loop of the remote debugger thread - @param (Libultra) A pointer to the affected thread - (Libdragon) A pointer to the exception struct - ==============================*/ - - static void debug_thread_rdb_loop(OSThread* affected) - { - // Handle the RDB packet - do - { - int usbheader = usb_poll(); - if (USBHEADER_GETTYPE(usbheader) == DATATYPE_RDBPACKET) - { - int i; - u8 found = FALSE; - u32 size = USBHEADER_GETSIZE(usbheader); - - // Read the GDB packet from USB - memset(debug_buffer, 0, BUFFER_SIZE); - usb_read(&debug_buffer, (size <= BUFFER_SIZE) ? size : BUFFER_SIZE); - - // Run a function based on what we received - for (i=0; i<(sizeof(lut_rdbpackets)/sizeof(lut_rdbpackets[0])); i++) - { - if (!strncmp(lut_rdbpackets[i].command, debug_buffer, strlen(lut_rdbpackets[i].command))) - { - found = TRUE; - lut_rdbpackets[i].func(affected); - break; - } - } - - // If we didn't find a supported command, then reply back with nothing - if (!found) - { - usb_purge(); - usb_write(DATATYPE_RDBPACKET, "\0", 1); - } - } - usb_purge(); - } - while (debug_rdbpaused); // Loop forever while we are paused - } - - /*============================== - debug_rdb_qsupported - Responds to GDB with the supported features - @param The affected thread, if any - ==============================*/ - - static void debug_rdb_qsupported(OSThread* t) - { - sprintf(debug_buffer, "swbreak+"); - usb_purge(); - usb_write(DATATYPE_RDBPACKET, debug_buffer, strlen(debug_buffer)); - } - - - /*============================== - debug_rdb_haltreason - Responds to GDB with the halt reason - @param The affected thread, if any - ==============================*/ - - static void debug_rdb_haltreason(OSThread* t) - { - usb_purge(); - usb_write(DATATYPE_RDBPACKET, "S02", 3+1); - } - - - #ifndef LIBDRAGON - /*============================== - register_fromindex - Gets a register type from a given index - @param The affected thread context - @param The register index - @returns The regType that matches the given index - ==============================*/ - - static regType register_fromindex(__OSThreadContext* context, int index) - { - regType reg = {0, NULL}; - switch (index) - { - case 0: // Zero register - case 26: // K0 - case 27: // K1 - case 71: // FCR0 - return reg; - case 32: reg.size = 4; reg.ptr = ((u32*)&context->sr); return reg; - case 33: reg.size = 8; reg.ptr = ((u64*)&context->lo); return reg; - case 34: reg.size = 8; reg.ptr = ((u64*)&context->hi); return reg; - case 35: reg.size = 4; reg.ptr = ((u32*)&context->badvaddr); return reg; - case 36: reg.size = 4; reg.ptr = ((u32*)&context->cause); return reg; - case 37: reg.size = 4; reg.ptr = ((u32*)&context->pc); return reg; - case 70: reg.size = 4; reg.ptr = ((u32*)&context->fpcsr); return reg; - default: - if (index < 32) - { - reg.size = 8; - if (index > 27) - reg.ptr = ((u64*)&context->gp)+(index-28); - else - reg.ptr = ((u64*)&context->at)+(index-1); - return reg; - } - else - { - reg.size = 8; - reg.ptr = ((u64*)&context->fp0)+(((u32)(index-38))/2); - return reg; - } - } - } - #else - /*============================== - register_fromindex - Gets a register type from a given index - @param The affected thread context - @param The register index - @returns The regType that matches the given index - ==============================*/ - - static regType register_fromindex(reg_block_t* context, int index) - { - regType reg = {0, NULL}; - switch (index) - { - case 0: // Zero register - case 26: // K0 - case 27: // K1 - case 71: // FCR0 - case 35: // BadVAddr - case 37: // pc - return reg; - case 32: reg.size = 4; reg.ptr = ((u32*)&context->sr); return reg; - case 33: reg.size = 8; reg.ptr = ((u64*)&context->lo); return reg; - case 34: reg.size = 8; reg.ptr = ((u64*)&context->hi); return reg; - case 36: reg.size = 4; reg.ptr = ((u32*)&context->cr); return reg; - case 70: reg.size = 4; reg.ptr = ((u32*)&context->fc31); return reg; - default: - if (index < 32) - { - reg.size = 8; - reg.ptr = (u64*)&context->gpr[index-1]; - return reg; - } - else - { - reg.size = 8; - reg.ptr = (u64*)&context->fpr[index-38]; - return reg; - } - } - return reg; - } #endif - - - /*============================== - debug_rdb_printreg_rle - Sprintf's a register value into a buffer, - compressed with Run-Length Encoding - @param The buffer to write to - @param The register type - @returns The number of bytes written - ==============================*/ - - static u32 debug_rdb_printreg_rle(char* buf, regType reg) - { - if (reg.ptr != NULL) - { - int i; - u8 count; - u32 totalwrote = 0; - char last; - char temp[REGISTER_SIZE+1]; - - // Read the register value into a string - if (reg.size == 8) - sprintf(temp, "%016llx", (u64)(*(u64*)reg.ptr)); - else - sprintf(temp, "%016llx", (u64)(*(u32*)reg.ptr)); - last = temp[0]; - count = 1; - - // Find repeated characters - for (i=1; i<(REGISTER_SIZE+1); i++) - { - if (temp[i] != last) - { - // If the repeat was more than 3, then it's worth RLE'ing - if (count > 3) - { - // Because 6 (#) and 7 ($) are special characters in GDB, we have to do them differently - if (count == 7) - totalwrote += sprintf(buf+totalwrote, "%c*\"%c", last, last); - else if (count == 8) - totalwrote += sprintf(buf+totalwrote, "%c*\"%c%c", last, last, last); - else - totalwrote += sprintf(buf+totalwrote, "%c*%c", last, ' '+(count-4)); - } - else - { - int j; - for (j=0; jcontext; - #else - reg_block_t* context = t->regs; - #endif - - // Start by sending a HEADER packet with the chunk count - header[0] = DATATYPE_RDBPACKET; - header[1] = chunkcount; - usb_purge(); - usb_write(DATATYPE_HEADER, &header, sizeof(u32)*2); - - // Perform the humpty dumpty - offset += sprintf(debug_buffer+offset, "0*,"); // Zero register - for (i=1; iepc)); - #endif - else - { - regType reg = register_fromindex(context, i); - offset += debug_rdb_printreg_rle(debug_buffer+offset, reg); - } - - // Send a chunk if we're about to overrun the debug buffer - if ((strlen(debug_buffer)+REGISTER_SIZE+1) > BUFFER_SIZE || i == (REGISTER_COUNT-1)) - { - usb_write(DATATYPE_RDBPACKET, debug_buffer, strlen(debug_buffer)+1); - memset(debug_buffer, 0, BUFFER_SIZE); - offset = 0; - chunkcount--; - } - } - - // Finish sending the other chunks - for (i=chunkcount; i>=0; i--) - usb_write(DATATYPE_RDBPACKET, "\0", 1); - } - else - { - usb_purge(); - usb_write(DATATYPE_RDBPACKET, "E00", 3+1); - } - } - - - /*============================== - hex2u64 - Converts a string containing a hexadecimal value - into a number. This exists because strtol is broken - on ModernSDK. - @param The string with the hexadecimal number - @returns The converted value - ==============================*/ - - static u64 hex2u64(char* addr) - { - int i = 0; - u64 ret = 0; - while (addr[i] != '\0') - { - u32 val; - if (addr[i] <= '9') - val = addr[i]-'0'; - else if (addr[i] <= 'F') - val = 10 + addr[i] - 'A'; - else - val = 10 + addr[i] - 'a'; - ret = (ret << 4) | (val & 0xF); - i++; - } - return ret; - } - - - /*============================== - debug_rdb_writeregisters - Writes a set of registers from a GDB packet - @param The affected thread, if any - ==============================*/ - - static void debug_rdb_writeregisters(OSThread* t) - { - if (t != NULL) - { - int i; - #ifndef LIBDRAGON - __OSThreadContext* context = &t->context; - #else - reg_block_t* context = t->regs; - #endif - - // The incoming data probably won't fit in the buffer, so we'll go bit by bit - usb_rewind(BUFFER_SIZE); - - // Skip the 'G' at the start of the command - usb_skip(1); - - // Do the writing - for (i=0; i= 0x80000000 && addr < 0x80000000 + osMemSize) - { - #ifndef LIBDRAGON - osWritebackDCache((u32*)addr, size); - #else - data_cache_hit_writeback((u32*)addr, size); - #endif - validaddress = TRUE; - } - - // Read the memory address, one byte at a time - while (read < size) - { - u8 val = 0; - if (validaddress) - val = *((vu8*)(addr+read)); - written += sprintf(debug_buffer+written, "%02x", val); - - // Send the partial address dump if we're almost overrunning the buffer, or if we've finished - read++; - if (written+3 >= BUFFER_SIZE || read == size) - { - usb_write(DATATYPE_RDBPACKET, &debug_buffer, strlen(debug_buffer)+1); - written = 0; - chunkcount--; - } - } - - // Finish sending the other chunks - for (i=chunkcount; i>=0; i--) - usb_write(DATATYPE_RDBPACKET, "\0", 1); - } - - - /*============================== - debug_rdb_writememory - Writes the memory from a GDB packet - @param The affected thread, if any - ==============================*/ - - static void debug_rdb_writememory(OSThread* t) - { - int i; - u32 addr; - u32 size; - #ifdef LIBDRAGON - u32 osMemSize = get_memory_size(); - #endif - char* commandp = &debug_buffer[0]; - - // Skip the 'M' at the start of the command - commandp++; - - // Extract the address value - strtok(commandp, ","); - addr = (u32)hex2u64(commandp); - - // Extract the size value - commandp = strtok(NULL, ":"); - size = (u32)hex2u64(commandp); - - // Finally, point to the data we're actually gonna write - commandp = strtok(NULL, "\0"); - - // We need to translate the address before trying to read it - addr = debug_rdb_translateaddr(addr); - - // Ensure we are writing to a valid memory address - if (addr >= 0x80000000 && addr < 0x80000000 + osMemSize) - { - // Read the memory address, one byte at a time - for (i=0; i= 0x80000000 && addr < 0x80000000 + osMemSize) - { - for (i=0; i= 0x80000000 && addr < 0x80000000 + osMemSize) - { - index = GET_BREAKPOINT_INDEX(*((u32*)addr))-1; - if (debug_bpoints[index].addr == (u32*)addr) - { - int i; - - // Remove the breakpoint - *((vu32*)addr) = debug_bpoints[index].instruction; - #ifndef LIBDRAGON - osWritebackDCache((u32*)addr, 4); - osInvalICache((u32*)addr, 4); - #else - data_cache_hit_writeback((u32*)addr, 4); - inst_cache_hit_invalidate((u32*)addr, 4); - #endif - - // Move all the breakpoints in front of it back - for (i=index; i 0) { @@ -642,17 +642,17 @@ void usb_read(void* buffer, int nbytes) left = usb_dataleft; if (block > left) block = left; - + // Call the read function if we're reading a new block if (usb_readblock != blockoffset) { usb_readblock = blockoffset; funcPointer_read(); } - + // Copy from the USB buffer to the supplied buffer - memcpy((void*)(((u32)buffer)+read), usb_buffer+copystart, block); - + memcpy(buffer+read, usb_buffer+copystart, block); + // Increment/decrement all our counters read += block; left -= block; @@ -729,7 +729,7 @@ char usb_timedout() version. ==============================*/ -void usb_sendheartbeat(void) +void usb_sendheartbeat() { u8 buffer[4]; @@ -900,7 +900,7 @@ static u32 usb_64drive_cui_read(u32 offset) // Wait until USB FIFO is disarmed while ((usb_io_read(D64_REG_USBCOMSTAT) & D64_CUI_ARM_MASK) != D64_CUI_ARM_IDLE) ; - + // Due to a 64drive bug, we need to ignore the last 512 bytes of the transfer if it's larger than 512 bytes if (size > 512) size -= 512; @@ -921,7 +921,7 @@ static u32 usb_64drive_cui_read(u32 offset) static void usb_64drive_write(int datatype, const void* data, int size) { - s32 left = size; + u32 left = size; u32 pi_address = D64_BASE + DEBUG_ADDRESS; // Return if previous transfer timed out @@ -942,16 +942,12 @@ static void usb_64drive_write(int datatype, const void* data, int size) // Copy data to PI DMA aligned buffer memcpy(usb_buffer, data, block); - - // Pad the buffer with zeroes if it wasn't 4 byte aligned - while (block%4) - usb_buffer[block++] = 0; // Copy block of data from RDRAM to SDRAM usb_dma_write(usb_buffer, pi_address, ALIGN(block, 2)); // Update pointers and variables - data = (void*)(((u32)data) + block); + data += block; left -= block; pi_address += block; } @@ -1019,7 +1015,7 @@ static void usb_64drive_read(void) @return FALSE on success, TRUE on failure ==============================*/ -static char usb_everdrive_usbbusy(void) +static char usb_everdrive_usbbusy(void) { u32 val; u32 timeout = usb_timeout_start(); @@ -1029,7 +1025,6 @@ static char usb_everdrive_usbbusy(void) if (usb_timeout_check(timeout, ED_TIMEOUT)) { usb_io_write(ED_REG_USBCFG, ED_USBMODE_RDNOP); - usb_didtimeout = TRUE; return TRUE; } } @@ -1044,11 +1039,11 @@ static char usb_everdrive_usbbusy(void) @return TRUE if it can read, FALSE if not ==============================*/ -static char usb_everdrive_canread(void) +static char usb_everdrive_canread(void) { u32 val; u32 status = ED_USBSTAT_POWER; - + // Read the USB register and check its status val = usb_io_read(ED_REG_USBCFG); status = val & (ED_USBSTAT_POWER | ED_USBSTAT_RXF); @@ -1068,15 +1063,15 @@ static char usb_everdrive_canread(void) static void usb_everdrive_readusb(void* buffer, int size) { u16 block, addr; - - while (size) + + while (size) { // Get the block size block = BUFFER_SIZE; if (block > size) block = size; addr = BUFFER_SIZE - block; - + // Request to read from the USB usb_io_write(ED_REG_USBCFG, ED_USBMODE_RD | addr); @@ -1109,7 +1104,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) int left = size; int offset = 8; u32 header = (size & 0x00FFFFFF) | (datatype << 24); - + // Put in the DMA header along with length and type information in the global buffer usb_buffer[0] = 'D'; usb_buffer[1] = 'M'; @@ -1119,7 +1114,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) usb_buffer[5] = (header >> 16) & 0xFF; usb_buffer[6] = (header >> 8) & 0xFF; usb_buffer[7] = header & 0xFF; - + // Write data to USB until we've finished while (left > 0) { @@ -1127,10 +1122,10 @@ static void usb_everdrive_write(int datatype, const void* data, int size) int blocksend, baddr; if (block+offset > BUFFER_SIZE) block = BUFFER_SIZE-offset; - + // Copy the data to the next available spots in the global buffer memcpy(usb_buffer+offset, (void*)((char*)data+read), block); - + // Restart the loop to write the CMP signal if we've finished if (!wrotecmp && read+block >= size) { @@ -1141,7 +1136,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) read = 0; continue; } - + // Ensure the data is 2 byte aligned and the block address is correct blocksend = ALIGN((block+offset), 2); baddr = BUFFER_SIZE - blocksend; @@ -1149,7 +1144,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) // Set USB to write mode and send data through USB usb_io_write(ED_REG_USBCFG, ED_USBMODE_WRNOP); usb_dma_write(usb_buffer, ED_REG_USBDAT + baddr, blocksend); - + // Set USB to write mode with the new address and wait for USB to end (or stop if it times out) usb_io_write(ED_REG_USBCFG, ED_USBMODE_WR | baddr); if (usb_everdrive_usbbusy()) @@ -1157,7 +1152,7 @@ static void usb_everdrive_write(int datatype, const void* data, int size) usb_didtimeout = TRUE; return; } - + // Keep track of what we've read so far left -= block; read += block; @@ -1176,49 +1171,49 @@ static void usb_everdrive_write(int datatype, const void* data, int size) static u32 usb_everdrive_poll(void) { - int len; - int offset = 0; - unsigned char buffaligned[32]; - unsigned char* buff = (unsigned char*)OS_DCACHE_ROUNDUP_ADDR(buffaligned); - + int len; + int offset = 0; + char buffaligned[32]; + char* buff = (char*)OS_DCACHE_ROUNDUP_ADDR(buffaligned); + // Wait for the USB to be ready if (usb_everdrive_usbbusy()) return 0; - + // Check if the USB is ready to be read if (!usb_everdrive_canread()) return 0; - + // Read the first 8 bytes that are being received and check if they're valid usb_everdrive_readusb(buff, 8); if (buff[0] != 'D' || buff[1] != 'M' || buff[2] != 'A' || buff[3] != '@') return 0; - + // Store information about the incoming data - usb_datatype = buff[4]; - usb_datasize = (buff[5] << 16) | (buff[6] << 8) | (buff[7] << 0); + usb_datatype = (int)buff[4]; + usb_datasize = (int)buff[5]<<16 | (int)buff[6]<<8 | (int)buff[7]<<0; usb_dataleft = usb_datasize; usb_readblock = -1; - + // Get the aligned data size. Must be 2 byte aligned len = ALIGN(usb_datasize, 2); - + // While there's data to service - while (len > 0) + while (len > 0) { u32 bytes_do = BUFFER_SIZE; if (len < BUFFER_SIZE) bytes_do = len; - + // Read a chunk from USB and store it into our temp buffer usb_everdrive_readusb(usb_buffer, bytes_do); - + // Copy received block to ROM usb_dma_write(usb_buffer, ED_BASE + DEBUG_ADDRESS + offset, bytes_do); offset += bytes_do; len -= bytes_do; } - + // Read the CMP Signal if (usb_everdrive_usbbusy()) return 0; @@ -1232,7 +1227,7 @@ static u32 usb_everdrive_poll(void) usb_readblock = -1; return 0; } - + // Return the data header return USBHEADER_CREATE(usb_datatype, usb_datasize); } @@ -1363,7 +1358,7 @@ static void usb_sc64_write(int datatype, const void* data, int size) usb_dma_write(usb_buffer, pi_address, ALIGN(block, 2)); // Update pointers and variables - data = (void*)(((u32)data) + block); + data += block; left -= block; pi_address += block; } @@ -1419,7 +1414,7 @@ static u32 usb_sc64_poll(void) // Return 0 if there's no data if (size == 0) return 0; - + // Fill USB read data variables usb_datatype = datatype; usb_dataleft = size; diff --git a/src/usb/usb.h b/src/usb/usb.h index 27262fc325..2155774687 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -6,61 +6,60 @@ /********************************* DataType macros *********************************/ - + // UNCOMMENT THE #DEFINE IF USING LIBDRAGON //#define LIBDRAGON - + // Settings #define USE_OSRAW 0 // Use if you're doing USB operations without the PI Manager (libultra only) #define DEBUG_ADDRESS_SIZE 8*1024*1024 // Max size of USB I/O. The bigger this value, the more ROM you lose! #define CHECK_EMULATOR 0 // Stops the USB library from working if it detects an emulator to prevent problems - + // Cart definitions #define CART_NONE 0 #define CART_64DRIVE 1 #define CART_EVERDRIVE 2 #define CART_SC64 3 - + // Data types defintions - #define DATATYPE_TEXT 0x01 - #define DATATYPE_RAWBINARY 0x02 - #define DATATYPE_HEADER 0x03 - #define DATATYPE_SCREENSHOT 0x04 - #define DATATYPE_HEARTBEAT 0x05 - #define DATATYPE_RDBPACKET 0x06 - - + #define DATATYPE_TEXT 0x01 + #define DATATYPE_RAWBINARY 0x02 + #define DATATYPE_HEADER 0x03 + #define DATATYPE_SCREENSHOT 0x04 + #define DATATYPE_HEARTBEAT 0x05 + + /********************************* Convenience macros *********************************/ - + // Use these to conveniently read the header from usb_poll() - #define USBHEADER_GETTYPE(header) (((header) & 0xFF000000) >> 24) - #define USBHEADER_GETSIZE(header) (((header) & 0x00FFFFFF)) - - + #define USBHEADER_GETTYPE(header) ((header & 0xFF000000) >> 24) + #define USBHEADER_GETSIZE(header) ((header & 0x00FFFFFF)) + + /********************************* USB Functions *********************************/ - + /*============================== usb_initialize Initializes the USB buffers and pointers @return 1 if the USB initialization was successful, 0 if not ==============================*/ - - extern char usb_initialize(void); - - + + extern char usb_initialize(); + + /*============================== usb_getcart Returns which flashcart is currently connected @return The CART macro that corresponds to the identified flashcart ==============================*/ - - extern char usb_getcart(void); - - + + extern char usb_getcart(); + + /*============================== usb_write Writes data to the USB. @@ -69,54 +68,54 @@ @param A buffer with the data to send @param The size of the data being sent ==============================*/ - + extern void usb_write(int datatype, const void* data, int size); - - + + /*============================== usb_poll Returns the header of data being received via USB The first byte contains the data type, the next 3 the number of bytes left to read @return The data header, or 0 ==============================*/ - + extern u32 usb_poll(); - - + + /*============================== usb_read Reads bytes from USB into the provided buffer @param The buffer to put the read data in @param The number of bytes to read ==============================*/ - + extern void usb_read(void* buffer, int size); - - + + /*============================== usb_skip Skips a USB read by the specified amount of bytes @param The number of bytes to skip ==============================*/ - + extern void usb_skip(int nbytes); - - + + /*============================== usb_rewind Rewinds a USB read by the specified amount of bytes @param The number of bytes to rewind ==============================*/ - + extern void usb_rewind(int nbytes); - - + + /*============================== usb_purge Purges the incoming USB data ==============================*/ - - extern void usb_purge(void); + + extern void usb_purge(); /*============================== @@ -125,7 +124,7 @@ @return 1 if the USB timed out, 0 if not ==============================*/ - extern char usb_timedout(void); + extern char usb_timedout(); /*============================== @@ -137,6 +136,6 @@ version. ==============================*/ - extern void usb_sendheartbeat(void); + extern void usb_sendheartbeat(); #endif diff --git a/text/define_text.inc.c b/text/define_text.inc.c index 069b13e369..c2abf7dcbe 100644 --- a/text/define_text.inc.c +++ b/text/define_text.inc.c @@ -1,26 +1,27 @@ // == dialog == // (defines en_dialog_table etc.) -#include "dialog_ids.h" +#include "game/ingame_menu.h" +#undef DEFINE_DIALOG #define DEFINE_DIALOG(id, _1, _2, _3, _4, str) \ - static const u8 dialog_text_ ## id[] = { str }; + static const char dialog_text_ ## id[] = { str }; -#include "dialogs.h" +#include DIALOG_FILE #undef DEFINE_DIALOG -#define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \ +#define DEFINE_DIALOG(id, voice, linesPerBox, leftOffset, width, _) \ static const struct DialogEntry dialog_entry_ ## id = { \ - unused, linesPerBox, leftOffset, width, dialog_text_ ## id \ + voice, linesPerBox, leftOffset, width, dialog_text_ ## id \ }; -#include "dialogs.h" +#include DIALOG_FILE #undef DEFINE_DIALOG -#define DEFINE_DIALOG(id, _1, _2, _3, _4, _5) [id] = &dialog_entry_ ## id, +#define DEFINE_DIALOG(id, _1, _2, _3, _4, _5) &dialog_entry_ ## id, -const struct DialogEntry *const seg2_dialog_table[] = { -#include "dialogs.h" +const struct DialogEntry *const DIALOG_TABLE[] = { +#include DIALOG_FILE NULL }; @@ -30,28 +31,27 @@ const struct DialogEntry *const seg2_dialog_table[] = { // The game duplicates this in levels/menu/leveldata.c in EU, so we split // it out into a separate include file. -#define COURSE_TABLE seg2_course_name_table #include "define_courses.inc.c" // == acts == // (defines en_act_name_table etc.) #define COURSE_ACTS(id, name, a,b,c,d,e,f) \ - static const u8 act_name_ ## id ## _1[] = { a }; \ - static const u8 act_name_ ## id ## _2[] = { b }; \ - static const u8 act_name_ ## id ## _3[] = { c }; \ - static const u8 act_name_ ## id ## _4[] = { d }; \ - static const u8 act_name_ ## id ## _5[] = { e }; \ - static const u8 act_name_ ## id ## _6[] = { f }; + static const char act_name_ ## id ## _1[] = { a }; \ + static const char act_name_ ## id ## _2[] = { b }; \ + static const char act_name_ ## id ## _3[] = { c }; \ + static const char act_name_ ## id ## _4[] = { d }; \ + static const char act_name_ ## id ## _5[] = { e }; \ + static const char act_name_ ## id ## _6[] = { f }; #define SECRET_STAR(id, name) #define CASTLE_SECRET_STARS(str) #undef EXTRA_TEXT #define EXTRA_TEXT(id, str) \ - static const u8 extra_text_ ## id[] = { str }; + static const char extra_text_ ## id[] = { str }; -#include "courses.h" +#include COURSE_FILE #undef COURSE_ACTS #undef EXTRA_TEXT @@ -61,7 +61,10 @@ const struct DialogEntry *const seg2_dialog_table[] = { act_name_ ## id ## _4, act_name_ ## id ## _5, act_name_ ## id ## _6, #define EXTRA_TEXT(id, str) extra_text_ ## id, -const u8 *const seg2_act_name_table[] = { -#include "courses.h" +const char *const ACT_NAME_TABLE[] = { +#include COURSE_FILE NULL }; + +#undef COURSE_ACTS +#undef EXTRA_TEXT diff --git a/textures/segment2/custom_text.i4.png b/textures/segment2/custom_text.i4.png new file mode 100644 index 0000000000000000000000000000000000000000..4bf8a055d40f36dde7b39ef35afe493c4f429301 GIT binary patch literal 2001 zcmV;?2QK)DP)w7V%H#erb^^?3-*nj$}^l0f6658FpO|KZffx zzV~Hq(`BIdPi?Sz?0uAA&8m4_`;NK|{?SJt-P3;IUR_^TulJhMJ&2(8JqTm#^WpEr z|1?H+mb$Tb;CCi}NYWLy>4VkZqKY4-7qK#fW%eEB^$q{u+k5}%g2x2?Ssm|k z-}_95gv(EIc)82FveEw{#bWB;m9YJ;?5?cO??6D6&uV{LA)u-LsRWeOyLvFYgMfZD z28n;GfB9X-|EwH6X)6o&DhH5&vOkj}VAVJAFD*C~e*oYw{SE{aeZu%zu2)Hy>hJ0Z z4@&i&AUeYnDUjX3$eEcc`s$K&yF8sDi zK-ruwKltK-*x?+#T`iJ{sH!d4{Ku>>=ID* zl9t9-wtLQdEp*?y9Y&sd9~b}X_=LPMJxf3xIqdWH9H6~k`_7N#&~@=*>X?N(xdF9HNxgPv%c`0uX&vRj$pa^RamRDk6m8ag(Ss*)ef!;wm-Y| zRdcg=RUIMeX8xx839g^Ba^OTO3;QAmWN~AX5V*wOG%iIBoJ=>^YESH*8Ovf#;x9Qv zKv`esH`{!euQ*>{RLozTLml`?LYeR7+u4hbQ+GM(_R#i(uiG#tJXE_I&*qw5tC(C( zK$QO4gFGnEL@e`p{xH^2*e2Ty*64GO11Qgq+^`Yuu^>9pZaPd2v zEPq%Z46l^LAZGa6`LFDyHBxiAI(6%d5vjy~*4}+l;~hRzds?#z2H1ueul%mK6`mz- z?WlNGE-O909XZlMy3v8(Kq+CjE_DM){B!-z5>S@FGdS*Qz1$@6m#h*{7oQ?;ET22R1XPiF}z`pD+)xb&PWqU_cIi*bj1G91(Rr*%7xXP4zJ4s+%I z>I;<9XcR5XRu57%MfKE6i2PFGHeq)D_B1YB6 z*Nd&84gp2-&0^^5tj05Fg^%ruC)v`!pUl|L&vNt{e!=>Os0I$wr3+p@2+4O8}nw1OQsSn}9k$ z@P>$+(-c#$4VF75jx2XOZ2oBxsyEhB9cZf0 z>N-OonXfoM6E!c(PjY~%`B~2Uno0;B`iKNEA@JxYizSV3<#mzG!NyN@j+n4RSIy^q zRQXe}B(e4J{i3AeXSJ=?P*NYvhN_dqw%ZF;-WWcton4ODrHqZQzKVb*{`Y-^*}jv2 zx^stNfH+|86wWG7(*+K(au-l_zM-U;?#i)}xSJffUELutwO{4`OLkt#luoaokG@Cm z%I%~7rj|T4_2{FsrWfR{|I*spd0b4f+~j{>?!a5L3N^iXrtz)Vz9X)8V)*ELbNlGO jt4~cm`skzIU3cX_gOe_a1yQ#E00000NkvXXu0mjfE5r;z literal 0 HcmV?d00001 diff --git a/textures/segment2/custom_text2.ia4.png b/textures/segment2/custom_text2.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..389a6cf0d6bd2a097e776140198d61bc5b628ce2 GIT binary patch literal 1560 zcmV+z2Iu*SP)lD)}_PWXjl2Fc;Z_&9e-M?Z)@al62rSVP!h3q=ApBjt~?|`z~Vy} zmwOigD{9SwNQeWb7NoL7@s34c!r`j~)zSF}6mhTom43xg4+X-5uua|Htp{=L*jfFG zo4f1j@Hx%5I$!6Jp=xvOPm5iYhbF2)VzLW>EiYTr=#$}N zG2Et#gOf%5)XGn>)kb%^&?^z09uSvz=o5!1Bjf zS$r4&4*xDcOyBJyPlG1&G|m_}L7wKCl|%z_a}5$L^!}j7JvJwKIH-7uSyByE?Tq`JiTt9#A#oB<0dN)&-E*r=1cWo^`*;Khu_M4B4NGm@Y~7n+Ozk=eP2-BY}e3!Dr{99^)J&AZ?Olg zCe&Y)FSE1Qjz7X(jUWHpPmJKhm@Fs!iQ>?pO3G|5N#@{Y7!_z&D|*emQk@ z^SS3rM=>h(-L3EPx5}&bBj#ncj(-JTjH&i5`bR8r|6XZlwX^v^^NQj-I*ZSGv-+#P zv7S`;$#lnG)!6aR_(vEO{y5{&hw;DKtNyHa%Y5WVn^Si@#!Lcy{Ki zQeTE~GXAcmfr zV!8D>xvNWp{Ida4d?@Y|x6Ut%@6?m|JMk;FN_>ZZr@!$L%5uBh@AS8m|I_AcH~y>f zW&Eu(GLe5`Ka_uV=FXFQ?(jJ=pP7G!zlyzr9rNR*&QF&fU&@C>*=| zb?bBaoc#W4$=d-KauIqx?9q0eBhq*AU-41y31M{|d5yUJ?JW0^e@oVP>g@E9BS$`6 z-v0gfb^xYS|MIwG7ysQK9_ORxy>dP*k4(y$rz1y>{4KKk{r4ZrYN-}RmpEMj0000< KMNUMnLSTZ#09qIT literal 0 HcmV?d00001 diff --git a/textures/segment2/custom_text3.i4.png b/textures/segment2/custom_text3.i4.png new file mode 100644 index 0000000000000000000000000000000000000000..0e106e66f509b6c247ef68876789cec6f73650ee GIT binary patch literal 1200 zcmV;h1W)^kP)C7{5BwJ>C4L{O%{22+E4`Y+PBe=gLE3QgM291e_#9;f^v2);e^+e%ecbNFBZ^Vb1 zBZ|jx|?kA+04b+on2vB;S8abP4l(m{A9RyZ%qGL49@!B6G8 zi?xfVp0Nv}6xaX|>e;t@I3ha)|5t`^hauxx;i|GhF|hF}>{V_wf23EOp`3nQ@Ag~C zSLHzSDY55+=nLUb6wR6?Q^5?2^z0cxTxe?zALxd;tNAaWB)c6ij z^0PYIf7ZYIj&Q(mIO|I6)jx_EnMMbjT2AANhiNLC$4=st+O>N@jElpjX&Sd zzq{|Z_4zn<>xup9#_#S}_Y5_$5rDj$3_jHk#oxu*6$C%KEDj!7o>YJ2e%H6C$4~dC z(ktv;K2>he{GAv`Jy8sXpZPcYj@}*pWBt`RQ1>m?|jwaU=~Ql|Ab_@SFDJw62Ha@c{ta@7*{H$hX?%vj!e!21?{31FV8}VV^yZpN2vG+=T2OsP` zD&6{6zFB`J$9!D;c6WivyNkot6X`o{6#m$GVtMK46=!Ju&K>KX(FI`u@Z)#=UU4Zn zE1&Eg!H@FOZLm@sGJwc(Wic2|RvW~(vO(*r{Mk3AzbN*T`VIri9otV-uX4EgU}j!< z@8&;MFM6NVi^MpMkCoH>s`aWhy7^^xq1(UtclUjYU!|T7M{K_JR2-^&u-F+s)HBq? zMgS$ztNqTG9U69k5d3O>2mdExU-9)IvRUsVJ)61go%OBoWVIpwReebOE`L>h^Bt2D zv31wSa>(Xq{F#2R`+;EW%x4yxeP3-*f2J1q{G-^^`0Bhk_KV#ornd~nECv$$i~H3* zgIVN50K#}(Y)k{x`qaEv{tdbPz2cHPOIKD={^tBo!gBIIarngCbkA?vm{S!252LXF O0000~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj52~bQ_MF0Q*|NsB|{QScj8AAX7010qNS#tmY4#NNd z4#NS*Z>VGd00SvWL_t(o!|j({y5k@ShQSr!4m|FEkt6Vdm^Mx4nVY#dral_fsIUB3 z(j-jOkqC)J8&*l)M!)G}+WgvjS@c4{im*9Qg{e^A16{3?&=Hx&k}YA=a(JmZlGO(_ z9fxk#&$3R7w$-3@vhGvMVc*xbj%-RGtMI&j!d6@Fb+vM-@I~HHmj_}G?YBTh)pd-V zhxi_-ZCb=tTytxH&`2LGEl1KiU|DW9J#v8xZ%mK$mS9RV9anNFZ#Jug5(hk3&~ zDuVX1lXpOEd_VhKQ`MCXbesZRTx)yoPe9cYeI}*=9B{Ulwe$!9)E@`vP9X9t&{2R6 zJ7|9bsJN}83ZPO~c@pt)a>(CVyp%&J!;jRy0cs;hSxf+ZIYKHx#ZJ=zsmn9}N$`tv zyI4RTZ3FcF3U1gqTcdLi?=dthLLCa`!{+kA zqhXP2wbyIs2Fi?WK4@qG8gaAD`59;dHxAQ3fsU%7SD@i13(!s{P`Lrx;9`9jrPtLYw^R{U+4ynaB+dj_v?13l*Qezv&w1XP_ZR5araRQU>2$EuUJ z3wHMj)Fm|d$f#d|#+`ps>5Iihn`!IZcLj!bV%#-j4XH)$8PEGAOTIJHIVRxCYfwrp z$02lp=g?dhKQ!_69zcn11c1r3f&R 1 else '.' - unfloader_zip_path = os.path.join(destpath, "UNFLoader.zip") - os.makedirs(destpath, exist_ok=True) + destpath = sys.argv[1] if len(sys.argv) > 1 else './' is_wsl = 'microsoft-standard' in str(platform.uname()).lower() unf_fn = 'UNFLoader.exe' if is_wsl else 'UNFLoader' artifact_url = get_latest_build_artifacts_url() @@ -34,24 +32,24 @@ def main(): # download unf zipfile artifact_res = request('GET', platform_artifact_url) - with open(unfloader_zip_path, 'wb') as unf_fp: + with open('UNFLoader.zip', 'wb') as unf_fp: unf_fp.write(artifact_res.content) # only extract the specific file that we need unfpath = None - with zipfile.ZipFile(unfloader_zip_path, 'r') as zip_ref: + with zipfile.ZipFile('UNFLoader.zip', 'r') as zip_ref: for zipinfo in zip_ref.infolist(): if not zipinfo.is_dir(): - unfpath = zip_ref.extract(zipinfo, destpath) + unfpath = zip_ref.extract(zipinfo) unf_bin_path = os.path.join(destpath, unf_fn) - # file gets extracted to [destpath]/unfloader-{platform}/UNFLoader[.exe], - # so move binary to [destpath]/UNFLoader[.exe] + # file gets extracted to ./unfloader-{platform}/UNFLoader[.exe], + # so move binary to ./UNFLoader[.exe] os.rename(unfpath, unf_bin_path) - # remove [destpath]/unfloader-{platform}/ directory + # remove ./unfloader-{platform}/ directory os.rmdir(unfpath.rstrip(unf_fn)) # remove UNFLoader.zip - os.remove(unfloader_zip_path) + os.remove('UNFLoader.zip') # now need to add executable file permissions to unfloader st = os.stat(unf_bin_path) diff --git a/tools/n64graphics.c b/tools/n64graphics.c index c0014d0ccc..1368c6a44a 100644 --- a/tools/n64graphics.c +++ b/tools/n64graphics.c @@ -643,7 +643,6 @@ typedef struct int bin_truncate; int pal_truncate; int rotate_envmap; - int word_swap; } graphics_config; static const graphics_config default_config = @@ -662,7 +661,6 @@ static const graphics_config default_config = .bin_truncate = 1, .pal_truncate = 1, .rotate_envmap = 0, - .word_swap = 0, }; typedef struct @@ -745,7 +743,7 @@ static int parse_encoding(write_encoding *encoding, const char *str) static void print_usage(void) { - ERROR("Usage: n64graphics -e/-i BIN_FILE -g IMG_FILE [-p PAL_FILE] [-o BIN_OFFSET] [-P PAL_OFFSET] [-f FORMAT] [-c CI_FORMAT] [-w WIDTH] [-h HEIGHT] [-r ROTATE] [-S] [-V]\n" + ERROR("Usage: n64graphics -e/-i BIN_FILE -g IMG_FILE [-p PAL_FILE] [-o BIN_OFFSET] [-P PAL_OFFSET] [-f FORMAT] [-c CI_FORMAT] [-w WIDTH] [-h HEIGHT] [-r ROTATE] [-V]\n" "\n" "n64graphics v" N64GRAPHICS_VERSION ": N64 graphics manipulator\n" "\n" @@ -760,7 +758,6 @@ static void print_usage(void) " -w WIDTH export texture width (default: %d)\n" " -h HEIGHT export texture height (default: %d)\n" " -r ROTATE rotate envmap texture for rgba extraction only (default: false)\n" - " -S swap words on odd lines (importing only, does not support ci4, ci8, or ia1 formats)\n" "CI arguments:\n" " -c CI_FORMAT CI palette format: rgba16, ia16 (default: %s)\n" " -p PAL_FILE palette binary file to import/export from/to\n" @@ -847,9 +844,6 @@ static int parse_arguments(int argc, char *argv[], graphics_config *config) return 0; } break; - case 'S': - config->word_swap = 1; - break; case 'v': g_verbosity = 1; break; @@ -906,6 +900,22 @@ int main(int argc, char *argv[]) } if (config.mode == MODE_IMPORT) { + if (0 == strcmp("-", config.bin_filename)) { + bin_fp = stdout; + } else { + if (config.bin_truncate) { + bin_fp = fopen(config.bin_filename, "wb"); + } else { + bin_fp = fopen(config.bin_filename, "r+b"); + } + } + if (!bin_fp) { + ERROR("Error opening \"%s\"\n", config.bin_filename); + return -1; + } + if (!config.bin_truncate) { + fseek(bin_fp, config.bin_offset, SEEK_SET); + } switch (config.format.format) { case IMG_FORMAT_RGBA: imgr = png2rgba(config.img_filename, &config.width, &config.height); @@ -1016,56 +1026,6 @@ int main(int argc, char *argv[]) ERROR("Error converting to raw format\n"); return EXIT_FAILURE; } - if (config.word_swap) { - if (config.format.depth == 1) { - ERROR("Word swapping unavailable for IA1 texture format\n"); - return EXIT_FAILURE; - } else if (config.format.format == IMG_FORMAT_CI) { - ERROR("Word swapping unavailable for CI texture formats\n"); - return EXIT_FAILURE; - } - - int swap_bytes = (config.format.depth == 32) ? 8 : 4; - int required_width = 2 * swap_bytes * 8; - if ((config.width * config.format.depth) % required_width == 0) { - uint8_t tmp; - int line_size = config.width * config.format.depth / 8; - for (int line = 1; line < config.height; line += 2) { - for (int x = 0; x < line_size; x += 2 * swap_bytes) { - int word_offset = line * line_size + x; - for (int i = 0; i < swap_bytes; i++) { - tmp = raw[word_offset + i]; - raw[word_offset + i] = raw[word_offset + swap_bytes + i]; - raw[word_offset + swap_bytes + i] = tmp; - } - } - } - } else { - for (unsigned i = 0; i < DIM(format_table); i++) { - if (format_table[i].format.format == config.format.format && format_table[i].format.depth == config.format.depth) { - ERROR("Image must be a multiple of %d pixels wide to create pre-swapped %s texture\n", required_width / config.format.depth, format_table[i].name); - break; - } - } - return EXIT_FAILURE; - } - } - if (0 == strcmp("-", config.bin_filename)) { - bin_fp = stdout; - } else { - if (config.bin_truncate) { - bin_fp = fopen(config.bin_filename, "wb"); - } else { - bin_fp = fopen(config.bin_filename, "r+b"); - } - } - if (!bin_fp) { - ERROR("Error opening \"%s\"\n", config.bin_filename); - return -1; - } - if (!config.bin_truncate) { - fseek(bin_fp, config.bin_offset, SEEK_SET); - } INFO("Writing 0x%X bytes to offset 0x%X of \"%s\"\n", length, config.bin_offset, config.bin_filename); flength = fprint_write_output(bin_fp, config.encoding, raw, length); if (config.encoding == ENCODING_RAW && flength != length) { From dc71d06d3bd4962eb48d5d6e8151fab20d039986 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Wed, 29 Jan 2025 21:25:03 -0500 Subject: [PATCH 4/7] more reverts --- Makefile | 36 +++++++---------------- Makefile.split | 52 +++++++++++++++++++++++++++++----- src/game/area.c | 4 --- src/game/fasttext.c | 14 ++++++--- src/game/newfont2_swapped.bin | Bin 0 -> 4032 bytes src/game/puppyprint.c | 4 +-- 6 files changed, 67 insertions(+), 43 deletions(-) create mode 100644 src/game/newfont2_swapped.bin diff --git a/Makefile b/Makefile index d380528f9f..1f74791573 100644 --- a/Makefile +++ b/Makefile @@ -450,8 +450,6 @@ else ifneq ($(call find-command,mips64-none-elf-ld),) CROSS := mips64-none-elf- else ifneq ($(call find-command,mips-ld),) CROSS := mips- -else ifneq ($(call find-command,mips-suse-linux-ld ),) - CROSS := mips-suse-linux- else $(error Unable to detect a suitable MIPS toolchain installed) endif @@ -565,19 +563,10 @@ endif EMU_FLAGS = -# Adding a txt file to this location will then reference a UNFLoader path specified in the file, instead of locally. -# This is expecially important for WSL users because UNFLoader.exe is incredibly slow when run within WSL's filesystem, so this can be used to point to the C drive. -# The file should only contain the directory path that contains UNFLoader[.exe] (do not specify the filename). -LOADER_DIR_FILE_SPECIFICATION_PATH = ~/.local/share/HackerSM64/UNFLoader-dir.txt -LOADER_DIR = ./$(TOOLS_DIR) - -ifneq (,$(wildcard $(LOADER_DIR_FILE_SPECIFICATION_PATH))) - LOADER_DIR = $(shell cat $(LOADER_DIR_FILE_SPECIFICATION_PATH)) -endif ifneq (,$(call find-command,wslview)) - LOADER_EXEC = $(LOADER_DIR)/UNFLoader.exe + LOADER = ./$(TOOLS_DIR)/UNFLoader.exe else - LOADER_EXEC = $(LOADER_DIR)/UNFLoader + LOADER = ./$(TOOLS_DIR)/UNFLoader endif SHA1SUM = sha1sum @@ -633,17 +622,17 @@ test-pj64: $(ROM) # someone2639 # download and extract most recent unfloader build if needed -$(LOADER_EXEC): -ifeq (,$(wildcard $(LOADER_EXEC))) +$(LOADER): +ifeq (,$(wildcard $(LOADER))) @$(PRINT) "Downloading latest UNFLoader...$(NO_COL)\n" - $(PYTHON) $(TOOLS_DIR)/get_latest_unfloader.py $(LOADER_DIR) + $(PYTHON) $(TOOLS_DIR)/get_latest_unfloader.py $(TOOLS_DIR) endif -load: $(ROM) $(LOADER_EXEC) - $(LOADER_EXEC) -r $< +load: $(ROM) $(LOADER) + $(LOADER) -r $< -unf: $(ROM) $(LOADER_EXEC) - $(LOADER_EXEC) -d -r $< +unf: $(ROM) $(LOADER) + $(LOADER) -d -r $< libultra: $(BUILD_DIR)/libultra.a @@ -653,7 +642,6 @@ patch: $(ROM) # Extra object file dependencies $(BUILD_DIR)/asm/ipl3.o: $(IPL3_RAW_FILES) $(BUILD_DIR)/src/game/crash_screen.o: $(CRASH_TEXTURE_C_FILES) -$(BUILD_DIR)/src/game/fasttext.o: $(FASTTEXT_TEXTURE_C_FILES) $(BUILD_DIR)/src/game/version.o: $(BUILD_DIR)/src/game/version_data.h $(BUILD_DIR)/lib/aspMain.o: $(BUILD_DIR)/rsp/audio.bin $(SOUND_BIN_DIR)/sound_data.o: $(SOUND_BIN_DIR)/sound_data.ctl $(SOUND_BIN_DIR)/sound_data.tbl $(SOUND_BIN_DIR)/sequences.bin $(SOUND_BIN_DIR)/bank_sets @@ -704,13 +692,9 @@ $(BUILD_DIR)/%: %.png $(call print,Converting:,$<,$@) $(V)$(N64GRAPHICS) -s raw -i $@ -g $< -f $(lastword $(subst ., ,$@)) -$(BUILD_DIR)/%.preswap.inc.c: %.preswap.png - $(call print,Converting:,$<,$@) - $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$*)) -S - $(BUILD_DIR)/%.inc.c: %.png $(call print,Converting:,$<,$@) - $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$*)) + $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$(basename $<))) # Color Index CI8 $(BUILD_DIR)/%.ci8.inc.c: %.ci8.png diff --git a/Makefile.split b/Makefile.split index 8be88378b0..9fe299e79f 100644 --- a/Makefile.split +++ b/Makefile.split @@ -41,15 +41,21 @@ LEVEL_FILES := $(addsuffix leveldata,$(LEVEL_DIRS)) LEVEL_ELF_FILES := $(foreach level_dir,$(LEVEL_DIRS),$(BUILD_DIR)/levels/$(level_dir)leveldata.elf) +VANILLA_ACTORS_FILES := $(addsuffix data,$(VNL_ACTRS_DIRS)) + +VANILLA_ACTORS_ELF_FILES := $(foreach level_dir,$(VNL_ACTRS_DIRS),$(BUILD_DIR)/actors/vanilla_actors/$(level_dir)data.elf) + SEG_FILES := \ $(SEGMENTS:%=$(BUILD_DIR)/bin/%.elf) \ $(ACTOR_GROUPS:%=$(BUILD_DIR)/actors/%.elf) \ - $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.elf) + $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.elf) \ + $(VANILLA_ACTORS_FILES:%=$(BUILD_DIR)/actors/vanilla_actors/%.elf) YAY0_FILES := \ $(SEGMENTS:%=$(BUILD_DIR)/bin/%.szp) \ $(ACTOR_GROUPS:%=$(BUILD_DIR)/actors/%.szp) \ - $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.szp) + $(LEVEL_FILES:%=$(BUILD_DIR)/levels/%.szp) \ + $(VANILLA_ACTORS_FILES:%=$(BUILD_DIR)/actors/vanilla_actors/%.szp) YAY0_OBJ_FILES := $(YAY0_FILES:.szp=.szp.o) @@ -243,9 +249,11 @@ $(BUILD_DIR)/bin/machine.elf: SEGMENT_ADDRESS := 0x09000000 $(BUILD_DIR)/bin/mountain.elf: SEGMENT_ADDRESS := 0x09000000 $(BUILD_DIR)/bin/grass.elf: SEGMENT_ADDRESS := 0x09000000 # EU segment 19 translations -$(BUILD_DIR)/bin/eu/translation_de.elf: SEGMENT_ADDRESS := 0x19000000 -$(BUILD_DIR)/bin/eu/translation_en.elf: SEGMENT_ADDRESS := 0x19000000 -$(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 +$(BUILD_DIR)/bin/translation_de.elf: SEGMENT_ADDRESS := 0x1B000000 +$(BUILD_DIR)/bin/translation_en.elf: SEGMENT_ADDRESS := 0x1B000000 +$(BUILD_DIR)/bin/translation_fr.elf: SEGMENT_ADDRESS := 0x1B000000 +$(BUILD_DIR)/bin/translation_jp.elf: SEGMENT_ADDRESS := 0x1B000000 +$(BUILD_DIR)/bin/translation_es.elf: SEGMENT_ADDRESS := 0x1B000000 # -------------------------------------- # Skybox Rules @@ -271,5 +279,35 @@ IPL3_RAW_FILES := $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%,$(IP CRASH_TEXTURE_FILES := $(wildcard $(TEXTURE_DIR)/crash_custom/*.png) CRASH_TEXTURE_C_FILES := $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%.inc.c,$(CRASH_TEXTURE_FILES))) -FASTTEXT_TEXTURE_FILES := $(wildcard $(TEXTURE_DIR)/fasttext/*.png) -FASTTEXT_TEXTURE_C_FILES := $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%.inc.c,$(FASTTEXT_TEXTURE_FILES))) +# -------------------------------------- +# Vanilla Objects Rules +# -------------------------------------- + +define vanilla_objects_rules = + VANILLA_ACTORS_$(1)_TEXTURE_FILES := $$(patsubst %.png,%.inc.c,$$(wildcard actors/vanilla_actors/$(1)/*.png)) + $$(BUILD_DIR)/actors/vanilla_actors/$(1)/data.o: $$(addprefix $$(BUILD_DIR)/,$$(VANILLA_ACTORS_$(1)_TEXTURE_FILES)) + $$(BUILD_DIR)/actors/vanilla_actors/$(1)/data.elf: SEGMENT_ADDRESS := 0x0e000000 + $$(BUILD_DIR)/actors/vanilla_actors/$(1)/data.elf: TEXTURE_BIN := $(2) +endef + +$(eval $(call vanilla_objects_rules,bob,generic)) +$(eval $(call vanilla_objects_rules,wf,grass)) +$(eval $(call vanilla_objects_rules,jrb,water)) +$(eval $(call vanilla_objects_rules,ccm,snow)) +$(eval $(call vanilla_objects_rules,bbh,spooky)) +$(eval $(call vanilla_objects_rules,hmc,cave)) +$(eval $(call vanilla_objects_rules,lll,fire)) +$(eval $(call vanilla_objects_rules,ssl,generic)) +$(eval $(call vanilla_objects_rules,ddd,water)) +$(eval $(call vanilla_objects_rules,sl,snow)) +$(eval $(call vanilla_objects_rules,wdw,grass)) +$(eval $(call vanilla_objects_rules,ttm,mountain)) +$(eval $(call vanilla_objects_rules,thi,grass)) +$(eval $(call vanilla_objects_rules,ttc,machine)) +$(eval $(call vanilla_objects_rules,rr,sky)) +$(eval $(call vanilla_objects_rules,bitdw,sky)) +$(eval $(call vanilla_objects_rules,bitfs,sky)) +$(eval $(call vanilla_objects_rules,bits,sky)) +$(eval $(call vanilla_objects_rules,vcutm,outside)) +$(eval $(call vanilla_objects_rules,castle_inside,inside)) +$(eval $(call vanilla_objects_rules,castle_grounds,outside)) diff --git a/src/game/area.c b/src/game/area.c index de14ab6aec..a693e6b25b 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -224,10 +224,6 @@ void load_area(s32 index) { gMarioCurrentRoom = 0; - if (gCurrentArea->surfaceRooms != NULL) { - bzero(gDoorAdjacentRooms, sizeof(gDoorAdjacentRooms)); - } - if (gCurrentArea->terrainData != NULL) { load_area_terrain(gCurrentArea->terrainData, gCurrentArea->surfaceRooms); } diff --git a/src/game/fasttext.c b/src/game/fasttext.c index 1c4804cabe..20357cb725 100644 --- a/src/game/fasttext.c +++ b/src/game/fasttext.c @@ -2,16 +2,22 @@ // See the original repo for more details. #include -#include "macros.h" #define TEX_ASCII_START '!' #define TAB_WIDTH 16 #define G_CC_TEXT PRIMITIVE, 0, TEXEL0, 0, 0, 0, 0, TEXEL0 -ALIGNED8 static const u8 fast_font[] = { -#include "textures/fasttext/newfont2.ia4.preswap.inc.c" -}; +__asm__( + ".section \".rodata\", \"a\", @progbits\n" + ".balign 16\n" + ".global fast_font\n" + "fast_font:\n" + ".incbin \"src/game/newfont2_swapped.bin\"\n" + ".previous\n" +); + +extern u8 fast_font[]; int computeS(unsigned char letter) { int idx = letter; diff --git a/src/game/newfont2_swapped.bin b/src/game/newfont2_swapped.bin new file mode 100644 index 0000000000000000000000000000000000000000..72cf2c53ed95e374a692e3647832d7c2fdec7223 GIT binary patch literal 4032 zcmd6pOP1U)2t_^d{yfpx`(J>^%DoR!<*u%LIyuP+Dj5j@f+sB3wr$%OW1EYZD%i#$ zKf+y#{KF#}A0+?P|9M zmTTAYS08_SzOTTa(5{g&5`Fg?_4E5t?Qd`x69AzHeiPgf_58fRX z4+P*G$^idOZf9_vb6$>{XAM)$O9!E=?T%r?D#YiHUZD)&`%^57gQye`%<>DFwyQcGE!h#$aH{xW} zZH&nCByQ#4tU25>IOO6RdDis9n&Z~h&Nha!)^DzUYdraqfj@PU_Xkdn>GeJhYR24@ z+s)J_rs@R~YdAJJ(bBkBi{|ZFddFNOmQv5hxDN7l6ZWe2-nFr07K3XRuDK#-f4F@j zDOEPU=PIUlb#!%aZCx_m?9ouKY)<`tY6ODrUEaP2dne<09VeZs?@~DNWqf+3NuByM zm*C5I=@%~>ZJDEUYn)XYYr-K$lH+@QdLMZ2)Ly06lXKz}lAA{W$3U>0Q(J?zN)(P_ z&?g@7w#W8{0gxDHx<1kH0;!*J@<3kwW>*UMeaKeL6FYk%=S&JM^M2{pXYjjNvuH%> znk9SDrGCqvRqRL^-POibFRnE>7m20R^X!G9vP8tgH3A>v!6Q81D-bYubFo-X@(wRK zF=`Z)u+t%K#3rpZiP1Q(lIyR0fhAFt{=+6dkr6}f9bXG`<47!=gYkoFXI>n+_uvCx zwD5z^`u3h@BL#opHd5ESXV6%qmzrbV-@LiVeed6QY-kf(R|@CCj!C5uxp{DX5_3|^ zBe^ZK9Jl@&7e2T3(${TcTatmGWE0*^J=@H)e4~}4esYe?!wF^v`oLh-nHUFCunc-6 z`qc5;9BE+({=r*aFsW|~cK~(S-94 z#whhz{n*9_m@FMR9ekEAkz%eLqm08Dm+Yx`-y`q(;G0DYmiS1Xb?>FV(9gXomfi)` z^ml=sv09_mN;Zri39(z(6fxh2M_r10Y7`y!nu{FY>yz)BA4AR}YW1$0Zz6;bEwmY_ zVbnveD7$x+)mLVoIRnPaWc~NivZ!r){*jj-Wjim0j^lUn=&pZJkF|rI z5z!NiYZ;5fb1b%rExNszHVU{hVqEP_vUDemz8^3Q? CYbyf) literal 0 HcmV?d00001 diff --git a/src/game/puppyprint.c b/src/game/puppyprint.c index 74f3be39d4..6afdc709a6 100644 --- a/src/game/puppyprint.c +++ b/src/game/puppyprint.c @@ -1595,7 +1595,7 @@ void print_small_text(s32 x, s32 y, const char *str, s32 align, s32 amount, u8 f lines = 0; shakeTablePos = gGlobalTimer % sizeof(sTextShakeTable); - gDPLoadTextureBlock_4bS(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, 0, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock_4b(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, 0, G_TX_NOLOD, G_TX_NOLOD); for (s32 i = 0, j = 0; i < textLength; i++, j++) { if (str[i] == '\n') { @@ -1717,7 +1717,7 @@ void print_small_text_light(s32 x, s32 y, const char *str, s32 align, s32 amount } lines = 0; - gDPLoadTextureBlock_4bS(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, 0, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, G_TX_NOLOD, G_TX_NOLOD); + gDPLoadTextureBlock_4b(gDisplayListHead++, fnt->tex, fnt->fmt, fnt->imW, fnt->imH, (G_TX_NOMIRROR | G_TX_CLAMP), (G_TX_NOMIRROR | G_TX_CLAMP), 0, 0, 0, G_TX_NOLOD, G_TX_NOLOD); for (s32 i = 0, j = 0; i < textLength; i++, j++) { if (str[i] == '\n') { From 8ac2d56d6aec2c8eb491168e8584df8beb4a27c7 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Wed, 29 Jan 2025 21:26:11 -0500 Subject: [PATCH 5/7] finalize unrebase --- textures/fasttext/newfont2.ia4.preswap.png | Bin 1334 -> 0 bytes textures/segment2/custom_text.i4.preswap.png | Bin 1308 -> 0 bytes textures/segment2/custom_text2.ia4.preswap.png | Bin 1329 -> 0 bytes textures/segment2/custom_text3.i4.preswap.png | Bin 776 -> 0 bytes textures/segment2/custom_text4.i4.preswap.png | Bin 848 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 textures/fasttext/newfont2.ia4.preswap.png delete mode 100644 textures/segment2/custom_text.i4.preswap.png delete mode 100644 textures/segment2/custom_text2.ia4.preswap.png delete mode 100644 textures/segment2/custom_text3.i4.preswap.png delete mode 100644 textures/segment2/custom_text4.i4.preswap.png diff --git a/textures/fasttext/newfont2.ia4.preswap.png b/textures/fasttext/newfont2.ia4.preswap.png deleted file mode 100644 index 590447e4d5b8607748d3a7071584c2a31cc08cb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1334 zcmV-61Px#1ZP1_K>z@;j|==^1poj52~bQ_MO9T*|Ns90001W_y!rqD00VSVPE-H?0N2V5 zK>z>%32;bRa{vGi!2kdb!2!6DYwZ941gA+vK~!i%?Np0$961Q|`u{&V^a~-)ti9P> z%2!v{6$CU5XlBRx_%uF<&(FsJmkX-%NZ#k_WAY8wjQ{cb_>aE5dMv=7QR9OJ)E`x> zz~i>jcW887eJlZIkg3ePwtL?3vUk4=k>VzKyj3S<(m%_eb{LMMVzSjq^|jaO8x~j zhgT^j0*rUwycne{3^()k+Pb`W%`YIG`sDN##IJgc1l|+;;I*g1N)}&7JJr6(D|p?c zuU&OwHGy||V&m9()lUuLJN_-aIiT9cV=nN;V>e0l!VnMaW-_(}#a*z?NIzzQDb?DJF8U_!5SVZusx5 zkhzyy<}iR#KI;p3S9uHCKXVa#JvqGIDm)(wKwReEMLcrxXmfw&-R(&($2m{Tb7O8W zm<~{}%2xq4*M44rlZ_QBvK)_3ry8nzPJLw>2VQ4+Qfk0Ms7@#*uZbd;mrhfbC%;TG zYd79ga~legH-m|J1z^`}iw=3bjp-$4;OFpp7zKG97awpG?(vOhF!>5p_aNMXc@-3k zX=< zu2*#!_rOX-Ij3{j@vu4nG>y+*vbVa6c~^JswRPG^h~43G_7pgIo(Oo$`vD?|jTTuesGZ2SAL1_1ss1^n7nCAHKjD0LD+K z(?!61gL^f&+>&Cj0<76SQ0_a%cAh@Y!*q645O1EEkuM(X=#M9xDx-pD$WHz6(x^)* za$6I({AnymcRSB{ZrZu3#g+sIGAVLWh?#)<#JjycczXi2YKbFOdW0L z%JqEIIEQHlNY7dYq|qlm{o*wzU^;+F&^63Aijo2+14Hw<2dU-I6XApOx=lodatq-j z={#QS%I$fO&R)EslpC9VctULozh%Cg6a0t{(>KuXpRd63@jvMO1^)I|^K9== s;@@y5+~J?N#T@b{1E2N!Gcq2JUqxRcOwRY=3;+NC07*qoM6N<$f*)m*s{jB1 diff --git a/textures/segment2/custom_text.i4.preswap.png b/textures/segment2/custom_text.i4.preswap.png deleted file mode 100644 index bc2425b587b0b63fd7947b0e0112e79d9ec9af2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1308 zcmV+%1>^dOP)~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj53{Xr|MF0Q*r>Cd?|Nl=z>%32;bRa{vGi z!vFvd!vV){sAK>D1er-hK~z}7&6f>wBPk4p1zZ5|1pr-uCilPFz9-Qgx8tN{cc-QX zR~v`sM|^q`L|E#qbL=9!)QPV$rJ#Cl|12rX-(1%BufnLaqmJ0Y8cq1S|Bt2O$l>Cb z#=HStS(+T(>> z7f?y>f%e)B{7-AF?Y2j%dIQRGHe|)ZB~11NTuFTcO|MHHvb1LMI`YyI$Q;C2tv-vy zwsN)4IbuX~4hoObiz9-Goig5aQIuG;0)X5)&31o%swf!YxJ9Vj2^%@elSp8fIhIIFK*L~?|?SEUoBX3 z=r&OpjWEQVdKQf&!;!(ol<^fjiLX+XCfePy`nm|QPpcU;a>5|HZkWalO^rF&MP8R0;@D=BQlkz%&o+@1r zIxklPOs8Ny;47HP?OXUAxK<=?QLa_xN1!w^lx*=bwoKVxcOI={C&kG3C(xQB!?6P> zB#2gXfQ9E{d&dA^eWVojtp+k(K)E>&{S8#TT~(WQD1`#TD627dq_;OvfRY#hlnz^% zIh?tAZQvf}1kXts%50A((6ZNBw1=pIsk86YKrx&^?Gqj=@jR%QA?XXy{sL5Sz`z5q zK))#TcmkU2WI{L+XzG!f6q{QQ9#&5$QK9_^_k6Sy=-A-|DE+3;ZJO5BbS(qQzFtpT z?*tmCrBw^liEYqD!#r#6i?}K+JekJFx&a+}2g-CYCZoV_15)(@O4r7998S5o5^g|0 z?m)wlwMadz?Wd4$mbg8KQh89Rs~A9)tUbqGr=GYJnGRr_(vFvqFE^ku`zGUT5d02x zW2N+%jo3hwHVJh->_`HjEgG&bJ55}*3n<%Bb*Xl{4&1IyA~&GXLW)-yUOk6}BVq1qXr_hs zzRwFNZ&r~03S6d+R{hkSzS!vJwFw6;a~>5BaMB2m`I!Au^)TjG%lE7+Q(0(>3<0$6 zG*icF1@HZo=NvXMZ)ikhKrtPDSLAgE%632HKY?;P*eDh2Yr%2F9Ln3@>nShaNLJol z>_3keIpp7!IOR8$sPYGjUod~R`suj+HK4EmdWNUVZTn9K{+9Ar{>$t1#`p(aQN;qW SV`XOm0000Px#1ZP1_K>z@;j|==^1poj52~bQ_MO9T*|Ns90001W_y!rqD00VSVPE-H?0N2V5 zK>z>%32;bRa{vGi!Tw zkOdTRqTWee^8=Oq6KD>v!dvnJ$(t9Wl!f7D-d~35-R%R_z}H}hZ&Tx{iQ}Ey@&e3(TYQ*?w^u)d*F7{~`n|@J z4`hx+9oc8|TYb~!`5kL5JRS_de);6O=crqdzUX-v8?Qf$bsHQB*Vmk}CqnJp`tPP0 zh=KO_wI-m#nuhrXy6V72CYJGn3b1DNLB8n>rv)|Wv7yujC{k`;2mCfQ7a{*JP9OfI z0b6c;`vUjorkKdZ;!7Ady5YaJLgqednZp1|`K&MCt?~-mKXVa#9XWdC&FhZ>%##X_ zT)gM>yq+TqFQN54^JeL{cZ0!nfQnUq3b48M^8%b`tWc5V`19#hLv_!ouT0~>>nu-7 z4Y<7OgktiVC~|q}G-Y}6%OtaQ<2^OEp%8g9n3yL3yPhpN# zfTM7aFFXT!jl~qzdyMlc;6CO{Cwwr zPP0$_X4V}Xea~GrO^#=f8)3h)!1byQUgH!yXA(?|U&sCHju8`Uw`a+ddhgX&!9+>OX-Ij3{j@vu4nG>y+*vRB>1 zysNwR+B$6{#BTg)*Lk+ww7EL$HrsRs%mn;JwRiiw|0Vc^I{uF@;LoV>csTP7(--LX&sSji_!sp4dHn6K n=GESRiJy3~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj522e~?MF0Q*|NsA`*`M72000SaNLh0L01m?d01m?e z$8V@)0007uNklZ;`1{9(&5jCIvW4`zEWj^QnKNAmfO-E}LWY}hs0<^OSr2E0wdfIG!=Kj1cXONY#4;f1(5{=%NJo@FQT8L(g z&TWwIb|&ES$MhReLl|j5ccf#F!VUM3!nm$==V;RbrTu9Kgm60k1j^{@SI7~lP$GAr zYOOQJB^3Qq4a|=!VJ$rRD4kbT{SnNPu}w4NU^&Z4kf)9q>I0~b zdU^uQJTA4*3(BXavwj^bJbm)F9ulX>ZOvAf!yC{DYi6Jkm(r=tr+lFXqF1x6e6(9YXD5sE z;9~0zROqiw9t^2a`SbCUYuoq>|7`G$e{a~00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj522e~?MF0Q*|NsA`*`M72000SaNLh0L01m+b01m+c zxRGn^0008hNkl{_Mxv<-!pH#6vWW?F(+U zco{FpuJ|b}>g@mZ_G*3`<`2Cz_%?U|-7q)Qd!W0a(Gk4@r_WugJ)4A&?{;)Me&^Xe zvhJs1zuR$NyF~P9{hTBSKl;MY8~ex$mlwa-7vJ%L*oXQ@pxEgO)HvqPKw~0^6yJ|K zgY#2c_6o`i)_G#>_z1+Tx6>uu8&~^*JE(lIZFyh$l>sQbi;sT-_#2=*pau%A^CzI3 z*eM%e2G`aOHGBkCl?^q4B4HD#+XR}s=LIM`b8lGV1+15u+yOo9*YtTI;CDbV4VgJP z_B)_Rku8Lf;PSV(DiA1Jj)enzyaI&)h1>}g^o0V2MmdQ@I}H2Xj)yFYG#{6L1Jop- z0rX`FO@Our9?4sIn(bnVlrsCh0fzsc08YDHAE49&=P_ryhUO+fGfkBacplah@UUm$5de^sA#`^%NCozH>qFcFTimtw5c-zD`i|7Io4JP05XJ zLjVfsg3Vj9Re;Ljd-A3gn^{C(1*(Uf+03#!HyL4NA9^eW6^kr&*~b~nD~mIQub-U_ z)Kl3$WT*hmb2Fg70V?1yw*CYP&Cn~*)JXxlYy!mt&{QH@b_ Date: Wed, 29 Jan 2025 21:59:23 -0500 Subject: [PATCH 6/7] move defines to a more suitable file --- include/sm64.h | 4 ++++ src/game/mario.h | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/sm64.h b/include/sm64.h index f9c44cd092..040ebd23de 100644 --- a/include/sm64.h +++ b/include/sm64.h @@ -262,6 +262,10 @@ enum MarioActionFlags { ACT_FLAG_THROWING = /* 0x80000000 */ (1 << 31), }; +/* State Machine Results */ +#define ACTION_CONTINUE TRUE // Continues running action logic, e.g. after Mario's action changes +#define ACTION_FINISH FALSE // Finishes running action logic for the current frame + #define ACT_UNINITIALIZED 0x00000000 // (0x000) // group 0x000: stationary actions diff --git a/src/game/mario.h b/src/game/mario.h index f640a0b6ab..cb2df1a1e1 100644 --- a/src/game/mario.h +++ b/src/game/mario.h @@ -6,11 +6,6 @@ #include "macros.h" #include "types.h" -// Continues running action logic, e.g. after Mario's action changes -#define ACTION_CONTINUE TRUE -// Finishes running action logic for the current frame -#define ACTION_FINISH FALSE - s32 is_anim_at_end(struct MarioState *m); s32 is_anim_past_end(struct MarioState *m); s16 set_mario_animation(struct MarioState *m, s32 targetAnimID); From 8c140d82f57906b4e59bfdee4ce32c3a1a845e12 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sun, 16 Feb 2025 09:21:03 -0500 Subject: [PATCH 7/7] oopsies! :P --- src/game/mario_actions_stationary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index 59815bdb3f..dc89d6da8e 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -1088,7 +1088,7 @@ s32 mario_execute_stationary_action(struct MarioState *m) { } if (mario_update_quicksand(m, 0.5f)) { - return ACTION_FINISH; + return ACTION_CONTINUE; } /* clang-format off */